From edbc7960bef7fd71ef1e44d0df15b864784b14c8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 19 May 2022 01:38:44 +0200 Subject: [PATCH 001/942] drm/bridge: ti-sn65dsi83: Handle dsi_lanes == 0 as invalid Handle empty data-lanes = < >; property, which translates to dsi_lanes = 0 as invalid. Fixes: ceb515ba29ba6 ("drm/bridge: ti-sn65dsi83: Add TI SN65DSI83 and SN65DSI84 driver") Signed-off-by: Marek Vasut Cc: Jonas Karlman Cc: Laurent Pinchart Cc: Lucas Stach Cc: Marek Vasut Cc: Maxime Ripard Cc: Neil Armstrong Cc: Robert Foss Cc: Sam Ravnborg Reviewed-by: Andrzej Hajda Reviewed-by: Lucas Stach Link: https://patchwork.freedesktop.org/patch/msgid/20220518233844.248504-1-marex@denx.de --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 19daaddd29a41..3d58110465fe9 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -573,7 +573,7 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) ctx->host_node = of_graph_get_remote_port_parent(endpoint); of_node_put(endpoint); - if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4) { + if (ctx->dsi_lanes <= 0 || ctx->dsi_lanes > 4) { ret = -EINVAL; goto err_put_node; } -- GitLab From 6e516faf04317db2c46cbec4e3b78b4653a5b109 Mon Sep 17 00:00:00 2001 From: Steven Price Date: Thu, 19 May 2022 16:20:03 +0100 Subject: [PATCH 002/942] drm/panfrost: Job should reference MMU not file_priv For a while now it's been allowed for a MMU context to outlive it's corresponding panfrost_priv, however the job structure still references panfrost_priv to get hold of the MMU context. If panfrost_priv has been freed this is a use-after-free which I've been able to trigger resulting in a splat. To fix this, drop the reference to panfrost_priv in the job structure and add a direct reference to the MMU structure which is what's actually needed. Fixes: 7fdc48cc63a3 ("drm/panfrost: Make sure MMU context lifetime is not bound to panfrost_priv") Signed-off-by: Steven Price Acked-by: Alyssa Rosenzweig Link: https://patchwork.freedesktop.org/patch/msgid/20220519152003.81081-1-steven.price@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 5 +++-- drivers/gpu/drm/panfrost/panfrost_job.c | 6 +++--- drivers/gpu/drm/panfrost/panfrost_job.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 94b6f0a19c83a..47780fe597f23 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -233,6 +233,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *file) { struct panfrost_device *pfdev = dev->dev_private; + struct panfrost_file_priv *file_priv = file->driver_priv; struct drm_panfrost_submit *args = data; struct drm_syncobj *sync_out = NULL; struct panfrost_job *job; @@ -262,12 +263,12 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, job->jc = args->jc; job->requirements = args->requirements; job->flush_id = panfrost_gpu_get_latest_flush_id(pfdev); - job->file_priv = file->driver_priv; + job->mmu = file_priv->mmu; slot = panfrost_job_get_slot(job); ret = drm_sched_job_init(&job->base, - &job->file_priv->sched_entity[slot], + &file_priv->sched_entity[slot], NULL); if (ret) goto out_put_job; diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index a6925dbb6224f..22c2af1a4627d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -201,7 +201,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) return; } - cfg = panfrost_mmu_as_get(pfdev, job->file_priv->mmu); + cfg = panfrost_mmu_as_get(pfdev, job->mmu); job_write(pfdev, JS_HEAD_NEXT_LO(js), lower_32_bits(jc_head)); job_write(pfdev, JS_HEAD_NEXT_HI(js), upper_32_bits(jc_head)); @@ -431,7 +431,7 @@ static void panfrost_job_handle_err(struct panfrost_device *pfdev, job->jc = 0; } - panfrost_mmu_as_put(pfdev, job->file_priv->mmu); + panfrost_mmu_as_put(pfdev, job->mmu); panfrost_devfreq_record_idle(&pfdev->pfdevfreq); if (signal_fence) @@ -452,7 +452,7 @@ static void panfrost_job_handle_done(struct panfrost_device *pfdev, * happen when we receive the DONE interrupt while doing a GPU reset). */ job->jc = 0; - panfrost_mmu_as_put(pfdev, job->file_priv->mmu); + panfrost_mmu_as_put(pfdev, job->mmu); panfrost_devfreq_record_idle(&pfdev->pfdevfreq); dma_fence_signal_locked(job->done_fence); diff --git a/drivers/gpu/drm/panfrost/panfrost_job.h b/drivers/gpu/drm/panfrost/panfrost_job.h index 77e6d0e6f612f..8becc1ba0eb95 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.h +++ b/drivers/gpu/drm/panfrost/panfrost_job.h @@ -17,7 +17,7 @@ struct panfrost_job { struct kref refcount; struct panfrost_device *pfdev; - struct panfrost_file_priv *file_priv; + struct panfrost_mmu *mmu; /* Fence to be signaled by IRQ handler when the job is complete. */ struct dma_fence *done_fence; -- GitLab From 743cdb7bd0f1cb32c03680c8b38257957db2e692 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 19 May 2022 17:45:21 +1000 Subject: [PATCH 003/942] powerpc/kasan: Mark more real-mode code as not to be instrumented This marks more files and functions that can possibly be called in real mode as not to be instrumented by KASAN. Most were found by inspection, except for get_pseries_errorlog() which was reported as causing a crash in testing. Reported-by: Nageswara R Sastry Signed-off-by: Paul Mackerras Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/YoX1kZPnmUX4RZEK@cleo --- arch/powerpc/kernel/Makefile | 2 ++ arch/powerpc/kernel/rtas.c | 4 ++-- arch/powerpc/kexec/crash.c | 2 +- arch/powerpc/platforms/powernv/Makefile | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2e2a2a9bcf43f..f91f0f29a566a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -37,6 +37,8 @@ KASAN_SANITIZE_paca.o := n KASAN_SANITIZE_setup_64.o := n KASAN_SANITIZE_mce.o := n KASAN_SANITIZE_mce_power.o := n +KASAN_SANITIZE_udbg.o := n +KASAN_SANITIZE_udbg_16550.o := n # we have to be particularly careful in ppc64 to exclude code that # runs with translations off, as we cannot access the shadow with diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 9bb43aa53d43e..a6fce3106e02b 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -993,8 +993,8 @@ int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...) * * Return: A pointer to the specified errorlog or NULL if not found. */ -struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log, - uint16_t section_id) +noinstr struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log, + uint16_t section_id) { struct rtas_ext_event_log_v6 *ext_log = (struct rtas_ext_event_log_v6 *)log->buffer; diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c index d85fa9fc6f3ca..80f54723cf6d1 100644 --- a/arch/powerpc/kexec/crash.c +++ b/arch/powerpc/kexec/crash.c @@ -224,7 +224,7 @@ void crash_kexec_secondary(struct pt_regs *regs) /* wait for all the CPUs to hit real mode but timeout if they don't come in */ #if defined(CONFIG_SMP) && defined(CONFIG_PPC64) -static void __maybe_unused crash_kexec_wait_realmode(int cpu) +noinstr static void __maybe_unused crash_kexec_wait_realmode(int cpu) { unsigned int msecs; int i; diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 6488b38421999..19f0fc5c6f1b4 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -4,6 +4,7 @@ # in particular, idle code runs a bunch of things in real mode KASAN_SANITIZE_idle.o := n KASAN_SANITIZE_pci-ioda.o := n +KASAN_SANITIZE_pci-ioda-tce.o := n # pnv_machine_check_early KASAN_SANITIZE_setup.o := n -- GitLab From a1b29ba2f2c171b9bea73be993bfdf0a62d37d15 Mon Sep 17 00:00:00 2001 From: He Ying Date: Thu, 20 Jan 2022 20:44:18 -0500 Subject: [PATCH 004/942] powerpc/kasan: Silence KASAN warnings in __get_wchan() The following KASAN warning was reported in our kernel. BUG: KASAN: stack-out-of-bounds in get_wchan+0x188/0x250 Read of size 4 at addr d216f958 by task ps/14437 CPU: 3 PID: 14437 Comm: ps Tainted: G O 5.10.0 #1 Call Trace: [daa63858] [c0654348] dump_stack+0x9c/0xe4 (unreliable) [daa63888] [c035cf0c] print_address_description.constprop.3+0x8c/0x570 [daa63908] [c035d6bc] kasan_report+0x1ac/0x218 [daa63948] [c00496e8] get_wchan+0x188/0x250 [daa63978] [c0461ec8] do_task_stat+0xce8/0xe60 [daa63b98] [c0455ac8] proc_single_show+0x98/0x170 [daa63bc8] [c03cab8c] seq_read_iter+0x1ec/0x900 [daa63c38] [c03cb47c] seq_read+0x1dc/0x290 [daa63d68] [c037fc94] vfs_read+0x164/0x510 [daa63ea8] [c03808e4] ksys_read+0x144/0x1d0 [daa63f38] [c005b1dc] ret_from_syscall+0x0/0x38 --- interrupt: c00 at 0x8fa8f4 LR = 0x8fa8cc The buggy address belongs to the page: page:98ebcdd2 refcount:0 mapcount:0 mapping:00000000 index:0x2 pfn:0x1216f flags: 0x0() raw: 00000000 00000000 01010122 00000000 00000002 00000000 ffffffff 00000000 raw: 00000000 page dumped because: kasan: bad access detected Memory state around the buggy address: d216f800: 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 00 00 00 d216f880: f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >d216f900: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 ^ d216f980: f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 d216fa00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 After looking into this issue, I find the buggy address belongs to the task stack region. It seems KASAN has something wrong. I look into the code of __get_wchan in x86 architecture and find the same issue has been resolved by the commit f7d27c35ddff ("x86/mm, kasan: Silence KASAN warnings in get_wchan()"). The solution could be applied to powerpc architecture too. As Andrey Ryabinin said, get_wchan() is racy by design, it may access volatile stack of running task, thus it may access redzone in a stack frame and cause KASAN to warn about this. Use READ_ONCE_NOCHECK() to silence these warnings. Reported-by: Wanming Hu Signed-off-by: He Ying Signed-off-by: Chen Jingwen Reviewed-by: Kees Cook Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220121014418.155675-1-heying24@huawei.com --- arch/powerpc/kernel/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index d00b20c659667..ca4d97688da90 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -2157,12 +2157,12 @@ static unsigned long ___get_wchan(struct task_struct *p) return 0; do { - sp = *(unsigned long *)sp; + sp = READ_ONCE_NOCHECK(*(unsigned long *)sp); if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD) || task_is_running(p)) return 0; if (count > 0) { - ip = ((unsigned long *)sp)[STACK_FRAME_LR_SAVE]; + ip = READ_ONCE_NOCHECK(((unsigned long *)sp)[STACK_FRAME_LR_SAVE]); if (!in_sched_functions(ip)) return ip; } -- GitLab From 1346d00e1bdfd4067f92bc14e8a6131a01de4190 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 25 May 2022 13:26:39 +1000 Subject: [PATCH 005/942] powerpc: Don't select HAVE_IRQ_EXIT_ON_IRQ_STACK The HAVE_IRQ_EXIT_ON_IRQ_STACK option tells generic code that irq_exit() is called while still running on the hard irq stack (hardirq_ctx[] in the powerpc code). Selecting the option means the generic code will *not* switch to the softirq stack before running softirqs, because the code is already running on the (mostly empty) hard irq stack. But since commit 1b1b6a6f4cc0 ("powerpc: handle irq_enter/irq_exit in interrupt handler wrappers"), irq_exit() is now called on the regular task stack, not the hard irq stack. That's because previously irq_exit() was called in __do_irq() which is run on the hard irq stack, but now it is called in interrupt_async_exit_prepare() which is called from do_irq() constructed by the wrapper macro, which is after the switch back to the task stack. So drop HAVE_IRQ_EXIT_ON_IRQ_STACK from the Kconfig. This will mean an extra stack switch when processing some interrupts, but should significantly reduce the likelihood of stack overflow. It also means the softirq stack will be used for running softirqs from other interrupts that don't use the hard irq stack, eg. timer interrupts. Fixes: 1b1b6a6f4cc0 ("powerpc: handle irq_enter/irq_exit in interrupt handler wrappers") Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220525032639.1947280-1-mpe@ellerman.id.au --- arch/powerpc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3eaddb8997a92..54dbbb1d4b366 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -223,7 +223,6 @@ config PPC select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx) select HAVE_IOREMAP_PROT - select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_IRQ_TIME_ACCOUNTING select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE -- GitLab From 9ff9f77f34e44a0054eadb9041e459548c955ccb Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 24 May 2022 06:31:54 -0400 Subject: [PATCH 006/942] MAINTAINERS: reciprocal co-maintainership for file locking and nfsd Chuck has agreed to backstop me as maintainer of the file locking code, and I'll do the same for him on knfsd. Signed-off-by: Jeff Layton Signed-off-by: Chuck Lever --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d6d879cb0afd5..82f89b035cce0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7572,6 +7572,7 @@ F: include/uapi/scsi/fc/ FILE LOCKING (flock() and fcntl()/lockf()) M: Jeff Layton +M: Chuck Lever L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/fcntl.c @@ -10646,6 +10647,7 @@ W: http://kernelnewbies.org/KernelJanitors KERNEL NFSD, SUNRPC, AND LOCKD SERVERS M: Chuck Lever +M: Jeff Layton L: linux-nfs@vger.kernel.org S: Supported W: http://nfs.sourceforge.net/ -- GitLab From 07bf9431b1590d1cd7a8d62075d0b50b073f0495 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Tue, 24 May 2022 16:53:53 +0530 Subject: [PATCH 007/942] powerpc/papr_scm: don't requests stats with '0' sized stats buffer Sachin reported [1] that on a POWER-10 lpar he is seeing a kernel panic being reported with vPMEM when papr_scm probe is being called. The panic is of the form below and is observed only with following option disabled(profile) for the said LPAR 'Enable Performance Information Collection' in the HMC: Kernel attempted to write user page (1c) - exploit attempt? (uid: 0) BUG: Kernel NULL pointer dereference on write at 0x0000001c Faulting instruction address: 0xc008000001b90844 Oops: Kernel access of bad area, sig: 11 [#1] NIP [c008000001b90844] drc_pmem_query_stats+0x5c/0x270 [papr_scm] LR [c008000001b92794] papr_scm_probe+0x2ac/0x6ec [papr_scm] Call Trace: 0xc00000000941bca0 (unreliable) papr_scm_probe+0x2ac/0x6ec [papr_scm] platform_probe+0x98/0x150 really_probe+0xfc/0x510 __driver_probe_device+0x17c/0x230 ---[ end trace 0000000000000000 ]--- Kernel panic - not syncing: Fatal exception On investigation looks like this panic was caused due to a 'stat_buffer' of size==0 being provided to drc_pmem_query_stats() to fetch all performance stats-ids of an NVDIMM. However drc_pmem_query_stats() shouldn't have been called since the vPMEM NVDIMM doesn't support and performance stat-id's. This was caused due to missing check for 'p->stat_buffer_len' at the beginning of papr_scm_pmu_check_events() which indicates that the NVDIMM doesn't support performance-stats. Fix this by introducing the check for 'p->stat_buffer_len' at the beginning of papr_scm_pmu_check_events(). [1] https://lore.kernel.org/all/6B3A522A-6A5F-4CC9-B268-0C63AA6E07D3@linux.ibm.com Fixes: 0e0946e22f3665d2732 ("powerpc/papr_scm: Fix leaking nvdimm_events_map elements") Reported-by: Sachin Sant Signed-off-by: Vaibhav Jain Tested-by: Sachin Sant Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220524112353.1718454-1-vaibhav@linux.ibm.com --- arch/powerpc/platforms/pseries/papr_scm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 181b855b30509..82cae08976bcd 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -465,6 +465,9 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu u32 available_events; int index, rc = 0; + if (!p->stat_buffer_len) + return -ENOENT; + available_events = (p->stat_buffer_len - sizeof(struct papr_scm_perf_stats)) / sizeof(struct papr_scm_perf_stat); if (available_events == 0) -- GitLab From 291e7d52d19f114cad6cbf802f3f19ef12a011f8 Mon Sep 17 00:00:00 2001 From: Ben Chuang Date: Fri, 20 May 2022 19:42:42 +0800 Subject: [PATCH 008/942] mmc: sdhci-pci-gli: Fix GL9763E runtime PM when the system resumes from suspend When the system resumes from suspend (S3 or S4), the power mode is MMC_POWER_OFF. In this status, gl9763e_runtime_resume() should not enable PLL. Add a condition to this function to enable PLL only when the power mode is MMC_POWER_ON. Fixes: d607667bb8fa (mmc: sdhci-pci-gli: Add runtime PM for GL9763E) Signed-off-by: Ben Chuang Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220520114242.150235-1-benchuanggli@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-gli.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 1499a64ec3aa1..f13c08db3da5f 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -982,6 +982,9 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip) struct sdhci_host *host = slot->host; u16 clock; + if (host->mmc->ios.power_mode != MMC_POWER_ON) + return 0; + clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL); clock |= SDHCI_CLOCK_PLL_EN; -- GitLab From 5f92df8ddacb4b97f6865a3bf687f240072f4f68 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 31 May 2022 08:54:02 -0700 Subject: [PATCH 009/942] Input: raspberrypi-ts - add missing HAS_IOMEM dependency Since JOYSTICK_SENSEHAT selects MFD_SIMPLE_MFD_I2C and the latter depends on HAS_IOMEM, and since 'select' does not follow any dependency chains, JOYSTICK_SENSEHAT should also depend on HAS_IOMEM to prevent a kconfig warning and a build error: WARNING: unmet direct dependencies detected for MFD_SIMPLE_MFD_I2C Depends on [n]: HAS_IOMEM [=n] && I2C [=y] Selected by [y]: - JOYSTICK_SENSEHAT [=y] && INPUT_JOYSTICK [=y] && INPUT [=y] && I2C [=y] s390-linux-ld: drivers/mfd/simple-mfd-i2c.o: in function `simple_mfd_i2c_probe': simple-mfd-i2c.c:(.text+0xc8): undefined reference to `devm_mfd_add_devices' Fixes: 41657514c796 ("Input: add Raspberry Pi Sense HAT joystick driver") Signed-off-by: Randy Dunlap Link: https://lore.kernel.org/r/20220531022942.16340-1-rdunlap@infradead.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 505a032e2786d..9dcf3f51f2dd9 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -402,6 +402,7 @@ config JOYSTICK_N64 config JOYSTICK_SENSEHAT tristate "Raspberry Pi Sense HAT joystick" depends on INPUT && I2C + depends on HAS_IOMEM select MFD_SIMPLE_MFD_I2C help Say Y here if you want to enable the driver for the -- GitLab From a051246b786af7e4a9d9219cc7038a6e8a411531 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 31 May 2022 20:19:22 +0300 Subject: [PATCH 010/942] mmc: block: Fix CQE recovery reset success The intention of the use of mmc_blk_reset_success() in mmc_blk_cqe_recovery() was to prevent repeated resets when retrying and getting the same error. However, that may not be the case - any amount of time and I/O may pass before another recovery is needed, in which case there would be no reason to deny it the opportunity to recover via a reset if necessary. CQE recovery is expected seldom and failure to recover (if the clear tasks command fails), even more seldom, so it is better to allow the reset always, which can be done by calling mmc_blk_reset_success() always. Fixes: 1e8e55b67030c6 ("mmc: block: Add CQE support") Cc: stable@vger.kernel.org Signed-off-by: Adrian Hunter Link: https://lore.kernel.org/r/20220531171922.76080-1-adrian.hunter@intel.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 1259ca22d6250..f4a1281658db0 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1499,8 +1499,7 @@ void mmc_blk_cqe_recovery(struct mmc_queue *mq) err = mmc_cqe_recovery(host); if (err) mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY); - else - mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); + mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); pr_debug("%s: CQE recovery done\n", mmc_hostname(host)); } -- GitLab From 282e5f8fe907dc3f2fbf9f2103b0e62ffc3a68a5 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 1 Jun 2022 10:47:35 +0200 Subject: [PATCH 011/942] netfilter: nat: really support inet nat without l3 address When no l3 address is given, priv->family is set to NFPROTO_INET and the evaluation function isn't called. Call it too so l4-only rewrite can work. Also add a test case for this. Fixes: a33f387ecd5aa ("netfilter: nft_nat: allow to specify layer 4 protocol NAT only") Reported-by: Yi Chen Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_nat.c | 3 +- tools/testing/selftests/netfilter/nft_nat.sh | 43 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c index 4394df4bc99b4..e5fd6995e4bf3 100644 --- a/net/netfilter/nft_nat.c +++ b/net/netfilter/nft_nat.c @@ -335,7 +335,8 @@ static void nft_nat_inet_eval(const struct nft_expr *expr, { const struct nft_nat *priv = nft_expr_priv(expr); - if (priv->family == nft_pf(pkt)) + if (priv->family == nft_pf(pkt) || + priv->family == NFPROTO_INET) nft_nat_eval(expr, regs, pkt); } diff --git a/tools/testing/selftests/netfilter/nft_nat.sh b/tools/testing/selftests/netfilter/nft_nat.sh index eb8543b9a5c40..924ecb3f1f737 100755 --- a/tools/testing/selftests/netfilter/nft_nat.sh +++ b/tools/testing/selftests/netfilter/nft_nat.sh @@ -374,6 +374,45 @@ EOF return $lret } +test_local_dnat_portonly() +{ + local family=$1 + local daddr=$2 + local lret=0 + local sr_s + local sr_r + +ip netns exec "$ns0" nft -f /dev/stdin < Date: Wed, 1 Jun 2022 16:00:00 +0200 Subject: [PATCH 012/942] netfilter: nf_tables: use kfree_rcu(ptr, rcu) to release hooks in clean_net path Use kfree_rcu(ptr, rcu) variant instead as described by ae089831ff28 ("netfilter: nf_tables: prefer kfree_rcu(ptr, rcu) variant"). Fixes: f9a43007d3f7 ("netfilter: nf_tables: double hook unregistration in netns path") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 746be13438eff..129d3ebd6ce5d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -7332,7 +7332,7 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net, nf_unregister_net_hook(net, &hook->ops); if (release_netdev) { list_del(&hook->list); - kfree_rcu(hook); + kfree_rcu(hook, rcu); } } } -- GitLab From 479260419fa4cb30e3e5d935a857fbdf0ffdd854 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 25 May 2022 20:42:04 -0500 Subject: [PATCH 013/942] dt-bindings: mmc: Fix unevaluatedProperties warnings in examples The 'unevaluatedProperties' schema checks is not fully working and doesn't catch some cases where there's a $ref to another schema. A fix is pending, but results in new warnings in examples. Fix the warnings by removing spurious properties or adding a missing property to the schema. Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220526014204.2873107-1-robh@kernel.org Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml | 2 -- Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml index b672202fff4e4..5ecdac9de484b 100644 --- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml +++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml @@ -75,7 +75,6 @@ examples: sd-uhs-sdr104; sdhci,auto-cmd12; interrupts = <0x0 0x26 0x4>; - interrupt-names = "sdio0_0"; clocks = <&scmi_clk 245>; clock-names = "sw_sdio"; }; @@ -94,7 +93,6 @@ examples: non-removable; bus-width = <0x8>; interrupts = <0x0 0x27 0x4>; - interrupt-names = "sdio1_0"; clocks = <&scmi_clk 245>; clock-names = "sw_sdio"; }; diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml index c79639e9027ed..aca1a4a8daea2 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml @@ -56,6 +56,9 @@ properties: - const: core - const: axi + interrupts: + maxItems: 1 + marvell,xenon-sdhc-id: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 -- GitLab From 4b81dd2cc6f4f4e8cea0ed6ee8d5193a8ae14a72 Mon Sep 17 00:00:00 2001 From: Sherry Wang Date: Tue, 10 May 2022 18:42:18 +0800 Subject: [PATCH 014/942] drm/amd/display: Read Golden Settings Table from VBIOS [Why] Dmub read AUX_DPHY_RX_CONTROL0 from Golden Setting Table, but driver will set it to default value 0x103d1110, which causes issue in some case [How] Remove the driver code, use the value set by dmub in dp_aux_init Reviewed-by: Nicholas Kazlauskas Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Sherry Wang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c index d94fd1010debc..8b12b4111c887 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c @@ -230,9 +230,7 @@ static void enc31_hw_init(struct link_encoder *enc) AUX_RX_PHASE_DETECT_LEN, [21,20] = 0x3 default is 3 AUX_RX_DETECTION_THRESHOLD [30:28] = 1 */ - AUX_REG_WRITE(AUX_DPHY_RX_CONTROL0, 0x103d1110); - - AUX_REG_WRITE(AUX_DPHY_TX_CONTROL, 0x21c7a); + // dmub will read AUX_DPHY_RX_CONTROL0/AUX_DPHY_TX_CONTROL from vbios table in dp_aux_init //AUX_DPHY_TX_REF_CONTROL'AUX_TX_REF_DIV HW default is 0x32; // Set AUX_TX_REF_DIV Divider to generate 2 MHz reference from refclk -- GitLab From 0ec744084793db817990424cc3cc9da63f665f3f Mon Sep 17 00:00:00 2001 From: "Leung, Martin" Date: Tue, 10 May 2022 12:27:08 -0400 Subject: [PATCH 015/942] drm/amd/display: revert Blank eDP on disable/enable drv why and how: Revert this change. It was causing a black screen with certain blocks Reviewed-by: George Shen Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Leung, Martin Signed-off-by: Alex Deucher --- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 8 +++++++- .../display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h | 2 ++ .../dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 5 +++-- .../dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 3 ++- drivers/gpu/drm/amd/display/dc/dc.h | 3 +++ .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 4 ---- .../gpu/drm/amd/display/dc/inc/hw/clk_mgr.h | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 18 ++++++++++++------ .../amd/display/dc/link/link_hwss_hpo_dp.c | 19 ++++++++++++++----- 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index ceb34376decbd..051322580014f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -638,8 +638,14 @@ static void dcn31_set_low_power_state(struct clk_mgr *clk_mgr_base) } } +int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base) +{ + return clk_mgr_base->clks.ref_dtbclk_khz; +} + static struct clk_mgr_funcs dcn31_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn31_update_clocks, .init_clocks = dcn31_init_clocks, .enable_pme_wa = dcn31_enable_pme_wa, @@ -719,7 +725,7 @@ void dcn31_clk_mgr_construct( } clk_mgr->base.base.dprefclk_khz = 600000; - clk_mgr->base.dccg->ref_dtbclk_khz = 600000; + clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; dce_clock_read_ss_info(&clk_mgr->base); /*if bios enabled SS, driver needs to adjust dtb clock, only enable with correct bios*/ //clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(clk_mgr_internal, clk_mgr->base.base.dprefclk_khz); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h index 961b10a494863..be06fdbd0c22e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.h @@ -51,6 +51,8 @@ void dcn31_clk_mgr_construct(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg); +int dcn31_get_dtb_ref_freq_khz(struct clk_mgr *clk_mgr_base); + void dcn31_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr_int); #endif //__DCN31_CLK_MGR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index a2ade6e93f5e8..29a3bf57b1571 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -580,6 +580,7 @@ static void dcn315_enable_pme_wa(struct clk_mgr *clk_mgr_base) static struct clk_mgr_funcs dcn315_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn315_update_clocks, .init_clocks = dcn31_init_clocks, .enable_pme_wa = dcn315_enable_pme_wa, @@ -656,9 +657,9 @@ void dcn315_clk_mgr_construct( clk_mgr->base.base.dprefclk_khz = 600000; clk_mgr->base.base.dprefclk_khz = dcn315_smu_get_dpref_clk(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; + clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; dce_clock_read_ss_info(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz); + clk_mgr->base.base.clks.ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz); clk_mgr->base.base.bw_params = &dcn315_bw_params; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c index fc3af81ed6c62..e4bb9c6193b57 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c @@ -571,6 +571,7 @@ static void dcn316_clk_mgr_helper_populate_bw_params( static struct clk_mgr_funcs dcn316_funcs = { .enable_pme_wa = dcn316_enable_pme_wa, .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, + .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, .update_clocks = dcn316_update_clocks, .init_clocks = dcn31_init_clocks, .are_clock_states_equal = dcn31_are_clock_states_equal, @@ -685,7 +686,7 @@ void dcn316_clk_mgr_construct( clk_mgr->base.base.dprefclk_khz = 600000; clk_mgr->base.base.dprefclk_khz = dcn316_smu_get_dpref_clk(&clk_mgr->base); - clk_mgr->base.dccg->ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; + clk_mgr->base.base.clks.ref_dtbclk_khz = clk_mgr->base.base.dprefclk_khz; dce_clock_read_ss_info(&clk_mgr->base); /*clk_mgr->base.dccg->ref_dtbclk_khz = dce_adjust_dp_ref_freq_for_ss(&clk_mgr->base, clk_mgr->base.base.dprefclk_khz);*/ diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3960c74482be6..4c1f977838b5b 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -416,6 +416,7 @@ struct dc_clocks { bool p_state_change_support; enum dcn_zstate_support_state zstate_support; bool dtbclk_en; + int ref_dtbclk_khz; enum dcn_pwr_state pwr_state; /* * Elements below are not compared for the purposes of @@ -719,6 +720,8 @@ struct dc_debug_options { bool apply_vendor_specific_lttpr_wa; bool extended_blank_optimization; union aux_wake_wa_options aux_wake_wa; + /* uses value at boot and disables switch */ + bool disable_dtb_ref_clk_switch; uint8_t psr_power_use_phy_fsm; enum dml_hostvm_override_opts dml_hostvm_override; }; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 287a1066b5472..616013c618a51 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -606,16 +606,12 @@ void dccg31_set_audio_dtbclk_dto( REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, 4); // 04 - DCCG_AUDIO_DTO_SEL_AUDIO_DTO_DTBCLK - - dccg->audio_dtbclk_khz = req_audio_dtbclk_khz; } else { REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_PHASE, 0); REG_WRITE(DCCG_AUDIO_DTBCLK_DTO_MODULO, 0); REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, 3); // 03 - DCCG_AUDIO_DTO_SEL_NO_AUDIO_DTO - - dccg->audio_dtbclk_khz = 0; } } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h index 46ce5a0ee4ec3..b5570aa8e39d9 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h @@ -237,6 +237,7 @@ struct clk_mgr_funcs { bool safe_to_lower); int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); + int (*get_dtb_ref_clk_frequency)(struct clk_mgr *clk_mgr); void (*set_low_power_state)(struct clk_mgr *clk_mgr); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index b2fa4de47734d..cc358a5ba5376 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -60,8 +60,17 @@ struct dccg { const struct dccg_funcs *funcs; int pipe_dppclk_khz[MAX_PIPES]; int ref_dppclk; - int dtbclk_khz[MAX_PIPES]; - int audio_dtbclk_khz; + //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ + //int audio_dtbclk_khz;/* TODO needs to be removed */ + //int ref_dtbclk_khz;/* TODO needs to be removed */ +}; + +struct dtbclk_dto_params { + const struct dc_crtc_timing *timing; + int otg_inst; + int pixclk_khz; + int req_audio_dtbclk_khz; + int num_odm_segments; int ref_dtbclk_khz; }; @@ -111,10 +120,7 @@ struct dccg_funcs { void (*set_dtbclk_dto)( struct dccg *dccg, - int dtbclk_inst, - int req_dtbclk_khz, - int num_odm_segments, - const struct dc_crtc_timing *timing); + const struct dtbclk_dto_params *params); void (*set_audio_dtbclk_dto)( struct dccg *dccg, diff --git a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c index 87972dc8443d6..ea6cf8bfce304 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_hwss_hpo_dp.c @@ -27,6 +27,7 @@ #include "core_types.h" #include "dccg.h" #include "dc_link_dp.h" +#include "clk_mgr.h" static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link) { @@ -106,14 +107,18 @@ static void setup_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) struct hpo_dp_link_encoder *link_enc = pipe_ctx->link_res.hpo_dp_link_enc; struct dccg *dccg = dc->res_pool->dccg; struct timing_generator *tg = pipe_ctx->stream_res.tg; - int odm_segment_count = get_odm_segment_count(pipe_ctx); + struct dtbclk_dto_params dto_params = {0}; enum phyd32clk_clock_source phyd32clk = get_phyd32clk_src(pipe_ctx->stream->link); + dto_params.otg_inst = tg->inst; + dto_params.pixclk_khz = pipe_ctx->stream->phy_pix_clk; + dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx); + dto_params.timing = &pipe_ctx->stream->timing; + dto_params.ref_dtbclk_khz = dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr); + dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst); dccg->funcs->enable_symclk32_se(dccg, stream_enc->inst, phyd32clk); - dccg->funcs->set_dtbclk_dto(dccg, tg->inst, pipe_ctx->stream->phy_pix_clk, - odm_segment_count, - &pipe_ctx->stream->timing); + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); stream_enc->funcs->enable_stream(stream_enc); stream_enc->funcs->map_stream_to_link(stream_enc, stream_enc->inst, link_enc->inst); } @@ -124,9 +129,13 @@ static void reset_hpo_dp_stream_encoder(struct pipe_ctx *pipe_ctx) struct hpo_dp_stream_encoder *stream_enc = pipe_ctx->stream_res.hpo_dp_stream_enc; struct dccg *dccg = dc->res_pool->dccg; struct timing_generator *tg = pipe_ctx->stream_res.tg; + struct dtbclk_dto_params dto_params = {0}; + + dto_params.otg_inst = tg->inst; + dto_params.timing = &pipe_ctx->stream->timing; stream_enc->funcs->disable(stream_enc); - dccg->funcs->set_dtbclk_dto(dccg, tg->inst, 0, 0, &pipe_ctx->stream->timing); + dccg->funcs->set_dtbclk_dto(dccg, &dto_params); dccg->funcs->disable_symclk32_se(dccg, stream_enc->inst); dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst); } -- GitLab From 8440f57532496d398a461887e56ca6f45089fbcf Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 6 May 2022 12:56:38 -0400 Subject: [PATCH 016/942] drm/amd/display: Pass the new context into disable OTG WA [Why] When enabling an HPO stream for the first time after having previously enabled a DIO stream there may be lingering DIO FIFO errors even though the DIO is no longer enabled. These can cause display clock change to hang if we don't apply the OTG disable workaround since the ramping logic is tied to OTG on. [How] The workaround wasn't being applied in the sequence of: 1 DIO stream 0 streams 1 HPO stream because current_state has no stream or planes in its context - and it's only swapped after optimize has finished. We should be using the incoming context instead to determine whether this logic is needed or not. Reviewed-by: Dmytro Laktyushkin Reviewed-by: Dmytro Laktyushkin Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 8 ++++---- .../drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 8 ++++---- .../drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 8 ++++---- drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 051322580014f..7310482b27840 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -99,13 +99,13 @@ static int dcn31_get_active_display_cnt_wa( return display_count; } -static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) +static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -211,11 +211,11 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn31_disable_otg_wa(clk_mgr_base, true); + dcn31_disable_otg_wa(clk_mgr_base, context, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn31_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn31_disable_otg_wa(clk_mgr_base, false); + dcn31_disable_otg_wa(clk_mgr_base, context, false); update_dispclk = true; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index 29a3bf57b1571..a50e1e519dffc 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -81,13 +81,13 @@ static int dcn315_get_active_display_cnt_wa( return display_count; } -static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) +static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -175,11 +175,11 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn315_disable_otg_wa(clk_mgr_base, true); + dcn315_disable_otg_wa(clk_mgr_base, context, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn315_disable_otg_wa(clk_mgr_base, false); + dcn315_disable_otg_wa(clk_mgr_base, context, false); update_dispclk = true; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c index e4bb9c6193b57..7192f30858eb4 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c @@ -112,13 +112,13 @@ static int dcn316_get_active_display_cnt_wa( return display_count; } -static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) +static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -221,11 +221,11 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn316_disable_otg_wa(clk_mgr_base, true); + dcn316_disable_otg_wa(clk_mgr_base, context, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn316_disable_otg_wa(clk_mgr_base, false); + dcn316_disable_otg_wa(clk_mgr_base, context, false); update_dispclk = true; } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index cc358a5ba5376..4c880b64f8ca1 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -120,7 +120,7 @@ struct dccg_funcs { void (*set_dtbclk_dto)( struct dccg *dccg, - const struct dtbclk_dto_params *params); + struct dtbclk_dto_params *dto_params); void (*set_audio_dtbclk_dto)( struct dccg *dccg, -- GitLab From 92909cde3235f894d7cdf59709d86e9b22f897ce Mon Sep 17 00:00:00 2001 From: hengzhou Date: Sat, 7 May 2022 09:43:08 +0800 Subject: [PATCH 017/942] drm/amd/display: Wait DMCUB to idle state before reset. [WHY] Very low rate to cause memory access issue while resetting DMCUB after the halt command was sent to it. The process of stopping fw of DMCUB may be timeout, that means it is not in idle state, such as the window frames may still be kept in cache, so reset by force will cause MMHUB hang. [HOW] After the halt command was sent, keep checking the DMCUB state until it is idle. Reviewed-by: Eric Yang Reviewed-by: Nicholas Kazlauskas Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: hengzhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h | 2 +- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 9 ++++++++- drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index 4c880b64f8ca1..c7021915bac88 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -62,7 +62,7 @@ struct dccg { int ref_dppclk; //int dtbclk_khz[MAX_PIPES];/* TODO needs to be removed */ //int audio_dtbclk_khz;/* TODO needs to be removed */ - //int ref_dtbclk_khz;/* TODO needs to be removed */ + int ref_dtbclk_khz;/* TODO needs to be removed */ }; struct dtbclk_dto_params { diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 7c9330a61ac1b..8d45748957576 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -84,7 +84,7 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) { union dmub_gpint_data_register cmd; const uint32_t timeout = 100; - uint32_t in_reset, scratch, i; + uint32_t in_reset, scratch, i, pwait_mode; REG_GET(DMCUB_CNTL2, DMCUB_SOFT_RESET, &in_reset); @@ -115,6 +115,13 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) udelay(1); } + for (i = 0; i < timeout; ++i) { + REG_GET(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS, &pwait_mode); + if (pwait_mode & (1 << 0)) + break; + + udelay(1); + } /* Force reset in case we timed out, DMCUB is likely hung. */ } diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index 59ddc81b5a0e4..f6db6f89d45dc 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -151,7 +151,8 @@ struct dmub_srv; DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET) \ DMUB_SF(DMCUB_INBOX0_WPTR, DMCUB_INBOX0_WPTR) \ DMUB_SF(DMCUB_INTERRUPT_ENABLE, DMCUB_GPINT_IH_INT_EN) \ - DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) + DMUB_SF(DMCUB_INTERRUPT_ACK, DMCUB_GPINT_IH_INT_ACK) \ + DMUB_SF(DMCUB_CNTL, DMCUB_PWAIT_MODE_STATUS) struct dmub_srv_dcn31_reg_offset { #define DMUB_SR(reg) uint32_t reg; -- GitLab From 6ecf9773a5030aa4932096754bacff20e1b944b8 Mon Sep 17 00:00:00 2001 From: "Hung, Cruise" Date: Fri, 13 May 2022 09:16:42 +0800 Subject: [PATCH 018/942] drm/amd/display: Fix DMUB outbox trace in S4 (#4465) [Why] DMUB Outbox0 read/write pointer not sync after resumed from S4. And that caused old traces were sent to outbox. [How] Disable DMUB Outbox0 interrupt and clear DMUB Outbox0 read/write pointer when resumes from S4. And then enable Outbox0 interrupt before starts DMCUB. Reviewed-by: Nicholas Kazlauskas Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Cruise Hung Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 61 +++++++++---------- .../gpu/drm/amd/display/dmub/src/dmub_dcn31.c | 2 + 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 616013c618a51..0eb89e117a6a1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -513,12 +513,10 @@ void dccg31_set_physymclk( /* Controls the generation of pixel valid for OTG in (OTG -> HPO case) */ static void dccg31_set_dtbclk_dto( struct dccg *dccg, - int dtbclk_inst, - int req_dtbclk_khz, - int num_odm_segments, - const struct dc_crtc_timing *timing) + struct dtbclk_dto_params *params) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + int req_dtbclk_khz = params->pixclk_khz; uint32_t dtbdto_div; /* Mode DTBDTO Rate DTBCLK_DTO_DIV Register @@ -529,57 +527,56 @@ static void dccg31_set_dtbclk_dto( * DSC native 4:2:2 pixel rate/2 4 * Other modes pixel rate 8 */ - if (num_odm_segments == 4) { + if (params->num_odm_segments == 4) { dtbdto_div = 2; - req_dtbclk_khz = req_dtbclk_khz / 4; - } else if ((num_odm_segments == 2) || - (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || - (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 - && !timing->dsc_cfg.ycbcr422_simple)) { + req_dtbclk_khz = params->pixclk_khz / 4; + } else if ((params->num_odm_segments == 2) || + (params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) || + (params->timing->flags.DSC && params->timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 + && !params->timing->dsc_cfg.ycbcr422_simple)) { dtbdto_div = 4; - req_dtbclk_khz = req_dtbclk_khz / 2; + req_dtbclk_khz = params->pixclk_khz / 2; } else dtbdto_div = 8; - if (dccg->ref_dtbclk_khz && req_dtbclk_khz) { + if (params->ref_dtbclk_khz && req_dtbclk_khz) { uint32_t modulo, phase; // phase / modulo = dtbclk / dtbclk ref - modulo = dccg->ref_dtbclk_khz * 1000; - phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + dccg->ref_dtbclk_khz - 1), - dccg->ref_dtbclk_khz); + modulo = params->ref_dtbclk_khz * 1000; + phase = div_u64((((unsigned long long)modulo * req_dtbclk_khz) + params->ref_dtbclk_khz - 1), + params->ref_dtbclk_khz); - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); - REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], modulo); - REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], phase); + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], modulo); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], phase); - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_ENABLE[dtbclk_inst], 1); + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 1); - REG_WAIT(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLKDTO_ENABLE_STATUS[dtbclk_inst], 1, + REG_WAIT(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLKDTO_ENABLE_STATUS[params->otg_inst], 1, 1, 100); /* The recommended programming sequence to enable DTBCLK DTO to generate * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should * be set only after DTO is enabled */ - REG_UPDATE(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - PIPE_DTO_SRC_SEL[dtbclk_inst], 1); - - dccg->dtbclk_khz[dtbclk_inst] = req_dtbclk_khz; + REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst], + PIPE_DTO_SRC_SEL[params->otg_inst], 1); } else { - REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[dtbclk_inst], - DTBCLK_DTO_ENABLE[dtbclk_inst], 0, - PIPE_DTO_SRC_SEL[dtbclk_inst], 0, - DTBCLK_DTO_DIV[dtbclk_inst], dtbdto_div); + REG_UPDATE_3(OTG_PIXEL_RATE_CNTL[params->otg_inst], + DTBCLK_DTO_ENABLE[params->otg_inst], 0, + PIPE_DTO_SRC_SEL[params->otg_inst], 0, + DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0); REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0); - dccg->dtbclk_khz[dtbclk_inst] = 0; + REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); + REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); } } diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 8d45748957576..c7bd7e2167109 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -132,6 +132,8 @@ void dmub_dcn31_reset(struct dmub_srv *dmub) REG_WRITE(DMCUB_INBOX1_WPTR, 0); REG_WRITE(DMCUB_OUTBOX1_RPTR, 0); REG_WRITE(DMCUB_OUTBOX1_WPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_RPTR, 0); + REG_WRITE(DMCUB_OUTBOX0_WPTR, 0); REG_WRITE(DMCUB_SCRATCH0, 0); /* Clear the GPINT command manually so we don't send anything during boot. */ -- GitLab From f0ad66f42a3d914ac5f9972731ec5bc97f35002d Mon Sep 17 00:00:00 2001 From: Alvin Date: Thu, 12 May 2022 16:49:16 -0400 Subject: [PATCH 019/942] drm/amd/display: Don't clear ref_dtbclk value [Description] ref_dtbclk value is assigned in clk_mgr_construct, but the clks struct is cleared in init_clocks. Make sure to restore the value or we will get 0 value for ref_dtbclk in DCN31. Reviewed-by: Chris Park Acked-by: Jasdeep Dhillon Tested-by: Daniel Wheeler Signed-off-by: Alvin Lee Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 3 --- drivers/gpu/drm/amd/display/include/ddc_service_types.h | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 7310482b27840..6a81c1aea0be5 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -287,8 +287,11 @@ static void dcn31_enable_pme_wa(struct clk_mgr *clk_mgr_base) void dcn31_init_clocks(struct clk_mgr *clk_mgr) { + uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; + memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); // Assumption is that boot state always supports pstate + clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk clk_mgr->clks.p_state_change_support = true; clk_mgr->clks.prev_p_state_change_support = true; clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN; diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 0eb89e117a6a1..bbc58d167c630 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -572,9 +572,6 @@ static void dccg31_set_dtbclk_dto( PIPE_DTO_SRC_SEL[params->otg_inst], 0, DTBCLK_DTO_DIV[params->otg_inst], dtbdto_div); - REG_WRITE(DTBCLK_DTO_MODULO[dtbclk_inst], 0); - REG_WRITE(DTBCLK_DTO_PHASE[dtbclk_inst], 0); - REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0); REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0); } diff --git a/drivers/gpu/drm/amd/display/include/ddc_service_types.h b/drivers/gpu/drm/amd/display/include/ddc_service_types.h index 73b9e0a87e548..20a3d4e23f661 100644 --- a/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ b/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -127,6 +127,8 @@ struct av_sync_data { static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0}; static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0}; +static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u"; + /*MST Dock*/ static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA"; -- GitLab From 583ad88871b38dc39f05a316dcde909e444b09a6 Mon Sep 17 00:00:00 2001 From: Ilya Date: Mon, 7 Feb 2022 17:39:10 -0500 Subject: [PATCH 020/942] drm/amd/display: Fix possible infinite loop in DP LT fallback [Why] It's possible for some fallback scenarios to result in infinite looping during link training. [How] This change modifies DP LT fallback behavior to more closely match the DP standard. Keep track of the link rate during the EQ_FAIL fallback, and use it as the maximum link rate for the CR sequence. Reviewed-by: Wenjing Liu Tested-by: Daniel Wheeler Signed-off-by: Ilya Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 106 ++++++++---------- 1 file changed, 49 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 3c9523218c199..03eedffbb5b21 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -114,8 +114,8 @@ static const struct dc_link_settings fail_safe_link_settings = { static bool decide_fallback_link_setting( struct dc_link *link, - struct dc_link_settings initial_link_settings, - struct dc_link_settings *current_link_setting, + struct dc_link_settings *max, + struct dc_link_settings *cur, enum link_training_result training_result); static void maximize_lane_settings(const struct link_training_settings *lt_settings, struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); @@ -2784,6 +2784,7 @@ bool perform_link_training_with_retries( enum dp_panel_mode panel_mode = dp_get_panel_mode(link); enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0; struct dc_link_settings cur_link_settings = *link_setting; + struct dc_link_settings max_link_settings = *link_setting; const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); int fail_count = 0; bool is_link_bw_low = false; /* link bandwidth < stream bandwidth */ @@ -2793,7 +2794,6 @@ bool perform_link_training_with_retries( dp_trace_commit_lt_init(link); - if (dp_get_link_encoding_format(&cur_link_settings) == DP_8b_10b_ENCODING) /* We need to do this before the link training to ensure the idle * pattern in SST mode will be sent right after the link training @@ -2909,19 +2909,15 @@ bool perform_link_training_with_retries( uint32_t req_bw; uint32_t link_bw; - decide_fallback_link_setting(link, *link_setting, &cur_link_settings, status); - /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to - * minimum link bandwidth. + decide_fallback_link_setting(link, &max_link_settings, + &cur_link_settings, status); + /* Fail link training if reduced link bandwidth no longer meets + * stream requirements. */ req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); link_bw = dc_link_bandwidth_kbps(link, &cur_link_settings); - is_link_bw_low = (req_bw > link_bw); - is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) && - (cur_link_settings.lane_count <= LANE_COUNT_ONE)); - - if (is_link_bw_low) - DC_LOG_WARNING("%s: Link bandwidth too low after fallback req_bw(%d) > link_bw(%d)\n", - __func__, req_bw, link_bw); + if (req_bw > link_bw) + break; } msleep(delay_between_attempts); @@ -3309,7 +3305,7 @@ static bool dp_verify_link_cap( int *fail_count) { struct dc_link_settings cur_link_settings = {0}; - struct dc_link_settings initial_link_settings = *known_limit_link_setting; + struct dc_link_settings max_link_settings = *known_limit_link_setting; bool success = false; bool skip_video_pattern; enum clock_source_id dp_cs_id = get_clock_source_id(link); @@ -3318,7 +3314,7 @@ static bool dp_verify_link_cap( struct link_resource link_res; memset(&irq_data, 0, sizeof(irq_data)); - cur_link_settings = initial_link_settings; + cur_link_settings = max_link_settings; /* Grant extended timeout request */ if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) { @@ -3361,7 +3357,7 @@ static bool dp_verify_link_cap( dp_trace_lt_result_update(link, status, true); dp_disable_link_phy(link, &link_res, link->connector_signal); } while (!success && decide_fallback_link_setting(link, - initial_link_settings, &cur_link_settings, status)); + &max_link_settings, &cur_link_settings, status)); link->verified_link_cap = success ? cur_link_settings : fail_safe_link_settings; @@ -3596,16 +3592,19 @@ static bool decide_fallback_link_setting_max_bw_policy( */ static bool decide_fallback_link_setting( struct dc_link *link, - struct dc_link_settings initial_link_settings, - struct dc_link_settings *current_link_setting, + struct dc_link_settings *max, + struct dc_link_settings *cur, enum link_training_result training_result) { - if (!current_link_setting) + if (!cur) return false; - if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING || + if (!max) + return false; + + if (dp_get_link_encoding_format(max) == DP_128b_132b_ENCODING || link->dc->debug.force_dp2_lt_fallback_method) - return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings, - current_link_setting, training_result); + return decide_fallback_link_setting_max_bw_policy(link, max, cur, + training_result); switch (training_result) { case LINK_TRAINING_CR_FAIL_LANE0: @@ -3613,28 +3612,18 @@ static bool decide_fallback_link_setting( case LINK_TRAINING_CR_FAIL_LANE23: case LINK_TRAINING_LQA_FAIL: { - if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - } else if (!reached_minimum_lane_count - (current_link_setting->lane_count)) { - current_link_setting->link_rate = - initial_link_settings.link_rate; + if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + } else if (!reached_minimum_lane_count(cur->lane_count)) { + cur->link_rate = max->link_rate; if (training_result == LINK_TRAINING_CR_FAIL_LANE0) return false; else if (training_result == LINK_TRAINING_CR_FAIL_LANE1) - current_link_setting->lane_count = - LANE_COUNT_ONE; - else if (training_result == - LINK_TRAINING_CR_FAIL_LANE23) - current_link_setting->lane_count = - LANE_COUNT_TWO; + cur->lane_count = LANE_COUNT_ONE; + else if (training_result == LINK_TRAINING_CR_FAIL_LANE23) + cur->lane_count = LANE_COUNT_TWO; else - current_link_setting->lane_count = - reduce_lane_count( - current_link_setting->lane_count); + cur->lane_count = reduce_lane_count(cur->lane_count); } else { return false; } @@ -3642,17 +3631,17 @@ static bool decide_fallback_link_setting( } case LINK_TRAINING_EQ_FAIL_EQ: { - if (!reached_minimum_lane_count - (current_link_setting->lane_count)) { - current_link_setting->lane_count = - reduce_lane_count( - current_link_setting->lane_count); - } else if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - current_link_setting->lane_count = initial_link_settings.lane_count; + if (!reached_minimum_lane_count(cur->lane_count)) { + cur->lane_count = reduce_lane_count(cur->lane_count); + } else if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + /* Reduce max link rate to avoid potential infinite loop. + * Needed so that any subsequent CR_FAIL fallback can't + * re-set the link rate higher than the link rate from + * the latest EQ_FAIL fallback. + */ + max->link_rate = cur->link_rate; + cur->lane_count = max->lane_count; } else { return false; } @@ -3660,12 +3649,15 @@ static bool decide_fallback_link_setting( } case LINK_TRAINING_EQ_FAIL_CR: { - if (!reached_minimum_link_rate - (current_link_setting->link_rate)) { - current_link_setting->link_rate = - reduce_link_rate( - current_link_setting->link_rate); - current_link_setting->lane_count = initial_link_settings.lane_count; + if (!reached_minimum_link_rate(cur->link_rate)) { + cur->link_rate = reduce_link_rate(cur->link_rate); + /* Reduce max link rate to avoid potential infinite loop. + * Needed so that any subsequent CR_FAIL fallback can't + * re-set the link rate higher than the link rate from + * the latest EQ_FAIL fallback. + */ + max->link_rate = cur->link_rate; + cur->lane_count = max->lane_count; } else { return false; } -- GitLab From 067541847781b8e3abd7400ffdc0d402432613c8 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Sun, 15 May 2022 21:52:38 -0400 Subject: [PATCH 021/942] drm/amd/display: 3.2.187 This version brings along the following fixes: * Changes to DP LT fallback behavior to more closely match the DP standard * Added new interfaces for lut pipeline * Restore ref_dtblck value when clk struct is cleared in init_clocks * Fixes DMUB outbox trace in S4 * Fixes lingering DIO FIFO errors when DIO no longer enabled * Reads Golden Settings Table from VBIOS Acked-by: Jasdeep Dhillon Signed-off-by: Aric Cyr Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 4c1f977838b5b..817028d3c4a0c 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -47,7 +47,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.186" +#define DC_VER "3.2.187" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- GitLab From 11594fa114276ed41b9fa3849f7eb79be10162d6 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 25 May 2022 17:37:02 +0800 Subject: [PATCH 022/942] drm/amdgpu: make program_imu_rlc_ram static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This symbol is not used outside of imu_v11_0.c, so marks it static. Fixes the following w1 warning: drivers/gpu/drm/amd/amdgpu/imu_v11_0.c:302:6: warning: no previous prototype for ‘program_imu_rlc_ram’ [-Wmissing-prototypes]. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/imu_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c b/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c index 5d2dfeff8fe5d..d63d3f2b8a161 100644 --- a/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c @@ -299,7 +299,7 @@ static const struct imu_rlc_ram_golden imu_rlc_ram_golden_11_0_2[] = IMU_RLC_RAM_GOLDEN_VALUE(GC, 0, regCPG_PSP_DEBUG, CPG_PSP_DEBUG__GPA_OVERRIDE_MASK, 0) }; -void program_imu_rlc_ram(struct amdgpu_device *adev, +static void program_imu_rlc_ram(struct amdgpu_device *adev, const struct imu_rlc_ram_golden *regs, const u32 array_size) { -- GitLab From 97e50305542f384741a5b45699aba349fe9fca73 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 26 May 2022 16:34:55 -0400 Subject: [PATCH 023/942] drm/amdgpu: update VCN codec support for Yellow Carp Supports AV1. Mesa already has support for this and doesn't rely on the kernel caps for yellow carp, so this was already working from an application perspective. Fixes: 554398174d98 ("amdgpu/nv.c - Added video codec support for Yellow Carp") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2002 Reviewed-by: Leo Liu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/nv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c index d016e3c3e221f..b3fba8dea63ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/nv.c +++ b/drivers/gpu/drm/amd/amdgpu/nv.c @@ -170,6 +170,7 @@ static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = { {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, + {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, }; static const struct amdgpu_video_codecs yc_video_codecs_decode = { -- GitLab From ae969b62e7a1e17affae24b815b217b9b87a62f4 Mon Sep 17 00:00:00 2001 From: Roman Li Date: Wed, 25 May 2022 17:20:21 -0400 Subject: [PATCH 024/942] drm/amdgpu: fix aper_base for APU [Why] Wrong fb offset results in dmub f/w errors and white screen. [drm:dc_dmub_srv_wait_idle [amdgpu]] *ERROR* Error waiting for DMUB idle: status=3 [How] Read aper_base from mmhub because GC is off by default v2: use BAR for passthrough (Alex) Signed-off-by: Roman Li Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index a0c0b7d9f444d..7f4b480ae66e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -638,6 +638,12 @@ static int gmc_v11_0_mc_init(struct amdgpu_device *adev) adev->gmc.aper_base = pci_resource_start(adev->pdev, 0); adev->gmc.aper_size = pci_resource_len(adev->pdev, 0); +#ifdef CONFIG_X86_64 + if ((adev->flags & AMD_IS_APU) && !amdgpu_passthrough(adev)) { + adev->gmc.aper_base = adev->mmhub.funcs->get_mc_fb_offset(adev); + adev->gmc.aper_size = adev->gmc.real_vram_size; + } +#endif /* In case the PCI BAR is larger than the actual amount of vram */ adev->gmc.visible_vram_size = adev->gmc.aper_size; if (adev->gmc.visible_vram_size > adev->gmc.real_vram_size) -- GitLab From 418214ddcf6e79e4e572f8c7a18e1de7cab195b4 Mon Sep 17 00:00:00 2001 From: sunliming Date: Sun, 29 May 2022 15:26:31 +0800 Subject: [PATCH 025/942] drm/amdgpu: fix a missing break in gfx_v11_0_handle_priv_fault Fixes the following w1 warning: drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:5873:2: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]. Reported-by: kernel test robot Signed-off-by: sunliming Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 8c0a3fc7aaa6d..4353192ecd999 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -6028,6 +6028,7 @@ static void gfx_v11_0_handle_priv_fault(struct amdgpu_device *adev, break; default: BUG(); + break; } } -- GitLab From 8365ed22d00b5e5889425c8d96462ad88ae463bc Mon Sep 17 00:00:00 2001 From: sunliming Date: Sun, 29 May 2022 14:26:31 +0800 Subject: [PATCH 026/942] drm/amdgpu: make gfx_v11_0_rlc_stop static This symbol is not used outside of gfx_v11_0.c, so marks it static. Fixes the following w1 warning: drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1945:6: warning: no previous prototype for function 'gfx_v11_0_rlc_stop' [-Wmissing-prototypes]. Reported-by: kernel test robot Signed-off-by: sunliming Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 4353192ecd999..628d3536938e7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1983,7 +1983,7 @@ static int gfx_v11_0_init_csb(struct amdgpu_device *adev) return 0; } -void gfx_v11_0_rlc_stop(struct amdgpu_device *adev) +static void gfx_v11_0_rlc_stop(struct amdgpu_device *adev) { u32 tmp = RREG32_SOC15(GC, 0, regRLC_CNTL); -- GitLab From fd843d03418ead2bba369159bb19b60e9d4b7b1e Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Thu, 14 Apr 2022 15:48:30 -0400 Subject: [PATCH 027/942] drm/amd/display: remove stale config guards This code should be executed. Signed-off-by: Aurabindo Pillai Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 -- drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index a50e1e519dffc..aa01a18df419f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -41,9 +41,7 @@ #include "dc_dmub_srv.h" -#if defined (CONFIG_DRM_AMD_DC_DP2_0) #include "dc_link_dp.h" -#endif #define TO_CLK_MGR_DCN315(clk_mgr)\ container_of(clk_mgr, struct clk_mgr_dcn315, base) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c index 789f7562cdc75..d2273674e8729 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dml_wrapper.c @@ -1284,10 +1284,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context) for (i = 0; i < dc->res_pool->pipe_count; i++) { if (!context->res_ctx.pipe_ctx[i].stream) continue; -#if defined (CONFIG_DRM_AMD_DC_DP2_0) if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i])) return true; -#endif } return false; } -- GitLab From 28caf8c467e2cb98b90a760b65767fa9aaf52ffb Mon Sep 17 00:00:00 2001 From: "Stanley.Yang" Date: Tue, 31 May 2022 18:57:06 +0800 Subject: [PATCH 028/942] drm/amdgpu: fix ras supported check Fix aldebaran ras supported check on SRIOV guest side, the previous check conditicon block all ras feature on baremetal Signed-off-by: Stanley.Yang Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 2de9309a41939..1b1b502897ef4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -2278,8 +2278,9 @@ static void amdgpu_ras_check_supported(struct amdgpu_device *adev) !amdgpu_ras_asic_supported(adev)) return; - if (!(amdgpu_sriov_vf(adev) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)))) + /* If driver run on sriov guest side, only enable ras for aldebaran */ + if (amdgpu_sriov_vf(adev) && + adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 2)) return; if (!adev->gmc.xgmi.connected_to_cpu) { -- GitLab From 2a460963350ec6b1534d28d7f943b5f84815aff2 Mon Sep 17 00:00:00 2001 From: Candice Li Date: Wed, 1 Jun 2022 17:10:44 +0800 Subject: [PATCH 029/942] drm/amdgpu: Resolve RAS GFX error count issue after cold boot on Arcturus Adjust the sequence for ras late init and separate ras reset error status from query status. v2: squash in fix from Candice Signed-off-by: Candice Li Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 9 ++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 27 ++++++++++++++++++++----- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index ede2fa56f6c90..16699158e00d8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -594,17 +594,20 @@ int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value) int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block) { int r; - r = amdgpu_ras_block_late_init(adev, ras_block); - if (r) - return r; if (amdgpu_ras_is_supported(adev, ras_block->block)) { if (!amdgpu_persistent_edc_harvesting_supported(adev)) amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX); + r = amdgpu_ras_block_late_init(adev, ras_block); + if (r) + return r; + r = amdgpu_irq_get(adev, &adev->gfx.cp_ecc_error_irq, 0); if (r) goto late_fini; + } else { + amdgpu_ras_feature_enable_on_boot(adev, ras_block, 0); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 1b1b502897ef4..dac202ae864dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -197,6 +197,13 @@ static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf, if (amdgpu_ras_query_error_status(obj->adev, &info)) return -EINVAL; + /* Hardware counter will be reset automatically after the query on Vega20 and Arcturus */ + if (obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && + obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { + if (amdgpu_ras_reset_error_status(obj->adev, info.head.block)) + dev_warn(obj->adev->dev, "Failed to reset error counter and error status"); + } + s = snprintf(val, sizeof(val), "%s: %lu\n%s: %lu\n", "ue", info.ue_count, "ce", info.ce_count); @@ -550,9 +557,10 @@ static ssize_t amdgpu_ras_sysfs_read(struct device *dev, if (amdgpu_ras_query_error_status(obj->adev, &info)) return -EINVAL; - if (obj->adev->asic_type == CHIP_ALDEBARAN) { + if (obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && + obj->adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { if (amdgpu_ras_reset_error_status(obj->adev, info.head.block)) - DRM_WARN("Failed to reset error counter and error status"); + dev_warn(obj->adev->dev, "Failed to reset error counter and error status"); } return sysfs_emit(buf, "%s: %lu\n%s: %lu\n", "ue", info.ue_count, @@ -1027,9 +1035,6 @@ int amdgpu_ras_query_error_status(struct amdgpu_device *adev, } } - if (!amdgpu_persistent_edc_harvesting_supported(adev)) - amdgpu_ras_reset_error_status(adev, info->head.block); - return 0; } @@ -1149,6 +1154,12 @@ int amdgpu_ras_query_error_count(struct amdgpu_device *adev, if (res) return res; + if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && + adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { + if (amdgpu_ras_reset_error_status(adev, info.head.block)) + dev_warn(adev->dev, "Failed to reset error counter and error status"); + } + ce += info.ce_count; ue += info.ue_count; } @@ -1792,6 +1803,12 @@ static void amdgpu_ras_log_on_err_counter(struct amdgpu_device *adev) continue; amdgpu_ras_query_error_status(adev, &info); + + if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 2) && + adev->ip_versions[MP0_HWIP][0] != IP_VERSION(11, 0, 4)) { + if (amdgpu_ras_reset_error_status(adev, info.head.block)) + dev_warn(adev->dev, "Failed to reset error counter and error status"); + } } } -- GitLab From fa582c6f3684ac0098a9d02ddf0ed52a02b37127 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Thu, 26 May 2022 16:15:38 -0400 Subject: [PATCH 030/942] drm/amdkfd: Use mmget_not_zero in MMU notifier MMU notifier callback may pass in mm with mm->mm_users==0 when process is exiting, use mmget_no_zero to avoid accessing invalid mm in deferred list work after mm is gone. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 2ebf0132c25bf..3bd0f1a670bb7 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -2307,6 +2307,8 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, if (range->event == MMU_NOTIFY_RELEASE) return true; + if (!mmget_not_zero(mni->mm)) + return true; start = mni->interval_tree.start; last = mni->interval_tree.last; @@ -2333,6 +2335,7 @@ svm_range_cpu_invalidate_pagetables(struct mmu_interval_notifier *mni, } svm_range_unlock(prange); + mmput(mni->mm); return true; } -- GitLab From e19f8fa6ce1ca9b8b934ba7d2e8f34c95abc6e60 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 1 Jun 2022 07:51:16 -0700 Subject: [PATCH 031/942] dma-debug: make things less spammy under memory pressure Limit the error msg to avoid flooding the console. If you have a lot of threads hitting this at once, they could have already gotten passed the dma_debug_disabled() check before they get to the point of allocation failure, resulting in quite a lot of this error message spamming the log. Use pr_err_once() to limit that. Signed-off-by: Rob Clark Signed-off-by: Christoph Hellwig --- kernel/dma/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index ac740630c79c2..2caafd13f8aac 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -564,7 +564,7 @@ static void add_dma_entry(struct dma_debug_entry *entry, unsigned long attrs) rc = active_cacheline_insert(entry); if (rc == -ENOMEM) { - pr_err("cacheline tracking ENOMEM, dma-debug disabled\n"); + pr_err_once("cacheline tracking ENOMEM, dma-debug disabled\n"); global_disable = true; } else if (rc == -EEXIST && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { err_printk(entry->dev, entry, -- GitLab From e15db62bc5648ab459a570862f654e787c498faf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 Jun 2022 20:49:39 +0200 Subject: [PATCH 032/942] swiotlb: fix setting ->force_bounce The swiotlb_init refactor messed up assigning ->force_bounce by doing it in different places based on what caused the setting of the flag. Fix this by passing the SWIOTLB_* flags to swiotlb_init_io_tlb_mem and just setting it there. Fixes: c6af2aa9ffc9 ("swiotlb: make the swiotlb_init interface more useful") Reported-by: Nathan Chancellor Signed-off-by: Christoph Hellwig Tested-by: Nathan Chancellor --- kernel/dma/swiotlb.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index dfa1de89dc944..cb50f8d383606 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -192,7 +192,7 @@ void __init swiotlb_update_mem_attributes(void) } static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, - unsigned long nslabs, bool late_alloc) + unsigned long nslabs, unsigned int flags, bool late_alloc) { void *vaddr = phys_to_virt(start); unsigned long bytes = nslabs << IO_TLB_SHIFT, i; @@ -203,8 +203,7 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, mem->index = 0; mem->late_alloc = late_alloc; - if (swiotlb_force_bounce) - mem->force_bounce = true; + mem->force_bounce = swiotlb_force_bounce || (flags & SWIOTLB_FORCE); spin_lock_init(&mem->lock); for (i = 0; i < mem->nslabs; i++) { @@ -275,8 +274,7 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags, panic("%s: Failed to allocate %zu bytes align=0x%lx\n", __func__, alloc_size, PAGE_SIZE); - swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, false); - mem->force_bounce = flags & SWIOTLB_FORCE; + swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, flags, false); if (flags & SWIOTLB_VERBOSE) swiotlb_print_info(); @@ -348,7 +346,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask, set_memory_decrypted((unsigned long)vstart, (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT); - swiotlb_init_io_tlb_mem(mem, virt_to_phys(vstart), nslabs, true); + swiotlb_init_io_tlb_mem(mem, virt_to_phys(vstart), nslabs, 0, true); swiotlb_print_info(); return 0; @@ -835,8 +833,8 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem, set_memory_decrypted((unsigned long)phys_to_virt(rmem->base), rmem->size >> PAGE_SHIFT); - swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false); - mem->force_bounce = true; + swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, SWIOTLB_FORCE, + false); mem->for_alloc = true; rmem->priv = mem; -- GitLab From b6d9014a3335194590abdd2a2471ef5147a67645 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 30 May 2022 18:40:06 +0200 Subject: [PATCH 033/942] netfilter: nf_tables: delete flowtable hooks via transaction list Remove inactive bool field in nft_hook object that was introduced in abadb2f865d7 ("netfilter: nf_tables: delete devices from flowtable"). Move stale flowtable hooks to transaction list instead. Deleting twice the same device does not result in ENOENT. Fixes: abadb2f865d7 ("netfilter: nf_tables: delete devices from flowtable") Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 1 - net/netfilter/nf_tables_api.c | 31 ++++++------------------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 20af9d3557b9d..279ae0fff7adb 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -1090,7 +1090,6 @@ struct nft_stats { struct nft_hook { struct list_head list; - bool inactive; struct nf_hook_ops ops; struct rcu_head rcu; }; diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 129d3ebd6ce5d..30588349f96c2 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1914,7 +1914,6 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, goto err_hook_dev; } hook->ops.dev = dev; - hook->inactive = false; return hook; @@ -7618,6 +7617,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, { const struct nlattr * const *nla = ctx->nla; struct nft_flowtable_hook flowtable_hook; + LIST_HEAD(flowtable_del_list); struct nft_hook *this, *hook; struct nft_trans *trans; int err; @@ -7633,7 +7633,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, err = -ENOENT; goto err_flowtable_del_hook; } - hook->inactive = true; + list_move(&hook->list, &flowtable_del_list); } trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE, @@ -7646,6 +7646,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, nft_trans_flowtable(trans) = flowtable; nft_trans_flowtable_update(trans) = true; INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans)); + list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans)); nft_flowtable_hook_release(&flowtable_hook); nft_trans_commit_list_add_tail(ctx->net, trans); @@ -7653,13 +7654,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx, return 0; err_flowtable_del_hook: - list_for_each_entry(this, &flowtable_hook.list, list) { - hook = nft_hook_list_find(&flowtable->hook_list, this); - if (!hook) - break; - - hook->inactive = false; - } + list_splice(&flowtable_del_list, &flowtable->hook_list); nft_flowtable_hook_release(&flowtable_hook); return err; @@ -8563,17 +8558,6 @@ void nft_chain_del(struct nft_chain *chain) list_del_rcu(&chain->list); } -static void nft_flowtable_hooks_del(struct nft_flowtable *flowtable, - struct list_head *hook_list) -{ - struct nft_hook *hook, *next; - - list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { - if (hook->inactive) - list_move(&hook->list, hook_list); - } -} - static void nf_tables_module_autoload_cleanup(struct net *net) { struct nftables_pernet *nft_net = nft_pernet(net); @@ -8918,8 +8902,6 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) break; case NFT_MSG_DELFLOWTABLE: if (nft_trans_flowtable_update(trans)) { - nft_flowtable_hooks_del(nft_trans_flowtable(trans), - &nft_trans_flowtable_hooks(trans)); nf_tables_flowtable_notify(&trans->ctx, nft_trans_flowtable(trans), &nft_trans_flowtable_hooks(trans), @@ -9000,7 +8982,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) struct nftables_pernet *nft_net = nft_pernet(net); struct nft_trans *trans, *next; struct nft_trans_elem *te; - struct nft_hook *hook; if (action == NFNL_ABORT_VALIDATE && nf_tables_validate(net) < 0) @@ -9131,8 +9112,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) break; case NFT_MSG_DELFLOWTABLE: if (nft_trans_flowtable_update(trans)) { - list_for_each_entry(hook, &nft_trans_flowtable(trans)->hook_list, list) - hook->inactive = false; + list_splice(&nft_trans_flowtable_hooks(trans), + &nft_trans_flowtable(trans)->hook_list); } else { trans->ctx.table->use++; nft_clear(trans->ctx.net, nft_trans_flowtable(trans)); -- GitLab From 3e8635fb2e072672cbc650989ffedf8300ad67fb Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 2 Jun 2022 00:31:14 +1000 Subject: [PATCH 034/942] powerpc/kasan: Force thread size increase with KASAN KASAN causes increased stack usage, which can lead to stack overflows. The logic in Kconfig to suggest a larger default doesn't work if a user has CONFIG_EXPERT enabled and has an existing .config with a smaller value. Follow the lead of x86 and arm64, and force the thread size to be increased when KASAN is enabled. That also has the effect of enlarging the stack for 64-bit KASAN builds, which is also desirable. Fixes: edbadaf06710 ("powerpc/kasan: Fix stack overflow by increasing THREAD_SHIFT") Reported-by: Erhard Furtner Reported-by: Christophe Leroy [mpe: Use MIN_THREAD_SHIFT as suggested by Christophe] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220601143114.133524-1-mpe@ellerman.id.au --- arch/powerpc/Kconfig | 1 - arch/powerpc/include/asm/thread_info.h | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 54dbbb1d4b366..b1760d615bb7d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -790,7 +790,6 @@ config THREAD_SHIFT range 13 15 default "15" if PPC_256K_PAGES default "14" if PPC64 - default "14" if KASAN default "13" help Used to define the stack size. The default is almost always what you diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 125328d1b9802..af58f1ed3952e 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -14,10 +14,16 @@ #ifdef __KERNEL__ -#if defined(CONFIG_VMAP_STACK) && CONFIG_THREAD_SHIFT < PAGE_SHIFT +#ifdef CONFIG_KASAN +#define MIN_THREAD_SHIFT (CONFIG_THREAD_SHIFT + 1) +#else +#define MIN_THREAD_SHIFT CONFIG_THREAD_SHIFT +#endif + +#if defined(CONFIG_VMAP_STACK) && MIN_THREAD_SHIFT < PAGE_SHIFT #define THREAD_SHIFT PAGE_SHIFT #else -#define THREAD_SHIFT CONFIG_THREAD_SHIFT +#define THREAD_SHIFT MIN_THREAD_SHIFT #endif #define THREAD_SIZE (1 << THREAD_SHIFT) -- GitLab From b6c71c66b0ad8f2b59d9bc08c7a5079b110bec01 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 31 May 2022 19:49:01 -0400 Subject: [PATCH 035/942] NFSD: Fix potential use-after-free in nfsd_file_put() nfsd_file_put_noref() can free @nf, so don't dereference @nf immediately upon return from nfsd_file_put_noref(). Suggested-by: Trond Myklebust Fixes: 999397926ab3 ("nfsd: Clean up nfsd_file_put()") Signed-off-by: Chuck Lever --- fs/nfsd/filecache.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index d32fcd8ad457d..148b25a43caf1 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -308,11 +308,12 @@ nfsd_file_put(struct nfsd_file *nf) if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) { nfsd_file_flush(nf); nfsd_file_put_noref(nf); - } else { + } else if (nf->nf_file) { nfsd_file_put_noref(nf); - if (nf->nf_file) - nfsd_file_schedule_laundrette(); - } + nfsd_file_schedule_laundrette(); + } else + nfsd_file_put_noref(nf); + if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT) nfsd_file_gc(); } -- GitLab From f012e95b377c73c0283f009823c633104dedb337 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 1 Jun 2022 12:46:52 -0400 Subject: [PATCH 036/942] SUNRPC: Trap RDMA segment overflows Prevent svc_rdma_build_writes() from walking off the end of a Write chunk's segment array. Caught with KASAN. The test that this fix replaces is invalid, and might have been left over from an earlier prototype of the PCL work. Fixes: 7a1cbfa18059 ("svcrdma: Use parsed chunk lists to construct RDMA Writes") Signed-off-by: Chuck Lever --- net/sunrpc/xprtrdma/svc_rdma_rw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 5f0155fdefc7b..11cf7c6466443 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -478,10 +478,10 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info, unsigned int write_len; u64 offset; - seg = &info->wi_chunk->ch_segments[info->wi_seg_no]; - if (!seg) + if (info->wi_seg_no >= info->wi_chunk->ch_segcount) goto out_overflow; + seg = &info->wi_chunk->ch_segments[info->wi_seg_no]; write_len = min(remaining, seg->rs_length - info->wi_seg_off); if (!write_len) goto out_overflow; -- GitLab From 587b9bfe0668bc997e51af9526a0c7c084d4660f Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Wed, 1 Jun 2022 01:11:02 +0300 Subject: [PATCH 037/942] kernel/reboot: Use static handler for register_platform_power_off() The register_platform_power_off() fails on m68k platform due to the memory allocation error that happens at a very early boot time when memory allocator isn't available yet. Fix it by using a static sys-off handler for the platform-level power-off handlers. Fixes: f0f7e5265b3b ("m68k: Switch to new sys-off handler API") Reported-by: Geert Uytterhoeven Signed-off-by: Dmitry Osipenko Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Rafael J. Wysocki --- kernel/reboot.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/kernel/reboot.c b/kernel/reboot.c index a091145ee7104..3b19b123efecb 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -315,6 +315,37 @@ static int sys_off_notify(struct notifier_block *nb, return handler->sys_off_cb(&data); } +static struct sys_off_handler platform_sys_off_handler; + +static struct sys_off_handler *alloc_sys_off_handler(int priority) +{ + struct sys_off_handler *handler; + + /* + * Platforms like m68k can't allocate sys_off handler dynamically + * at the early boot time because memory allocator isn't available yet. + */ + if (priority == SYS_OFF_PRIO_PLATFORM) { + handler = &platform_sys_off_handler; + if (handler->cb_data) + return ERR_PTR(-EBUSY); + } else { + handler = kzalloc(sizeof(*handler), GFP_KERNEL); + if (!handler) + return ERR_PTR(-ENOMEM); + } + + return handler; +} + +static void free_sys_off_handler(struct sys_off_handler *handler) +{ + if (handler == &platform_sys_off_handler) + memset(handler, 0, sizeof(*handler)); + else + kfree(handler); +} + /** * register_sys_off_handler - Register sys-off handler * @mode: Sys-off mode @@ -345,9 +376,9 @@ register_sys_off_handler(enum sys_off_mode mode, struct sys_off_handler *handler; int err; - handler = kzalloc(sizeof(*handler), GFP_KERNEL); - if (!handler) - return ERR_PTR(-ENOMEM); + handler = alloc_sys_off_handler(priority); + if (IS_ERR(handler)) + return handler; switch (mode) { case SYS_OFF_MODE_POWER_OFF_PREPARE: @@ -364,7 +395,7 @@ register_sys_off_handler(enum sys_off_mode mode, break; default: - kfree(handler); + free_sys_off_handler(handler); return ERR_PTR(-EINVAL); } @@ -391,7 +422,7 @@ register_sys_off_handler(enum sys_off_mode mode, } if (err) { - kfree(handler); + free_sys_off_handler(handler); return ERR_PTR(err); } @@ -422,7 +453,7 @@ void unregister_sys_off_handler(struct sys_off_handler *handler) /* sanity check, shall never happen */ WARN_ON(err); - kfree(handler); + free_sys_off_handler(handler); } EXPORT_SYMBOL_GPL(unregister_sys_off_handler); -- GitLab From 2c9e4559773c261900c674a86b8e455911675d71 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 1 Jun 2022 17:49:36 +0200 Subject: [PATCH 038/942] netfilter: nf_tables: always initialize flowtable hook list in transaction The hook list is used if nft_trans_flowtable_update(trans) == true. However, initialize this list for other cases for safety reasons. Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 30588349f96c2..2faa77cd2fe25 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -544,6 +544,7 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, if (msg_type == NFT_MSG_NEWFLOWTABLE) nft_activate_next(ctx->net, flowtable); + INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans)); nft_trans_flowtable(trans) = flowtable; nft_trans_commit_list_add_tail(ctx->net, trans); -- GitLab From 7c4f4f197e0c5c93a70329627f17fcc5883f3593 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 31 May 2022 18:56:41 -0500 Subject: [PATCH 039/942] drm/amdkfd: Add GC 10.3.6 and 10.3.7 KFD definitions Loading amdgpu on GC 10.3.7 shows an ERR level message: `kfd kfd: amdgpu: GC IP 0a0307 not supported in kfd` Add these targets to match yellow carp structures. Reported-by: David Chang Reviewed-by: Felix Kuehling Tested-by: Jesse(Jie) Zhang Signed-off-by: Mario Limonciello Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.18.x --- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 ++ drivers/gpu/drm/amd/amdkfd/kfd_device.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 5e9adbc71bbd3..cbfb32b3d2352 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -1516,6 +1516,8 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev, num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info); break; case IP_VERSION(10, 3, 3): + case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */ + case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */ pcache_info = yellow_carp_cache_info; num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info); break; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 8667e3df2d0b9..f8635e7685136 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -73,6 +73,8 @@ static void kfd_device_info_set_sdma_info(struct kfd_dev *kfd) case IP_VERSION(4, 1, 2):/* RENOIR */ case IP_VERSION(5, 2, 1):/* VANGOGH */ case IP_VERSION(5, 2, 3):/* YELLOW_CARP */ + case IP_VERSION(5, 2, 6):/* GC 10.3.6 */ + case IP_VERSION(5, 2, 7):/* GC 10.3.7 */ case IP_VERSION(6, 0, 1): kfd->device_info.num_sdma_queues_per_engine = 2; break; @@ -127,6 +129,8 @@ static void kfd_device_info_set_event_interrupt_class(struct kfd_dev *kfd) case IP_VERSION(9, 4, 2): /* ALDEBARAN */ case IP_VERSION(10, 3, 1): /* VANGOGH */ case IP_VERSION(10, 3, 3): /* YELLOW_CARP */ + case IP_VERSION(10, 3, 6): /* GC 10.3.6 */ + case IP_VERSION(10, 3, 7): /* GC 10.3.7 */ case IP_VERSION(10, 1, 3): /* CYAN_SKILLFISH */ case IP_VERSION(10, 1, 4): case IP_VERSION(10, 1, 10): /* NAVI10 */ @@ -368,6 +372,16 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) if (!vf) f2g = &gfx_v10_3_kfd2kgd; break; + case IP_VERSION(10, 3, 6): + gfx_target_version = 100306; + if (!vf) + f2g = &gfx_v10_3_kfd2kgd; + break; + case IP_VERSION(10, 3, 7): + gfx_target_version = 100307; + if (!vf) + f2g = &gfx_v10_3_kfd2kgd; + break; case IP_VERSION(11, 0, 0): gfx_target_version = 110000; f2g = &gfx_v11_kfd2kgd; -- GitLab From 371017309a9f1725bfd3283afe61efa4ac34d30c Mon Sep 17 00:00:00 2001 From: Sunil Khatri Date: Mon, 30 May 2022 23:24:09 +0530 Subject: [PATCH 040/942] drm/amdgpu: enable tmz by default for GC 10.3.7 Add IP GC 10.3.7 in the list of target to have tmz enabled by default. Signed-off-by: Sunil Khatri Reviewed-by: Alexander Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.18.x --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 798c56214a239..aebc384531ac8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -518,6 +518,8 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev) case IP_VERSION(9, 1, 0): /* RENOIR looks like RAVEN */ case IP_VERSION(9, 3, 0): + /* GC 10.3.7 */ + case IP_VERSION(10, 3, 7): if (amdgpu_tmz == 0) { adev->gmc.tmz_enabled = false; dev_info(adev->dev, @@ -540,8 +542,6 @@ void amdgpu_gmc_tmz_set(struct amdgpu_device *adev) case IP_VERSION(10, 3, 1): /* YELLOW_CARP*/ case IP_VERSION(10, 3, 3): - /* GC 10.3.7 */ - case IP_VERSION(10, 3, 7): /* Don't enable it by default yet. */ if (amdgpu_tmz < 1) { -- GitLab From 4d1e5f12b7a0d2ade73003d2522a23b4559c7e02 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Wed, 1 Jun 2022 19:02:45 -0400 Subject: [PATCH 041/942] drm/amdgpu: Update PDEs flush TLB if PTB/PDB moved MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flush TLBs when existing PDEs are updated because a PTB or PDB moved, but avoids unnecessary TLB flushes when new PDBs or PTBs are added to the page table, which commonly happens when memory is mapped for the first time. Suggested-by: Christian König Signed-off-by: Philip Yang Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 2ceeaa4c793ae..109d8dd71c116 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -679,6 +679,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, { struct amdgpu_vm_update_params params; struct amdgpu_vm_bo_base *entry; + bool flush_tlb_needed = false; int r, idx; if (list_empty(&vm->relocated)) @@ -697,6 +698,9 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, goto error; list_for_each_entry(entry, &vm->relocated, vm_status) { + /* vm_flush_needed after updating moved PDEs */ + flush_tlb_needed |= entry->moved; + r = amdgpu_vm_pde_update(¶ms, entry); if (r) goto error; @@ -706,8 +710,8 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev, if (r) goto error; - /* vm_flush_needed after updating PDEs */ - atomic64_inc(&vm->tlb_seq); + if (flush_tlb_needed) + atomic64_inc(&vm->tlb_seq); while (!list_empty(&vm->relocated)) { entry = list_first_entry(&vm->relocated, -- GitLab From 4fac4fcf4500bce515b0f32195e7bb86aa0246c6 Mon Sep 17 00:00:00 2001 From: Lang Yu Date: Tue, 31 May 2022 09:19:43 +0800 Subject: [PATCH 042/942] drm/amdkfd: add pinned BOs to kfd_bo_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kfd_bo_list is used to restore process BOs after evictions. As page tables could be destroyed during evictions, we should also update pinned BOs' page tables during restoring to make sure they are valid. So for pinned BOs, 1, Validate them and update their page tables. 2, Don't add eviction fence for them. v2: - Don't handle pinned ones specially in BO validation.(Felix) Signed-off-by: Lang Yu Acked-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 67abf8dcd30ac..6b6d46e29e6e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1918,9 +1918,6 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev, return -EINVAL; } - /* delete kgd_mem from kfd_bo_list to avoid re-validating - * this BO in BO's restoring after eviction. - */ mutex_lock(&mem->process_info->lock); ret = amdgpu_bo_reserve(bo, true); @@ -1943,7 +1940,6 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct amdgpu_device *adev, amdgpu_amdkfd_remove_eviction_fence( bo, mem->process_info->eviction_fence); - list_del_init(&mem->validate_list.head); if (size) *size = amdgpu_bo_size(bo); @@ -2512,12 +2508,15 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef) process_info->eviction_fence = new_fence; *ef = dma_fence_get(&new_fence->base); - /* Attach new eviction fence to all BOs */ + /* Attach new eviction fence to all BOs except pinned ones */ list_for_each_entry(mem, &process_info->kfd_bo_list, - validate_list.head) + validate_list.head) { + if (mem->bo->tbo.pin_count) + continue; + amdgpu_bo_fence(mem->bo, &process_info->eviction_fence->base, true); - + } /* Attach eviction fence to PD / PT BOs */ list_for_each_entry(peer_vm, &process_info->vm_list_head, vm_list_node) { -- GitLab From 88467db6e2f46a2e79b1b67ce6873c284e4cf417 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Fri, 3 Jun 2022 09:19:34 -0400 Subject: [PATCH 043/942] drm/amdkfd: Fix partial migration bugs Migration range from system memory to VRAM, if system page can not be locked or unmapped, we do partial migration and leave some pages in system memory. Several bugs found to copy pages and update GPU mapping for this situation: 1. copy to vram should use migrate->npage which is total pages of range as npages, not migrate->cpages which is number of pages can be migrated. 2. After partial copy, set VRAM res cursor as j + 1, j is number of system pages copied plus 1 page to skip copy. 3. copy to ram, should collect all continuous VRAM pages and copy together. 4. Call amdgpu_vm_update_range, should pass in offset as bytes, not as number of pages. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 6 +++--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c index 997650d597eca..e44376c2ecdcd 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -296,7 +296,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, struct migrate_vma *migrate, struct dma_fence **mfence, dma_addr_t *scratch) { - uint64_t npages = migrate->cpages; + uint64_t npages = migrate->npages; struct device *dev = adev->dev; struct amdgpu_res_cursor cursor; dma_addr_t *src; @@ -344,7 +344,7 @@ svm_migrate_copy_to_vram(struct amdgpu_device *adev, struct svm_range *prange, mfence); if (r) goto out_free_vram_pages; - amdgpu_res_next(&cursor, j << PAGE_SHIFT); + amdgpu_res_next(&cursor, (j + 1) << PAGE_SHIFT); j = 0; } else { amdgpu_res_next(&cursor, PAGE_SIZE); @@ -590,7 +590,7 @@ svm_migrate_copy_to_ram(struct amdgpu_device *adev, struct svm_range *prange, continue; } src[i] = svm_migrate_addr(adev, spage); - if (i > 0 && src[i] != src[i - 1] + PAGE_SIZE) { + if (j > 0 && src[i] != src[i - 1] + PAGE_SIZE) { r = svm_migrate_copy_memory_gart(adev, dst + i - j, src + i - j, j, FROM_VRAM_TO_RAM, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 3bd0f1a670bb7..7b332246eda3e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1295,7 +1295,7 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange, r = amdgpu_vm_update_range(adev, vm, false, false, flush_tlb, NULL, last_start, prange->start + i, pte_flags, - last_start - prange->start, + (last_start - prange->start) << PAGE_SHIFT, bo_adev ? bo_adev->vm_manager.vram_base_offset : 0, NULL, dma_addr, &vm->last_update); -- GitLab From 4513edf74cc82c15bc1cefc2ab62ff25fe67028e Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 30 May 2022 11:37:07 +0800 Subject: [PATCH 044/942] drm/amd/pm: suppress compile warnings about possible unaligned accesses Suppress the following compile warnings: >> drivers/gpu/drm/amd/amdgpu/../pm/swsmu/inc/smu_v11_0_pptable.h:163:17: warning: field smc_pptable within 'struct smu_11_0_powerplay_table' is less aligned than 'PPTable_t' and is usually due to 'struct smu_11_0_powerplay_table' being packed, which can lead to unaligned accesses [-Wunaligned-access] PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h ^ 1 warning generated. -- >> drivers/gpu/drm/amd/amdgpu/../pm/swsmu/inc/smu_v11_0_7_pptable.h:193:17: warning: field smc_pptable within 'struct smu_11_0_7_powerplay_table' is less aligned than 'PPTable_t' and is usually due to 'struct smu_11_0_7_powerplay_table' being packed, which can lead to unaligned accesses [-Wunaligned-access] PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h ^ 1 warning generated. -- >> drivers/gpu/drm/amd/amdgpu/../pm/swsmu/inc/smu_v13_0_pptable.h:161:12: warning: field smc_pptable within 'struct smu_13_0_powerplay_table' is less aligned than 'PPTable_t' and is usually due to 'struct smu_13_0_powerplay_table' being packed, which can lead to unaligned accesses [-Wunaligned-access] Signed-off-by: Evan Quan Reported-by: kernel test robot Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h | 9 ++++++--- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h | 9 ++++++--- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h | 5 ++++- drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h | 10 +++++++--- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h index 247c6e9632ba1..1cb399dbc7cc8 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_7_pptable.h @@ -22,6 +22,7 @@ #ifndef SMU_11_0_7_PPTABLE_H #define SMU_11_0_7_PPTABLE_H +#pragma pack(push, 1) #define SMU_11_0_7_TABLE_FORMAT_REVISION 15 @@ -139,7 +140,7 @@ struct smu_11_0_7_overdrive_table uint32_t max[SMU_11_0_7_MAX_ODSETTING]; //default maximum settings uint32_t min[SMU_11_0_7_MAX_ODSETTING]; //default minimum settings int16_t pm_setting[SMU_11_0_7_MAX_PMSETTING]; //Optimized power mode feature settings -} __attribute__((packed)); +}; enum SMU_11_0_7_PPCLOCK_ID { SMU_11_0_7_PPCLOCK_GFXCLK = 0, @@ -166,7 +167,7 @@ struct smu_11_0_7_power_saving_clock_table uint32_t count; //power_saving_clock_count = SMU_11_0_7_PPCLOCK_COUNT uint32_t max[SMU_11_0_7_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Maximum array In MHz uint32_t min[SMU_11_0_7_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz -} __attribute__((packed)); +}; struct smu_11_0_7_powerplay_table { @@ -191,6 +192,8 @@ struct smu_11_0_7_powerplay_table struct smu_11_0_7_overdrive_table overdrive_table; PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h -} __attribute__((packed)); +}; + +#pragma pack(pop) #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h index 7a63cf8e85ed9..0116e3d04fad2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h @@ -22,6 +22,7 @@ #ifndef SMU_11_0_PPTABLE_H #define SMU_11_0_PPTABLE_H +#pragma pack(push, 1) #define SMU_11_0_TABLE_FORMAT_REVISION 12 @@ -109,7 +110,7 @@ struct smu_11_0_overdrive_table uint8_t cap[SMU_11_0_MAX_ODFEATURE]; //OD feature support flags uint32_t max[SMU_11_0_MAX_ODSETTING]; //default maximum settings uint32_t min[SMU_11_0_MAX_ODSETTING]; //default minimum settings -} __attribute__((packed)); +}; enum SMU_11_0_PPCLOCK_ID { SMU_11_0_PPCLOCK_GFXCLK = 0, @@ -133,7 +134,7 @@ struct smu_11_0_power_saving_clock_table uint32_t count; //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT uint32_t max[SMU_11_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Maximum array In MHz uint32_t min[SMU_11_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz -} __attribute__((packed)); +}; struct smu_11_0_powerplay_table { @@ -162,6 +163,8 @@ struct smu_11_0_powerplay_table #ifndef SMU_11_0_PARTIAL_PPTABLE PPTable_t smc_pptable; //PPTable_t in smu11_driver_if.h #endif -} __attribute__((packed)); +}; + +#pragma pack(pop) #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h index 3f29f4327378c..478862ded0bde 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h @@ -22,6 +22,8 @@ #ifndef SMU_13_0_7_PPTABLE_H #define SMU_13_0_7_PPTABLE_H +#pragma pack(push, 1) + #define SMU_13_0_7_TABLE_FORMAT_REVISION 15 //// POWERPLAYTABLE::ulPlatformCaps @@ -194,7 +196,8 @@ struct smu_13_0_7_powerplay_table struct smu_13_0_7_overdrive_table overdrive_table; uint8_t padding1; PPTable_t smc_pptable; //PPTable_t in driver_if.h -} __attribute__((packed)); +}; +#pragma pack(pop) #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h index 1f311396b7067..0433074855286 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_pptable.h @@ -22,6 +22,8 @@ #ifndef SMU_13_0_PPTABLE_H #define SMU_13_0_PPTABLE_H +#pragma pack(push, 1) + #define SMU_13_0_TABLE_FORMAT_REVISION 1 //// POWERPLAYTABLE::ulPlatformCaps @@ -109,7 +111,7 @@ struct smu_13_0_overdrive_table { uint8_t cap[SMU_13_0_MAX_ODFEATURE]; //OD feature support flags uint32_t max[SMU_13_0_MAX_ODSETTING]; //default maximum settings uint32_t min[SMU_13_0_MAX_ODSETTING]; //default minimum settings -} __attribute__((packed)); +}; enum SMU_13_0_PPCLOCK_ID { SMU_13_0_PPCLOCK_GFXCLK = 0, @@ -132,7 +134,7 @@ struct smu_13_0_power_saving_clock_table { uint32_t count; //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT uint32_t max[SMU_13_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Maximum array In MHz uint32_t min[SMU_13_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz -} __attribute__((packed)); +}; struct smu_13_0_powerplay_table { struct atom_common_table_header header; @@ -160,6 +162,8 @@ struct smu_13_0_powerplay_table { #ifndef SMU_13_0_PARTIAL_PPTABLE PPTable_t smc_pptable; //PPTable_t in driver_if.h #endif -} __attribute__((packed)); +}; + +#pragma pack(pop) #endif -- GitLab From 12d6c18cfa708e954a7de27dd76cf45054c8855a Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 30 May 2022 14:58:08 +0800 Subject: [PATCH 045/942] drm/amdgpu: suppress the compile warning about 64 bit type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suppress the compile warning below: drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c:1292 gfx_v11_0_rlc_backdoor_autoload_copy_ucode() warn: should '1 << id' be a 64 bit type? Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Evan Quan Reviewed-by: Guchun Chen Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 628d3536938e7..10e180b2d0f52 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1316,7 +1316,7 @@ static void gfx_v11_0_rlc_backdoor_autoload_copy_ucode(struct amdgpu_device *ade memset(ptr + toc_offset + fw_size, 0, toc_fw_size - fw_size); if ((id != SOC21_FIRMWARE_ID_RS64_PFP) && (id != SOC21_FIRMWARE_ID_RS64_ME)) - *(uint64_t *)fw_autoload_mask |= 1 << id; + *(uint64_t *)fw_autoload_mask |= 1ULL << id; } static void gfx_v11_0_rlc_backdoor_autoload_copy_toc_ucode(struct amdgpu_device *adev, -- GitLab From 7ad4bd887d27c6b6ffbef216f19c19f8fe2b8f52 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 4 Jun 2022 17:50:50 +0900 Subject: [PATCH 046/942] powerpc/book3e: get rid of #include You cannot include here because it is generated in init/Makefile but there is no guarantee that it happens before arch/powerpc/mm/nohash/kaslr_booke.c is compiled for parallel builds. The places where you can reliably include are: - init/ (because init/Makefile can specify the dependency) - arch/*/boot/ (because it is compiled after vmlinux) Commit f231e4333312 ("hexagon: get rid of #include ") fixed the last breakage at that time, but powerpc re-added this. was unneeded because 'build_str' is almost the same as 'linux_banner' defined in init/version.c Let's copy the solution from MIPS. (get_random_boot() in arch/mips/kernel/relocate.c) Fixes: 6a38ea1d7b94 ("powerpc/fsl_booke/32: randomize the kernel image offset") Signed-off-by: Masahiro Yamada Acked-by: Scott Wood Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220604085050.4078927-1-masahiroy@kernel.org --- arch/powerpc/mm/nohash/kaslr_booke.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c index 1f3f9fedf1bc2..0d04f9d5da8d2 100644 --- a/arch/powerpc/mm/nohash/kaslr_booke.c +++ b/arch/powerpc/mm/nohash/kaslr_booke.c @@ -19,7 +19,6 @@ #include #include #include -#include #include struct regions { @@ -37,10 +36,6 @@ struct regions { int reserved_mem_size_cells; }; -/* Simplified build-specific string for starting entropy. */ -static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; - struct regions __initdata regions; static __init void kaslr_get_cmdline(void *fdt) @@ -71,7 +66,8 @@ static unsigned long __init get_boot_seed(void *fdt) { unsigned long hash = 0; - hash = rotate_xor(hash, build_str, sizeof(build_str)); + /* build-specific string for starting entropy. */ + hash = rotate_xor(hash, linux_banner, strlen(linux_banner)); hash = rotate_xor(hash, fdt, fdt_totalsize(fdt)); return hash; -- GitLab From a734510fa8b4e61e6a37176f0da01f4c55fa52de Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 25 May 2022 13:49:42 +0200 Subject: [PATCH 047/942] ata: libata: drop 'sas_last_tag' Unused now. Fixes: 4f1a22ee7b57 ("libata: Improve ATA queued command allocation") Cc: John Garry Signed-off-by: Hannes Reinecke Reviewed-by: John Garry Signed-off-by: Damien Le Moal --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/libata.h b/include/linux/libata.h index 732de90146261..0f2a59c9c735a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -822,7 +822,6 @@ struct ata_port { struct ata_queued_cmd qcmd[ATA_MAX_QUEUE + 1]; u64 qc_active; int nr_active_links; /* #links with active qcs */ - unsigned int sas_last_tag; /* track next tag hw expects */ struct ata_link link; /* host default link */ struct ata_link *slave_link; /* see ata_slave_link_init() */ -- GitLab From bf476fe22aa1851bab4728e0c49025a6a0bea307 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sat, 21 May 2022 23:34:10 +0300 Subject: [PATCH 048/942] ata: libata-core: fix NULL pointer deref in ata_host_alloc_pinfo() In an unlikely (and probably wrong?) case that the 'ppi' parameter of ata_host_alloc_pinfo() points to an array starting with a NULL pointer, there's going to be a kernel oops as the 'pi' local variable won't get reassigned from the initial value of NULL. Initialize 'pi' instead to '&ata_dummy_port_info' to fix the possible kernel oops for good... Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 40e816419f48c..c214ff928e452 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5462,7 +5462,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, const struct ata_port_info * const * ppi, int n_ports) { - const struct ata_port_info *pi; + const struct ata_port_info *pi = &ata_dummy_port_info; struct ata_host *host; int i, j; @@ -5470,7 +5470,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, if (!host) return NULL; - for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) { + for (i = 0, j = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; if (ppi[j]) -- GitLab From 10d6bdf532902be1d8aa5900b3c03c5671612aa2 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Wed, 1 Jun 2022 12:59:26 +0400 Subject: [PATCH 049/942] ata: pata_octeon_cf: Fix refcount leak in octeon_cf_probe of_find_device_by_node() takes reference, we should use put_device() to release it when not need anymore. Add missing put_device() to avoid refcount leak. Fixes: 43f01da0f279 ("MIPS/OCTEON/ata: Convert pata_octeon_cf.c to use device tree.") Signed-off-by: Miaoqian Lin Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_octeon_cf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 6b5ed3046b44d..35608a0cf552e 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -856,12 +856,14 @@ static int octeon_cf_probe(struct platform_device *pdev) int i; res_dma = platform_get_resource(dma_dev, IORESOURCE_MEM, 0); if (!res_dma) { + put_device(&dma_dev->dev); of_node_put(dma_node); return -EINVAL; } cf_port->dma_base = (u64)devm_ioremap(&pdev->dev, res_dma->start, resource_size(res_dma)); if (!cf_port->dma_base) { + put_device(&dma_dev->dev); of_node_put(dma_node); return -EINVAL; } @@ -871,6 +873,7 @@ static int octeon_cf_probe(struct platform_device *pdev) irq = i; irq_handler = octeon_cf_interrupt; } + put_device(&dma_dev->dev); } of_node_put(dma_node); } -- GitLab From c36ee7dab7749f7be21f7a72392744490b2a9a2b Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Sun, 5 Jun 2022 19:54:26 -0300 Subject: [PATCH 050/942] cifs: fix reconnect on smb3 mount types cifs.ko defines two file system types: cifs & smb3, and __cifs_get_super() was not including smb3 file system type when looking up superblocks, therefore failing to reconnect tcons in cifs_tree_connect(). Fix this by calling iterate_supers_type() on both file system types. Link: https://lore.kernel.org/r/CAFrh3J9soC36+BVuwHB=g9z_KB5Og2+p2_W+BBoBOZveErz14w@mail.gmail.com Cc: stable@vger.kernel.org Tested-by: Satadru Pramanik Reported-by: Satadru Pramanik Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsfs.h | 2 +- fs/cifs/misc.c | 27 ++++++++++++++++----------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 12c872800326f..325423180fd2b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1086,7 +1086,7 @@ struct file_system_type cifs_fs_type = { }; MODULE_ALIAS_FS("cifs"); -static struct file_system_type smb3_fs_type = { +struct file_system_type smb3_fs_type = { .owner = THIS_MODULE, .name = "smb3", .init_fs_context = smb3_init_fs_context, diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index dd7e070ca243c..b17be47a8e595 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -38,7 +38,7 @@ static inline unsigned long cifs_get_time(struct dentry *dentry) return (unsigned long) dentry->d_fsdata; } -extern struct file_system_type cifs_fs_type; +extern struct file_system_type cifs_fs_type, smb3_fs_type; extern const struct address_space_operations cifs_addr_ops; extern const struct address_space_operations cifs_addr_ops_smallbuf; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 35962a1a23b90..8e67a2d406abd 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1211,18 +1211,23 @@ static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void .data = data, .sb = NULL, }; + struct file_system_type **fs_type = (struct file_system_type *[]) { + &cifs_fs_type, &smb3_fs_type, NULL, + }; - iterate_supers_type(&cifs_fs_type, f, &sd); - - if (!sd.sb) - return ERR_PTR(-EINVAL); - /* - * Grab an active reference in order to prevent automounts (DFS links) - * of expiring and then freeing up our cifs superblock pointer while - * we're doing failover. - */ - cifs_sb_active(sd.sb); - return sd.sb; + for (; *fs_type; fs_type++) { + iterate_supers_type(*fs_type, f, &sd); + if (sd.sb) { + /* + * Grab an active reference in order to prevent automounts (DFS links) + * of expiring and then freeing up our cifs superblock pointer while + * we're doing failover. + */ + cifs_sb_active(sd.sb); + return sd.sb; + } + } + return ERR_PTR(-EINVAL); } static void __cifs_put_super(struct super_block *sb) -- GitLab From 2130a790ca49763f724ec45cf93b9dd765e2023e Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 2 Jun 2022 15:05:26 +0200 Subject: [PATCH 051/942] kernel: add platform_has() infrastructure Add a simple infrastructure for setting, resetting and querying platform feature flags. Flags can be either global or architecture specific. Signed-off-by: Juergen Gross Reviewed-by: Oleksandr Tyshchenko Tested-by: Oleksandr Tyshchenko # Arm64 only Reviewed-by: Christoph Hellwig Acked-by: Borislav Petkov Signed-off-by: Juergen Gross --- MAINTAINERS | 8 ++++++++ include/asm-generic/Kbuild | 1 + include/asm-generic/platform-feature.h | 8 ++++++++ include/linux/platform-feature.h | 15 ++++++++++++++ kernel/Makefile | 2 +- kernel/platform-feature.c | 27 ++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 include/asm-generic/platform-feature.h create mode 100644 include/linux/platform-feature.h create mode 100644 kernel/platform-feature.c diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d0..06678abc22ca2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15824,6 +15824,14 @@ S: Maintained F: Documentation/devicetree/bindings/iio/chemical/plantower,pms7003.yaml F: drivers/iio/chemical/pms7003.c +PLATFORM FEATURE INFRASTRUCTURE +M: Juergen Gross +S: Maintained +F: arch/*/include/asm/platform-feature.h +F: include/asm-generic/platform-feature.h +F: include/linux/platform-feature.h +F: kernel/platform-feature.c + PLDMFW LIBRARY M: Jacob Keller S: Maintained diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild index 302506bbc2a4f..8e47d483b5240 100644 --- a/include/asm-generic/Kbuild +++ b/include/asm-generic/Kbuild @@ -44,6 +44,7 @@ mandatory-y += msi.h mandatory-y += pci.h mandatory-y += percpu.h mandatory-y += pgalloc.h +mandatory-y += platform-feature.h mandatory-y += preempt.h mandatory-y += rwonce.h mandatory-y += sections.h diff --git a/include/asm-generic/platform-feature.h b/include/asm-generic/platform-feature.h new file mode 100644 index 0000000000000..4b0af3d515888 --- /dev/null +++ b/include/asm-generic/platform-feature.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_GENERIC_PLATFORM_FEATURE_H +#define _ASM_GENERIC_PLATFORM_FEATURE_H + +/* Number of arch specific feature flags. */ +#define PLATFORM_ARCH_FEAT_N 0 + +#endif /* _ASM_GENERIC_PLATFORM_FEATURE_H */ diff --git a/include/linux/platform-feature.h b/include/linux/platform-feature.h new file mode 100644 index 0000000000000..6ed859928b978 --- /dev/null +++ b/include/linux/platform-feature.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _PLATFORM_FEATURE_H +#define _PLATFORM_FEATURE_H + +#include +#include + +/* The platform features are starting with the architecture specific ones. */ +#define PLATFORM_FEAT_N (0 + PLATFORM_ARCH_FEAT_N) + +void platform_set(unsigned int feature); +void platform_clear(unsigned int feature); +bool platform_has(unsigned int feature); + +#endif /* _PLATFORM_FEATURE_H */ diff --git a/kernel/Makefile b/kernel/Makefile index 318789c728d32..a7e1f49ab2b3b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -7,7 +7,7 @@ obj-y = fork.o exec_domain.o panic.o \ cpu.o exit.o softirq.o resource.o \ sysctl.o capability.o ptrace.o user.o \ signal.o sys.o umh.o workqueue.o pid.o task_work.o \ - extable.o params.o \ + extable.o params.o platform-feature.o \ kthread.o sys_ni.o nsproxy.o \ notifier.o ksysfs.o cred.o reboot.o \ async.o range.o smpboot.o ucount.o regset.o diff --git a/kernel/platform-feature.c b/kernel/platform-feature.c new file mode 100644 index 0000000000000..cb6a6c3e4fed1 --- /dev/null +++ b/kernel/platform-feature.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include + +#define PLATFORM_FEAT_ARRAY_SZ BITS_TO_LONGS(PLATFORM_FEAT_N) +static unsigned long __read_mostly platform_features[PLATFORM_FEAT_ARRAY_SZ]; + +void platform_set(unsigned int feature) +{ + set_bit(feature, platform_features); +} +EXPORT_SYMBOL_GPL(platform_set); + +void platform_clear(unsigned int feature) +{ + clear_bit(feature, platform_features); +} +EXPORT_SYMBOL_GPL(platform_clear); + +bool platform_has(unsigned int feature) +{ + return test_bit(feature, platform_features); +} +EXPORT_SYMBOL_GPL(platform_has); -- GitLab From 3f9dfbebdc48cebfbda738f6f3d1dbf6d7232f90 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Mon, 6 Jun 2022 08:09:16 +0200 Subject: [PATCH 052/942] virtio: replace arch_has_restricted_virtio_memory_access() Instead of using arch_has_restricted_virtio_memory_access() together with CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS, replace those with platform_has() and a new platform feature PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS. Signed-off-by: Juergen Gross Reviewed-by: Oleksandr Tyshchenko Tested-by: Oleksandr Tyshchenko # Arm64 only Reviewed-by: Christoph Hellwig Acked-by: Borislav Petkov --- arch/s390/Kconfig | 1 - arch/s390/mm/init.c | 13 +++---------- arch/x86/Kconfig | 1 - arch/x86/mm/mem_encrypt.c | 7 ------- arch/x86/mm/mem_encrypt_amd.c | 4 ++++ drivers/virtio/Kconfig | 6 ------ drivers/virtio/virtio.c | 5 ++--- include/linux/platform-feature.h | 6 +++++- include/linux/virtio_config.h | 9 --------- 9 files changed, 14 insertions(+), 38 deletions(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b1a88f6cc3494..bf253628c136d 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -768,7 +768,6 @@ menu "Virtualization" config PROTECTED_VIRTUALIZATION_GUEST def_bool n prompt "Protected virtualization guest support" - select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS help Select this option, if you want to be able to run this kernel as a protected virtualization KVM guest. diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 6fb6bf64326f9..6a0ac00d5a42b 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -168,22 +169,14 @@ bool force_dma_unencrypted(struct device *dev) return is_prot_virt_guest(); } -#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS - -int arch_has_restricted_virtio_memory_access(void) -{ - return is_prot_virt_guest(); -} -EXPORT_SYMBOL(arch_has_restricted_virtio_memory_access); - -#endif - /* protected virtualization */ static void pv_init(void) { if (!is_prot_virt_guest()) return; + platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); + /* make sure bounce buffers are shared */ swiotlb_init(true, SWIOTLB_FORCE | SWIOTLB_VERBOSE); swiotlb_update_mem_attributes(); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 9783ebc4e0212..be0b95e51df66 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1542,7 +1542,6 @@ config X86_CPA_STATISTICS config X86_MEM_ENCRYPT select ARCH_HAS_FORCE_DMA_UNENCRYPTED select DYNAMIC_PHYSICAL_MASK - select ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS def_bool n config AMD_MEM_ENCRYPT diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index 11350e2fd7366..9f27e14e185f3 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -12,7 +12,6 @@ #include #include #include -#include /* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */ bool force_dma_unencrypted(struct device *dev) @@ -87,9 +86,3 @@ void __init mem_encrypt_init(void) print_mem_encrypt_feature_info(); } - -int arch_has_restricted_virtio_memory_access(void) -{ - return cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT); -} -EXPORT_SYMBOL_GPL(arch_has_restricted_virtio_memory_access); diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c index e8f7953fda83a..f6d038e2cd8e8 100644 --- a/arch/x86/mm/mem_encrypt_amd.c +++ b/arch/x86/mm/mem_encrypt_amd.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -242,6 +243,9 @@ void __init sev_setup_arch(void) size = total_mem * 6 / 100; size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G); swiotlb_adjust_size(size); + + /* Set restricted memory access for virtio. */ + platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); } static unsigned long pg_level_to_pfn(int level, pte_t *kpte, pgprot_t *ret_prot) diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index b5adf6abd241e..a6dc8b5846fe7 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -6,12 +6,6 @@ config VIRTIO bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG or CONFIG_S390_GUEST. -config ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS - bool - help - This option is selected if the architecture may need to enforce - VIRTIO_F_ACCESS_PLATFORM - config VIRTIO_PCI_LIB tristate help diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index ef04a96942bfb..6bace84ae37ec 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -5,6 +5,7 @@ #include #include #include +#include #include /* Unique numbering for virtio devices. */ @@ -170,12 +171,10 @@ EXPORT_SYMBOL_GPL(virtio_add_status); static int virtio_features_ok(struct virtio_device *dev) { unsigned int status; - int ret; might_sleep(); - ret = arch_has_restricted_virtio_memory_access(); - if (ret) { + if (platform_has(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS)) { if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) { dev_warn(&dev->dev, "device must provide VIRTIO_F_VERSION_1\n"); diff --git a/include/linux/platform-feature.h b/include/linux/platform-feature.h index 6ed859928b978..b2f48be999fa4 100644 --- a/include/linux/platform-feature.h +++ b/include/linux/platform-feature.h @@ -6,7 +6,11 @@ #include /* The platform features are starting with the architecture specific ones. */ -#define PLATFORM_FEAT_N (0 + PLATFORM_ARCH_FEAT_N) + +/* Used to enable platform specific DMA handling for virtio devices. */ +#define PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS (0 + PLATFORM_ARCH_FEAT_N) + +#define PLATFORM_FEAT_N (1 + PLATFORM_ARCH_FEAT_N) void platform_set(unsigned int feature); void platform_clear(unsigned int feature); diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index 9a36051ceb767..49c7c32815f15 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -604,13 +604,4 @@ static inline void virtio_cwrite64(struct virtio_device *vdev, _r; \ }) -#ifdef CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS -int arch_has_restricted_virtio_memory_access(void); -#else -static inline int arch_has_restricted_virtio_memory_access(void) -{ - return 0; -} -#endif /* CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS */ - #endif /* _LINUX_VIRTIO_CONFIG_H */ -- GitLab From 9bf22421dc8a69cade3c994771637e9693ff0216 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Thu, 2 Jun 2022 22:23:46 +0300 Subject: [PATCH 053/942] arm/xen: Introduce xen_setup_dma_ops() This patch introduces new helper and places it in new header. The helper's purpose is to assign any Xen specific DMA ops in a single place. For now, we deal with xen-swiotlb DMA ops only. The one of the subsequent commits in current series will add xen-grant DMA ops case. Also re-use the xen_swiotlb_detect() check on Arm32. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini [For arm64] Acked-by: Catalin Marinas Link: https://lore.kernel.org/r/1654197833-25362-2-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- arch/arm/include/asm/xen/xen-ops.h | 2 ++ arch/arm/mm/dma-mapping.c | 7 ++----- arch/arm64/include/asm/xen/xen-ops.h | 2 ++ arch/arm64/mm/dma-mapping.c | 7 ++----- include/xen/arm/xen-ops.h | 15 +++++++++++++++ 5 files changed, 23 insertions(+), 10 deletions(-) create mode 100644 arch/arm/include/asm/xen/xen-ops.h create mode 100644 arch/arm64/include/asm/xen/xen-ops.h create mode 100644 include/xen/arm/xen-ops.h diff --git a/arch/arm/include/asm/xen/xen-ops.h b/arch/arm/include/asm/xen/xen-ops.h new file mode 100644 index 0000000000000..7ebb7eb0bd937 --- /dev/null +++ b/arch/arm/include/asm/xen/xen-ops.h @@ -0,0 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 82ffac621854f..059cce0185706 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include "dma.h" #include "mm.h" @@ -2287,10 +2287,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, set_dma_ops(dev, dma_ops); -#ifdef CONFIG_XEN - if (xen_initial_domain()) - dev->dma_ops = &xen_swiotlb_dma_ops; -#endif + xen_setup_dma_ops(dev); dev->archdata.dma_ops_setup = true; } diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h new file mode 100644 index 0000000000000..7ebb7eb0bd937 --- /dev/null +++ b/arch/arm64/include/asm/xen/xen-ops.h @@ -0,0 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 6719f9efea093..6099c81b93223 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -9,9 +9,9 @@ #include #include #include -#include #include +#include void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir) @@ -52,8 +52,5 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (iommu) iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1); -#ifdef CONFIG_XEN - if (xen_swiotlb_detect()) - dev->dma_ops = &xen_swiotlb_dma_ops; -#endif + xen_setup_dma_ops(dev); } diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h new file mode 100644 index 0000000000000..288deb1c3ac96 --- /dev/null +++ b/include/xen/arm/xen-ops.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM_XEN_OPS_H +#define _ASM_ARM_XEN_OPS_H + +#include + +static inline void xen_setup_dma_ops(struct device *dev) +{ +#ifdef CONFIG_XEN + if (xen_swiotlb_detect()) + dev->dma_ops = &xen_swiotlb_dma_ops; +#endif +} + +#endif /* _ASM_ARM_XEN_OPS_H */ -- GitLab From 02a9e681a3f7998074f39ec265080bf934871530 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 2 Jun 2022 22:23:47 +0300 Subject: [PATCH 054/942] xen/grants: support allocating consecutive grants For support of virtio via grant mappings in rare cases larger mappings using consecutive grants are needed. Support those by adding a bitmap of free grants. As consecutive grants will be needed only in very rare cases (e.g. when configuring a virtio device with a multi-page ring), optimize for the normal case of non-consecutive allocations. Signed-off-by: Juergen Gross Reviewed-by: Boris Ostrovsky Link: https://lore.kernel.org/r/1654197833-25362-3-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- drivers/xen/grant-table.c | 251 ++++++++++++++++++++++++++++++++------ include/xen/grant_table.h | 4 + 2 files changed, 219 insertions(+), 36 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 7a18292540bc3..738029de3c672 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -33,6 +33,7 @@ #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -70,9 +71,32 @@ static grant_ref_t **gnttab_list; static unsigned int nr_grant_frames; + +/* + * Handling of free grants: + * + * Free grants are in a simple list anchored in gnttab_free_head. They are + * linked by grant ref, the last element contains GNTTAB_LIST_END. The number + * of free entries is stored in gnttab_free_count. + * Additionally there is a bitmap of free entries anchored in + * gnttab_free_bitmap. This is being used for simplifying allocation of + * multiple consecutive grants, which is needed e.g. for support of virtio. + * gnttab_last_free is used to add free entries of new frames at the end of + * the free list. + * gnttab_free_tail_ptr specifies the variable which references the start + * of consecutive free grants ending with gnttab_last_free. This pointer is + * updated in a rather defensive way, in order to avoid performance hits in + * hot paths. + * All those variables are protected by gnttab_list_lock. + */ static int gnttab_free_count; -static grant_ref_t gnttab_free_head; +static unsigned int gnttab_size; +static grant_ref_t gnttab_free_head = GNTTAB_LIST_END; +static grant_ref_t gnttab_last_free = GNTTAB_LIST_END; +static grant_ref_t *gnttab_free_tail_ptr; +static unsigned long *gnttab_free_bitmap; static DEFINE_SPINLOCK(gnttab_list_lock); + struct grant_frames xen_auto_xlat_grant_frames; static unsigned int xen_gnttab_version; module_param_named(version, xen_gnttab_version, uint, 0); @@ -168,16 +192,116 @@ static int get_free_entries(unsigned count) ref = head = gnttab_free_head; gnttab_free_count -= count; - while (count-- > 1) - head = gnttab_entry(head); + while (count--) { + bitmap_clear(gnttab_free_bitmap, head, 1); + if (gnttab_free_tail_ptr == __gnttab_entry(head)) + gnttab_free_tail_ptr = &gnttab_free_head; + if (count) + head = gnttab_entry(head); + } gnttab_free_head = gnttab_entry(head); gnttab_entry(head) = GNTTAB_LIST_END; + if (!gnttab_free_count) { + gnttab_last_free = GNTTAB_LIST_END; + gnttab_free_tail_ptr = NULL; + } + spin_unlock_irqrestore(&gnttab_list_lock, flags); return ref; } +static int get_seq_entry_count(void) +{ + if (gnttab_last_free == GNTTAB_LIST_END || !gnttab_free_tail_ptr || + *gnttab_free_tail_ptr == GNTTAB_LIST_END) + return 0; + + return gnttab_last_free - *gnttab_free_tail_ptr + 1; +} + +/* Rebuilds the free grant list and tries to find count consecutive entries. */ +static int get_free_seq(unsigned int count) +{ + int ret = -ENOSPC; + unsigned int from, to; + grant_ref_t *last; + + gnttab_free_tail_ptr = &gnttab_free_head; + last = &gnttab_free_head; + + for (from = find_first_bit(gnttab_free_bitmap, gnttab_size); + from < gnttab_size; + from = find_next_bit(gnttab_free_bitmap, gnttab_size, to + 1)) { + to = find_next_zero_bit(gnttab_free_bitmap, gnttab_size, + from + 1); + if (ret < 0 && to - from >= count) { + ret = from; + bitmap_clear(gnttab_free_bitmap, ret, count); + from += count; + gnttab_free_count -= count; + if (from == to) + continue; + } + + /* + * Recreate the free list in order to have it properly sorted. + * This is needed to make sure that the free tail has the maximum + * possible size. + */ + while (from < to) { + *last = from; + last = __gnttab_entry(from); + gnttab_last_free = from; + from++; + } + if (to < gnttab_size) + gnttab_free_tail_ptr = __gnttab_entry(to - 1); + } + + *last = GNTTAB_LIST_END; + if (gnttab_last_free != gnttab_size - 1) + gnttab_free_tail_ptr = NULL; + + return ret; +} + +static int get_free_entries_seq(unsigned int count) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&gnttab_list_lock, flags); + + if (gnttab_free_count < count) { + ret = gnttab_expand(count - gnttab_free_count); + if (ret < 0) + goto out; + } + + if (get_seq_entry_count() < count) { + ret = get_free_seq(count); + if (ret >= 0) + goto out; + ret = gnttab_expand(count - get_seq_entry_count()); + if (ret < 0) + goto out; + } + + ret = *gnttab_free_tail_ptr; + *gnttab_free_tail_ptr = gnttab_entry(ret + count - 1); + gnttab_free_count -= count; + if (!gnttab_free_count) + gnttab_free_tail_ptr = NULL; + bitmap_clear(gnttab_free_bitmap, ret, count); + + out: + spin_unlock_irqrestore(&gnttab_list_lock, flags); + + return ret; +} + static void do_free_callbacks(void) { struct gnttab_free_callback *callback, *next; @@ -204,21 +328,51 @@ static inline void check_free_callbacks(void) do_free_callbacks(); } -static void put_free_entry(grant_ref_t ref) +static void put_free_entry_locked(grant_ref_t ref) { - unsigned long flags; - if (unlikely(ref < GNTTAB_NR_RESERVED_ENTRIES)) return; - spin_lock_irqsave(&gnttab_list_lock, flags); gnttab_entry(ref) = gnttab_free_head; gnttab_free_head = ref; + if (!gnttab_free_count) + gnttab_last_free = ref; + if (gnttab_free_tail_ptr == &gnttab_free_head) + gnttab_free_tail_ptr = __gnttab_entry(ref); gnttab_free_count++; + bitmap_set(gnttab_free_bitmap, ref, 1); +} + +static void put_free_entry(grant_ref_t ref) +{ + unsigned long flags; + + spin_lock_irqsave(&gnttab_list_lock, flags); + put_free_entry_locked(ref); check_free_callbacks(); spin_unlock_irqrestore(&gnttab_list_lock, flags); } +static void gnttab_set_free(unsigned int start, unsigned int n) +{ + unsigned int i; + + for (i = start; i < start + n - 1; i++) + gnttab_entry(i) = i + 1; + + gnttab_entry(i) = GNTTAB_LIST_END; + if (!gnttab_free_count) { + gnttab_free_head = start; + gnttab_free_tail_ptr = &gnttab_free_head; + } else { + gnttab_entry(gnttab_last_free) = start; + } + gnttab_free_count += n; + gnttab_last_free = i; + + bitmap_set(gnttab_free_bitmap, start, n); +} + /* * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2. * Introducing a valid entry into the grant table: @@ -450,23 +604,31 @@ void gnttab_free_grant_references(grant_ref_t head) { grant_ref_t ref; unsigned long flags; - int count = 1; - if (head == GNTTAB_LIST_END) - return; + spin_lock_irqsave(&gnttab_list_lock, flags); - ref = head; - while (gnttab_entry(ref) != GNTTAB_LIST_END) { - ref = gnttab_entry(ref); - count++; + while (head != GNTTAB_LIST_END) { + ref = gnttab_entry(head); + put_free_entry_locked(head); + head = ref; } - gnttab_entry(ref) = gnttab_free_head; - gnttab_free_head = head; - gnttab_free_count += count; check_free_callbacks(); spin_unlock_irqrestore(&gnttab_list_lock, flags); } EXPORT_SYMBOL_GPL(gnttab_free_grant_references); +void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count) +{ + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&gnttab_list_lock, flags); + for (i = count; i > 0; i--) + put_free_entry_locked(head + i - 1); + check_free_callbacks(); + spin_unlock_irqrestore(&gnttab_list_lock, flags); +} +EXPORT_SYMBOL_GPL(gnttab_free_grant_reference_seq); + int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) { int h = get_free_entries(count); @@ -480,6 +642,24 @@ int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) } EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); +int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first) +{ + int h; + + if (count == 1) + h = get_free_entries(1); + else + h = get_free_entries_seq(count); + + if (h < 0) + return -ENOSPC; + + *first = h; + + return 0; +} +EXPORT_SYMBOL_GPL(gnttab_alloc_grant_reference_seq); + int gnttab_empty_grant_references(const grant_ref_t *private_head) { return (*private_head == GNTTAB_LIST_END); @@ -572,16 +752,13 @@ static int grow_gnttab_list(unsigned int more_frames) goto grow_nomem; } + gnttab_set_free(gnttab_size, extra_entries); - for (i = grefs_per_frame * nr_grant_frames; - i < grefs_per_frame * new_nr_grant_frames - 1; i++) - gnttab_entry(i) = i + 1; - - gnttab_entry(i) = gnttab_free_head; - gnttab_free_head = grefs_per_frame * nr_grant_frames; - gnttab_free_count += extra_entries; + if (!gnttab_free_tail_ptr) + gnttab_free_tail_ptr = __gnttab_entry(gnttab_size); nr_grant_frames = new_nr_grant_frames; + gnttab_size += extra_entries; check_free_callbacks(); @@ -1424,20 +1601,20 @@ static int gnttab_expand(unsigned int req_entries) int gnttab_init(void) { int i; - unsigned long max_nr_grant_frames; + unsigned long max_nr_grant_frames, max_nr_grefs; unsigned int max_nr_glist_frames, nr_glist_frames; - unsigned int nr_init_grefs; int ret; gnttab_request_version(); max_nr_grant_frames = gnttab_max_grant_frames(); + max_nr_grefs = max_nr_grant_frames * + gnttab_interface->grefs_per_grant_frame; nr_grant_frames = 1; /* Determine the maximum number of frames required for the * grant reference free list on the current hypervisor. */ - max_nr_glist_frames = (max_nr_grant_frames * - gnttab_interface->grefs_per_grant_frame / RPP); + max_nr_glist_frames = max_nr_grefs / RPP; gnttab_list = kmalloc_array(max_nr_glist_frames, sizeof(grant_ref_t *), @@ -1454,6 +1631,12 @@ int gnttab_init(void) } } + gnttab_free_bitmap = bitmap_zalloc(max_nr_grefs, GFP_KERNEL); + if (!gnttab_free_bitmap) { + ret = -ENOMEM; + goto ini_nomem; + } + ret = arch_gnttab_init(max_nr_grant_frames, nr_status_frames(max_nr_grant_frames)); if (ret < 0) @@ -1464,15 +1647,10 @@ int gnttab_init(void) goto ini_nomem; } - nr_init_grefs = nr_grant_frames * - gnttab_interface->grefs_per_grant_frame; - - for (i = GNTTAB_NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) - gnttab_entry(i) = i + 1; + gnttab_size = nr_grant_frames * gnttab_interface->grefs_per_grant_frame; - gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; - gnttab_free_count = nr_init_grefs - GNTTAB_NR_RESERVED_ENTRIES; - gnttab_free_head = GNTTAB_NR_RESERVED_ENTRIES; + gnttab_set_free(GNTTAB_NR_RESERVED_ENTRIES, + gnttab_size - GNTTAB_NR_RESERVED_ENTRIES); printk("Grant table initialized\n"); return 0; @@ -1481,6 +1659,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); + bitmap_free(gnttab_free_bitmap); return ret; } EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index 527c9907f99c6..e279be353e3f1 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -127,10 +127,14 @@ int gnttab_try_end_foreign_access(grant_ref_t ref); */ int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head); +int gnttab_alloc_grant_reference_seq(unsigned int count, grant_ref_t *first); + void gnttab_free_grant_reference(grant_ref_t ref); void gnttab_free_grant_references(grant_ref_t head); +void gnttab_free_grant_reference_seq(grant_ref_t head, unsigned int count); + int gnttab_empty_grant_references(const grant_ref_t *pprivate_head); int gnttab_claim_grant_reference(grant_ref_t *pprivate_head); -- GitLab From d6aca3504c7ded5f4f46957e3685b9344d9743dd Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 2 Jun 2022 22:23:48 +0300 Subject: [PATCH 055/942] xen/grant-dma-ops: Add option to restrict memory access under Xen Introduce Xen grant DMA-mapping layer which contains special DMA-mapping routines for providing grant references as DMA addresses to be used by frontends (e.g. virtio) in Xen guests. Add the needed functionality by providing a special set of DMA ops handling the needed grant operations for the I/O pages. The subsequent commit will introduce the use case for xen-grant DMA ops layer to enable using virtio devices in Xen guests in a safe manner. Signed-off-by: Juergen Gross Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Link: https://lore.kernel.org/r/1654197833-25362-4-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- drivers/xen/Kconfig | 4 + drivers/xen/Makefile | 1 + drivers/xen/grant-dma-ops.c | 312 ++++++++++++++++++++++++++++++++++++ include/xen/xen-ops.h | 8 + 4 files changed, 325 insertions(+) create mode 100644 drivers/xen/grant-dma-ops.c diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 120d32f164ace..313a9127fd5c3 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -335,4 +335,8 @@ config XEN_UNPOPULATED_ALLOC having to balloon out RAM regions in order to obtain physical memory space to create such mappings. +config XEN_GRANT_DMA_OPS + bool + select DMA_OPS + endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 5aae66e638a7c..1a23cb0dc1889 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -39,3 +39,4 @@ xen-gntalloc-y := gntalloc.o xen-privcmd-y := privcmd.o privcmd-buf.o obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF) += xen-front-pgdir-shbuf.o obj-$(CONFIG_XEN_UNPOPULATED_ALLOC) += unpopulated-alloc.o +obj-$(CONFIG_XEN_GRANT_DMA_OPS) += grant-dma-ops.o diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c new file mode 100644 index 0000000000000..aaff35cda5175 --- /dev/null +++ b/drivers/xen/grant-dma-ops.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Xen grant DMA-mapping layer - contains special DMA-mapping routines + * for providing grant references as DMA addresses to be used by frontends + * (e.g. virtio) in Xen guests + * + * Copyright (c) 2021, Juergen Gross + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct xen_grant_dma_data { + /* The ID of backend domain */ + domid_t backend_domid; + /* Is device behaving sane? */ + bool broken; +}; + +static DEFINE_XARRAY(xen_grant_dma_devices); + +#define XEN_GRANT_DMA_ADDR_OFF (1ULL << 63) + +static inline dma_addr_t grant_to_dma(grant_ref_t grant) +{ + return XEN_GRANT_DMA_ADDR_OFF | ((dma_addr_t)grant << PAGE_SHIFT); +} + +static inline grant_ref_t dma_to_grant(dma_addr_t dma) +{ + return (grant_ref_t)((dma & ~XEN_GRANT_DMA_ADDR_OFF) >> PAGE_SHIFT); +} + +static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev) +{ + struct xen_grant_dma_data *data; + + xa_lock(&xen_grant_dma_devices); + data = xa_load(&xen_grant_dma_devices, (unsigned long)dev); + xa_unlock(&xen_grant_dma_devices); + + return data; +} + +/* + * DMA ops for Xen frontends (e.g. virtio). + * + * Used to act as a kind of software IOMMU for Xen guests by using grants as + * DMA addresses. + * Such a DMA address is formed by using the grant reference as a frame + * number and setting the highest address bit (this bit is for the backend + * to be able to distinguish it from e.g. a mmio address). + * + * Note that for now we hard wire dom0 to be the backend domain. In order + * to support any domain as backend we'd need to add a way to communicate + * the domid of this backend, e.g. via Xenstore, via the PCI-device's + * config space or DT/ACPI. + */ +static void *xen_grant_dma_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + unsigned long pfn; + grant_ref_t grant; + void *ret; + + data = find_xen_grant_dma_data(dev); + if (!data) + return NULL; + + if (unlikely(data->broken)) + return NULL; + + ret = alloc_pages_exact(n_pages * PAGE_SIZE, gfp); + if (!ret) + return NULL; + + pfn = virt_to_pfn(ret); + + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) { + free_pages_exact(ret, n_pages * PAGE_SIZE); + return NULL; + } + + for (i = 0; i < n_pages; i++) { + gnttab_grant_foreign_access_ref(grant + i, data->backend_domid, + pfn_to_gfn(pfn + i), 0); + } + + *dma_handle = grant_to_dma(grant); + + return ret; +} + +static void xen_grant_dma_free(struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle, unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + + data = find_xen_grant_dma_data(dev); + if (!data) + return; + + if (unlikely(data->broken)) + return; + + grant = dma_to_grant(dma_handle); + + for (i = 0; i < n_pages; i++) { + if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) { + dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n"); + data->broken = true; + return; + } + } + + gnttab_free_grant_reference_seq(grant, n_pages); + + free_pages_exact(vaddr, n_pages * PAGE_SIZE); +} + +static struct page *xen_grant_dma_alloc_pages(struct device *dev, size_t size, + dma_addr_t *dma_handle, + enum dma_data_direction dir, + gfp_t gfp) +{ + void *vaddr; + + vaddr = xen_grant_dma_alloc(dev, size, dma_handle, gfp, 0); + if (!vaddr) + return NULL; + + return virt_to_page(vaddr); +} + +static void xen_grant_dma_free_pages(struct device *dev, size_t size, + struct page *vaddr, dma_addr_t dma_handle, + enum dma_data_direction dir) +{ + xen_grant_dma_free(dev, size, page_to_virt(vaddr), dma_handle, 0); +} + +static dma_addr_t xen_grant_dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + dma_addr_t dma_handle; + + if (WARN_ON(dir == DMA_NONE)) + return DMA_MAPPING_ERROR; + + data = find_xen_grant_dma_data(dev); + if (!data) + return DMA_MAPPING_ERROR; + + if (unlikely(data->broken)) + return DMA_MAPPING_ERROR; + + if (gnttab_alloc_grant_reference_seq(n_pages, &grant)) + return DMA_MAPPING_ERROR; + + for (i = 0; i < n_pages; i++) { + gnttab_grant_foreign_access_ref(grant + i, data->backend_domid, + xen_page_to_gfn(page) + i, dir == DMA_TO_DEVICE); + } + + dma_handle = grant_to_dma(grant) + offset; + + return dma_handle; +} + +static void xen_grant_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction dir, + unsigned long attrs) +{ + struct xen_grant_dma_data *data; + unsigned int i, n_pages = PFN_UP(size); + grant_ref_t grant; + + if (WARN_ON(dir == DMA_NONE)) + return; + + data = find_xen_grant_dma_data(dev); + if (!data) + return; + + if (unlikely(data->broken)) + return; + + grant = dma_to_grant(dma_handle); + + for (i = 0; i < n_pages; i++) { + if (unlikely(!gnttab_end_foreign_access_ref(grant + i))) { + dev_alert(dev, "Grant still in use by backend domain, disabled for further use\n"); + data->broken = true; + return; + } + } + + gnttab_free_grant_reference_seq(grant, n_pages); +} + +static void xen_grant_dma_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct scatterlist *s; + unsigned int i; + + if (WARN_ON(dir == DMA_NONE)) + return; + + for_each_sg(sg, s, nents, i) + xen_grant_dma_unmap_page(dev, s->dma_address, sg_dma_len(s), dir, + attrs); +} + +static int xen_grant_dma_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, + unsigned long attrs) +{ + struct scatterlist *s; + unsigned int i; + + if (WARN_ON(dir == DMA_NONE)) + return -EINVAL; + + for_each_sg(sg, s, nents, i) { + s->dma_address = xen_grant_dma_map_page(dev, sg_page(s), s->offset, + s->length, dir, attrs); + if (s->dma_address == DMA_MAPPING_ERROR) + goto out; + + sg_dma_len(s) = s->length; + } + + return nents; + +out: + xen_grant_dma_unmap_sg(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); + sg_dma_len(sg) = 0; + + return -EIO; +} + +static int xen_grant_dma_supported(struct device *dev, u64 mask) +{ + return mask == DMA_BIT_MASK(64); +} + +static const struct dma_map_ops xen_grant_dma_ops = { + .alloc = xen_grant_dma_alloc, + .free = xen_grant_dma_free, + .alloc_pages = xen_grant_dma_alloc_pages, + .free_pages = xen_grant_dma_free_pages, + .mmap = dma_common_mmap, + .get_sgtable = dma_common_get_sgtable, + .map_page = xen_grant_dma_map_page, + .unmap_page = xen_grant_dma_unmap_page, + .map_sg = xen_grant_dma_map_sg, + .unmap_sg = xen_grant_dma_unmap_sg, + .dma_supported = xen_grant_dma_supported, +}; + +void xen_grant_setup_dma_ops(struct device *dev) +{ + struct xen_grant_dma_data *data; + + data = find_xen_grant_dma_data(dev); + if (data) { + dev_err(dev, "Xen grant DMA data is already created\n"); + return; + } + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + goto err; + + /* XXX The dom0 is hardcoded as the backend domain for now */ + data->backend_domid = 0; + + if (xa_err(xa_store(&xen_grant_dma_devices, (unsigned long)dev, data, + GFP_KERNEL))) { + dev_err(dev, "Cannot store Xen grant DMA data\n"); + goto err; + } + + dev->dma_ops = &xen_grant_dma_ops; + + return; + +err: + dev_err(dev, "Cannot set up Xen grant DMA ops, retain platform DMA ops\n"); +} + +MODULE_DESCRIPTION("Xen grant DMA-mapping layer"); +MODULE_AUTHOR("Juergen Gross "); +MODULE_LICENSE("GPL"); diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index c7c1b46ff4cd4..afd586d717a45 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -214,4 +214,12 @@ static inline void xen_preemptible_hcall_end(void) { } #endif /* CONFIG_XEN_PV && !CONFIG_PREEMPTION */ +#ifdef CONFIG_XEN_GRANT_DMA_OPS +void xen_grant_setup_dma_ops(struct device *dev); +#else +static inline void xen_grant_setup_dma_ops(struct device *dev) +{ +} +#endif /* CONFIG_XEN_GRANT_DMA_OPS */ + #endif /* INCLUDE_XEN_OPS_H */ -- GitLab From 2aab03b86766a27f99a0b24f63e1730faac128d0 Mon Sep 17 00:00:00 2001 From: Xiang wangx Date: Sun, 5 Jun 2022 20:55:09 +0800 Subject: [PATCH 056/942] fs: Fix syntax errors in comments Delete the redundant word 'not'. Link: https://lore.kernel.org/r/20220605125509.14837-1-wangxiang@cdjrlc.com Signed-off-by: Xiang wangx Signed-off-by: Jan Kara --- fs/ext2/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 360ce3604a2d2..e6b932219803e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1549,7 +1549,7 @@ static int __ext2_write_inode(struct inode *inode, int do_sync) if (IS_ERR(raw_inode)) return -EIO; - /* For fields not not tracking in the in-memory inode, + /* For fields not tracking in the in-memory inode, * initialise them to zero for new inodes. */ if (ei->i_state & EXT2_STATE_NEW) memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size); -- GitLab From 10e14073107dd0b6d97d9516a02845a8e501c2c9 Mon Sep 17 00:00:00 2001 From: Jchao Sun Date: Tue, 24 May 2022 08:05:40 -0700 Subject: [PATCH 057/942] writeback: Fix inode->i_io_list not be protected by inode->i_lock error Commit b35250c0816c ("writeback: Protect inode->i_io_list with inode->i_lock") made inode->i_io_list not only protected by wb->list_lock but also inode->i_lock, but inode_io_list_move_locked() was missed. Add lock there and also update comment describing things protected by inode->i_lock. This also fixes a race where __mark_inode_dirty() could move inode under flush worker's hands and thus sync(2) could miss writing some inodes. Fixes: b35250c0816c ("writeback: Protect inode->i_io_list with inode->i_lock") Link: https://lore.kernel.org/r/20220524150540.12552-1-sunjunchao2870@gmail.com CC: stable@vger.kernel.org Signed-off-by: Jchao Sun Signed-off-by: Jan Kara --- fs/fs-writeback.c | 37 ++++++++++++++++++++++++++++--------- fs/inode.c | 2 +- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index a21d8f1a56d19..05221366a16dc 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -120,6 +120,7 @@ static bool inode_io_list_move_locked(struct inode *inode, struct list_head *head) { assert_spin_locked(&wb->list_lock); + assert_spin_locked(&inode->i_lock); list_move(&inode->i_io_list, head); @@ -1365,9 +1366,9 @@ static int move_expired_inodes(struct list_head *delaying_queue, inode = wb_inode(delaying_queue->prev); if (inode_dirtied_after(inode, dirtied_before)) break; + spin_lock(&inode->i_lock); list_move(&inode->i_io_list, &tmp); moved++; - spin_lock(&inode->i_lock); inode->i_state |= I_SYNC_QUEUED; spin_unlock(&inode->i_lock); if (sb_is_blkdev_sb(inode->i_sb)) @@ -1383,7 +1384,12 @@ static int move_expired_inodes(struct list_head *delaying_queue, goto out; } - /* Move inodes from one superblock together */ + /* + * Although inode's i_io_list is moved from 'tmp' to 'dispatch_queue', + * we don't take inode->i_lock here because it is just a pointless overhead. + * Inode is already marked as I_SYNC_QUEUED so writeback list handling is + * fully under our control. + */ while (!list_empty(&tmp)) { sb = wb_inode(tmp.prev)->i_sb; list_for_each_prev_safe(pos, node, &tmp) { @@ -1826,8 +1832,8 @@ static long writeback_sb_inodes(struct super_block *sb, * We'll have another go at writing back this inode * when we completed a full scan of b_io. */ - spin_unlock(&inode->i_lock); requeue_io(inode, wb); + spin_unlock(&inode->i_lock); trace_writeback_sb_inodes_requeue(inode); continue; } @@ -2358,6 +2364,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) { struct super_block *sb = inode->i_sb; int dirtytime = 0; + struct bdi_writeback *wb = NULL; trace_writeback_mark_inode_dirty(inode, flags); @@ -2409,6 +2416,17 @@ void __mark_inode_dirty(struct inode *inode, int flags) inode->i_state &= ~I_DIRTY_TIME; inode->i_state |= flags; + /* + * Grab inode's wb early because it requires dropping i_lock and we + * need to make sure following checks happen atomically with dirty + * list handling so that we don't move inodes under flush worker's + * hands. + */ + if (!was_dirty) { + wb = locked_inode_to_wb_and_lock_list(inode); + spin_lock(&inode->i_lock); + } + /* * If the inode is queued for writeback by flush worker, just * update its dirty state. Once the flush worker is done with @@ -2416,7 +2434,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) * list, based upon its state. */ if (inode->i_state & I_SYNC_QUEUED) - goto out_unlock_inode; + goto out_unlock; /* * Only add valid (hashed) inodes to the superblock's @@ -2424,22 +2442,19 @@ void __mark_inode_dirty(struct inode *inode, int flags) */ if (!S_ISBLK(inode->i_mode)) { if (inode_unhashed(inode)) - goto out_unlock_inode; + goto out_unlock; } if (inode->i_state & I_FREEING) - goto out_unlock_inode; + goto out_unlock; /* * If the inode was already on b_dirty/b_io/b_more_io, don't * reposition it (that would break b_dirty time-ordering). */ if (!was_dirty) { - struct bdi_writeback *wb; struct list_head *dirty_list; bool wakeup_bdi = false; - wb = locked_inode_to_wb_and_lock_list(inode); - inode->dirtied_when = jiffies; if (dirtytime) inode->dirtied_time_when = jiffies; @@ -2453,6 +2468,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) dirty_list); spin_unlock(&wb->list_lock); + spin_unlock(&inode->i_lock); trace_writeback_dirty_inode_enqueue(inode); /* @@ -2467,6 +2483,9 @@ void __mark_inode_dirty(struct inode *inode, int flags) return; } } +out_unlock: + if (wb) + spin_unlock(&wb->list_lock); out_unlock_inode: spin_unlock(&inode->i_lock); } diff --git a/fs/inode.c b/fs/inode.c index 9d9b422504d1a..bd4da9c5207ea 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -27,7 +27,7 @@ * Inode locking rules: * * inode->i_lock protects: - * inode->i_state, inode->i_hash, __iget() + * inode->i_state, inode->i_hash, __iget(), inode->i_io_list * Inode LRU list locks protect: * inode->i_sb->s_inode_lru, inode->i_lru * inode->i_sb->s_inode_list_lock protects: -- GitLab From 537e11cdc7a6b3ce94fa25ed41306193df9677b7 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Sun, 5 Jun 2022 15:38:13 +0100 Subject: [PATCH 058/942] quota: Prevent memory allocation recursion while holding dq_lock As described in commit 02117b8ae9c0 ("f2fs: Set GF_NOFS in read_cache_page_gfp while doing f2fs_quota_read"), we must not enter filesystem reclaim while holding the dq_lock. Prevent this more generally by using memalloc_nofs_save() while holding the lock. Link: https://lore.kernel.org/r/20220605143815.2330891-2-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) Signed-off-by: Jan Kara --- fs/quota/dquot.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index a74aef99bd3d6..09d1307959d08 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -79,6 +79,7 @@ #include #include #include +#include #include "../internal.h" /* ugh */ #include @@ -425,9 +426,11 @@ EXPORT_SYMBOL(mark_info_dirty); int dquot_acquire(struct dquot *dquot) { int ret = 0, ret2 = 0; + unsigned int memalloc; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); mutex_lock(&dquot->dq_lock); + memalloc = memalloc_nofs_save(); if (!test_bit(DQ_READ_B, &dquot->dq_flags)) { ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); if (ret < 0) @@ -458,6 +461,7 @@ int dquot_acquire(struct dquot *dquot) smp_mb__before_atomic(); set_bit(DQ_ACTIVE_B, &dquot->dq_flags); out_iolock: + memalloc_nofs_restore(memalloc); mutex_unlock(&dquot->dq_lock); return ret; } @@ -469,9 +473,11 @@ EXPORT_SYMBOL(dquot_acquire); int dquot_commit(struct dquot *dquot) { int ret = 0; + unsigned int memalloc; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); mutex_lock(&dquot->dq_lock); + memalloc = memalloc_nofs_save(); if (!clear_dquot_dirty(dquot)) goto out_lock; /* Inactive dquot can be only if there was error during read/init @@ -481,6 +487,7 @@ int dquot_commit(struct dquot *dquot) else ret = -EIO; out_lock: + memalloc_nofs_restore(memalloc); mutex_unlock(&dquot->dq_lock); return ret; } @@ -492,9 +499,11 @@ EXPORT_SYMBOL(dquot_commit); int dquot_release(struct dquot *dquot) { int ret = 0, ret2 = 0; + unsigned int memalloc; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); mutex_lock(&dquot->dq_lock); + memalloc = memalloc_nofs_save(); /* Check whether we are not racing with some other dqget() */ if (dquot_is_busy(dquot)) goto out_dqlock; @@ -510,6 +519,7 @@ int dquot_release(struct dquot *dquot) } clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); out_dqlock: + memalloc_nofs_restore(memalloc); mutex_unlock(&dquot->dq_lock); return ret; } -- GitLab From 386cbe7f1b152c8476a7d322d39512b1b4259ed5 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 12 May 2022 20:39:21 +0300 Subject: [PATCH 059/942] gpio: crystalcove: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-crystalcove.c | 40 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index b55c74a5e0648..cf33041533aa6 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -15,6 +15,7 @@ #include #include #include +#include #define CRYSTALCOVE_GPIO_NUM 16 #define CRYSTALCOVE_VGPIO_NUM 95 @@ -238,34 +239,43 @@ static void crystalcove_bus_sync_unlock(struct irq_data *data) static void crystalcove_irq_unmask(struct irq_data *data) { - struct crystalcove_gpio *cg = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct crystalcove_gpio *cg = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(data); - if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { - cg->set_irq_mask = false; - cg->update |= UPDATE_IRQ_MASK; - } + if (hwirq >= CRYSTALCOVE_GPIO_NUM) + return; + + gpiochip_enable_irq(gc, hwirq); + + cg->set_irq_mask = false; + cg->update |= UPDATE_IRQ_MASK; } static void crystalcove_irq_mask(struct irq_data *data) { - struct crystalcove_gpio *cg = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct crystalcove_gpio *cg = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(data); - if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { - cg->set_irq_mask = true; - cg->update |= UPDATE_IRQ_MASK; - } + if (hwirq >= CRYSTALCOVE_GPIO_NUM) + return; + + cg->set_irq_mask = true; + cg->update |= UPDATE_IRQ_MASK; + + gpiochip_disable_irq(gc, hwirq); } -static struct irq_chip crystalcove_irqchip = { +static const struct irq_chip crystalcove_irqchip = { .name = "Crystal Cove", .irq_mask = crystalcove_irq_mask, .irq_unmask = crystalcove_irq_unmask, .irq_set_type = crystalcove_irq_type, .irq_bus_lock = crystalcove_bus_lock, .irq_bus_sync_unlock = crystalcove_bus_sync_unlock, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) @@ -353,7 +363,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) cg->regmap = pmic->regmap; girq = &cg->chip.irq; - girq->chip = &crystalcove_irqchip; + gpio_irq_chip_set_chip(girq, &crystalcove_irqchip); /* This will let us handle the parent IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; -- GitLab From b34d2ad73af3c58dbaf8aa71b7308f17d9863780 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 1 Jun 2022 17:18:02 +0300 Subject: [PATCH 060/942] gpio: crystalcove: Use specific type and API for IRQ number Use specific type and API for IRQ number in the callbacks. Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-crystalcove.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index cf33041533aa6..36870d14323fd 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -188,8 +188,9 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned int type) { struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); + irq_hw_number_t hwirq = irqd_to_hwirq(data); - if (data->hwirq >= CRYSTALCOVE_GPIO_NUM) + if (hwirq >= CRYSTALCOVE_GPIO_NUM) return 0; switch (type) { @@ -226,12 +227,12 @@ static void crystalcove_bus_sync_unlock(struct irq_data *data) { struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); - int gpio = data->hwirq; + irq_hw_number_t hwirq = irqd_to_hwirq(data); if (cg->update & UPDATE_IRQ_TYPE) - crystalcove_update_irq_ctrl(cg, gpio); + crystalcove_update_irq_ctrl(cg, hwirq); if (cg->update & UPDATE_IRQ_MASK) - crystalcove_update_irq_mask(cg, gpio); + crystalcove_update_irq_mask(cg, hwirq); cg->update = 0; mutex_unlock(&cg->buslock); -- GitLab From 68a12c19e1cb0f3332d3f59e1d5447f2aff97cd7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 1 Jun 2022 17:22:04 +0300 Subject: [PATCH 061/942] gpio: crystalcove: Join function declarations and long lines There is no more hard limit of 80 characters for long lines, so join a few of them for better readability. Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-crystalcove.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 36870d14323fd..1ee62cd58582b 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -111,8 +111,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) return reg + gpio % 8; } -static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, - int gpio) +static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, int gpio) { u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0; int mask = BIT(gpio % 8); @@ -141,8 +140,7 @@ static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio) return regmap_write(cg->regmap, reg, CTLO_INPUT_SET); } -static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, - int value) +static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio, int value) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); int reg = to_reg(gpio, CTRL_OUT); @@ -169,8 +167,7 @@ static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned int gpio) return val & 0x1; } -static void crystalcove_gpio_set(struct gpio_chip *chip, - unsigned int gpio, int value) +static void crystalcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); int reg = to_reg(gpio, CTRL_OUT); @@ -186,8 +183,7 @@ static void crystalcove_gpio_set(struct gpio_chip *chip, static int crystalcove_irq_type(struct irq_data *data, unsigned int type) { - struct crystalcove_gpio *cg = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); irq_hw_number_t hwirq = irqd_to_hwirq(data); if (hwirq >= CRYSTALCOVE_GPIO_NUM) @@ -217,16 +213,14 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned int type) static void crystalcove_bus_lock(struct irq_data *data) { - struct crystalcove_gpio *cg = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); mutex_lock(&cg->buslock); } static void crystalcove_bus_sync_unlock(struct irq_data *data) { - struct crystalcove_gpio *cg = - gpiochip_get_data(irq_data_get_irq_chip_data(data)); + struct crystalcove_gpio *cg = gpiochip_get_data(irq_data_get_irq_chip_data(data)); irq_hw_number_t hwirq = irqd_to_hwirq(data); if (cg->update & UPDATE_IRQ_TYPE) @@ -304,8 +298,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static void crystalcove_gpio_dbg_show(struct seq_file *s, - struct gpio_chip *chip) +static void crystalcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct crystalcove_gpio *cg = gpiochip_get_data(chip); int gpio, offset; -- GitLab From 41a18c4918dcd57a49b0d046d9f2d587878de739 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 12 May 2022 20:39:21 +0300 Subject: [PATCH 062/942] gpio: wcove: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko Reviewed-by: Kuppuswamy Sathyanarayanan --- drivers/gpio/gpio-wcove.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 16a0fae1e32eb..c18b6b47384f1 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -299,6 +299,8 @@ static void wcove_irq_unmask(struct irq_data *data) if (gpio >= WCOVE_GPIO_NUM) return; + gpiochip_enable_irq(chip, gpio); + wg->set_irq_mask = false; wg->update |= UPDATE_IRQ_MASK; } @@ -314,15 +316,19 @@ static void wcove_irq_mask(struct irq_data *data) wg->set_irq_mask = true; wg->update |= UPDATE_IRQ_MASK; + + gpiochip_disable_irq(chip, gpio); } -static struct irq_chip wcove_irqchip = { +static const struct irq_chip wcove_irqchip = { .name = "Whiskey Cove", .irq_mask = wcove_irq_mask, .irq_unmask = wcove_irq_unmask, .irq_set_type = wcove_irq_type, .irq_bus_lock = wcove_bus_lock, .irq_bus_sync_unlock = wcove_bus_sync_unlock, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) @@ -452,7 +458,7 @@ static int wcove_gpio_probe(struct platform_device *pdev) } girq = &wg->chip.irq; - girq->chip = &wcove_irqchip; + gpio_irq_chip_set_chip(girq, &wcove_irqchip); /* This will let us handle the parent IRQ in the driver */ girq->parent_handler = NULL; girq->num_parents = 0; -- GitLab From a80fed9fb643175832e2fb8481d38f5d92cbcd34 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 12 May 2022 20:39:21 +0300 Subject: [PATCH 063/942] gpio: merrifield: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-merrifield.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index f3d1baeacbe97..72ac09a597029 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -220,10 +220,8 @@ static void mrfld_irq_ack(struct irq_data *d) raw_spin_unlock_irqrestore(&priv->lock, flags); } -static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask) +static void mrfld_irq_unmask_mask(struct mrfld_gpio *priv, u32 gpio, bool unmask) { - struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d); - u32 gpio = irqd_to_hwirq(d); void __iomem *gimr = gpio_reg(&priv->chip, gpio, GIMR); unsigned long flags; u32 value; @@ -241,12 +239,20 @@ static void mrfld_irq_unmask_mask(struct irq_data *d, bool unmask) static void mrfld_irq_mask(struct irq_data *d) { - mrfld_irq_unmask_mask(d, false); + struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d); + u32 gpio = irqd_to_hwirq(d); + + mrfld_irq_unmask_mask(priv, gpio, false); + gpiochip_disable_irq(&priv->chip, gpio); } static void mrfld_irq_unmask(struct irq_data *d) { - mrfld_irq_unmask_mask(d, true); + struct mrfld_gpio *priv = irq_data_get_irq_chip_data(d); + u32 gpio = irqd_to_hwirq(d); + + gpiochip_enable_irq(&priv->chip, gpio); + mrfld_irq_unmask_mask(priv, gpio, true); } static int mrfld_irq_set_type(struct irq_data *d, unsigned int type) @@ -329,13 +335,15 @@ static int mrfld_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } -static struct irq_chip mrfld_irqchip = { +static const struct irq_chip mrfld_irqchip = { .name = "gpio-merrifield", .irq_ack = mrfld_irq_ack, .irq_mask = mrfld_irq_mask, .irq_unmask = mrfld_irq_unmask, .irq_set_type = mrfld_irq_set_type, .irq_set_wake = mrfld_irq_set_wake, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static void mrfld_irq_handler(struct irq_desc *desc) @@ -482,7 +490,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id return retval; girq = &priv->chip.irq; - girq->chip = &mrfld_irqchip; + gpio_irq_chip_set_chip(girq, &mrfld_irqchip); girq->init_hw = mrfld_irq_init_hw; girq->parent_handler = mrfld_irq_handler; girq->num_parents = 1; -- GitLab From f1138dacb7ff5221c4a37b823e42fc0a34df8731 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 1 Jun 2022 18:36:56 +0300 Subject: [PATCH 064/942] gpio: sch: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko Reviewed-by: Bartosz Golaszewski --- drivers/gpio/gpio-sch.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index acda4c5052d38..8a83f7bf4382b 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -38,7 +38,6 @@ struct sch_gpio { struct gpio_chip chip; - struct irq_chip irqchip; spinlock_t lock; unsigned short iobase; unsigned short resume_base; @@ -218,11 +217,9 @@ static void sch_irq_ack(struct irq_data *d) spin_unlock_irqrestore(&sch->lock, flags); } -static void sch_irq_mask_unmask(struct irq_data *d, int val) +static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct sch_gpio *sch = gpiochip_get_data(gc); - irq_hw_number_t gpio_num = irqd_to_hwirq(d); unsigned long flags; spin_lock_irqsave(&sch->lock, flags); @@ -232,14 +229,32 @@ static void sch_irq_mask_unmask(struct irq_data *d, int val) static void sch_irq_mask(struct irq_data *d) { - sch_irq_mask_unmask(d, 0); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t gpio_num = irqd_to_hwirq(d); + + sch_irq_mask_unmask(gc, gpio_num, 0); + gpiochip_disable_irq(gc, gpio_num); } static void sch_irq_unmask(struct irq_data *d) { - sch_irq_mask_unmask(d, 1); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + irq_hw_number_t gpio_num = irqd_to_hwirq(d); + + gpiochip_enable_irq(gc, gpio_num); + sch_irq_mask_unmask(gc, gpio_num, 1); } +static const struct irq_chip sch_irqchip = { + .name = "sch_gpio", + .irq_ack = sch_irq_ack, + .irq_mask = sch_irq_mask, + .irq_unmask = sch_irq_unmask, + .irq_set_type = sch_irq_type, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context) { struct sch_gpio *sch = context; @@ -367,14 +382,8 @@ static int sch_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sch); - sch->irqchip.name = "sch_gpio"; - sch->irqchip.irq_ack = sch_irq_ack; - sch->irqchip.irq_mask = sch_irq_mask; - sch->irqchip.irq_unmask = sch_irq_unmask; - sch->irqchip.irq_set_type = sch_irq_type; - girq = &sch->chip.irq; - girq->chip = &sch->irqchip; + gpio_irq_chip_set_chip(girq, &sch_irqchip); girq->num_parents = 0; girq->parents = NULL; girq->parent_handler = NULL; -- GitLab From b93a8b2c5161696e732185311d309e0aaf0575be Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 12 May 2022 20:39:21 +0300 Subject: [PATCH 065/942] gpio: dln2: make irq_chip immutable Since recently, the kernel is nagging about mutable irq_chips: "not an immutable chip, please consider fixing it!" Drop the unneeded copy, flag it as IRQCHIP_IMMUTABLE, add the new helper functions and call the appropriate gpiolib functions. Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-dln2.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 08b9e2cf4f2d6..71fa437b491f6 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -46,7 +46,6 @@ struct dln2_gpio { struct platform_device *pdev; struct gpio_chip gpio; - struct irq_chip irqchip; /* * Cache pin direction to save us one transfer, since the hardware has @@ -306,6 +305,7 @@ static void dln2_irq_unmask(struct irq_data *irqd) struct dln2_gpio *dln2 = gpiochip_get_data(gc); int pin = irqd_to_hwirq(irqd); + gpiochip_enable_irq(gc, pin); set_bit(pin, dln2->unmasked_irqs); } @@ -316,6 +316,7 @@ static void dln2_irq_mask(struct irq_data *irqd) int pin = irqd_to_hwirq(irqd); clear_bit(pin, dln2->unmasked_irqs); + gpiochip_disable_irq(gc, pin); } static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) @@ -384,6 +385,17 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd) mutex_unlock(&dln2->irq_lock); } +static const struct irq_chip dln2_irqchip = { + .name = "dln2-irq", + .irq_mask = dln2_irq_mask, + .irq_unmask = dln2_irq_unmask, + .irq_set_type = dln2_irq_set_type, + .irq_bus_lock = dln2_irq_bus_lock, + .irq_bus_sync_unlock = dln2_irq_bus_unlock, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + static void dln2_gpio_event(struct platform_device *pdev, u16 echo, const void *data, int len) { @@ -465,15 +477,8 @@ static int dln2_gpio_probe(struct platform_device *pdev) dln2->gpio.direction_output = dln2_gpio_direction_output; dln2->gpio.set_config = dln2_gpio_set_config; - dln2->irqchip.name = "dln2-irq", - dln2->irqchip.irq_mask = dln2_irq_mask, - dln2->irqchip.irq_unmask = dln2_irq_unmask, - dln2->irqchip.irq_set_type = dln2_irq_set_type, - dln2->irqchip.irq_bus_lock = dln2_irq_bus_lock, - dln2->irqchip.irq_bus_sync_unlock = dln2_irq_bus_unlock, - girq = &dln2->gpio.irq; - girq->chip = &dln2->irqchip; + gpio_irq_chip_set_chip(girq, &dln2_irqchip); /* The event comes from the outside so no parent handler */ girq->parent_handler = NULL; girq->num_parents = 0; -- GitLab From fed3d9297a9bf8b342c034e74a1fdba6940fe84a Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 30 May 2022 12:01:51 +0800 Subject: [PATCH 066/942] ASoC: nau8822: Disable internal PLL if freq_out is zero After finishing the playback or recording, the machine driver might call snd_soc_dai_set_pll(codec, pll_id, 0, 0, 0) to stop the internal PLL, but with the codec driver nau8822, it will print error as below: nau8822 0-001a: Unsupported input clock 0 fsl-asoc-card sound-nau8822: failed to stop FLL: -22 Refer to the function wm8962_set_fll() in the codec driver wm8962, if the freq_out is zero, turn off the internal PLL and return 0. Cc: David Lin Cc: John Hsu Cc: Seven Li Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20220530040151.95221-3-hui.wang@canonical.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8822.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 08f6c56dc387f..fd9c766e277fb 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -726,6 +726,13 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, struct nau8822_pll *pll_param = &nau8822->pll; int ret, fs; + if (freq_out == 0) { + dev_dbg(component->dev, "PLL disabled\n"); + snd_soc_component_update_bits(component, + NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF); + return 0; + } + fs = freq_out / 256; ret = nau8822_calc_pll(freq_in, fs, pll_param); -- GitLab From 45c6c5e052df2ee0d87e74743d8bb72e70fd0887 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 3 Jun 2022 12:06:07 +0530 Subject: [PATCH 067/942] ASoC: tegra: Add binding doc for OPE module This patch adds YAML schema for DT bindings of Output Processing Engine (OPE) module. It consists of Parametric Equalizer (PEQ) and Multi Band Dynamic Range Compressor (MBDRC) sub blocks and binding doc for these blocks are added as well. The OPE will be registered as an ASoC component and can be plugged into an audio path as per need via ALSA mixer controls. The DT bindings are applicable on Tegra210 and later SoCs where OPE module is present. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1654238172-16293-2-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra210-ahub.yaml | 4 + .../bindings/sound/nvidia,tegra210-mbdrc.yaml | 47 ++++++++++ .../bindings/sound/nvidia,tegra210-ope.yaml | 87 +++++++++++++++++++ .../bindings/sound/nvidia,tegra210-peq.yaml | 48 ++++++++++ 4 files changed, 186 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-mbdrc.yaml create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-ope.yaml create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra210-peq.yaml diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml index 6df6f858038cc..47b6e712e4fbc 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ahub.yaml @@ -110,6 +110,10 @@ patternProperties: type: object $ref: nvidia,tegra186-asrc.yaml# + '^processing-engine@[0-9a-f]+$': + type: object + $ref: nvidia,tegra210-ope.yaml# + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-mbdrc.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mbdrc.yaml new file mode 100644 index 0000000000000..5b9198602fc6a --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-mbdrc.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mbdrc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Tegra210 MBDRC + +description: + The Multi Band Dynamic Range Compressor (MBDRC) is part of Output + Processing Engine (OPE) which interfaces with Audio Hub (AHUB) via + Audio Client Interface (ACIF). MBDRC can be used as a traditional + single full band or a dual band or a multi band dynamic processor. + +maintainers: + - Jon Hunter + - Mohan Kumar + - Sameer Pujar + +properties: + compatible: + oneOf: + - const: nvidia,tegra210-mbdrc + - items: + - enum: + - nvidia,tegra234-mbdrc + - nvidia,tegra194-mbdrc + - nvidia,tegra186-mbdrc + - const: nvidia,tegra210-mbdrc + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + dynamic-range-compressor@702d8200 { + compatible = "nvidia,tegra210-mbdrc"; + reg = <0x702d8200 0x200>; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-ope.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ope.yaml new file mode 100644 index 0000000000000..9dc9ba590fa39 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-ope.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-ope.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Tegra210 OPE + +description: + The Output Processing Engine (OPE) is one of the AHUB client. It has + PEQ (Parametric Equalizer) and MBDRC (Multi Band Dynamic Range Compressor) + sub blocks for data processing. + +maintainers: + - Jon Hunter + - Mohan Kumar + - Sameer Pujar + +allOf: + - $ref: name-prefix.yaml# + +properties: + compatible: + oneOf: + - const: nvidia,tegra210-ope + - items: + - enum: + - nvidia,tegra234-ope + - nvidia,tegra194-ope + - nvidia,tegra186-ope + - const: nvidia,tegra210-ope + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + + sound-name-prefix: + pattern: "^OPE[1-9]$" + + ports: + $ref: /schemas/graph.yaml#/properties/ports + properties: + port@0: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: + OPE ACIF (Audio Client Interface) input port. This is connected + to corresponding ACIF output port on AHUB (Audio Hub). + + port@1: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + description: + OPE ACIF output port. This is connected to corresponding ACIF + input port on AHUB. + +patternProperties: + '^equalizer@[0-9a-f]+$': + type: object + $ref: nvidia,tegra210-peq.yaml# + + '^dynamic-range-compressor@[0-9a-f]+$': + type: object + $ref: nvidia,tegra210-mbdrc.yaml# + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + processing-engine@702d8000 { + compatible = "nvidia,tegra210-ope"; + reg = <0x702d8000 0x100>; + sound-name-prefix = "OPE1"; + }; + +... diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra210-peq.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra210-peq.yaml new file mode 100644 index 0000000000000..1e373c49d639b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra210-peq.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/nvidia,tegra210-peq.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Tegra210 PEQ + +description: + The Parametric Equalizer (PEQ) is a cascade of biquad filters with + each filter tuned based on certain parameters. It can be used to + equalize the irregularities in the speaker frequency response. + PEQ sits inside Output Processing Engine (OPE) which interfaces + with Audio Hub (AHUB) via Audio Client Interface (ACIF). + +maintainers: + - Jon Hunter + - Mohan Kumar + - Sameer Pujar + +properties: + compatible: + oneOf: + - const: nvidia,tegra210-peq + - items: + - enum: + - nvidia,tegra234-peq + - nvidia,tegra194-peq + - nvidia,tegra186-peq + - const: nvidia,tegra210-peq + + reg: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + equalizer@702d8100 { + compatible = "nvidia,tegra210-peq"; + reg = <0x702d8100 0x100>; + }; + +... -- GitLab From 7358a803c778f28314721e78339f3fa5b787f55c Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 3 Jun 2022 12:06:08 +0530 Subject: [PATCH 068/942] ASoC: tegra: Add Tegra210 based OPE driver The Output Processing Engine (OPE) is one of the AHUB client. It has PEQ (Parametric Equalizer) and MBDRC (Multi Band Dynamic Range Compressor) sub blocks for data processing. The PEQ block gets samples from the MBDRC block. This patch registers OPE driver with ASoC framework. The component driver exposes DAPM widgets, routes and kcontrols for the device. The DAI driver exposes OPE interfaces, which can be used to connect different components in the ASoC layer. Makefile and Kconfig support is added to allow build the driver. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1654238172-16293-3-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/Kconfig | 9 + sound/soc/tegra/Makefile | 2 + sound/soc/tegra/tegra210_mbdrc.c | 1012 ++++++++++++++++++++++++++++++ sound/soc/tegra/tegra210_mbdrc.h | 215 +++++++ sound/soc/tegra/tegra210_ope.c | 419 +++++++++++++ sound/soc/tegra/tegra210_ope.h | 90 +++ sound/soc/tegra/tegra210_peq.c | 434 +++++++++++++ sound/soc/tegra/tegra210_peq.h | 56 ++ 8 files changed, 2237 insertions(+) create mode 100644 sound/soc/tegra/tegra210_mbdrc.c create mode 100644 sound/soc/tegra/tegra210_mbdrc.h create mode 100644 sound/soc/tegra/tegra210_ope.c create mode 100644 sound/soc/tegra/tegra210_ope.h create mode 100644 sound/soc/tegra/tegra210_peq.c create mode 100644 sound/soc/tegra/tegra210_peq.h diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 2482d98673577..b6712a3d1fa11 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -85,6 +85,15 @@ config SND_SOC_TEGRA210_I2S compatible devices. Say Y or M if you want to add support for Tegra210 I2S module. +config SND_SOC_TEGRA210_OPE + tristate "Tegra210 OPE module" + help + Config to enable the Output Processing Engine (OPE) which includes + Parametric Equalizer (PEQ) and Multi Band Dynamic Range Compressor + (MBDRC) sub blocks for data processing. It can support up to 8 + channels. + Say Y or M if you want to add support for Tegra210 OPE module. + config SND_SOC_TEGRA186_ASRC tristate "Tegra186 ASRC module" help diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 70a498ddb2fab..b723c78e665da 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -19,6 +19,7 @@ snd-soc-tegra210-sfc-objs := tegra210_sfc.o snd-soc-tegra210-amx-objs := tegra210_amx.o snd-soc-tegra210-adx-objs := tegra210_adx.o snd-soc-tegra210-mixer-objs := tegra210_mixer.o +snd-soc-tegra210-ope-objs := tegra210_ope.o tegra210_mbdrc.o tegra210_peq.o obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o obj-$(CONFIG_SND_SOC_TEGRA20_AC97) += snd-soc-tegra20-ac97.o @@ -38,6 +39,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_SFC) += snd-soc-tegra210-sfc.o obj-$(CONFIG_SND_SOC_TEGRA210_AMX) += snd-soc-tegra210-amx.o obj-$(CONFIG_SND_SOC_TEGRA210_ADX) += snd-soc-tegra210-adx.o obj-$(CONFIG_SND_SOC_TEGRA210_MIXER) += snd-soc-tegra210-mixer.o +obj-$(CONFIG_SND_SOC_TEGRA210_OPE) += snd-soc-tegra210-ope.o # Tegra machine Support snd-soc-tegra-wm8903-objs := tegra_wm8903.o diff --git a/sound/soc/tegra/tegra210_mbdrc.c b/sound/soc/tegra/tegra210_mbdrc.c new file mode 100644 index 0000000000000..7d9da33a99512 --- /dev/null +++ b/sound/soc/tegra/tegra210_mbdrc.c @@ -0,0 +1,1012 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// tegra210_mbdrc.c - Tegra210 MBDRC driver +// +// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tegra210_mbdrc.h" +#include "tegra210_ope.h" + +#define MBDRC_FILTER_REG(reg, id) \ + ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE)) + +#define MBDRC_FILTER_REG_DEFAULTS(id) \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a}, \ + { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000} + +static const struct reg_default tegra210_mbdrc_reg_defaults[] = { + { TEGRA210_MBDRC_CFG, 0x0030de51}, + { TEGRA210_MBDRC_CHANNEL_MASK, 0x00000003}, + { TEGRA210_MBDRC_FAST_FACTOR, 0x30000800}, + + MBDRC_FILTER_REG_DEFAULTS(0), + MBDRC_FILTER_REG_DEFAULTS(1), + MBDRC_FILTER_REG_DEFAULTS(2), +}; + +/* Default MBDRC parameters */ +static const struct tegra210_mbdrc_config mbdrc_init_config = { + .mode = 0, /* Bypass */ + .rms_off = 48, + .peak_rms_mode = 1, /* PEAK */ + .fliter_structure = 0, /* All-pass tree */ + .shift_ctrl = 30, + .frame_size = 32, + .channel_mask = 0x3, + .fa_factor = 2048, + .fr_factor = 14747, + + .band_params[MBDRC_LOW_BAND] = { + .band = MBDRC_LOW_BAND, + .iir_stages = 5, + .in_attack_tc = 1044928780, + .in_release_tc = 138497695, + .fast_attack_tc = 2147483647, + .in_threshold = {130, 80, 20, 6}, + .out_threshold = {155, 55, 13, 6}, + .ratio = {40960, 8192, 2867, 2048, 410}, + .makeup_gain = 4, + .gain_init = 419430, + .gain_attack_tc = 14268942, + .gain_release_tc = 1440547090, + .fast_release_tc = 2147480170, + + .biquad_params = { + /* + * Gains: + * + * b0, b1, a0, + * a1, a2, + */ + + /* Band-0 */ + 961046798, -2030431983, 1073741824, + 2030431983, -961046798, + /* Band-1 */ + 1030244425, -2099481453, 1073741824, + 2099481453, -1030244425, + /* Band-2 */ + 1067169294, -2136327263, 1073741824, + 2136327263, -1067169294, + /* Band-3 */ + 434951949, -1306567134, 1073741824, + 1306567134, -434951949, + /* Band-4 */ + 780656019, -1605955641, 1073741824, + 1605955641, -780656019, + /* Band-5 */ + 1024497031, -1817128152, 1073741824, + 1817128152, -1024497031, + /* Band-6 */ + 1073741824, 0, 0, + 0, 0, + /* Band-7 */ + 1073741824, 0, 0, + 0, 0, + } + }, + + .band_params[MBDRC_MID_BAND] = { + .band = MBDRC_MID_BAND, + .iir_stages = 5, + .in_attack_tc = 1581413104, + .in_release_tc = 35494783, + .fast_attack_tc = 2147483647, + .in_threshold = {130, 50, 30, 6}, + .out_threshold = {106, 50, 30, 13}, + .ratio = {40960, 2867, 4096, 2867, 410}, + .makeup_gain = 6, + .gain_init = 419430, + .gain_attack_tc = 4766887, + .gain_release_tc = 1044928780, + .fast_release_tc = 2147480170, + + .biquad_params = { + /* + * Gains: + * + * b0, b1, a0, + * a1, a2, + */ + + /* Band-0 */ + -1005668963, 1073741824, 0, + 1005668963, 0, + /* Band-1 */ + 998437058, -2067742187, 1073741824, + 2067742187, -998437058, + /* Band-2 */ + 1051963422, -2121153948, 1073741824, + 2121153948, -1051963422, + /* Band-3 */ + 434951949, -1306567134, 1073741824, + 1306567134, -434951949, + /* Band-4 */ + 780656019, -1605955641, 1073741824, + 1605955641, -780656019, + /* Band-5 */ + 1024497031, -1817128152, 1073741824, + 1817128152, -1024497031, + /* Band-6 */ + 1073741824, 0, 0, + 0, 0, + /* Band-7 */ + 1073741824, 0, 0, + 0, 0, + } + }, + + .band_params[MBDRC_HIGH_BAND] = { + .band = MBDRC_HIGH_BAND, + .iir_stages = 5, + .in_attack_tc = 2144750688, + .in_release_tc = 70402888, + .fast_attack_tc = 2147483647, + .in_threshold = {130, 50, 30, 6}, + .out_threshold = {106, 50, 30, 13}, + .ratio = {40960, 2867, 4096, 2867, 410}, + .makeup_gain = 6, + .gain_init = 419430, + .gain_attack_tc = 4766887, + .gain_release_tc = 1044928780, + .fast_release_tc = 2147480170, + + .biquad_params = { + /* + * Gains: + * + * b0, b1, a0, + * a1, a2, + */ + + /* Band-0 */ + 1073741824, 0, 0, + 0, 0, + /* Band-1 */ + 1073741824, 0, 0, + 0, 0, + /* Band-2 */ + 1073741824, 0, 0, + 0, 0, + /* Band-3 */ + -619925131, 1073741824, 0, + 619925131, 0, + /* Band-4 */ + 606839335, -1455425976, 1073741824, + 1455425976, -606839335, + /* Band-5 */ + 917759617, -1724690840, 1073741824, + 1724690840, -917759617, + /* Band-6 */ + 1073741824, 0, 0, + 0, 0, + /* Band-7 */ + 1073741824, 0, 0, + 0, 0, + } + } +}; + +static void tegra210_mbdrc_write_ram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size) +{ + unsigned int val; + unsigned int i; + + val = ram_offset & TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK; + val |= TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN; + val |= TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN; + val |= TEGRA210_MBDRC_RAM_CTRL_RW_WRITE; + + regmap_write(regmap, reg_ctrl, val); + + for (i = 0; i < size; i++) + regmap_write(regmap, reg_data, data[i]); +} + +static int tegra210_mbdrc_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int val; + + regmap_read(ope->mbdrc_regmap, mc->reg, &val); + + ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max; + + return 0; +} + +static int tegra210_mbdrc_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int val = ucontrol->value.integer.value[0]; + bool change = false; + + val = val << mc->shift; + + regmap_update_bits_check(ope->mbdrc_regmap, mc->reg, + (mc->max << mc->shift), val, &change); + + return change ? 1 : 0; +} + +static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int val; + + regmap_read(ope->mbdrc_regmap, e->reg, &val); + + ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask; + + return 0; +} + +static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + bool change = false; + unsigned int val; + unsigned int mask; + + if (ucontrol->value.enumerated.item[0] > e->items - 1) + return -EINVAL; + + val = ucontrol->value.enumerated.item[0] << e->shift_l; + mask = e->mask << e->shift_l; + + regmap_update_bits_check(ope->mbdrc_regmap, e->reg, mask, val, + &change); + + return change ? 1 : 0; +} + +static int tegra210_mbdrc_band_params_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 *data = (u32 *)ucontrol->value.bytes.data; + u32 regs = params->soc.base; + u32 mask = params->soc.mask; + u32 shift = params->shift; + unsigned int i; + + for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) { + regmap_read(ope->mbdrc_regmap, regs, &data[i]); + + data[i] = ((data[i] & mask) >> shift); + } + + return 0; +} + +static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 *data = (u32 *)ucontrol->value.bytes.data; + u32 regs = params->soc.base; + u32 mask = params->soc.mask; + u32 shift = params->shift; + bool change = false; + unsigned int i; + + for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) { + bool update = false; + + regmap_update_bits_check(ope->mbdrc_regmap, regs, mask, + data[i] << shift, &update); + + change |= update; + } + + return change ? 1 : 0; +} + +static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 *data = (u32 *)ucontrol->value.bytes.data; + u32 regs = params->soc.base; + u32 num_regs = params->soc.num_regs; + u32 val; + unsigned int i; + + for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) { + regmap_read(ope->mbdrc_regmap, regs, &val); + + data[i] = (val & TEGRA210_MBDRC_THRESH_1ST_MASK) >> + TEGRA210_MBDRC_THRESH_1ST_SHIFT; + data[i + 1] = (val & TEGRA210_MBDRC_THRESH_2ND_MASK) >> + TEGRA210_MBDRC_THRESH_2ND_SHIFT; + data[i + 2] = (val & TEGRA210_MBDRC_THRESH_3RD_MASK) >> + TEGRA210_MBDRC_THRESH_3RD_SHIFT; + data[i + 3] = (val & TEGRA210_MBDRC_THRESH_4TH_MASK) >> + TEGRA210_MBDRC_THRESH_4TH_SHIFT; + } + + return 0; +} + +static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 *data = (u32 *)ucontrol->value.bytes.data; + u32 regs = params->soc.base; + u32 num_regs = params->soc.num_regs; + bool change = false; + unsigned int i; + + for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) { + bool update = false; + + data[i] = (((data[i] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT) & + TEGRA210_MBDRC_THRESH_1ST_MASK) | + ((data[i + 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT) & + TEGRA210_MBDRC_THRESH_2ND_MASK) | + ((data[i + 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT) & + TEGRA210_MBDRC_THRESH_3RD_MASK) | + ((data[i + 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT) & + TEGRA210_MBDRC_THRESH_4TH_MASK)); + + regmap_update_bits_check(ope->mbdrc_regmap, regs, 0xffffffff, + data[i], &update); + + change |= update; + } + + return change ? 1 : 0; +} + +static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + u32 *data = (u32 *)ucontrol->value.bytes.data; + + memset(data, 0, params->soc.num_regs * cmpnt->val_bytes); + + return 0; +} + +static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 reg_ctrl = params->soc.base; + u32 reg_data = reg_ctrl + cmpnt->val_bytes; + u32 *data = (u32 *)ucontrol->value.bytes.data; + + tegra210_mbdrc_write_ram(ope->mbdrc_regmap, reg_ctrl, reg_data, + params->shift, data, params->soc.num_regs); + + return 1; +} + +static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes *params = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = params->num_regs * sizeof(u32); + + return 0; +} + +static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + int val; + + regmap_read(ope->mbdrc_regmap, mc->reg, &val); + + ucontrol->value.integer.value[0] = + ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN); + + return 0; +} + +static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + int val = ucontrol->value.integer.value[0]; + bool change = false; + + val += TEGRA210_MBDRC_MASTER_VOL_MIN; + + regmap_update_bits_check(ope->mbdrc_regmap, mc->reg, + mc->max << mc->shift, val << mc->shift, + &change); + + regmap_read(ope->mbdrc_regmap, mc->reg, &val); + + return change ? 1 : 0; +} + +static const char * const tegra210_mbdrc_mode_text[] = { + "Bypass", "Fullband", "Dualband", "Multiband" +}; + +static const struct soc_enum tegra210_mbdrc_mode_enum = + SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT, + 4, tegra210_mbdrc_mode_text); + +static const char * const tegra210_mbdrc_peak_rms_text[] = { + "Peak", "RMS" +}; + +static const struct soc_enum tegra210_mbdrc_peak_rms_enum = + SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT, + 2, tegra210_mbdrc_peak_rms_text); + +static const char * const tegra210_mbdrc_filter_structure_text[] = { + "All-pass-tree", "Flexible" +}; + +static const struct soc_enum tegra210_mbdrc_filter_structure_enum = + SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT, 2, + tegra210_mbdrc_filter_structure_text); + +static const char * const tegra210_mbdrc_frame_size_text[] = { + "N1", "N2", "N4", "N8", "N16", "N32", "N64" +}; + +static const struct soc_enum tegra210_mbdrc_frame_size_enum = + SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT, + 7, tegra210_mbdrc_frame_size_text); + +#define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo) \ + TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \ + tegra210_mbdrc_band_params_get, \ + tegra210_mbdrc_band_params_put, \ + tegra210_mbdrc_param_info) + +#define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo) \ + TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT, \ + xshift, xmask, xinfo) + +static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500); + +static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = { + SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum, + tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum), + + SOC_ENUM_EXT("MBDRC Filter Structure", + tegra210_mbdrc_filter_structure_enum, + tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum), + + SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum, + tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum), + + SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum, + tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum), + + SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT, 0x1ff, 0, + tegra210_mbdrc_get, tegra210_mbdrc_put), + + SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT, 0x1f, 0, + tegra210_mbdrc_get, tegra210_mbdrc_put), + + SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR, + TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0, + tegra210_mbdrc_get, tegra210_mbdrc_put), + + SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR, + TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0, + tegra210_mbdrc_get, tegra210_mbdrc_put), + + SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume", + TEGRA210_MBDRC_MASTER_VOL, + TEGRA210_MBDRC_MASTER_VOL_SHIFT, + 0, 0x1ff, 0, + tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put, + mdbrc_vol_tlv), + + TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT, + TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT, + TEGRA210_MBDRC_IN_ATTACK_TC_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT, + TEGRA210_MBDRC_IN_RELEASE_TC_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT, + TEGRA210_MBDRC_FAST_ATTACK_TC_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_THRESHOLD, + TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff, + tegra210_mbdrc_threshold_get, + tegra210_mbdrc_threshold_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD, + TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff, + tegra210_mbdrc_threshold_get, + tegra210_mbdrc_threshold_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST, + TEGRA210_MBDRC_FILTER_COUNT * 5, + TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT, + TEGRA210_MBDRC_MAKEUP_GAIN_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_INIT_GAIN_SHIFT, + TEGRA210_MBDRC_INIT_GAIN_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_GAIN_ATTACK_SHIFT, + TEGRA210_MBDRC_GAIN_ATTACK_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_GAIN_RELEASE_SHIFT, + TEGRA210_MBDRC_GAIN_RELEASE_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain", + TEGRA210_MBDRC_FAST_RELEASE, + TEGRA210_MBDRC_FILTER_COUNT, + TEGRA210_MBDRC_FAST_RELEASE_SHIFT, + TEGRA210_MBDRC_FAST_RELEASE_MASK, + tegra210_mbdrc_band_params_get, + tegra210_mbdrc_band_params_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs", + TEGRA210_MBDRC_CFG_RAM_CTRL, + TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, + tegra210_mbdrc_biquad_coeffs_get, + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs", + TEGRA210_MBDRC_CFG_RAM_CTRL + + TEGRA210_MBDRC_FILTER_PARAM_STRIDE, + TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, + tegra210_mbdrc_biquad_coeffs_get, + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), + + TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs", + TEGRA210_MBDRC_CFG_RAM_CTRL + + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2), + TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff, + tegra210_mbdrc_biquad_coeffs_get, + tegra210_mbdrc_biquad_coeffs_put, + tegra210_mbdrc_param_info), +}; + +static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg) +{ + if (reg >= TEGRA210_MBDRC_IIR_CFG) + reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) % + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * + TEGRA210_MBDRC_FILTER_COUNT)); + + switch (reg) { + case TEGRA210_MBDRC_SOFT_RESET: + case TEGRA210_MBDRC_CG: + case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA: + return true; + default: + return false; + } +} + +static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg) +{ + if (tegra210_mbdrc_wr_reg(dev, reg)) + return true; + + if (reg >= TEGRA210_MBDRC_IIR_CFG) + reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) % + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * + TEGRA210_MBDRC_FILTER_COUNT)); + + switch (reg) { + case TEGRA210_MBDRC_STATUS: + return true; + default: + return false; + } +} + +static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg) +{ + if (reg >= TEGRA210_MBDRC_IIR_CFG) + reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) % + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * + TEGRA210_MBDRC_FILTER_COUNT)); + + switch (reg) { + case TEGRA210_MBDRC_SOFT_RESET: + case TEGRA210_MBDRC_STATUS: + case TEGRA210_MBDRC_CFG_RAM_CTRL: + case TEGRA210_MBDRC_CFG_RAM_DATA: + return true; + default: + return false; + } +} + +static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg) +{ + if (reg >= TEGRA210_MBDRC_IIR_CFG) + reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) % + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * + TEGRA210_MBDRC_FILTER_COUNT)); + + switch (reg) { + case TEGRA210_MBDRC_CFG_RAM_DATA: + return true; + default: + return false; + } +} + +static const struct regmap_config tegra210_mbdrc_regmap_cfg = { + .name = "mbdrc", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA210_MBDRC_MAX_REG, + .writeable_reg = tegra210_mbdrc_wr_reg, + .readable_reg = tegra210_mbdrc_rd_reg, + .volatile_reg = tegra210_mbdrc_volatile_reg, + .precious_reg = tegra210_mbdrc_precious_reg, + .reg_defaults = tegra210_mbdrc_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tegra210_mbdrc_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + +int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt) +{ + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + const struct tegra210_mbdrc_config *conf = &mbdrc_init_config; + u32 val = 0; + unsigned int i; + + regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val); + + if (val & TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS) + return 0; + + for (i = 0; i < MBDRC_NUM_BAND; i++) { + const struct tegra210_mbdrc_band_params *params = + &conf->band_params[i]; + + u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE; + + tegra210_mbdrc_write_ram(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL, + reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, + 0, (u32 *)¶ms->biquad_params[0], + TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5); + } + return 0; +} + +int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt) +{ + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + const struct tegra210_mbdrc_config *conf = &mbdrc_init_config; + unsigned int i; + u32 val; + + pm_runtime_get_sync(cmpnt->dev); + + /* Initialize MBDRC registers and AHUB RAM with default params */ + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK, + conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK, + conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_PEAK_RMS_MASK, + conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK, + conf->fliter_structure << + TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK, + conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, + TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK, + __ffs(conf->frame_size) << + TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK, + TEGRA210_MBDRC_CHANNEL_MASK_MASK, + conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR, + TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK, + conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR, + TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK, + conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT); + + for (i = 0; i < MBDRC_NUM_BAND; i++) { + const struct tegra210_mbdrc_band_params *params = + &conf->band_params[i]; + u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE; + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_IIR_CFG, + TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK, + params->iir_stages << + TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_IN_ATTACK, + TEGRA210_MBDRC_IN_ATTACK_TC_MASK, + params->in_attack_tc << + TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_IN_RELEASE, + TEGRA210_MBDRC_IN_RELEASE_TC_MASK, + params->in_release_tc << + TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_FAST_ATTACK, + TEGRA210_MBDRC_FAST_ATTACK_TC_MASK, + params->fast_attack_tc << + TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT); + + val = (((params->in_threshold[0] >> + TEGRA210_MBDRC_THRESH_1ST_SHIFT) & + TEGRA210_MBDRC_THRESH_1ST_MASK) | + ((params->in_threshold[1] >> + TEGRA210_MBDRC_THRESH_2ND_SHIFT) & + TEGRA210_MBDRC_THRESH_2ND_MASK) | + ((params->in_threshold[2] >> + TEGRA210_MBDRC_THRESH_3RD_SHIFT) & + TEGRA210_MBDRC_THRESH_3RD_MASK) | + ((params->in_threshold[3] >> + TEGRA210_MBDRC_THRESH_4TH_SHIFT) & + TEGRA210_MBDRC_THRESH_4TH_MASK)); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_IN_THRESHOLD, + 0xffffffff, val); + + val = (((params->out_threshold[0] >> + TEGRA210_MBDRC_THRESH_1ST_SHIFT) & + TEGRA210_MBDRC_THRESH_1ST_MASK) | + ((params->out_threshold[1] >> + TEGRA210_MBDRC_THRESH_2ND_SHIFT) & + TEGRA210_MBDRC_THRESH_2ND_MASK) | + ((params->out_threshold[2] >> + TEGRA210_MBDRC_THRESH_3RD_SHIFT) & + TEGRA210_MBDRC_THRESH_3RD_MASK) | + ((params->out_threshold[3] >> + TEGRA210_MBDRC_THRESH_4TH_SHIFT) & + TEGRA210_MBDRC_THRESH_4TH_MASK)); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_OUT_THRESHOLD, + 0xffffffff, val); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_RATIO_1ST, + TEGRA210_MBDRC_RATIO_1ST_MASK, + params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_RATIO_2ND, + TEGRA210_MBDRC_RATIO_2ND_MASK, + params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_RATIO_3RD, + TEGRA210_MBDRC_RATIO_3RD_MASK, + params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_RATIO_4TH, + TEGRA210_MBDRC_RATIO_4TH_MASK, + params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_RATIO_5TH, + TEGRA210_MBDRC_RATIO_5TH_MASK, + params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_MAKEUP_GAIN, + TEGRA210_MBDRC_MAKEUP_GAIN_MASK, + params->makeup_gain << + TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_INIT_GAIN, + TEGRA210_MBDRC_INIT_GAIN_MASK, + params->gain_init << + TEGRA210_MBDRC_INIT_GAIN_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_GAIN_ATTACK, + TEGRA210_MBDRC_GAIN_ATTACK_MASK, + params->gain_attack_tc << + TEGRA210_MBDRC_GAIN_ATTACK_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_GAIN_RELEASE, + TEGRA210_MBDRC_GAIN_RELEASE_MASK, + params->gain_release_tc << + TEGRA210_MBDRC_GAIN_RELEASE_SHIFT); + + regmap_update_bits(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_FAST_RELEASE, + TEGRA210_MBDRC_FAST_RELEASE_MASK, + params->fast_release_tc << + TEGRA210_MBDRC_FAST_RELEASE_SHIFT); + + tegra210_mbdrc_write_ram(ope->mbdrc_regmap, + reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL, + reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, 0, + (u32 *)¶ms->biquad_params[0], + TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5); + } + + pm_runtime_put_sync(cmpnt->dev); + + snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls, + ARRAY_SIZE(tegra210_mbdrc_controls)); + + return 0; +} + +int tegra210_mbdrc_regmap_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra210_ope *ope = dev_get_drvdata(dev); + struct device_node *child; + struct resource mem; + void __iomem *regs; + int err; + + child = of_get_child_by_name(dev->of_node, "dynamic-range-compressor"); + if (!child) + return -ENODEV; + + err = of_address_to_resource(child, 0, &mem); + of_node_put(child); + if (err < 0) { + dev_err(dev, "fail to get MBDRC resource\n"); + return err; + } + + mem.flags = IORESOURCE_MEM; + regs = devm_ioremap_resource(dev, &mem); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + ope->mbdrc_regmap = devm_regmap_init_mmio(dev, regs, + &tegra210_mbdrc_regmap_cfg); + if (IS_ERR(ope->mbdrc_regmap)) { + dev_err(dev, "regmap init failed\n"); + return PTR_ERR(ope->mbdrc_regmap); + } + + regcache_cache_only(ope->mbdrc_regmap, true); + + return 0; +} diff --git a/sound/soc/tegra/tegra210_mbdrc.h b/sound/soc/tegra/tegra210_mbdrc.h new file mode 100644 index 0000000000000..4c48da0e1dea6 --- /dev/null +++ b/sound/soc/tegra/tegra210_mbdrc.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * tegra210_mbdrc.h - Definitions for Tegra210 MBDRC driver + * + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + */ + +#ifndef __TEGRA210_MBDRC_H__ +#define __TEGRA210_MBDRC_H__ + +#include +#include + +/* Register offsets from TEGRA210_MBDRC*_BASE */ +#define TEGRA210_MBDRC_SOFT_RESET 0x4 +#define TEGRA210_MBDRC_CG 0x8 +#define TEGRA210_MBDRC_STATUS 0xc +#define TEGRA210_MBDRC_CFG 0x28 +#define TEGRA210_MBDRC_CHANNEL_MASK 0x2c +#define TEGRA210_MBDRC_MASTER_VOL 0x30 +#define TEGRA210_MBDRC_FAST_FACTOR 0x34 + +#define TEGRA210_MBDRC_FILTER_COUNT 3 +#define TEGRA210_MBDRC_FILTER_PARAM_STRIDE 0x4 + +#define TEGRA210_MBDRC_IIR_CFG 0x38 +#define TEGRA210_MBDRC_IN_ATTACK 0x44 +#define TEGRA210_MBDRC_IN_RELEASE 0x50 +#define TEGRA210_MBDRC_FAST_ATTACK 0x5c +#define TEGRA210_MBDRC_IN_THRESHOLD 0x68 +#define TEGRA210_MBDRC_OUT_THRESHOLD 0x74 +#define TEGRA210_MBDRC_RATIO_1ST 0x80 +#define TEGRA210_MBDRC_RATIO_2ND 0x8c +#define TEGRA210_MBDRC_RATIO_3RD 0x98 +#define TEGRA210_MBDRC_RATIO_4TH 0xa4 +#define TEGRA210_MBDRC_RATIO_5TH 0xb0 +#define TEGRA210_MBDRC_MAKEUP_GAIN 0xbc +#define TEGRA210_MBDRC_INIT_GAIN 0xc8 +#define TEGRA210_MBDRC_GAIN_ATTACK 0xd4 +#define TEGRA210_MBDRC_GAIN_RELEASE 0xe0 +#define TEGRA210_MBDRC_FAST_RELEASE 0xec +#define TEGRA210_MBDRC_CFG_RAM_CTRL 0xf8 +#define TEGRA210_MBDRC_CFG_RAM_DATA 0x104 + +#define TEGRA210_MBDRC_MAX_REG (TEGRA210_MBDRC_CFG_RAM_DATA + \ + (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * \ + (TEGRA210_MBDRC_FILTER_COUNT - 1))) + +/* Fields for TEGRA210_MBDRC_CFG */ +#define TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT 16 +#define TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK (0x1ff << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT) + +#define TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT 14 +#define TEGRA210_MBDRC_CFG_PEAK_RMS_MASK (0x1 << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT) +#define TEGRA210_MBDRC_CFG_PEAK (1 << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT) + +#define TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT 13 +#define TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK (0x1 << TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT) +#define TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_FLEX (1 << TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT) + +#define TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT 8 +#define TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK (0x1f << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT) + +#define TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT 4 +#define TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK (0xf << TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT) + +#define TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT 0 +#define TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK (0x3 << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT) +#define TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS (0 << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT) + +/* Fields for TEGRA210_MBDRC_CHANNEL_MASK */ +#define TEGRA210_MBDRC_CHANNEL_MASK_SHIFT 0 +#define TEGRA210_MBDRC_CHANNEL_MASK_MASK (0xff << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT) + +/* Fields for TEGRA210_MBDRC_MASTER_VOL */ +#define TEGRA210_MBDRC_MASTER_VOL_SHIFT 23 +#define TEGRA210_MBDRC_MASTER_VOL_MIN -256 +#define TEGRA210_MBDRC_MASTER_VOL_MAX 256 + +/* Fields for TEGRA210_MBDRC_FAST_FACTOR */ +#define TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT 16 +#define TEGRA210_MBDRC_FAST_FACTOR_RELEASE_MASK (0xffff << TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT) + +#define TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT 0 +#define TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK (0xffff << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT) + +/* Fields for TEGRA210_MBDRC_IIR_CFG */ +#define TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT 0 +#define TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK (0xf << TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_ATTACK */ +#define TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT 0 +#define TEGRA210_MBDRC_IN_ATTACK_TC_MASK (0xffffffff << TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_RELEASE */ +#define TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT 0 +#define TEGRA210_MBDRC_IN_RELEASE_TC_MASK (0xffffffff << TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_FAST_ATTACK */ +#define TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT 0 +#define TEGRA210_MBDRC_FAST_ATTACK_TC_MASK (0xffffffff << TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT) + +/* Fields for TEGRA210_MBDRC_IN_THRESHOLD / TEGRA210_MBDRC_OUT_THRESHOLD */ +#define TEGRA210_MBDRC_THRESH_4TH_SHIFT 24 +#define TEGRA210_MBDRC_THRESH_4TH_MASK (0xff << TEGRA210_MBDRC_THRESH_4TH_SHIFT) + +#define TEGRA210_MBDRC_THRESH_3RD_SHIFT 16 +#define TEGRA210_MBDRC_THRESH_3RD_MASK (0xff << TEGRA210_MBDRC_THRESH_3RD_SHIFT) + +#define TEGRA210_MBDRC_THRESH_2ND_SHIFT 8 +#define TEGRA210_MBDRC_THRESH_2ND_MASK (0xff << TEGRA210_MBDRC_THRESH_2ND_SHIFT) + +#define TEGRA210_MBDRC_THRESH_1ST_SHIFT 0 +#define TEGRA210_MBDRC_THRESH_1ST_MASK (0xff << TEGRA210_MBDRC_THRESH_1ST_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_1ST */ +#define TEGRA210_MBDRC_RATIO_1ST_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_1ST_MASK (0xffff << TEGRA210_MBDRC_RATIO_1ST_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_2ND */ +#define TEGRA210_MBDRC_RATIO_2ND_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_2ND_MASK (0xffff << TEGRA210_MBDRC_RATIO_2ND_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_3RD */ +#define TEGRA210_MBDRC_RATIO_3RD_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_3RD_MASK (0xffff << TEGRA210_MBDRC_RATIO_3RD_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_4TH */ +#define TEGRA210_MBDRC_RATIO_4TH_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_4TH_MASK (0xffff << TEGRA210_MBDRC_RATIO_4TH_SHIFT) + +/* Fields for TEGRA210_MBDRC_RATIO_5TH */ +#define TEGRA210_MBDRC_RATIO_5TH_SHIFT 0 +#define TEGRA210_MBDRC_RATIO_5TH_MASK (0xffff << TEGRA210_MBDRC_RATIO_5TH_SHIFT) + +/* Fields for TEGRA210_MBDRC_MAKEUP_GAIN */ +#define TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT 0 +#define TEGRA210_MBDRC_MAKEUP_GAIN_MASK (0x3f << TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT) + +/* Fields for TEGRA210_MBDRC_INIT_GAIN */ +#define TEGRA210_MBDRC_INIT_GAIN_SHIFT 0 +#define TEGRA210_MBDRC_INIT_GAIN_MASK (0xffffffff << TEGRA210_MBDRC_INIT_GAIN_SHIFT) + +/* Fields for TEGRA210_MBDRC_GAIN_ATTACK */ +#define TEGRA210_MBDRC_GAIN_ATTACK_SHIFT 0 +#define TEGRA210_MBDRC_GAIN_ATTACK_MASK (0xffffffff << TEGRA210_MBDRC_GAIN_ATTACK_SHIFT) + +/* Fields for TEGRA210_MBDRC_GAIN_RELEASE */ +#define TEGRA210_MBDRC_GAIN_RELEASE_SHIFT 0 +#define TEGRA210_MBDRC_GAIN_RELEASE_MASK (0xffffffff << TEGRA210_MBDRC_GAIN_RELEASE_SHIFT) + +/* Fields for TEGRA210_MBDRC_FAST_RELEASE */ +#define TEGRA210_MBDRC_FAST_RELEASE_SHIFT 0 +#define TEGRA210_MBDRC_FAST_RELEASE_MASK (0xffffffff << TEGRA210_MBDRC_FAST_RELEASE_SHIFT) + +#define TEGRA210_MBDRC_RAM_CTRL_RW_READ 0 +#define TEGRA210_MBDRC_RAM_CTRL_RW_WRITE (1 << 14) +#define TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN (1 << 13) +#define TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN (1 << 12) +#define TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK 0x1ff + +/* + * Order and size of each structure element for following structures should not + * be altered size order of elements and their size are based on PEQ co-eff ram + * and shift ram layout. + */ +#define TEGRA210_MBDRC_THRESHOLD_NUM 4 +#define TEGRA210_MBDRC_RATIO_NUM (TEGRA210_MBDRC_THRESHOLD_NUM + 1) +#define TEGRA210_MBDRC_MAX_BIQUAD_STAGES 8 + +/* Order of these enums are same as the order of band specific hw registers */ +enum { + MBDRC_LOW_BAND, + MBDRC_MID_BAND, + MBDRC_HIGH_BAND, + MBDRC_NUM_BAND, +}; + +struct tegra210_mbdrc_band_params { + u32 band; + u32 iir_stages; + u32 in_attack_tc; + u32 in_release_tc; + u32 fast_attack_tc; + u32 in_threshold[TEGRA210_MBDRC_THRESHOLD_NUM]; + u32 out_threshold[TEGRA210_MBDRC_THRESHOLD_NUM]; + u32 ratio[TEGRA210_MBDRC_RATIO_NUM]; + u32 makeup_gain; + u32 gain_init; + u32 gain_attack_tc; + u32 gain_release_tc; + u32 fast_release_tc; + /* For biquad_params[][5] order of coeff is b0, b1, a0, a1, a2 */ + u32 biquad_params[TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5]; +}; + +struct tegra210_mbdrc_config { + unsigned int mode; + unsigned int rms_off; + unsigned int peak_rms_mode; + unsigned int fliter_structure; + unsigned int shift_ctrl; + unsigned int frame_size; + unsigned int channel_mask; + unsigned int fa_factor; /* Fast attack factor */ + unsigned int fr_factor; /* Fast release factor */ + struct tegra210_mbdrc_band_params band_params[MBDRC_NUM_BAND]; +}; + +int tegra210_mbdrc_regmap_init(struct platform_device *pdev); +int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt); +int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt); + +#endif diff --git a/sound/soc/tegra/tegra210_ope.c b/sound/soc/tegra/tegra210_ope.c new file mode 100644 index 0000000000000..3dd2bdec657bc --- /dev/null +++ b/sound/soc/tegra/tegra210_ope.c @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// tegra210_ope.c - Tegra210 OPE driver +// +// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tegra210_mbdrc.h" +#include "tegra210_ope.h" +#include "tegra210_peq.h" +#include "tegra_cif.h" + +static const struct reg_default tegra210_ope_reg_defaults[] = { + { TEGRA210_OPE_RX_INT_MASK, 0x00000001}, + { TEGRA210_OPE_RX_CIF_CTRL, 0x00007700}, + { TEGRA210_OPE_TX_INT_MASK, 0x00000001}, + { TEGRA210_OPE_TX_CIF_CTRL, 0x00007700}, + { TEGRA210_OPE_CG, 0x1}, +}; + +static int tegra210_ope_set_audio_cif(struct tegra210_ope *ope, + struct snd_pcm_hw_params *params, + unsigned int reg) +{ + int channels, audio_bits; + struct tegra_cif_conf cif_conf; + + memset(&cif_conf, 0, sizeof(struct tegra_cif_conf)); + + channels = params_channels(params); + if (channels < 2) + return -EINVAL; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + audio_bits = TEGRA_ACIF_BITS_16; + break; + case SNDRV_PCM_FORMAT_S32_LE: + audio_bits = TEGRA_ACIF_BITS_32; + break; + default: + return -EINVAL; + } + + cif_conf.audio_ch = channels; + cif_conf.client_ch = channels; + cif_conf.audio_bits = audio_bits; + cif_conf.client_bits = audio_bits; + + tegra_set_cif(ope->regmap, reg, &cif_conf); + + return 0; +} + +static int tegra210_ope_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct device *dev = dai->dev; + struct tegra210_ope *ope = snd_soc_dai_get_drvdata(dai); + int err; + + /* Set RX and TX CIF */ + err = tegra210_ope_set_audio_cif(ope, params, + TEGRA210_OPE_RX_CIF_CTRL); + if (err) { + dev_err(dev, "Can't set OPE RX CIF: %d\n", err); + return err; + } + + err = tegra210_ope_set_audio_cif(ope, params, + TEGRA210_OPE_TX_CIF_CTRL); + if (err) { + dev_err(dev, "Can't set OPE TX CIF: %d\n", err); + return err; + } + + tegra210_mbdrc_hw_params(dai->component); + + return err; +} + +static int tegra210_ope_component_probe(struct snd_soc_component *cmpnt) +{ + struct tegra210_ope *ope = dev_get_drvdata(cmpnt->dev); + + tegra210_peq_component_init(cmpnt); + tegra210_mbdrc_component_init(cmpnt); + + /* + * The OPE, PEQ and MBDRC functionalities are combined under one + * device registered by OPE driver. In fact OPE HW block includes + * sub blocks PEQ and MBDRC. However driver registers separate + * regmap interfaces for each of these. ASoC core depends on + * dev_get_regmap() to populate the regmap field for a given ASoC + * component. A component can have one regmap reference and since + * the DAPM routes depend on OPE regmap only, below explicit + * assignment is done to highlight this. This is needed for ASoC + * core to access correct regmap during DAPM path setup. + */ + snd_soc_component_init_regmap(cmpnt, ope->regmap); + + return 0; +} + +static const struct snd_soc_dai_ops tegra210_ope_dai_ops = { + .hw_params = tegra210_ope_hw_params, +}; + +static struct snd_soc_dai_driver tegra210_ope_dais[] = { + { + .name = "OPE-RX-CIF", + .playback = { + .stream_name = "RX-CIF-Playback", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "RX-CIF-Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + }, + { + .name = "OPE-TX-CIF", + .playback = { + .stream_name = "TX-CIF-Playback", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "TX-CIF-Capture", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &tegra210_ope_dai_ops, + } +}; + +static const struct snd_soc_dapm_widget tegra210_ope_widgets[] = { + SND_SOC_DAPM_AIF_IN("RX", NULL, 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("TX", NULL, 0, TEGRA210_OPE_ENABLE, + TEGRA210_OPE_EN_SHIFT, 0), +}; + +#define OPE_ROUTES(sname) \ + { "RX XBAR-" sname, NULL, "XBAR-TX" }, \ + { "RX-CIF-" sname, NULL, "RX XBAR-" sname }, \ + { "RX", NULL, "RX-CIF-" sname }, \ + { "TX-CIF-" sname, NULL, "TX" }, \ + { "TX XBAR-" sname, NULL, "TX-CIF-" sname }, \ + { "XBAR-RX", NULL, "TX XBAR-" sname } + +static const struct snd_soc_dapm_route tegra210_ope_routes[] = { + { "TX", NULL, "RX" }, + OPE_ROUTES("Playback"), + OPE_ROUTES("Capture"), +}; + +static const char * const tegra210_ope_data_dir_text[] = { + "MBDRC to PEQ", + "PEQ to MBDRC" +}; + +static const struct soc_enum tegra210_ope_data_dir_enum = + SOC_ENUM_SINGLE(TEGRA210_OPE_DIR, TEGRA210_OPE_DIR_SHIFT, + 2, tegra210_ope_data_dir_text); + +static int tegra210_ope_get_data_dir(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + + ucontrol->value.enumerated.item[0] = ope->data_dir; + + return 0; +} + +static int tegra210_ope_put_data_dir(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int value = ucontrol->value.enumerated.item[0]; + + if (value == ope->data_dir) + return 0; + + ope->data_dir = value; + + return 1; +} + +static const struct snd_kcontrol_new tegra210_ope_controls[] = { + SOC_ENUM_EXT("Data Flow Direction", tegra210_ope_data_dir_enum, + tegra210_ope_get_data_dir, tegra210_ope_put_data_dir), +}; + +static const struct snd_soc_component_driver tegra210_ope_cmpnt = { + .probe = tegra210_ope_component_probe, + .dapm_widgets = tegra210_ope_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra210_ope_widgets), + .dapm_routes = tegra210_ope_routes, + .num_dapm_routes = ARRAY_SIZE(tegra210_ope_routes), + .controls = tegra210_ope_controls, + .num_controls = ARRAY_SIZE(tegra210_ope_controls), +}; + +static bool tegra210_ope_wr_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_OPE_RX_INT_MASK ... TEGRA210_OPE_RX_CIF_CTRL: + case TEGRA210_OPE_TX_INT_MASK ... TEGRA210_OPE_TX_CIF_CTRL: + case TEGRA210_OPE_ENABLE ... TEGRA210_OPE_CG: + case TEGRA210_OPE_DIR: + return true; + default: + return false; + } +} + +static bool tegra210_ope_rd_reg(struct device *dev, unsigned int reg) +{ + if (tegra210_ope_wr_reg(dev, reg)) + return true; + + switch (reg) { + case TEGRA210_OPE_RX_STATUS: + case TEGRA210_OPE_RX_INT_STATUS: + case TEGRA210_OPE_TX_STATUS: + case TEGRA210_OPE_TX_INT_STATUS: + case TEGRA210_OPE_STATUS: + case TEGRA210_OPE_INT_STATUS: + return true; + default: + return false; + } +} + +static bool tegra210_ope_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_OPE_RX_STATUS: + case TEGRA210_OPE_RX_INT_STATUS: + case TEGRA210_OPE_TX_STATUS: + case TEGRA210_OPE_TX_INT_STATUS: + case TEGRA210_OPE_SOFT_RESET: + case TEGRA210_OPE_STATUS: + case TEGRA210_OPE_INT_STATUS: + return true; + default: + return false; + } +} + +static const struct regmap_config tegra210_ope_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA210_OPE_DIR, + .writeable_reg = tegra210_ope_wr_reg, + .readable_reg = tegra210_ope_rd_reg, + .volatile_reg = tegra210_ope_volatile_reg, + .reg_defaults = tegra210_ope_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tegra210_ope_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + +static int tegra210_ope_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra210_ope *ope; + void __iomem *regs; + int err; + + ope = devm_kzalloc(dev, sizeof(*ope), GFP_KERNEL); + if (!ope) + return -ENOMEM; + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + ope->regmap = devm_regmap_init_mmio(dev, regs, + &tegra210_ope_regmap_config); + if (IS_ERR(ope->regmap)) { + dev_err(dev, "regmap init failed\n"); + return PTR_ERR(ope->regmap); + } + + regcache_cache_only(ope->regmap, true); + + dev_set_drvdata(dev, ope); + + err = tegra210_peq_regmap_init(pdev); + if (err < 0) { + dev_err(dev, "PEQ init failed\n"); + return err; + } + + err = tegra210_mbdrc_regmap_init(pdev); + if (err < 0) { + dev_err(dev, "MBDRC init failed\n"); + return err; + } + + err = devm_snd_soc_register_component(dev, &tegra210_ope_cmpnt, + tegra210_ope_dais, + ARRAY_SIZE(tegra210_ope_dais)); + if (err) { + dev_err(dev, "can't register OPE component, err: %d\n", err); + return err; + } + + pm_runtime_enable(dev); + + return 0; +} + +static int tegra210_ope_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + + return 0; +} + +static int __maybe_unused tegra210_ope_runtime_suspend(struct device *dev) +{ + struct tegra210_ope *ope = dev_get_drvdata(dev); + + tegra210_peq_save(ope->peq_regmap, ope->peq_biquad_gains, + ope->peq_biquad_shifts); + + regcache_cache_only(ope->mbdrc_regmap, true); + regcache_cache_only(ope->peq_regmap, true); + regcache_cache_only(ope->regmap, true); + + regcache_mark_dirty(ope->regmap); + regcache_mark_dirty(ope->peq_regmap); + regcache_mark_dirty(ope->mbdrc_regmap); + + return 0; +} + +static int __maybe_unused tegra210_ope_runtime_resume(struct device *dev) +{ + struct tegra210_ope *ope = dev_get_drvdata(dev); + + regcache_cache_only(ope->regmap, false); + regcache_cache_only(ope->peq_regmap, false); + regcache_cache_only(ope->mbdrc_regmap, false); + + regcache_sync(ope->regmap); + regcache_sync(ope->peq_regmap); + regcache_sync(ope->mbdrc_regmap); + + tegra210_peq_restore(ope->peq_regmap, ope->peq_biquad_gains, + ope->peq_biquad_shifts); + + return 0; +} + +static const struct dev_pm_ops tegra210_ope_pm_ops = { + SET_RUNTIME_PM_OPS(tegra210_ope_runtime_suspend, + tegra210_ope_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static const struct of_device_id tegra210_ope_of_match[] = { + { .compatible = "nvidia,tegra210-ope" }, + {}, +}; +MODULE_DEVICE_TABLE(of, tegra210_ope_of_match); + +static struct platform_driver tegra210_ope_driver = { + .driver = { + .name = "tegra210-ope", + .of_match_table = tegra210_ope_of_match, + .pm = &tegra210_ope_pm_ops, + }, + .probe = tegra210_ope_probe, + .remove = tegra210_ope_remove, +}; +module_platform_driver(tegra210_ope_driver) + +MODULE_AUTHOR("Sumit Bhattacharya "); +MODULE_DESCRIPTION("Tegra210 OPE ASoC driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/tegra/tegra210_ope.h b/sound/soc/tegra/tegra210_ope.h new file mode 100644 index 0000000000000..2835af6ce6312 --- /dev/null +++ b/sound/soc/tegra/tegra210_ope.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * tegra210_ope.h - Definitions for Tegra210 OPE driver + * + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + */ + +#ifndef __TEGRA210_OPE_H__ +#define __TEGRA210_OPE_H__ + +#include +#include + +#include "tegra210_peq.h" + +/* + * OPE_RX registers are with respect to XBAR. + * The data comes from XBAR to OPE + */ +#define TEGRA210_OPE_RX_STATUS 0xc +#define TEGRA210_OPE_RX_INT_STATUS 0x10 +#define TEGRA210_OPE_RX_INT_MASK 0x14 +#define TEGRA210_OPE_RX_INT_SET 0x18 +#define TEGRA210_OPE_RX_INT_CLEAR 0x1c +#define TEGRA210_OPE_RX_CIF_CTRL 0x20 + +/* + * OPE_TX registers are with respect to XBAR. + * The data goes out from OPE to XBAR + */ +#define TEGRA210_OPE_TX_STATUS 0x4c +#define TEGRA210_OPE_TX_INT_STATUS 0x50 +#define TEGRA210_OPE_TX_INT_MASK 0x54 +#define TEGRA210_OPE_TX_INT_SET 0x58 +#define TEGRA210_OPE_TX_INT_CLEAR 0x5c +#define TEGRA210_OPE_TX_CIF_CTRL 0x60 + +/* OPE Gloabal registers */ +#define TEGRA210_OPE_ENABLE 0x80 +#define TEGRA210_OPE_SOFT_RESET 0x84 +#define TEGRA210_OPE_CG 0x88 +#define TEGRA210_OPE_STATUS 0x8c +#define TEGRA210_OPE_INT_STATUS 0x90 +#define TEGRA210_OPE_DIR 0x94 + +/* Fields for TEGRA210_OPE_ENABLE */ +#define TEGRA210_OPE_EN_SHIFT 0 +#define TEGRA210_OPE_EN (1 << TEGRA210_OPE_EN_SHIFT) + +/* Fields for TEGRA210_OPE_SOFT_RESET */ +#define TEGRA210_OPE_SOFT_RESET_SHIFT 0 +#define TEGRA210_OPE_SOFT_RESET_EN (1 << TEGRA210_OPE_SOFT_RESET_SHIFT) + +#define TEGRA210_OPE_DIR_SHIFT 0 + +struct tegra210_ope { + struct regmap *regmap; + struct regmap *peq_regmap; + struct regmap *mbdrc_regmap; + u32 peq_biquad_gains[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH]; + u32 peq_biquad_shifts[TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH]; + unsigned int data_dir; +}; + +/* Extension of soc_bytes structure defined in sound/soc.h */ +struct tegra_soc_bytes { + struct soc_bytes soc; + u32 shift; /* Used as offset for AHUB RAM related programing */ +}; + +/* Utility structures for using mixer control of type snd_soc_bytes */ +#define TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, \ + xhandler_get, xhandler_put, xinfo) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .info = xinfo, \ + .get = xhandler_get, \ + .put = xhandler_put, \ + .private_value = ((unsigned long)&(struct tegra_soc_bytes) \ + { \ + .soc.base = xbase, \ + .soc.num_regs = xregs, \ + .soc.mask = xmask, \ + .shift = xshift \ + }) \ +} + +#endif diff --git a/sound/soc/tegra/tegra210_peq.c b/sound/soc/tegra/tegra210_peq.c new file mode 100644 index 0000000000000..205d956abb42a --- /dev/null +++ b/sound/soc/tegra/tegra210_peq.c @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// tegra210_peq.c - Tegra210 PEQ driver +// +// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tegra210_ope.h" +#include "tegra210_peq.h" + +static const struct reg_default tegra210_peq_reg_defaults[] = { + { TEGRA210_PEQ_CFG, 0x00000013}, + { TEGRA210_PEQ_CFG_RAM_CTRL, 0x00004000}, + { TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 0x00004000}, +}; + +static const u32 biquad_init_gains[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH] = { + 1495012349, /* Pre-gain */ + + /* Gains : b0, b1, a0, a1, a2 */ + 536870912, -1073741824, 536870912, 2143508246, -1069773768, /* Band-0 */ + 134217728, -265414508, 131766272, 2140402222, -1071252997, /* Band-1 */ + 268435456, -233515765, -33935948, 1839817267, -773826124, /* Band-2 */ + 536870912, -672537913, 139851540, 1886437554, -824433167, /* Band-3 */ + 268435456, -114439279, 173723964, 205743566, 278809729, /* Band-4 */ + 1, 0, 0, 0, 0, /* Band-5 */ + 1, 0, 0, 0, 0, /* Band-6 */ + 1, 0, 0, 0, 0, /* Band-7 */ + 1, 0, 0, 0, 0, /* Band-8 */ + 1, 0, 0, 0, 0, /* Band-9 */ + 1, 0, 0, 0, 0, /* Band-10 */ + 1, 0, 0, 0, 0, /* Band-11 */ + + 963423114, /* Post-gain */ +}; + +static const u32 biquad_init_shifts[TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH] = { + 23, /* Pre-shift */ + 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, /* Shift for bands */ + 28, /* Post-shift */ +}; + +static s32 biquad_coeff_buffer[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH]; + +static void tegra210_peq_read_ram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size) +{ + unsigned int val; + unsigned int i; + + val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK; + val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN; + val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN; + val |= TEGRA210_PEQ_RAM_CTRL_RW_READ; + + regmap_write(regmap, reg_ctrl, val); + + /* + * Since all ahub non-io modules work under same ahub clock it is not + * necessary to check ahub read busy bit after every read. + */ + for (i = 0; i < size; i++) + regmap_read(regmap, reg_data, &data[i]); +} + +static void tegra210_peq_write_ram(struct regmap *regmap, unsigned int reg_ctrl, + unsigned int reg_data, unsigned int ram_offset, + unsigned int *data, size_t size) +{ + unsigned int val; + unsigned int i; + + val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK; + val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN; + val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN; + val |= TEGRA210_PEQ_RAM_CTRL_RW_WRITE; + + regmap_write(regmap, reg_ctrl, val); + + for (i = 0; i < size; i++) + regmap_write(regmap, reg_data, data[i]); +} + +static int tegra210_peq_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int mask = (1 << fls(mc->max)) - 1; + unsigned int val; + + regmap_read(ope->peq_regmap, mc->reg, &val); + + ucontrol->value.integer.value[0] = (val >> mc->shift) & mask; + + if (!mc->invert) + return 0; + + ucontrol->value.integer.value[0] = + mc->max - ucontrol->value.integer.value[0]; + + return 0; +} + +static int tegra210_peq_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int mask = (1 << fls(mc->max)) - 1; + bool change = false; + unsigned int val; + + val = (ucontrol->value.integer.value[0] & mask); + + if (mc->invert) + val = mc->max - val; + + val = val << mc->shift; + + regmap_update_bits_check(ope->peq_regmap, mc->reg, (mask << mc->shift), + val, &change); + + return change ? 1 : 0; +} + +static int tegra210_peq_ram_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 i, reg_ctrl = params->soc.base; + u32 reg_data = reg_ctrl + cmpnt->val_bytes; + s32 *data = (s32 *)biquad_coeff_buffer; + + pm_runtime_get_sync(cmpnt->dev); + + tegra210_peq_read_ram(ope->peq_regmap, reg_ctrl, reg_data, + params->shift, data, params->soc.num_regs); + + pm_runtime_put_sync(cmpnt->dev); + + for (i = 0; i < params->soc.num_regs; i++) + ucontrol->value.integer.value[i] = (long)data[i]; + + return 0; +} + +static int tegra210_peq_ram_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct tegra_soc_bytes *params = (void *)kcontrol->private_value; + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + u32 i, reg_ctrl = params->soc.base; + u32 reg_data = reg_ctrl + cmpnt->val_bytes; + s32 *data = (s32 *)biquad_coeff_buffer; + + for (i = 0; i < params->soc.num_regs; i++) + data[i] = (s32)ucontrol->value.integer.value[i]; + + pm_runtime_get_sync(cmpnt->dev); + + tegra210_peq_write_ram(ope->peq_regmap, reg_ctrl, reg_data, + params->shift, data, params->soc.num_regs); + + pm_runtime_put_sync(cmpnt->dev); + + return 1; +} + +static int tegra210_peq_param_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct soc_bytes *params = (void *)kcontrol->private_value; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = INT_MIN; + uinfo->value.integer.max = INT_MAX; + uinfo->count = params->num_regs; + + return 0; +} + +#define TEGRA210_PEQ_GAIN_PARAMS_CTRL(chan) \ + TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Gain Params", \ + TEGRA210_PEQ_CFG_RAM_CTRL, \ + TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH, \ + (TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH * chan), 0xffffffff, \ + tegra210_peq_ram_get, tegra210_peq_ram_put, \ + tegra210_peq_param_info) + +#define TEGRA210_PEQ_SHIFT_PARAMS_CTRL(chan) \ + TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Shift Params", \ + TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, \ + TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH, \ + (TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH * chan), 0x1f, \ + tegra210_peq_ram_get, tegra210_peq_ram_put, \ + tegra210_peq_param_info) + +static const struct snd_kcontrol_new tegra210_peq_controls[] = { + SOC_SINGLE_EXT("PEQ Active", TEGRA210_PEQ_CFG, + TEGRA210_PEQ_CFG_MODE_SHIFT, 1, 0, + tegra210_peq_get, tegra210_peq_put), + + SOC_SINGLE_EXT("PEQ Biquad Stages", TEGRA210_PEQ_CFG, + TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT, + TEGRA210_PEQ_MAX_BIQUAD_STAGES - 1, 0, + tegra210_peq_get, tegra210_peq_put), + + TEGRA210_PEQ_GAIN_PARAMS_CTRL(0), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(1), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(2), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(3), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(4), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(5), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(6), + TEGRA210_PEQ_GAIN_PARAMS_CTRL(7), + + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(0), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(1), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(2), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(3), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(4), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(5), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(6), + TEGRA210_PEQ_SHIFT_PARAMS_CTRL(7), +}; + +static bool tegra210_peq_wr_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_PEQ_SOFT_RESET: + case TEGRA210_PEQ_CG: + case TEGRA210_PEQ_CFG ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: + return true; + default: + return false; + } +} + +static bool tegra210_peq_rd_reg(struct device *dev, unsigned int reg) +{ + if (tegra210_peq_wr_reg(dev, reg)) + return true; + + switch (reg) { + case TEGRA210_PEQ_STATUS: + return true; + default: + return false; + } +} + +static bool tegra210_peq_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_PEQ_SOFT_RESET: + case TEGRA210_PEQ_STATUS: + case TEGRA210_PEQ_CFG_RAM_CTRL ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: + return true; + default: + return false; + } +} + +static bool tegra210_peq_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_PEQ_CFG_RAM_DATA: + case TEGRA210_PEQ_CFG_RAM_SHIFT_DATA: + return true; + default: + return false; + } +} + +static const struct regmap_config tegra210_peq_regmap_config = { + .name = "peq", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, + .writeable_reg = tegra210_peq_wr_reg, + .readable_reg = tegra210_peq_rd_reg, + .volatile_reg = tegra210_peq_volatile_reg, + .precious_reg = tegra210_peq_precious_reg, + .reg_defaults = tegra210_peq_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tegra210_peq_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + +void tegra210_peq_restore(struct regmap *regmap, u32 *biquad_gains, + u32 *biquad_shifts) +{ + unsigned int i; + + for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { + tegra210_peq_write_ram(regmap, TEGRA210_PEQ_CFG_RAM_CTRL, + TEGRA210_PEQ_CFG_RAM_DATA, + (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), + biquad_gains, + TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); + + tegra210_peq_write_ram(regmap, + TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, + TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, + (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), + biquad_shifts, + TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); + + } +} + +void tegra210_peq_save(struct regmap *regmap, u32 *biquad_gains, + u32 *biquad_shifts) +{ + unsigned int i; + + for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { + tegra210_peq_read_ram(regmap, + TEGRA210_PEQ_CFG_RAM_CTRL, + TEGRA210_PEQ_CFG_RAM_DATA, + (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), + biquad_gains, + TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); + + tegra210_peq_read_ram(regmap, + TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, + TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, + (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), + biquad_shifts, + TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); + } +} + +int tegra210_peq_component_init(struct snd_soc_component *cmpnt) +{ + struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt); + unsigned int i; + + pm_runtime_get_sync(cmpnt->dev); + regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG, + TEGRA210_PEQ_CFG_MODE_MASK, + 0 << TEGRA210_PEQ_CFG_MODE_SHIFT); + regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG, + TEGRA210_PEQ_CFG_BIQUAD_STAGES_MASK, + (TEGRA210_PEQ_BIQUAD_INIT_STAGE - 1) << + TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT); + + /* Initialize PEQ AHUB RAM with default params */ + for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) { + + /* Set default gain params */ + tegra210_peq_write_ram(ope->peq_regmap, + TEGRA210_PEQ_CFG_RAM_CTRL, + TEGRA210_PEQ_CFG_RAM_DATA, + (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH), + (u32 *)&biquad_init_gains, + TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH); + + /* Set default shift params */ + tegra210_peq_write_ram(ope->peq_regmap, + TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, + TEGRA210_PEQ_CFG_RAM_SHIFT_DATA, + (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH), + (u32 *)&biquad_init_shifts, + TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH); + + } + + pm_runtime_put_sync(cmpnt->dev); + + snd_soc_add_component_controls(cmpnt, tegra210_peq_controls, + ARRAY_SIZE(tegra210_peq_controls)); + + return 0; +} + +int tegra210_peq_regmap_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra210_ope *ope = dev_get_drvdata(dev); + struct device_node *child; + struct resource mem; + void __iomem *regs; + int err; + + child = of_get_child_by_name(dev->of_node, "equalizer"); + if (!child) + return -ENODEV; + + err = of_address_to_resource(child, 0, &mem); + of_node_put(child); + if (err < 0) { + dev_err(dev, "fail to get PEQ resource\n"); + return err; + } + + mem.flags = IORESOURCE_MEM; + regs = devm_ioremap_resource(dev, &mem); + if (IS_ERR(regs)) + return PTR_ERR(regs); + ope->peq_regmap = devm_regmap_init_mmio(dev, regs, + &tegra210_peq_regmap_config); + if (IS_ERR(ope->peq_regmap)) { + dev_err(dev, "regmap init failed\n"); + return PTR_ERR(ope->peq_regmap); + } + + regcache_cache_only(ope->peq_regmap, true); + + return 0; +} diff --git a/sound/soc/tegra/tegra210_peq.h b/sound/soc/tegra/tegra210_peq.h new file mode 100644 index 0000000000000..6d3de4ff05cc0 --- /dev/null +++ b/sound/soc/tegra/tegra210_peq.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * tegra210_peq.h - Definitions for Tegra210 PEQ driver + * + * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + */ + +#ifndef __TEGRA210_PEQ_H__ +#define __TEGRA210_PEQ_H__ + +#include +#include +#include + +/* Register offsets from PEQ base */ +#define TEGRA210_PEQ_SOFT_RESET 0x0 +#define TEGRA210_PEQ_CG 0x4 +#define TEGRA210_PEQ_STATUS 0x8 +#define TEGRA210_PEQ_CFG 0xc +#define TEGRA210_PEQ_CFG_RAM_CTRL 0x10 +#define TEGRA210_PEQ_CFG_RAM_DATA 0x14 +#define TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL 0x18 +#define TEGRA210_PEQ_CFG_RAM_SHIFT_DATA 0x1c + +/* Fields in TEGRA210_PEQ_CFG */ +#define TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT 2 +#define TEGRA210_PEQ_CFG_BIQUAD_STAGES_MASK (0xf << TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT) + +#define TEGRA210_PEQ_CFG_MODE_SHIFT 0 +#define TEGRA210_PEQ_CFG_MODE_MASK (0x1 << TEGRA210_PEQ_CFG_MODE_SHIFT) + +#define TEGRA210_PEQ_RAM_CTRL_RW_READ 0 +#define TEGRA210_PEQ_RAM_CTRL_RW_WRITE (1 << 14) +#define TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN (1 << 13) +#define TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN (1 << 12) +#define TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK 0x1ff + +/* PEQ register definition ends here */ +#define TEGRA210_PEQ_MAX_BIQUAD_STAGES 12 + +#define TEGRA210_PEQ_MAX_CHANNELS 8 + +#define TEGRA210_PEQ_BIQUAD_INIT_STAGE 5 + +#define TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH (2 + TEGRA210_PEQ_MAX_BIQUAD_STAGES * 5) +#define TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH (2 + TEGRA210_PEQ_MAX_BIQUAD_STAGES) + +int tegra210_peq_regmap_init(struct platform_device *pdev); +int tegra210_peq_component_init(struct snd_soc_component *cmpnt); +void tegra210_peq_restore(struct regmap *regmap, u32 *biquad_gains, + u32 *biquad_shifts); +void tegra210_peq_save(struct regmap *regmap, u32 *biquad_gains, + u32 *biquad_shifts); + +#endif -- GitLab From 7ee0910d03168535ffeea2f4ce924eebb3b24863 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Fri, 3 Jun 2022 12:06:09 +0530 Subject: [PATCH 069/942] ASoC: tegra: AHUB routes for OPE module Add AHUB routes for OPE module. The OPE module can be plugged into audio path as per the need. The routing controls can be used to setup the audio path with OPE similar to the already existing routes. The support is added on Tegra210 and later Tegra SoCs where OPE module is present. Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1654238172-16293-4-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_ahub.c | 39 +++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index e1f90daea7a1d..b38d205b69cc2 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -170,6 +170,11 @@ static struct snd_soc_dai_driver tegra210_ahub_dais[] = { DAI(MIXER1 TX3), DAI(MIXER1 TX4), DAI(MIXER1 TX5), + /* XBAR -> OPE -> XBAR */ + DAI(OPE1 RX), + DAI(OPE1 TX), + DAI(OPE2 RX), + DAI(OPE2 TX), }; static struct snd_soc_dai_driver tegra186_ahub_dais[] = { @@ -294,6 +299,9 @@ static struct snd_soc_dai_driver tegra186_ahub_dais[] = { DAI(ASRC1 RX6), DAI(ASRC1 TX6), DAI(ASRC1 RX7), + /* XBAR -> OPE -> XBAR */ + DAI(OPE1 RX), + DAI(OPE1 TX), }; static const char * const tegra210_ahub_mux_texts[] = { @@ -337,6 +345,8 @@ static const char * const tegra210_ahub_mux_texts[] = { "MIXER1 TX3", "MIXER1 TX4", "MIXER1 TX5", + "OPE1", + "OPE2", }; static const char * const tegra186_ahub_mux_texts[] = { @@ -408,6 +418,7 @@ static const char * const tegra186_ahub_mux_texts[] = { "ASRC1 TX4", "ASRC1 TX5", "ASRC1 TX6", + "OPE1", }; static const unsigned int tegra210_ahub_mux_values[] = { @@ -459,6 +470,9 @@ static const unsigned int tegra210_ahub_mux_values[] = { MUX_VALUE(1, 2), MUX_VALUE(1, 3), MUX_VALUE(1, 4), + /* OPE */ + MUX_VALUE(2, 0), + MUX_VALUE(2, 1), }; static const unsigned int tegra186_ahub_mux_values[] = { @@ -540,6 +554,8 @@ static const unsigned int tegra186_ahub_mux_values[] = { MUX_VALUE(3, 27), MUX_VALUE(3, 28), MUX_VALUE(3, 29), + /* OPE */ + MUX_VALUE(2, 0), }; /* Controls for t210 */ @@ -584,6 +600,8 @@ MUX_ENUM_CTRL_DECL(t210_mixer17_tx, 0x26); MUX_ENUM_CTRL_DECL(t210_mixer18_tx, 0x27); MUX_ENUM_CTRL_DECL(t210_mixer19_tx, 0x28); MUX_ENUM_CTRL_DECL(t210_mixer110_tx, 0x29); +MUX_ENUM_CTRL_DECL(t210_ope1_tx, 0x40); +MUX_ENUM_CTRL_DECL(t210_ope2_tx, 0x41); /* Controls for t186 */ MUX_ENUM_CTRL_DECL_186(t186_admaif1_tx, 0x00); @@ -657,6 +675,7 @@ MUX_ENUM_CTRL_DECL_186(t186_asrc14_tx, 0x6f); MUX_ENUM_CTRL_DECL_186(t186_asrc15_tx, 0x70); MUX_ENUM_CTRL_DECL_186(t186_asrc16_tx, 0x71); MUX_ENUM_CTRL_DECL_186(t186_asrc17_tx, 0x72); +MUX_ENUM_CTRL_DECL_186(t186_ope1_tx, 0x40); /* Controls for t234 */ MUX_ENUM_CTRL_DECL_234(t234_mvc1_tx, 0x44); @@ -758,6 +777,8 @@ static const struct snd_soc_dapm_widget tegra210_ahub_widgets[] = { TX_WIDGETS("MIXER1 TX3"), TX_WIDGETS("MIXER1 TX4"), TX_WIDGETS("MIXER1 TX5"), + WIDGETS("OPE1", t210_ope1_tx), + WIDGETS("OPE2", t210_ope2_tx), }; static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = { @@ -867,6 +888,7 @@ static const struct snd_soc_dapm_widget tegra186_ahub_widgets[] = { TX_WIDGETS("ASRC1 TX4"), TX_WIDGETS("ASRC1 TX5"), TX_WIDGETS("ASRC1 TX6"), + WIDGETS("OPE1", t186_ope1_tx), }; static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { @@ -976,6 +998,7 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { TX_WIDGETS("ASRC1 TX4"), TX_WIDGETS("ASRC1 TX5"), TX_WIDGETS("ASRC1 TX6"), + WIDGETS("OPE1", t186_ope1_tx), }; #define TEGRA_COMMON_MUX_ROUTES(name) \ @@ -1018,7 +1041,11 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "MIXER1 TX2", "MIXER1 TX2 XBAR-RX" }, \ { name " Mux", "MIXER1 TX3", "MIXER1 TX3 XBAR-RX" }, \ { name " Mux", "MIXER1 TX4", "MIXER1 TX4 XBAR-RX" }, \ - { name " Mux", "MIXER1 TX5", "MIXER1 TX5 XBAR-RX" }, + { name " Mux", "MIXER1 TX5", "MIXER1 TX5 XBAR-RX" }, \ + { name " Mux", "OPE1", "OPE1 XBAR-RX" }, + +#define TEGRA210_ONLY_MUX_ROUTES(name) \ + { name " Mux", "OPE2", "OPE2 XBAR-RX" }, #define TEGRA186_ONLY_MUX_ROUTES(name) \ { name " Mux", "ADMAIF11", "ADMAIF11 XBAR-RX" }, \ @@ -1050,10 +1077,11 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "ASRC1 TX5", "ASRC1 TX5 XBAR-RX" }, \ { name " Mux", "ASRC1 TX6", "ASRC1 TX6 XBAR-RX" }, -#define TEGRA210_MUX_ROUTES(name) \ - TEGRA_COMMON_MUX_ROUTES(name) +#define TEGRA210_MUX_ROUTES(name) \ + TEGRA_COMMON_MUX_ROUTES(name) \ + TEGRA210_ONLY_MUX_ROUTES(name) -#define TEGRA186_MUX_ROUTES(name) \ +#define TEGRA186_MUX_ROUTES(name) \ TEGRA_COMMON_MUX_ROUTES(name) \ TEGRA186_ONLY_MUX_ROUTES(name) @@ -1121,6 +1149,8 @@ static const struct snd_soc_dapm_route tegra210_ahub_routes[] = { TEGRA210_MUX_ROUTES("MIXER1 RX8") TEGRA210_MUX_ROUTES("MIXER1 RX9") TEGRA210_MUX_ROUTES("MIXER1 RX10") + TEGRA210_MUX_ROUTES("OPE1") + TEGRA210_MUX_ROUTES("OPE2") }; static const struct snd_soc_dapm_route tegra186_ahub_routes[] = { @@ -1215,6 +1245,7 @@ static const struct snd_soc_dapm_route tegra186_ahub_routes[] = { TEGRA186_MUX_ROUTES("ASRC1 RX5") TEGRA186_MUX_ROUTES("ASRC1 RX6") TEGRA186_MUX_ROUTES("ASRC1 RX7") + TEGRA186_MUX_ROUTES("OPE1") }; static const struct snd_soc_component_driver tegra210_ahub_component = { -- GitLab From 90b12a88b710cdc80c00552dfbd589228978bffe Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:50 +0200 Subject: [PATCH 070/942] ALSA: Add snd_pcm_direction_name() helper Allow for retrieving string naming a direction of a stream without the need of substream pointer. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/sound/pcm.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 6b99310b5b889..26523cfe428d3 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1392,6 +1392,20 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) const char *snd_pcm_format_name(snd_pcm_format_t format); +/** + * snd_pcm_direction_name - Get a string naming the direction of a stream + * @direction: Stream's direction, one of SNDRV_PCM_STREAM_XXX + * + * Returns a string naming the direction of the stream. + */ +static inline const char *snd_pcm_direction_name(int direction) +{ + if (direction == SNDRV_PCM_STREAM_PLAYBACK) + return "Playback"; + else + return "Capture"; +} + /** * snd_pcm_stream_str - Get a string naming the direction of a stream * @substream: the pcm substream instance @@ -1400,10 +1414,7 @@ const char *snd_pcm_format_name(snd_pcm_format_t format); */ static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) { - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return "Playback"; - else - return "Capture"; + return snd_pcm_direction_name(substream->stream); } /* -- GitLab From b5df2a7dca1cc6c66eee0005c92094855dc2028c Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:51 +0200 Subject: [PATCH 071/942] ASoC: codecs: Add HD-Audio codec driver Add generic ASoC equivalent of ALSA HD-Audio codec. This codec is designed to follow HDA_DEV_LEGACY convention. Driver wrapps existing hda_codec.c handlers to prevent code duplication within the newly added code. Number of DAIs created is dependent on capabilities exposed by the codec itself. Because of this, single solution can be applied to support every single HD-Audio codec type. At the same time, through the ASoC topology, platform drivers may limit the number of endpoints available to the userspace as codec driver exposes BE DAIs only. Both hda_codec_probe() and hda_codec_remove() declare their expectations on device's usage_count and suspended-status. This is to catch any unexpected behavior as PM-related code for HD-Audio has been changing quite a bit throughout the years. In order for codec DAI list to reflect its actual PCM capabilities, PCMs need to be built and that can only happen once codec device is constructed. To do that, a valid component->card->snd_card pointer is needed. Said pointer will be provided by the framework once all card components are accounted for and their probing can begin. Usage of "binder" BE DAI solves the problem - codec can be listed as one of HD-Audio card components without declaring any actual BE DAIs statically. Relation with hdac_hda: Addition of parallel solution is motivated by behavioral differences between hdac_hda.c and its legacy equivalent found in sound/pci/hda e.g.: lack of dynamic, based on codec capabilities, resource allocation and high cost of removing such differences on actively used targets. Major goal of codec driver presented here is to follow HD-Audio legacy behavior in 1:1 fashion by becoming a wrapper. Doing so increases code coverage of the legacy code and reduces the maintenance cost for both solutions. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/hda-dai.c | 102 ++++++++++ sound/soc/codecs/hda.c | 395 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/hda.h | 19 ++ 5 files changed, 528 insertions(+) create mode 100644 sound/soc/codecs/hda-dai.c create mode 100644 sound/soc/codecs/hda.c create mode 100644 sound/soc/codecs/hda.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6165db92a6297..5a60633a196c1 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -937,6 +937,16 @@ config SND_SOC_HDAC_HDA tristate select SND_HDA +config SND_SOC_HDA + tristate "HD-Audio codec driver" + select SND_HDA_EXT_CORE + select SND_HDA + help + This enables HD-Audio codec support in ASoC subsystem. Compared + to SND_SOC_HDAC_HDA, driver's behavior is identical to HD-Audio + legacy solution - including the dynamic resource allocation + based on actual codec capabilities. + config SND_SOC_ICS43432 tristate "ICS43423 and compatible i2s microphones" diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 28dc4edfd01fd..d32026ae326f8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -106,6 +106,7 @@ snd-soc-es8328-spi-objs := es8328-spi.o snd-soc-gtm601-objs := gtm601.o snd-soc-hdac-hdmi-objs := hdac_hdmi.o snd-soc-hdac-hda-objs := hdac_hda.o +snd-soc-hda-codec-objs := hda.o hda-dai.o snd-soc-ics43432-objs := ics43432.o snd-soc-inno-rk3036-objs := inno_rk3036.o snd-soc-isabelle-objs := isabelle.o @@ -458,6 +459,7 @@ obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o +obj-$(CONFIG_SND_SOC_HDA) += snd-soc-hda-codec.o obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o diff --git a/sound/soc/codecs/hda-dai.c b/sound/soc/codecs/hda-dai.c new file mode 100644 index 0000000000000..5371ff0862618 --- /dev/null +++ b/sound/soc/codecs/hda-dai.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include "hda.h" + +static int hda_codec_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + struct hda_pcm *pcm; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + pcm = container_of(stream_info, struct hda_pcm, stream[substream->stream]); + + dev_dbg(dai->dev, "open stream codec: %08x, info: %p, pcm: %p %s substream: %p\n", + codec->core.vendor_id, stream_info, pcm, pcm->name, substream); + + snd_hda_codec_pcm_get(pcm); + + ret = stream_info->ops.open(stream_info, codec, substream); + if (ret < 0) { + dev_err(dai->dev, "codec open failed: %d\n", ret); + snd_hda_codec_pcm_put(pcm); + return ret; + } + + return 0; +} + +static void hda_codec_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + struct hda_pcm *pcm; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + pcm = container_of(stream_info, struct hda_pcm, stream[substream->stream]); + + dev_dbg(dai->dev, "close stream codec: %08x, info: %p, pcm: %p %s substream: %p\n", + codec->core.vendor_id, stream_info, pcm, pcm->name, substream); + + ret = stream_info->ops.close(stream_info, codec, substream); + if (ret < 0) + dev_err(dai->dev, "codec close failed: %d\n", ret); + + snd_hda_codec_pcm_put(pcm); +} + +static int hda_codec_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct hda_pcm_stream *stream_info; + struct hda_codec *codec; + + codec = dev_to_hda_codec(dai->dev); + stream_info = snd_soc_dai_get_dma_data(dai, substream); + + snd_hda_codec_cleanup(codec, stream_info, substream); + + return 0; +} + +static int hda_codec_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct hda_pcm_stream *stream_info; + struct hdac_stream *stream; + struct hda_codec *codec; + unsigned int format; + int ret; + + codec = dev_to_hda_codec(dai->dev); + stream = substream->runtime->private_data; + stream_info = snd_soc_dai_get_dma_data(dai, substream); + format = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format, + runtime->sample_bits, 0); + + ret = snd_hda_codec_prepare(codec, stream_info, stream->stream_tag, format, substream); + if (ret < 0) { + dev_err(dai->dev, "codec prepare failed: %d\n", ret); + return ret; + } + + return 0; +} + +const struct snd_soc_dai_ops snd_soc_hda_codec_dai_ops = { + .startup = hda_codec_dai_startup, + .shutdown = hda_codec_dai_shutdown, + .hw_free = hda_codec_dai_hw_free, + .prepare = hda_codec_dai_prepare, +}; +EXPORT_SYMBOL_GPL(snd_soc_hda_codec_dai_ops); diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c new file mode 100644 index 0000000000000..edcb8bc6806bd --- /dev/null +++ b/sound/soc/codecs/hda.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include +#include +#include +#include +#include "hda.h" + +static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count, + struct snd_soc_dai_driver **drivers) +{ + struct device *dev = &codec->core.dev; + struct snd_soc_dai_driver *drvs; + struct hda_pcm *pcm; + int i; + + drvs = devm_kcalloc(dev, pcm_count, sizeof(*drvs), GFP_KERNEL); + if (!drvs) + return -ENOMEM; + + pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); + + for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { + struct snd_soc_pcm_stream *stream; + int dir; + + dev_info(dev, "creating for %s %d\n", pcm->name, i); + drvs[i].id = i; + drvs[i].name = pcm->name; + drvs[i].ops = &snd_soc_hda_codec_dai_ops; + + dir = SNDRV_PCM_STREAM_PLAYBACK; + stream = &drvs[i].playback; + if (!pcm->stream[dir].substreams) { + dev_info(dev, "skipping playback dai for %s\n", pcm->name); + goto capture_dais; + } + + stream->stream_name = + devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + if (!stream->stream_name) + return -ENOMEM; + stream->channels_min = pcm->stream[dir].channels_min; + stream->channels_max = pcm->stream[dir].channels_max; + stream->rates = pcm->stream[dir].rates; + stream->formats = pcm->stream[dir].formats; + stream->sig_bits = pcm->stream[dir].maxbps; + +capture_dais: + dir = SNDRV_PCM_STREAM_CAPTURE; + stream = &drvs[i].capture; + if (!pcm->stream[dir].substreams) { + dev_info(dev, "skipping capture dai for %s\n", pcm->name); + continue; + } + + stream->stream_name = + devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + if (!stream->stream_name) + return -ENOMEM; + stream->channels_min = pcm->stream[dir].channels_min; + stream->channels_max = pcm->stream[dir].channels_max; + stream->rates = pcm->stream[dir].rates; + stream->formats = pcm->stream[dir].formats; + stream->sig_bits = pcm->stream[dir].maxbps; + } + + *drivers = drvs; + return 0; +} + +static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_component *component) +{ + struct snd_soc_dai_driver *drvs = NULL; + struct snd_soc_dapm_context *dapm; + struct hda_pcm *pcm; + int ret, pcm_count = 0; + + if (list_empty(&codec->pcm_list_head)) + return -EINVAL; + list_for_each_entry(pcm, &codec->pcm_list_head, list) + pcm_count++; + + ret = hda_codec_create_dais(codec, pcm_count, &drvs); + if (ret < 0) + return ret; + + dapm = snd_soc_component_get_dapm(component); + + list_for_each_entry(pcm, &codec->pcm_list_head, list) { + struct snd_soc_dai *dai; + + dai = snd_soc_register_dai(component, drvs, false); + if (!dai) { + dev_err(component->dev, "register dai for %s failed\n", pcm->name); + return -EINVAL; + } + + ret = snd_soc_dapm_new_dai_widgets(dapm, dai); + if (ret < 0) { + dev_err(component->dev, "create widgets failed: %d\n", ret); + snd_soc_unregister_dai(dai); + return ret; + } + + snd_soc_dai_init_dma_data(dai, &pcm->stream[0], &pcm->stream[1]); + drvs++; + } + + return 0; +} + +static void hda_codec_unregister_dais(struct hda_codec *codec, + struct snd_soc_component *component) +{ + struct snd_soc_dai *dai, *save; + struct hda_pcm *pcm; + + for_each_component_dais_safe(component, dai, save) { + list_for_each_entry(pcm, &codec->pcm_list_head, list) { + if (strcmp(dai->driver->name, pcm->name)) + continue; + + if (dai->playback_widget) + snd_soc_dapm_free_widget(dai->playback_widget); + if (dai->capture_widget) + snd_soc_dapm_free_widget(dai->capture_widget); + snd_soc_unregister_dai(dai); + break; + } + } +} + +int hda_codec_probe_complete(struct hda_codec *codec) +{ + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + int ret; + + ret = snd_hda_codec_build_controls(codec); + if (ret < 0) { + dev_err(&hdev->dev, "unable to create controls %d\n", ret); + goto out; + } + + /* Bus suspended codecs as it does not manage their pm */ + pm_runtime_set_active(&hdev->dev); + /* rpm was forbidden in snd_hda_codec_device_new() */ + snd_hda_codec_set_power_save(codec, 2000); + snd_hda_codec_register(codec); +out: + /* Complement pm_runtime_get_sync(bus) in probe */ + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + + return ret; +} +EXPORT_SYMBOL_GPL(hda_codec_probe_complete); + +/* Expects codec with usage_count=1 and status=suspended */ +static int hda_codec_probe(struct snd_soc_component *component) +{ + struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + struct hdac_ext_link *hlink; + hda_codec_patch_t patch; + int ret; + +#ifdef CONFIG_PM + WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || + !pm_runtime_status_suspended(&hdev->dev)); +#endif + + hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + if (!hlink) { + dev_err(&hdev->dev, "hdac link not found\n"); + return -EIO; + } + + pm_runtime_get_sync(bus->dev); + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, true); + snd_hdac_ext_bus_link_get(bus, hlink); + + ret = snd_hda_codec_device_new(codec->bus, component->card->snd_card, hdev->addr, codec, + false); + if (ret < 0) { + dev_err(&hdev->dev, "create hda codec failed: %d\n", ret); + goto device_new_err; + } + + ret = snd_hda_codec_set_name(codec, codec->preset->name); + if (ret < 0) { + dev_err(&hdev->dev, "name failed %s\n", codec->preset->name); + goto err; + } + + ret = snd_hdac_regmap_init(&codec->core); + if (ret < 0) { + dev_err(&hdev->dev, "regmap init failed\n"); + goto err; + } + + patch = (hda_codec_patch_t)codec->preset->driver_data; + if (!patch) { + dev_err(&hdev->dev, "no patch specified?\n"); + ret = -EINVAL; + goto err; + } + + ret = patch(codec); + if (ret < 0) { + dev_err(&hdev->dev, "patch failed %d\n", ret); + goto err; + } + + /* configure codec for 1:1 PCM:DAI mapping */ + codec->mst_no_extra_pcms = 1; + + ret = snd_hda_codec_parse_pcms(codec); + if (ret < 0) { + dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret); + goto parse_pcms_err; + } + + ret = hda_codec_register_dais(codec, component); + if (ret < 0) { + dev_err(&hdev->dev, "update dais failed: %d\n", ret); + goto parse_pcms_err; + } + + if (!hda_codec_is_display(codec)) { + ret = hda_codec_probe_complete(codec); + if (ret < 0) + goto complete_err; + } + + codec->core.lazy_cache = true; + + return 0; + +complete_err: + hda_codec_unregister_dais(codec, component); +parse_pcms_err: + if (codec->patch_ops.free) + codec->patch_ops.free(codec); +err: + snd_hda_codec_cleanup_for_unbind(codec); +device_new_err: + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, false); + + snd_hdac_ext_bus_link_put(bus, hlink); + + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + return ret; +} + +/* Leaves codec with usage_count=1 and status=suspended */ +static void hda_codec_remove(struct snd_soc_component *component) +{ + struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hdac_device *hdev = &codec->core; + struct hdac_bus *bus = hdev->bus; + struct hdac_ext_link *hlink; + bool was_registered = codec->registered; + + /* Don't allow any more runtime suspends */ + pm_runtime_forbid(&hdev->dev); + + hda_codec_unregister_dais(codec, component); + + if (codec->patch_ops.free) + codec->patch_ops.free(codec); + + snd_hda_codec_cleanup_for_unbind(codec); + pm_runtime_put_noidle(&hdev->dev); + /* snd_hdac_device_exit() is only called on bus remove */ + pm_runtime_set_suspended(&hdev->dev); + + if (hda_codec_is_display(codec)) + snd_hdac_display_power(bus, hdev->addr, false); + + hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + if (hlink) + snd_hdac_ext_bus_link_put(bus, hlink); + /* + * HDMI card's hda_codec_probe_complete() (see late_probe()) may + * not be called due to early error, leaving bus uc unbalanced + */ + if (!was_registered) { + pm_runtime_mark_last_busy(bus->dev); + pm_runtime_put_autosuspend(bus->dev); + } + +#ifdef CONFIG_PM + WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || + !pm_runtime_status_suspended(&hdev->dev)); +#endif +} + +static const struct snd_soc_dapm_route hda_dapm_routes[] = { + {"AIF1TX", NULL, "Codec Input Pin1"}, + {"AIF2TX", NULL, "Codec Input Pin2"}, + {"AIF3TX", NULL, "Codec Input Pin3"}, + + {"Codec Output Pin1", NULL, "AIF1RX"}, + {"Codec Output Pin2", NULL, "AIF2RX"}, + {"Codec Output Pin3", NULL, "AIF3RX"}, +}; + +static const struct snd_soc_dapm_widget hda_dapm_widgets[] = { + /* Audio Interface */ + SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0), + + /* Input Pins */ + SND_SOC_DAPM_INPUT("Codec Input Pin1"), + SND_SOC_DAPM_INPUT("Codec Input Pin2"), + SND_SOC_DAPM_INPUT("Codec Input Pin3"), + + /* Output Pins */ + SND_SOC_DAPM_OUTPUT("Codec Output Pin1"), + SND_SOC_DAPM_OUTPUT("Codec Output Pin2"), + SND_SOC_DAPM_OUTPUT("Codec Output Pin3"), +}; + +static struct snd_soc_dai_driver card_binder_dai = { + .id = -1, + .name = "codec-probing-DAI", +}; + +static int hda_hdev_attach(struct hdac_device *hdev) +{ + struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); + struct snd_soc_component_driver *comp_drv; + + comp_drv = devm_kzalloc(&hdev->dev, sizeof(*comp_drv), GFP_KERNEL); + if (!comp_drv) + return -ENOMEM; + + /* + * It's save to rely on dev_name() rather than a copy as component + * driver's lifetime is directly tied to hda codec one + */ + comp_drv->name = dev_name(&hdev->dev); + comp_drv->probe = hda_codec_probe; + comp_drv->remove = hda_codec_remove; + comp_drv->idle_bias_on = false; + if (!hda_codec_is_display(codec)) { + comp_drv->dapm_widgets = hda_dapm_widgets; + comp_drv->num_dapm_widgets = ARRAY_SIZE(hda_dapm_widgets); + comp_drv->dapm_routes = hda_dapm_routes; + comp_drv->num_dapm_routes = ARRAY_SIZE(hda_dapm_routes); + } + + return snd_soc_register_component(&hdev->dev, comp_drv, &card_binder_dai, 1); +} + +static int hda_hdev_detach(struct hdac_device *hdev) +{ + struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); + + if (codec->registered) + cancel_delayed_work_sync(&codec->jackpoll_work); + + snd_soc_unregister_component(&hdev->dev); + + return 0; +} + +const struct hdac_ext_bus_ops soc_hda_ext_bus_ops = { + .hdev_attach = hda_hdev_attach, + .hdev_detach = hda_hdev_detach, +}; +EXPORT_SYMBOL_GPL(soc_hda_ext_bus_ops); + +MODULE_DESCRIPTION("HD-Audio codec driver"); +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/hda.h b/sound/soc/codecs/hda.h new file mode 100644 index 0000000000000..78a2be4945b13 --- /dev/null +++ b/sound/soc/codecs/hda.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright(c) 2021-2022 Intel Corporation. All rights reserved. + * + * Author: Cezary Rojewski + */ + +#ifndef SND_SOC_CODECS_HDA_H +#define SND_SOC_CODECS_HDA_H + +#define hda_codec_is_display(codec) \ + ((((codec)->core.vendor_id >> 16) & 0xFFFF) == 0x8086) + +extern const struct snd_soc_dai_ops snd_soc_hda_codec_dai_ops; + +extern const struct hdac_ext_bus_ops soc_hda_ext_bus_ops; +int hda_codec_probe_complete(struct hda_codec *codec); + +#endif -- GitLab From 97030a43371ea29d65f332d288eb73e8f7bdb3a9 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:52 +0200 Subject: [PATCH 072/942] ASoC: Intel: avs: Add HDAudio machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connect AVS driver with ASoC HDAudio codec with help of this machine board. Similarly to its platform and codec components, DAI links and routes are being created dynamically so single board can be used across all HDAudio codec types. Card makes use of "binder" BE DAI Link so HDAudio codec driver can be listed as one of its components. This allows for BE DAIs to be created dynamically, based on HDAudio codec capabilities. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 3 + sound/soc/intel/avs/Makefile | 3 + sound/soc/intel/avs/boards/Kconfig | 15 ++ sound/soc/intel/avs/boards/Makefile | 5 + sound/soc/intel/avs/boards/hdaudio.c | 294 +++++++++++++++++++++++++++ 5 files changed, 320 insertions(+) create mode 100644 sound/soc/intel/avs/boards/Kconfig create mode 100644 sound/soc/intel/avs/boards/Makefile create mode 100644 sound/soc/intel/avs/boards/hdaudio.c diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 7c85d1bb9c129..e5107a3ce16a5 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -226,5 +226,8 @@ config SND_SOC_INTEL_AVS capabilities. This includes Skylake, Kabylake, Amberlake and Apollolake. +# Machine board drivers +source "sound/soc/intel/avs/boards/Kconfig" + # ASoC codec drivers source "sound/soc/intel/boards/Kconfig" diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile index b6b93ae80304b..919212825f216 100644 --- a/sound/soc/intel/avs/Makefile +++ b/sound/soc/intel/avs/Makefile @@ -10,3 +10,6 @@ snd-soc-avs-objs += trace.o CFLAGS_trace.o := -I$(src) obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o + +# Machine support +obj-$(CONFIG_SND_SOC) += boards/ diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig new file mode 100644 index 0000000000000..de62c0437f6ed --- /dev/null +++ b/sound/soc/intel/avs/boards/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "Intel AVS Machine drivers" + depends on SND_SOC_INTEL_AVS + +comment "Available DSP configurations" + +config SND_SOC_INTEL_AVS_MACH_HDAUDIO + tristate "HD-Audio generic board" + select SND_SOC_HDA + help + This adds support for AVS with HDAudio codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + +endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile new file mode 100644 index 0000000000000..e5281148e5d4b --- /dev/null +++ b/sound/soc/intel/avs/boards/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +snd-soc-avs-hdaudio-objs := hdaudio.o + +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c new file mode 100644 index 0000000000000..d2fc41d39448d --- /dev/null +++ b/sound/soc/intel/avs/boards/hdaudio.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include "../../../codecs/hda.h" + +static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int pcm_count, + const char *platform_name, struct snd_soc_dai_link **links) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + struct hda_pcm *pcm; + const char *cname = dev_name(&codec->core.dev); + int i; + + dl = devm_kcalloc(dev, pcm_count, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); + + for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { + dl[i].name = devm_kasprintf(dev, GFP_KERNEL, "%s link%d", cname, i); + if (!dl[i].name) + return -ENOMEM; + + dl[i].id = i; + dl[i].nonatomic = 1; + dl[i].no_pcm = 1; + dl[i].dpcm_playback = 1; + dl[i].dpcm_capture = 1; + dl[i].platforms = platform; + dl[i].num_platforms = 1; + + dl[i].codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + dl[i].cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + if (!dl[i].codecs || !dl[i].cpus) + return -ENOMEM; + + dl[i].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d", cname, i); + if (!dl[i].cpus->dai_name) + return -ENOMEM; + + dl[i].codecs->name = devm_kstrdup(dev, cname, GFP_KERNEL); + dl[i].codecs->dai_name = pcm->name; + dl[i].num_codecs = 1; + dl[i].num_cpus = 1; + } + + *links = dl; + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, struct hda_codec *codec, int pcm_count, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + struct hda_pcm *pcm; + const char *cname = dev_name(&codec->core.dev); + int i, n = 0; + + /* at max twice the number of pcms */ + dr = devm_kcalloc(dev, pcm_count * 2, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); + + for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { + struct hda_pcm_stream *stream; + int dir; + + dir = SNDRV_PCM_STREAM_PLAYBACK; + stream = &pcm->stream[dir]; + if (!stream->substreams) + goto capture_routes; + + dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Tx", cname, i); + if (!dr[n].sink || !dr[n].source) + return -ENOMEM; + n++; + +capture_routes: + dir = SNDRV_PCM_STREAM_CAPTURE; + stream = &pcm->stream[dir]; + if (!stream->substreams) + continue; + + dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Rx", cname, i); + dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, + snd_pcm_direction_name(dir)); + if (!dr[n].sink || !dr[n].source) + return -ENOMEM; + n++; + } + + *routes = dr; + *num_routes = n; + return 0; +} + +/* Should be aligned with SectionPCM's name from topology */ +#define FEDAI_NAME_PREFIX "HDMI" + +static struct snd_pcm * +avs_card_hdmi_pcm_at(struct snd_soc_card *card, int hdmi_idx) +{ + struct snd_soc_pcm_runtime *rtd; + int dir = SNDRV_PCM_STREAM_PLAYBACK; + + for_each_card_rtds(card, rtd) { + struct snd_pcm *spcm; + int ret, n; + + spcm = rtd->pcm ? rtd->pcm->streams[dir].pcm : NULL; + if (!spcm || !strstr(spcm->id, FEDAI_NAME_PREFIX)) + continue; + + ret = sscanf(spcm->id, FEDAI_NAME_PREFIX "%d", &n); + if (ret != 1) + continue; + if (n == hdmi_idx) + return rtd->pcm; + } + + return NULL; +} + +static int avs_card_late_probe(struct snd_soc_card *card) +{ + struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); + struct hda_codec *codec = mach->pdata; + struct hda_pcm *hpcm; + /* Topology pcm indexing is 1-based */ + int i = 1; + + list_for_each_entry(hpcm, &codec->pcm_list_head, list) { + struct snd_pcm *spcm; + + spcm = avs_card_hdmi_pcm_at(card, i); + if (spcm) { + hpcm->pcm = spcm; + hpcm->device = spcm->device; + dev_info(card->dev, "%s: mapping HDMI converter %d to PCM %d (%p)\n", + __func__, i, hpcm->device, spcm); + } else { + hpcm->pcm = NULL; + hpcm->device = SNDRV_PCM_INVALID_DEVICE; + dev_warn(card->dev, "%s: no PCM in topology for HDMI converter %d\n", + __func__, i); + } + i++; + } + + return hda_codec_probe_complete(codec); +} + +static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_acpi_mach *mach; + struct snd_soc_dai_link *links = NULL; + struct snd_soc_card *card = rtm->card; + struct hda_codec *codec; + struct hda_pcm *pcm; + int ret, n, pcm_count = 0; + + mach = dev_get_platdata(card->dev); + codec = mach->pdata; + + if (list_empty(&codec->pcm_list_head)) + return -EINVAL; + list_for_each_entry(pcm, &codec->pcm_list_head, list) + pcm_count++; + + ret = avs_create_dai_links(card->dev, codec, pcm_count, mach->mach_params.platform, &links); + if (ret < 0) { + dev_err(card->dev, "create links failed: %d\n", ret); + return ret; + } + + for (n = 0; n < pcm_count; n++) { + ret = snd_soc_add_pcm_runtime(card, &links[n]); + if (ret < 0) { + dev_err(card->dev, "add links failed: %d\n", ret); + return ret; + } + } + + ret = avs_create_dapm_routes(card->dev, codec, pcm_count, &routes, &n); + if (ret < 0) { + dev_err(card->dev, "create routes failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, routes, n); + if (ret < 0) { + dev_err(card->dev, "add routes failed: %d\n", ret); + return ret; + } + + return 0; +} + +SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); + +static struct snd_soc_dai_link probing_link = { + .name = "probing-LINK", + .id = -1, + .nonatomic = 1, + .no_pcm = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .cpus = dummy, + .num_cpus = ARRAY_SIZE(dummy), + .init = avs_probing_link_init, +}; + +static int avs_hdaudio_probe(struct platform_device *pdev) +{ + struct snd_soc_dai_link *binder; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + struct hda_codec *codec; + + mach = dev_get_platdata(dev); + codec = mach->pdata; + + /* codec may be unloaded before card's probe() fires */ + if (!device_is_registered(&codec->core.dev)) + return -ENODEV; + + binder = devm_kmemdup(dev, &probing_link, sizeof(probing_link), GFP_KERNEL); + if (!binder) + return -ENOMEM; + + binder->platforms = devm_kzalloc(dev, sizeof(*binder->platforms), GFP_KERNEL); + binder->codecs = devm_kzalloc(dev, sizeof(*binder->codecs), GFP_KERNEL); + if (!binder->platforms || !binder->codecs) + return -ENOMEM; + + binder->codecs->name = devm_kstrdup(dev, dev_name(&codec->core.dev), GFP_KERNEL); + if (!binder->codecs->name) + return -ENOMEM; + + binder->platforms->name = mach->mach_params.platform; + binder->num_platforms = 1; + binder->codecs->dai_name = "codec-probing-DAI"; + binder->num_codecs = 1; + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = binder->codecs->name; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = binder; + card->num_links = 1; + card->fully_routed = true; + if (hda_codec_is_display(codec)) + card->late_probe = avs_card_late_probe; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_hdaudio_driver = { + .probe = avs_hdaudio_probe, + .driver = { + .name = "avs_hdaudio", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_hdaudio_driver) + +MODULE_DESCRIPTION("Intel HD-Audio machine driver"); +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_hdaudio"); -- GitLab From 6575e5cae7525b07d0b5fbd7d42323363919a867 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:53 +0200 Subject: [PATCH 073/942] ASoC: Intel: avs: Add DMIC machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support AVS-DMIC configuration by implementing board connecting AVS platform component with DMIC codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 8 +++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/dmic.c | 93 +++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 sound/soc/intel/avs/boards/dmic.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index de62c0437f6ed..1d4597fa9814a 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -4,6 +4,14 @@ menu "Intel AVS Machine drivers" comment "Available DSP configurations" +config SND_SOC_INTEL_AVS_MACH_DMIC + tristate "DMIC generic board" + select SND_SOC_DMIC + help + This adds support for AVS with Digital Mic array configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_HDAUDIO tristate "HD-Audio generic board" select SND_SOC_HDA diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index e5281148e5d4b..2ff35d4d97d8d 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only +snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o diff --git a/sound/soc/intel/avs/boards/dmic.c b/sound/soc/intel/avs/boards/dmic.c new file mode 100644 index 0000000000000..90a9216385729 --- /dev/null +++ b/sound/soc/intel/avs/boards/dmic.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include + +SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); +SND_SOC_DAILINK_DEF(dmic_wov_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC WoV Pin"))); +SND_SOC_DAILINK_DEF(dmic_codec, DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); +/* Name overridden on probe */ +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM(""))); + +static struct snd_soc_dai_link card_dai_links[] = { + /* Back ends */ + { + .name = "DMIC", + .id = 0, + .dpcm_capture = 1, + .nonatomic = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), + }, + { + .name = "DMIC WoV", + .id = 1, + .dpcm_capture = 1, + .nonatomic = 1, + .no_pcm = 1, + .ignore_suspend = 1, + SND_SOC_DAILINK_REG(dmic_wov_pin, dmic_codec, platform), + }, +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_MIC("SoC DMIC", NULL), +}; + +static const struct snd_soc_dapm_route card_routes[] = { + {"DMic", NULL, "SoC DMIC"}, + {"DMIC Rx", NULL, "Capture"}, + {"DMIC WoV Rx", NULL, "Capture"}, +}; + +static int avs_dmic_probe(struct platform_device *pdev) +{ + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + int ret; + + mach = dev_get_platdata(dev); + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_dmic"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = card_dai_links; + card->num_links = ARRAY_SIZE(card_dai_links); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = card_routes; + card->num_dapm_routes = ARRAY_SIZE(card_routes); + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_dmic_driver = { + .probe = avs_dmic_probe, + .driver = { + .name = "avs_dmic", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_dmic_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_dmic"); -- GitLab From e39acc4cfd9250e7b8ec01897570f3009659c3d6 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:54 +0200 Subject: [PATCH 074/942] ASoC: Intel: avs: Add I2S-test machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow for testing audio streaming over I2S interface through SSP loopback. No actual codec is needed here as board is intended for SSP loopback scenarios only. One playback and one capture endpoint is exposed per SSP port. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 6 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/i2s_test.c | 180 ++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 sound/soc/intel/avs/boards/i2s_test.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 1d4597fa9814a..5b89fcb5f07f4 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -20,4 +20,10 @@ config SND_SOC_INTEL_AVS_MACH_HDAUDIO Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_I2S_TEST + tristate "I2S test board" + help + This adds support for I2S test-board which can be used to verify + transfer over I2S interface with SSP loopback scenarios. + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 2ff35d4d97d8d..fa1a279106beb 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -2,6 +2,8 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o +snd-soc-avs-i2s-test-objs := i2s_test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c new file mode 100644 index 0000000000000..461b651cd3314 --- /dev/null +++ b/sound/soc/intel/avs/boards/i2s_test.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "snd-soc-dummy"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "snd-soc-dummy-dai"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_dr = 2; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + dr[0].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%dpb", ssp_port); + dr[0].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[0].sink || !dr[0].source) + return -ENOMEM; + + dr[1].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[1].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%dcp", ssp_port); + if (!dr[1].sink || !dr[1].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_create_dapm_widgets(struct device *dev, int ssp_port, + struct snd_soc_dapm_widget **widgets, int *num_widgets) +{ + struct snd_soc_dapm_widget *dw; + const int num_dw = 2; + + dw = devm_kcalloc(dev, num_dw, sizeof(*dw), GFP_KERNEL); + if (!dw) + return -ENOMEM; + + dw[0].id = snd_soc_dapm_hp; + dw[0].reg = SND_SOC_NOPM; + dw[0].name = devm_kasprintf(dev, GFP_KERNEL, "ssp%dpb", ssp_port); + if (!dw[0].name) + return -ENOMEM; + + dw[1].id = snd_soc_dapm_mic; + dw[1].reg = SND_SOC_NOPM; + dw[1].name = devm_kasprintf(dev, GFP_KERNEL, "ssp%dcp", ssp_port); + if (!dw[1].name) + return -ENOMEM; + + *widgets = dw; + *num_widgets = num_dw; + + return 0; +} + +static int avs_i2s_test_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_widget *widgets; + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, num_widgets; + int ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = devm_kasprintf(dev, GFP_KERNEL, "ssp%ld-loopback", ssp_port); + if (!card->name) + return -ENOMEM; + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d\n", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d\n", ret); + return ret; + } + + ret = avs_create_dapm_widgets(dev, ssp_port, &widgets, &num_widgets); + if (ret) { + dev_err(dev, "Failed to create dapm widgets: %d\n", ret); + return ret; + } + + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->dapm_widgets = widgets; + card->num_dapm_widgets = num_widgets; + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_i2s_test_driver = { + .probe = avs_i2s_test_probe, + .driver = { + .name = "avs_i2s_test", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_i2s_test_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_i2s_test"); -- GitLab From e2a4cbf277c4561d01f1aafa3cfafe46bf3feec7 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:55 +0200 Subject: [PATCH 075/942] ASoC: Intel: avs: Add rt274 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-rt274 configuration add machine board connecting AVS platform component driver with rt274 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/rt274.c | 310 ++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 sound/soc/intel/avs/boards/rt274.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 5b89fcb5f07f4..9058919c99a75 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -26,4 +26,14 @@ config SND_SOC_INTEL_AVS_MACH_I2S_TEST This adds support for I2S test-board which can be used to verify transfer over I2S interface with SSP loopback scenarios. +config SND_SOC_INTEL_AVS_MACH_RT274 + tristate "rt274 in I2S mode" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_RT274 + help + This adds support for ASoC machine driver with RT274 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index fa1a279106beb..e94f04d00ffcf 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -3,7 +3,9 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o +snd-soc-avs-rt274-objs := rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c new file mode 100644 index 0000000000000..afef5a3ca60b9 --- /dev/null +++ b/sound/soc/intel/avs/boards/rt274.c @@ -0,0 +1,310 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include "../../../codecs/rt274.h" + +#define AVS_RT274_FREQ_OUT 24000000 +#define AVS_RT274_BE_FIXUP_RATE 48000 +#define RT274_CODEC_DAI "rt274-aif1" + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Mic Jack"), +}; + +static int +avs_rt274_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, RT274_CODEC_DAI); + if (!codec_dai) + return -EINVAL; + + /* Codec needs clock for Jack detection and button press */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT274_SCLK_S_PLL2, AVS_RT274_FREQ_OUT, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "set codec sysclk failed: %d\n", ret); + return ret; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + int ratio = 100; + + snd_soc_dai_set_bclk_ratio(codec_dai, ratio); + + ret = snd_soc_dai_set_pll(codec_dai, 0, RT274_PLL2_S_BCLK, + AVS_RT274_BE_FIXUP_RATE * ratio, AVS_RT274_FREQ_OUT); + if (ret) { + dev_err(codec_dai->dev, "failed to enable PLL2: %d\n", ret); + return ret; + } + } + + return 0; +} + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, avs_rt274_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + {"Headphone Jack", NULL, "HPO Pin"}, + {"MIC", NULL, "Mic Jack"}, + + {"Headphone Jack", NULL, "Platform Clock"}, + {"MIC", NULL, "Platform Clock"}, +}; + +static struct snd_soc_jack_pin card_headset_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_component *component = codec_dai->component; + struct snd_soc_jack_pin *pins; + struct snd_soc_jack *jack; + struct snd_soc_card *card = runtime->card; + int num_pins, ret; + + jack = snd_soc_card_get_drvdata(card); + num_pins = ARRAY_SIZE(card_headset_pins); + + pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + if (!pins) + return -ENOMEM; + + ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET, jack, pins, num_pins); + if (ret) + return ret; + + snd_soc_component_set_jack(component, jack, NULL); + + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); + if (ret < 0) { + dev_err(card->dev, "can't set codec pcm format %d\n", ret); + return ret; + } + + card->dapm.idle_bias_off = true; + + return 0; +} + +static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will convert the FE rate to 48k, stereo */ + rate->min = rate->max = AVS_RT274_BE_FIXUP_RATE; + channels->min = channels->max = 2; + + /* set SSPN to 24 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT34C2:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt274-aif1"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_rt274_codec_init; + dl->be_hw_params_fixup = avs_rt274_be_fixup; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + return avs_card_set_jack(card, jack); +} + +static int avs_rt274_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_rt274"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_rt274_driver = { + .probe = avs_rt274_probe, + .driver = { + .name = "avs_rt274", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_rt274_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_rt274"); -- GitLab From 1d395ee2e19b33a1008acfc7af186f2851b63d01 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:56 +0200 Subject: [PATCH 076/942] ASoC: Intel: avs: Add rt286 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-rt286 configuration add machine board connecting AVS platform component driver with rt286 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/rt286.c | 281 ++++++++++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 sound/soc/intel/avs/boards/rt286.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 9058919c99a75..707e9e96746d8 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -36,4 +36,14 @@ config SND_SOC_INTEL_AVS_MACH_RT274 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_RT286 + tristate "rt286 in I2S mode" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_RT286 + help + This adds support for ASoC machine driver with RT286 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index e94f04d00ffcf..7ea4ad38c7df9 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -4,8 +4,10 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o snd-soc-avs-rt274-objs := rt274.o +snd-soc-avs-rt286-objs := rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c new file mode 100644 index 0000000000000..e51d4e1812742 --- /dev/null +++ b/sound/soc/intel/avs/boards/rt286.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include "../../../codecs/rt286.h" + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Mic Jack"), + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + /* HP jack connectors - unknown if we have jack detect */ + {"Headphone Jack", NULL, "HPO Pin"}, + {"MIC1", NULL, "Mic Jack"}, + + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "SPOL"}, +}; + +static struct snd_soc_jack_pin card_headset_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_jack_pin *pins; + struct snd_soc_jack *jack; + struct snd_soc_card *card = runtime->card; + int num_pins, ret; + + jack = snd_soc_card_get_drvdata(card); + num_pins = ARRAY_SIZE(card_headset_pins); + + pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + if (!pins) + return -ENOMEM; + + ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, jack, + pins, num_pins); + if (ret) + return ret; + + snd_soc_component_set_jack(component, jack, NULL); + + return 0; +} + +static int avs_rt286_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will convert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP0 to 24 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int +avs_rt286_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *runtime = substream->private_data; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + int ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(runtime->dev, "Set codec sysclk failed: %d\n", ret); + + return ret; +} + +static const struct snd_soc_ops avs_rt286_ops = { + .hw_params = avs_rt286_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt286-aif1"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_rt286_codec_init; + dl->be_hw_params_fixup = avs_rt286_be_fixup; + dl->ops = &avs_rt286_ops; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + return avs_card_set_jack(card, jack); +} + +static int avs_rt286_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_rt286"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_rt286_driver = { + .probe = avs_rt286_probe, + .driver = { + .name = "avs_rt286", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_rt286_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_rt286"); -- GitLab From 88429ab16df4cd4a1a77d45b90ec95cf62cc22d1 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:57 +0200 Subject: [PATCH 077/942] ASoC: Intel: avs: Add rt298 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-rt298 configuration add machine board connecting AVS platform component driver with rt298 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/rt298.c | 281 ++++++++++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 sound/soc/intel/avs/boards/rt298.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 707e9e96746d8..b4dc2b02097d8 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -46,4 +46,14 @@ config SND_SOC_INTEL_AVS_MACH_RT286 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_RT298 + tristate "rt298 in I2S mode" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_RT298 + help + This adds support for ASoC machine driver with RT298 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 7ea4ad38c7df9..0fd664694c8c3 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -5,9 +5,11 @@ snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o +snd-soc-avs-rt298-objs := rt298.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c new file mode 100644 index 0000000000000..b28d36872dcba --- /dev/null +++ b/sound/soc/intel/avs/boards/rt298.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include "../../../codecs/rt298.h" + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Mic Jack"), + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + /* HP jack connectors - unknown if we have jack detect */ + {"Headphone Jack", NULL, "HPO Pin"}, + {"MIC1", NULL, "Mic Jack"}, + + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "SPOL"}, +}; + +static struct snd_soc_jack_pin card_headset_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Mic Jack", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_jack_pin *pins; + struct snd_soc_jack *jack; + struct snd_soc_card *card = runtime->card; + int num_pins, ret; + + jack = snd_soc_card_get_drvdata(card); + num_pins = ARRAY_SIZE(card_headset_pins); + + pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + if (!pins) + return -ENOMEM; + + ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, jack, + pins, num_pins); + if (ret) + return ret; + + snd_soc_component_set_jack(component, jack, NULL); + + return 0; +} + +static int avs_rt298_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will convert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP0 to 24 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int +avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + int ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret); + + return ret; +} + +static const struct snd_soc_ops avs_rt298_ops = { + .hw_params = avs_rt298_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt298-aif1"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_rt298_codec_init; + dl->be_hw_params_fixup = avs_rt298_be_fixup; + dl->ops = &avs_rt298_ops; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + return avs_card_set_jack(card, jack); +} + +static int avs_rt298_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_rt298"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_rt298_driver = { + .probe = avs_rt298_probe, + .driver = { + .name = "avs_rt298", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_rt298_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_rt298"); -- GitLab From 748102786b3ce0bf402c2dc42386cbfaab71ac39 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:58 +0200 Subject: [PATCH 078/942] ASoC: Intel: avs: Add rt5682 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-rt5682 configuration add machine board connecting AVS platform component driver with rt5682 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/rt5682.c | 340 ++++++++++++++++++++++++++++ 3 files changed, 352 insertions(+) create mode 100644 sound/soc/intel/avs/boards/rt5682.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index b4dc2b02097d8..767eae57be576 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -56,4 +56,14 @@ config SND_SOC_INTEL_AVS_MACH_RT298 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_RT5682 + tristate "rt5682 in I2S mode" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_RT5682_I2C + help + This adds support for ASoC machine driver with RT5682 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 0fd664694c8c3..fd49bd2a58767 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -6,6 +6,7 @@ snd-soc-avs-i2s-test-objs := i2s_test.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o snd-soc-avs-rt298-objs := rt298.o +snd-soc-avs-rt5682-objs := rt5682.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o @@ -13,3 +14,4 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682) += snd-soc-avs-rt5682.o diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c new file mode 100644 index 0000000000000..01f9b9f0c12bc --- /dev/null +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../common/soc-intel-quirks.h" +#include "../../../codecs/rt5682.h" + +#define AVS_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) +#define AVS_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) +#define AVS_RT5682_MCLK_EN BIT(3) +#define AVS_RT5682_MCLK_24MHZ BIT(4) + +/* Default: MCLK on, MCLK 19.2M, SSP0 */ +static unsigned long avs_rt5682_quirk = AVS_RT5682_MCLK_EN | AVS_RT5682_SSP_CODEC(0); + +static int avs_rt5682_quirk_cb(const struct dmi_system_id *id) +{ + avs_rt5682_quirk = (unsigned long)id->driver_data; + return 1; +} + +static const struct dmi_system_id avs_rt5682_quirk_table[] = { + { + .callback = avs_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"), + }, + .driver_data = (void *)(AVS_RT5682_MCLK_EN | + AVS_RT5682_MCLK_24MHZ | + AVS_RT5682_SSP_CODEC(1)), + }, + { + .callback = avs_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), + }, + .driver_data = (void *)(AVS_RT5682_MCLK_EN | + AVS_RT5682_SSP_CODEC(0)), + }, + {} +}; + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + /* HP jack connectors - unknown if we have jack detect */ + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + + /* other jacks */ + { "IN1P", NULL, "Headset Mic" }, +}; + +static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_jack *jack; + struct snd_soc_card *card = runtime->card; + int ret; + + jack = snd_soc_card_get_drvdata(card); + + /* Need to enable ASRC function for 24MHz mclk rate */ + if ((avs_rt5682_quirk & AVS_RT5682_MCLK_EN) && + (avs_rt5682_quirk & AVS_RT5682_MCLK_24MHZ)) { + rt5682_sel_asrc_clk_src(component, RT5682_DA_STEREO1_FILTER | + RT5682_AD_STEREO1_FILTER, RT5682_CLK_SEL_I2S1_ASRC); + } + + /* + * Headset buttons map to the google Reference headset. + * These can be configured by userspace. + */ + ret = snd_soc_card_jack_new(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, jack); + if (ret) { + dev_err(card->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(card->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + + return 0; +}; + +static int +avs_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + int clk_id, clk_freq; + int pll_out, ret; + + if (avs_rt5682_quirk & AVS_RT5682_MCLK_EN) { + clk_id = RT5682_PLL1_S_MCLK; + if (avs_rt5682_quirk & AVS_RT5682_MCLK_24MHZ) + clk_freq = 24000000; + else + clk_freq = 19200000; + } else { + clk_id = RT5682_PLL1_S_BCLK1; + clk_freq = params_rate(params) * 50; + } + + pll_out = params_rate(params) * 512; + + ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); + if (ret < 0) + dev_err(runtime->dev, "snd_soc_dai_set_pll err = %d\n", ret); + + /* Configure sysclk for codec */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, pll_out, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(runtime->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); + + /* slot_width should equal or large than data length, set them be the same */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x0, 0x0, 2, params_width(params)); + if (ret < 0) { + dev_err(runtime->dev, "set TDM slot err:%d\n", ret); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops avs_rt5682_ops = { + .hw_params = avs_rt5682_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5682:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt5682-aif1"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->init = avs_rt5682_codec_init; + dl->ops = &avs_rt5682_ops; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + return avs_card_set_jack(card, jack); +} + +static int avs_rt5682_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + if (pdev->id_entry && pdev->id_entry->driver_data) + avs_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; + + dmi_check_system(avs_rt5682_quirk_table); + dev_dbg(dev, "avs_rt5682_quirk = %lx\n", avs_rt5682_quirk); + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_rt5682"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_rt5682_driver = { + .probe = avs_rt5682_probe, + .driver = { + .name = "avs_rt5682", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_rt5682_driver) + +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_rt5682"); -- GitLab From 32ee40b5590081a6b38a55e4ab16b47085f93afe Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:23:59 +0200 Subject: [PATCH 079/942] ASoC: Intel: avs: Add nau8825 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-nau8825 configuration add machine board connecting AVS platform component driver with nau8825 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 11 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/nau8825.c | 353 +++++++++++++++++++++++++++ 3 files changed, 366 insertions(+) create mode 100644 sound/soc/intel/avs/boards/nau8825.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 767eae57be576..6bf8fa1924a22 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -26,6 +26,17 @@ config SND_SOC_INTEL_AVS_MACH_I2S_TEST This adds support for I2S test-board which can be used to verify transfer over I2S interface with SSP loopback scenarios. +config SND_SOC_INTEL_AVS_MACH_NAU8825 + tristate "nau8825 I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_NAU8825 + help + This adds support for ASoC machine driver with NAU8825 I2S audio codec. + It is meant to be used with AVS driver. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_RT274 tristate "rt274 in I2S mode" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index fd49bd2a58767..9ac14b269f568 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -3,6 +3,7 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o +snd-soc-avs-nau8825-objs := nau8825.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o snd-soc-avs-rt298-objs := rt298.o @@ -11,6 +12,7 @@ snd-soc-avs-rt5682-objs := rt5682.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c new file mode 100644 index 0000000000000..f76909e9f990a --- /dev/null +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../codecs/nau8825.h" + +#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" + +static int +avs_nau8825_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found\n"); + return -EINVAL; + } + + if (!SND_SOC_DAPM_EVENT_ON(event)) { + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "set sysclk err = %d\n", ret); + return ret; + } + } + + return 0; +} + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, avs_nau8825_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + + { "MIC", NULL, "Headset Mic" }, + + { "Headphone Jack", NULL, "Platform Clock" }, + { "Headset Mic", NULL, "Platform Clock" }, +}; + +static struct snd_soc_jack_pin card_headset_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_component *component = codec_dai->component; + struct snd_soc_jack_pin *pins; + struct snd_soc_jack *jack; + struct snd_soc_card *card = runtime->card; + int num_pins, ret; + + jack = snd_soc_card_get_drvdata(card); + num_pins = ARRAY_SIZE(card_headset_pins); + + pins = devm_kmemdup(card->dev, card_headset_pins, sizeof(*pins) * num_pins, GFP_KERNEL); + if (!pins) + return -ENOMEM; + + /* + * 4 buttons here map to the google Reference headset. + * The use of these buttons can be decided by the user space. + */ + ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, + jack, pins, num_pins); + if (ret) + return ret; + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + //snd_soc_component_set_jack(component, jack, NULL); + // TODO: Fix nau8825 codec to use .set_jack, like everyone else + nau8825_enable_jack_detect(component, jack); + + return 0; +} + +static int +avs_nau8825_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will convert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP to 24 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int avs_nau8825_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtm = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtm, 0); + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS, 0, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(codec_dai->dev, "can't set FS clock %d\n", ret); + break; + } + + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, runtime->rate, runtime->rate * 256); + if (ret < 0) + dev_err(codec_dai->dev, "can't set FLL: %d\n", ret); + break; + + case SNDRV_PCM_TRIGGER_RESUME: + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, runtime->rate, runtime->rate * 256); + if (ret < 0) + dev_err(codec_dai->dev, "can't set FLL: %d\n", ret); + break; + } + + return ret; +} + + +static const struct snd_soc_ops avs_nau8825_ops = { + .trigger = avs_nau8825_trigger, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10508825:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, SKL_NUVOTON_CODEC_DAI); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_nau8825_codec_init; + dl->be_hw_params_fixup = avs_nau8825_be_fixup; + dl->ops = &avs_nau8825_ops; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found\n"); + return -EINVAL; + } + + if (codec_dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK] && + codec_dai->playback_widget->active) + snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS, 0, SND_SOC_CLOCK_IN); + + return avs_card_set_jack(card, jack); +} + +static int avs_nau8825_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_nau8825"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_nau8825_driver = { + .probe = avs_nau8825_probe, + .driver = { + .name = "avs_nau8825", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_nau8825_driver) + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_nau8825"); -- GitLab From 69ea14efe99b533652255b07a9736a9856f50ea5 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:24:00 +0200 Subject: [PATCH 080/942] ASoC: Intel: avs: Add ssm4567 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-ssm4567 configuration add machine board connecting AVS platform component driver with ssm4567 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 11 ++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/ssm4567.c | 271 +++++++++++++++++++++++++++ 3 files changed, 284 insertions(+) create mode 100644 sound/soc/intel/avs/boards/ssm4567.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 6bf8fa1924a22..7020e7bf196e5 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -77,4 +77,15 @@ config SND_SOC_INTEL_AVS_MACH_RT5682 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_SSM4567 + tristate "ssm4567 I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_SSM4567 + help + This adds support for ASoC machine driver with SSM4567 I2S audio codec. + It is meant to be used with AVS driver. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + endmenu diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 9ac14b269f568..ea67fc711d9d7 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -8,6 +8,7 @@ snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o snd-soc-avs-rt298-objs := rt298.o snd-soc-avs-rt5682-objs := rt5682.o +snd-soc-avs-ssm4567-objs := ssm4567.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o @@ -17,3 +18,4 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682) += snd-soc-avs-rt5682.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567) += snd-soc-avs-ssm4567.o diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c new file mode 100644 index 0000000000000..9f84c8ab34478 --- /dev/null +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -0,0 +1,271 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include +#include +#include "../../../codecs/nau8825.h" + +#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" +#define SKL_SSM_CODEC_DAI "ssm4567-hifi" + +static struct snd_soc_codec_conf card_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF("i2c-INT343B:00"), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF("i2c-INT343B:01"), + .name_prefix = "Right", + }, +}; + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Left Speaker"), + SOC_DAPM_PIN_SWITCH("Right Speaker"), +}; + +static int +platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *control, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found\n"); + return -EINVAL; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_MCLK, 24000000, + SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(card->dev, "set sysclk err = %d\n", ret); + } else { + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(card->dev, "set sysclk err = %d\n", ret); + } + + return ret; +} + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_SPK("Left Speaker", NULL), + SND_SOC_DAPM_SPK("Right Speaker", NULL), + SND_SOC_DAPM_SPK("DP1", NULL), + SND_SOC_DAPM_SPK("DP2", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + {"Left Speaker", NULL, "Left OUT"}, + {"Right Speaker", NULL, "Right OUT"}, +}; + +static int avs_ssm4567_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret; + + /* Slot 1 for left */ + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(runtime, 0), 0x01, 0x01, 2, 48); + if (ret < 0) + return ret; + + /* Slot 2 for right */ + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(runtime, 1), 0x02, 0x02, 2, 48); + if (ret < 0) + return ret; + + return 0; +} + +static int +avs_ssm4567_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will covert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP0 to 24 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343B:00"); + dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssm4567-hifi"); + dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343B:01"); + dl->codecs[1].dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssm4567-hifi"); + if (!dl->cpus->dai_name || !dl->codecs[0].name || !dl->codecs[0].dai_name || + !dl->codecs[1].name || !dl->codecs[1].dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 2; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_ssm4567_codec_init; + dl->be_hw_params_fixup = avs_ssm4567_be_fixup; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + dl->ignore_pmdown_time = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 4; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Left Capture Sense"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Right Capture Sense"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_ssm4567_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_ssm4567-adi"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->codec_conf = card_codec_conf; + card->num_configs = ARRAY_SIZE(card_codec_conf); + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + card->disable_route_checks = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_ssm4567_driver = { + .probe = avs_ssm4567_probe, + .driver = { + .name = "avs_ssm4567", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_ssm4567_driver) + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_ssm4567"); -- GitLab From 282c8f8de72f95325225d94caef61f3cc96401da Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:24:01 +0200 Subject: [PATCH 081/942] ASoC: Intel: avs: Add max98357a machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-max98357a configuration add machine board connecting AVS platform component driver with max98357a codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 ++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/max98357a.c | 154 +++++++++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 sound/soc/intel/avs/boards/max98357a.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 7020e7bf196e5..28e6691270d9f 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -26,6 +26,16 @@ config SND_SOC_INTEL_AVS_MACH_I2S_TEST This adds support for I2S test-board which can be used to verify transfer over I2S interface with SSP loopback scenarios. +config SND_SOC_INTEL_AVS_MACH_MAX98357A + tristate "max98357A I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_MAX98357A + help + This adds support for AVS with MAX98357A I2S codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_NAU8825 tristate "nau8825 I2S board" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index ea67fc711d9d7..f7ac1151a8f77 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -3,6 +3,7 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o +snd-soc-avs-max98357a-objs := max98357a.o snd-soc-avs-nau8825-objs := nau8825.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o @@ -13,6 +14,7 @@ snd-soc-avs-ssm4567-objs := ssm4567.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c new file mode 100644 index 0000000000000..921f42caf7e09 --- /dev/null +++ b/sound/soc/intel/avs/boards/max98357a.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Spk"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_SPK("Spk", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + { "Spk", NULL, "Speaker" }, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "MX98357A:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "HiFi"); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 1; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "HiFi Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_max98357a_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_max98357a"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_max98357a_driver = { + .probe = avs_max98357a_probe, + .driver = { + .name = "avs_max98357a", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_max98357a_driver) + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_max98357a"); -- GitLab From 223a0a945821b96f4ccd9940ee975499706e1794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 11 May 2022 18:24:02 +0200 Subject: [PATCH 082/942] ASoC: Intel: avs: Add max98373 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-max98373 configuration add machine board connecting AVS platform component driver with max98373 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-14-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 ++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/max98373.c | 239 ++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 sound/soc/intel/avs/boards/max98373.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 28e6691270d9f..d3be6dc1fc106 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -36,6 +36,16 @@ config SND_SOC_INTEL_AVS_MACH_MAX98357A Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_MAX98373 + tristate "max98373 I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_MAX98373 + help + This adds support for AVS with MAX98373 I2S codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_NAU8825 tristate "nau8825 I2S board" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index f7ac1151a8f77..0bce31e192ceb 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -4,6 +4,7 @@ snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o snd-soc-avs-max98357a-objs := max98357a.o +snd-soc-avs-max98373-objs := max98373.o snd-soc-avs-nau8825-objs := nau8825.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o @@ -15,6 +16,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c new file mode 100644 index 0000000000000..0fa8f5606385b --- /dev/null +++ b/sound/soc/intel/avs/boards/max98373.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include + +#define MAX98373_DEV0_NAME "i2c-MX98373:00" +#define MAX98373_DEV1_NAME "i2c-MX98373:01" +#define MAX98373_CODEC_NAME "max98373-aif1" + +static struct snd_soc_codec_conf card_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF(MAX98373_DEV0_NAME), + .name_prefix = "Right", + }, + { + .dlc = COMP_CODEC_CONF(MAX98373_DEV1_NAME), + .name_prefix = "Left", + }, +}; + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + { "Left Spk", NULL, "Left BE_OUT" }, + { "Right Spk", NULL, "Right BE_OUT" }, +}; + +static int +avs_max98373_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will covert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP0 to 16 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + return 0; +} + +static int avs_max98373_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai; + int ret, i; + + for_each_rtd_codec_dais(runtime, i, codec_dai) { + if (!strcmp(codec_dai->component->name, MAX98373_DEV0_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); + if (ret < 0) { + dev_err(runtime->dev, "DEV0 TDM slot err:%d\n", ret); + return ret; + } + } + if (!strcmp(codec_dai->component->name, MAX98373_DEV1_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); + if (ret < 0) { + dev_err(runtime->dev, "DEV1 TDM slot err:%d\n", ret); + return ret; + } + } + } + + return 0; +} + +static const struct snd_soc_ops avs_max98373_ops = { + .hw_params = avs_max98373_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_DEV0_NAME); + dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_CODEC_NAME); + dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_DEV1_NAME); + dl->codecs[1].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_CODEC_NAME); + if (!dl->cpus->dai_name || !dl->codecs[0].name || !dl->codecs[0].dai_name || + !dl->codecs[1].name || !dl->codecs[1].dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 2; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + dl->be_hw_params_fixup = avs_max98373_be_fixup; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + dl->ignore_pmdown_time = 1; + dl->ops = &avs_max98373_ops; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left HiFi Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right HiFi Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_max98373_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_max98373"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->codec_conf = card_codec_conf; + card->num_configs = ARRAY_SIZE(card_codec_conf); + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_max98373_driver = { + .probe = avs_max98373_probe, + .driver = { + .name = "avs_max98373", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_max98373_driver) + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_max98373"); -- GitLab From 6b5b0d6f36dd45e22f1710e8bcd97f28b4ba41f5 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 11 May 2022 18:24:03 +0200 Subject: [PATCH 083/942] ASoC: Intel: avs: Add da7219 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-da7219 configuration add machine board connecting AVS platform component driver with da7219 codec one. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220511162403.3987658-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 + sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/da7219.c | 282 ++++++++++++++++++++++++++++ 3 files changed, 294 insertions(+) create mode 100644 sound/soc/intel/avs/boards/da7219.c diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index d3be6dc1fc106..4d68e3ef992ba 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -4,6 +4,16 @@ menu "Intel AVS Machine drivers" comment "Available DSP configurations" +config SND_SOC_INTEL_AVS_MACH_DA7219 + tristate "da7219 I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_DA7219 + help + This adds support for AVS with DA7219 I2S codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_DMIC tristate "DMIC generic board" select SND_SOC_DMIC diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 0bce31e192ceb..25e8c4bb07dbf 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only +snd-soc-avs-da7219-objs := da7219.o snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o @@ -12,6 +13,7 @@ snd-soc-avs-rt298-objs := rt298.o snd-soc-avs-rt5682-objs := rt5682.o snd-soc-avs-ssm4567-objs := ssm4567.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219) += snd-soc-avs-da7219.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c new file mode 100644 index 0000000000000..02ae542ad7792 --- /dev/null +++ b/sound/soc/intel/avs/boards/da7219.c @@ -0,0 +1,282 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Author: Cezary Rojewski +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../../codecs/da7219.h" +#include "../../../codecs/da7219-aad.h" + +#define DA7219_DAI_NAME "da7219-hifi" + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + int ret = 0; + + codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found. Unable to set/unset codec pll\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_OFF(event)) { + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); + if (ret) + dev_err(card->dev, "failed to stop PLL: %d\n", ret); + } else if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM, + 0, DA7219_PLL_FREQ_OUT_98304); + if (ret) + dev_err(card->dev, "failed to start PLL: %d\n", ret); + } + + return ret; +} + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + /* HP jack connectors - unknown if we have jack detection */ + {"Headphone Jack", NULL, "HPL"}, + {"Headphone Jack", NULL, "HPR"}, + + {"MIC", NULL, "Headset Mic"}, + + { "Headphone Jack", NULL, "Platform Clock" }, + { "Headset Mic", NULL, "Platform Clock" }, +}; + +static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_card *card = runtime->card; + struct snd_soc_jack *jack; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + int clk_freq; + int ret; + + jack = snd_soc_card_get_drvdata(card); + clk_freq = 19200000; + + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "can't set codec sysclk configuration\n"); + return ret; + } + + /* + * Headset buttons map to the google Reference headset. + * These can be configured by userspace. + */ + ret = snd_soc_card_jack_new(card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3 | SND_JACK_LINEOUT, jack); + if (ret) { + dev_err(card->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); + + da7219_aad_jack_det(component, jack); + + return 0; +} + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-DLGS7219:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, DA7219_DAI_NAME); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_da7219_codec_init; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Capture"); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) +{ + struct snd_soc_component *component; + + for_each_card_components(card, component) + snd_soc_component_set_jack(component, jack, NULL); + return 0; +} + +static int avs_card_remove(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_suspend_pre(struct snd_soc_card *card) +{ + return avs_card_set_jack(card, NULL); +} + +static int avs_card_resume_post(struct snd_soc_card *card) +{ + struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); + + return avs_card_set_jack(card, jack); +} + +static int avs_da7219_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct snd_soc_jack *jack; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!jack || !card) + return -ENOMEM; + + card->name = "avs_da7219"; + card->dev = dev; + card->owner = THIS_MODULE; + card->remove = avs_card_remove; + card->suspend_pre = avs_card_suspend_pre; + card->resume_post = avs_card_resume_post; + card->dai_link = dai_link; + card->num_links = 1; + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + snd_soc_card_set_drvdata(card, jack); + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_da7219_driver = { + .probe = avs_da7219_probe, + .driver = { + .name = "avs_da7219", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_da7219_driver); + +MODULE_AUTHOR("Cezary Rojewski "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_da7219"); -- GitLab From 905f3a04e184854555fc248ca4e692fdbf2f2547 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:23 +0100 Subject: [PATCH 084/942] ASoC: core: Add set_fmt_new callback that directly specifies provider The original set_fmt callback always passes clock provider/consumer with respect to the CODEC. This made sense when the framework was directly broken down into platforms and CODECs. Now everything is componentised it simplifies things if each side of the link is just told if it is provider or consumer of the clocks. To start this migration add a new callback that can be used to receive a direct specification of clocking. As there are more CODEC drivers than platform drivers, we make the new flags identical to the old CODEC flags meaning CODEC drivers will not require an update. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 7 +++++++ sound/soc/soc-core.c | 3 ++- sound/soc/soc-dai.c | 5 ++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index bbd821d2df9ca..9c1d92d5a3738 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -124,6 +124,12 @@ struct snd_compr_stream; #define SND_SOC_DAIFMT_CBM_CFS SND_SOC_DAIFMT_CBP_CFC #define SND_SOC_DAIFMT_CBS_CFS SND_SOC_DAIFMT_CBC_CFC +/* when passed to set_fmt directly indicate if the device is provider or consumer */ +#define SND_SOC_DAIFMT_BP_FP SND_SOC_DAIFMT_CBP_CFP +#define SND_SOC_DAIFMT_BC_FP SND_SOC_DAIFMT_CBC_CFP +#define SND_SOC_DAIFMT_BP_FC SND_SOC_DAIFMT_CBP_CFC +#define SND_SOC_DAIFMT_BC_FC SND_SOC_DAIFMT_CBC_CFC + /* Describes the possible PCM format */ #define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT 48 #define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_MASK (0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) @@ -282,6 +288,7 @@ struct snd_soc_dai_ops { * Called by soc_card drivers, normally in their hw_params. */ int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); + int (*set_fmt_new)(struct snd_soc_dai *dai, unsigned int fmt); int (*xlate_tdm_slot_mask)(unsigned int slots, unsigned int *tx_mask, unsigned int *rx_mask); int (*set_tdm_slot)(struct snd_soc_dai *dai, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9574f86dd4de2..90f4265bea501 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1235,7 +1235,8 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, for_each_rtd_cpu_dais(rtd, i, cpu_dai) { unsigned int fmt = dai_fmt; - if (snd_soc_component_is_codec(cpu_dai->component)) + if (cpu_dai->driver->ops->set_fmt_new || + snd_soc_component_is_codec(cpu_dai->component)) fmt = inv_dai_fmt; ret = snd_soc_dai_set_fmt(cpu_dai, fmt); diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 6078afe335f88..996712f4d9bfd 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -209,7 +209,10 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) int ret = -ENOTSUPP; if (dai->driver->ops && - dai->driver->ops->set_fmt) + dai->driver->ops->set_fmt_new) + ret = dai->driver->ops->set_fmt_new(dai, fmt); + else if (dai->driver->ops && + dai->driver->ops->set_fmt) ret = dai->driver->ops->set_fmt(dai, fmt); return soc_dai_ret(dai, ret); -- GitLab From ab890e0f83a65624d20b0ca4a7cb6306b8511558 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:24 +0100 Subject: [PATCH 085/942] ASoC: amd: vangogh: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/amd/vangogh/acp5x-i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c index 59a98f89a669a..40fbd0bc77fde 100644 --- a/sound/soc/amd/vangogh/acp5x-i2s.c +++ b/sound/soc/amd/vangogh/acp5x-i2s.c @@ -37,10 +37,10 @@ static int acp5x_i2s_set_fmt(struct snd_soc_dai *cpu_dai, } mode = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; switch (mode) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: adata->master_mode = I2S_MASTER_MODE_ENABLE; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: adata->master_mode = I2S_MASTER_MODE_DISABLE; break; } @@ -339,7 +339,7 @@ static int acp5x_i2s_trigger(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops acp5x_i2s_dai_ops = { .hw_params = acp5x_i2s_hwparams, .trigger = acp5x_i2s_trigger, - .set_fmt = acp5x_i2s_set_fmt, + .set_fmt_new = acp5x_i2s_set_fmt, .set_tdm_slot = acp5x_i2s_set_tdm_slot, }; -- GitLab From 0fd054a577180cd807992e32c7cd394e54c85903 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:25 +0100 Subject: [PATCH 086/942] ASoC: atmel: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-i2s.c | 6 +++--- sound/soc/atmel/atmel_ssc_dai.c | 20 ++++++++++---------- sound/soc/atmel/mchp-i2s-mcc.c | 10 +++++----- sound/soc/atmel/mchp-pdmc.c | 6 +++--- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c index 1934767690b51..c5ce695da5866 100644 --- a/sound/soc/atmel/atmel-i2s.c +++ b/sound/soc/atmel/atmel-i2s.c @@ -343,7 +343,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream, } switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: /* codec is slave, so cpu is master */ mr |= ATMEL_I2SC_MR_MODE_MASTER; ret = atmel_i2s_get_gck_param(dev, params_rate(params)); @@ -351,7 +351,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream, return ret; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: /* codec is master, so cpu is slave */ mr |= ATMEL_I2SC_MR_MODE_SLAVE; dev->gck_param = NULL; @@ -533,7 +533,7 @@ static const struct snd_soc_dai_ops atmel_i2s_dai_ops = { .prepare = atmel_i2s_prepare, .trigger = atmel_i2s_trigger, .hw_params = atmel_i2s_hw_params, - .set_fmt = atmel_i2s_set_dai_fmt, + .set_fmt_new = atmel_i2s_set_dai_fmt, }; static int atmel_i2s_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index c1dea8d624164..da094762dc994 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -210,7 +210,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, return frame_size; switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BC_FP: if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE) && ssc->clk_from_rk_pin) /* Receiver Frame Synchro (i.e. capture) @@ -220,7 +220,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, mck_div = 3; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK) && !ssc->clk_from_rk_pin) /* Transmit Frame Synchro (i.e. playback) @@ -233,7 +233,7 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, } switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: r.num = ssc_p->mck_rate / mck_div / frame_size; ret = snd_interval_ratnum(i, 1, &r, &num, &den); @@ -243,8 +243,8 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, } break; - case SND_SOC_DAIFMT_CBP_CFC: - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FP: + case SND_SOC_DAIFMT_BC_FC: t.min = 8000; t.max = ssc_p->mck_rate / mck_div / frame_size; t.openmin = t.openmax = 0; @@ -433,8 +433,8 @@ static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p) { switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFC: - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BC_FP: + case SND_SOC_DAIFMT_BP_FP: return 1; } return 0; @@ -444,8 +444,8 @@ static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p) static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p) { switch (ssc_p->daifmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFP: - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FC: + case SND_SOC_DAIFMT_BP_FP: return 1; } return 0; @@ -835,7 +835,7 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { .prepare = atmel_ssc_prepare, .trigger = atmel_ssc_trigger, .hw_params = atmel_ssc_hw_params, - .set_fmt = atmel_ssc_set_dai_fmt, + .set_fmt_new = atmel_ssc_set_dai_fmt, .set_clkdiv = atmel_ssc_set_dai_clkdiv, }; diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c index 6d1227a1d67b5..48d434e0c3318 100644 --- a/sound/soc/atmel/mchp-i2s-mcc.c +++ b/sound/soc/atmel/mchp-i2s-mcc.c @@ -350,7 +350,7 @@ static int mchp_i2s_mcc_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; /* We can't generate only FSYNC */ - if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == SND_SOC_DAIFMT_CBP_CFC) + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == SND_SOC_DAIFMT_BC_FP) return -EINVAL; /* We can only reconfigure the IP when it's stopped */ @@ -547,19 +547,19 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, } switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: /* cpu is BCLK and LRC master */ mra |= MCHP_I2SMCC_MRA_MODE_MASTER; if (dev->sysclk) mra |= MCHP_I2SMCC_MRA_IMCKMODE_GEN; set_divs = 1; break; - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BP_FC: /* cpu is BCLK master */ mrb |= MCHP_I2SMCC_MRB_CLKSEL_INT; set_divs = 1; fallthrough; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: /* cpu is slave */ mra |= MCHP_I2SMCC_MRA_MODE_SLAVE; if (dev->sysclk) @@ -877,7 +877,7 @@ static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = { .trigger = mchp_i2s_mcc_trigger, .hw_params = mchp_i2s_mcc_hw_params, .hw_free = mchp_i2s_mcc_hw_free, - .set_fmt = mchp_i2s_mcc_set_dai_fmt, + .set_fmt_new = mchp_i2s_mcc_set_dai_fmt, .set_tdm_slot = mchp_i2s_mcc_set_dai_tdm_slot, }; diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index a3856c73e2214..b3f04fa2f6089 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -492,8 +492,8 @@ static int mchp_pdmc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int fmt_format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; /* IP needs to be bitclock master */ - if (fmt_master != SND_SOC_DAIFMT_CBS_CFS && - fmt_master != SND_SOC_DAIFMT_CBS_CFM) + if (fmt_master != SND_SOC_DAIFMT_BP_FP && + fmt_master != SND_SOC_DAIFMT_BP_FC) return -EINVAL; /* IP supports only PDM interface */ @@ -708,7 +708,7 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = { - .set_fmt = mchp_pdmc_set_fmt, + .set_fmt_new = mchp_pdmc_set_fmt, .startup = mchp_pdmc_startup, .shutdown = mchp_pdmc_shutdown, .hw_params = mchp_pdmc_hw_params, -- GitLab From fee11f70849b21a244e6e27d281f3858b671bfea Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:26 +0100 Subject: [PATCH 087/942] ASoC: au1x: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/au1x/i2sc.c | 4 ++-- sound/soc/au1x/psc-i2s.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 740d4e052e4df..72f16b7fda3e9 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -121,7 +121,7 @@ static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) /* I2S controller only supports provider */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: /* CODEC consumer */ + case SND_SOC_DAIFMT_BP_FP: /* CODEC consumer */ break; default: goto out; @@ -206,7 +206,7 @@ static const struct snd_soc_dai_ops au1xi2s_dai_ops = { .startup = au1xi2s_startup, .trigger = au1xi2s_trigger, .hw_params = au1xi2s_hw_params, - .set_fmt = au1xi2s_set_fmt, + .set_fmt_new = au1xi2s_set_fmt, }; static struct snd_soc_dai_driver au1xi2s_dai_driver = { diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index b2b8896bb593c..d82c1353f2f09 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -91,10 +91,10 @@ static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, } switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: /* CODEC provider */ + case SND_SOC_DAIFMT_BC_FC: /* CODEC provider */ ct |= PSC_I2SCFG_MS; /* PSC I2S consumer mode */ break; - case SND_SOC_DAIFMT_CBC_CFC: /* CODEC consumer */ + case SND_SOC_DAIFMT_BP_FP: /* CODEC consumer */ ct &= ~PSC_I2SCFG_MS; /* PSC I2S provider mode */ break; default: @@ -266,7 +266,7 @@ static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { .startup = au1xpsc_i2s_startup, .trigger = au1xpsc_i2s_trigger, .hw_params = au1xpsc_i2s_hw_params, - .set_fmt = au1xpsc_i2s_set_fmt, + .set_fmt_new = au1xpsc_i2s_set_fmt, }; static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { -- GitLab From 04ea2404468b7885c560c3673f6f2fd368f305a2 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:27 +0100 Subject: [PATCH 088/942] ASoC: bcm: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/bcm/bcm2835-i2s.c | 22 +++++++++++----------- sound/soc/bcm/cygnus-ssp.c | 6 +++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index e3fc4bee8cfdc..aa7d8e081f89a 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -133,8 +133,8 @@ static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) return; switch (provider) { - case SND_SOC_DAIFMT_CBC_CFC: - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BP_FC: clk_prepare_enable(dev->clk); dev->clk_prepared = true; break; @@ -385,12 +385,12 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* Check if CPU is bit clock provider */ switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BP_FC: bit_clock_provider = true; break; - case SND_SOC_DAIFMT_CBP_CFC: - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FP: + case SND_SOC_DAIFMT_BC_FC: bit_clock_provider = false; break; default: @@ -399,12 +399,12 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, /* Check if CPU is frame sync provider */ switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BC_FP: frame_sync_provider = true; break; - case SND_SOC_DAIFMT_CBC_CFP: - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BP_FC: + case SND_SOC_DAIFMT_BC_FC: frame_sync_provider = false; break; default: @@ -743,7 +743,7 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { .prepare = bcm2835_i2s_prepare, .trigger = bcm2835_i2s_trigger, .hw_params = bcm2835_i2s_hw_params, - .set_fmt = bcm2835_i2s_set_dai_fmt, + .set_fmt_new = bcm2835_i2s_set_dai_fmt, .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio, .set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot, }; diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c index 9698f4531c90f..257f3657bcd6e 100644 --- a/sound/soc/bcm/cygnus-ssp.c +++ b/sound/soc/bcm/cygnus-ssp.c @@ -849,11 +849,11 @@ static int cygnus_ssp_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) ssp_newcfg = 0; switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: ssp_newcfg |= BIT(I2S_OUT_CFGX_SLAVE_MODE); aio->is_slave = 1; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: ssp_newcfg &= ~BIT(I2S_OUT_CFGX_SLAVE_MODE); aio->is_slave = 0; break; @@ -1148,7 +1148,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .shutdown = cygnus_ssp_shutdown, .trigger = cygnus_ssp_trigger, .hw_params = cygnus_ssp_hw_params, - .set_fmt = cygnus_ssp_set_fmt, + .set_fmt_new = cygnus_ssp_set_fmt, .set_sysclk = cygnus_ssp_set_sysclk, .set_tdm_slot = cygnus_set_dai_tdm_slot, }; -- GitLab From 5d6124e58d56818249a6266f56d9c3739e72e1bd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:28 +0100 Subject: [PATCH 089/942] ASoC: ep93xx: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-i2s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 2c8cd843d049c..2c8b1c76b834c 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -246,12 +246,12 @@ static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, } switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: /* CPU is provider */ clk_cfg |= EP93XX_I2S_CLKCFG_MASTER; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: /* Codec is provider */ clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER; break; @@ -398,7 +398,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { .shutdown = ep93xx_i2s_shutdown, .hw_params = ep93xx_i2s_hw_params, .set_sysclk = ep93xx_i2s_set_sysclk, - .set_fmt = ep93xx_i2s_set_dai_fmt, + .set_fmt_new = ep93xx_i2s_set_dai_fmt, }; #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) -- GitLab From ca0444f1f7b228ae3b8d1a5c0f0d1b4463171f98 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:29 +0100 Subject: [PATCH 090/942] ASoC: dwc: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/dwc/dwc-i2s.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 1edac3e10f345..d3778d2d739d8 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -357,20 +357,20 @@ static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) int ret = 0; switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: if (dev->capability & DW_I2S_SLAVE) ret = 0; else ret = -EINVAL; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: if (dev->capability & DW_I2S_MASTER) ret = 0; else ret = -EINVAL; break; - case SND_SOC_DAIFMT_CBP_CFC: - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BC_FP: + case SND_SOC_DAIFMT_BP_FC: ret = -EINVAL; break; default: @@ -387,7 +387,7 @@ static const struct snd_soc_dai_ops dw_i2s_dai_ops = { .hw_params = dw_i2s_hw_params, .prepare = dw_i2s_prepare, .trigger = dw_i2s_trigger, - .set_fmt = dw_i2s_set_fmt, + .set_fmt_new = dw_i2s_set_fmt, }; #ifdef CONFIG_PM -- GitLab From 3b14c15a333b8225ea38479e13c0366539d3374a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:30 +0100 Subject: [PATCH 091/942] ASoC: fsl: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_audmix.c | 6 +++--- sound/soc/fsl/fsl_esai.c | 10 +++++----- sound/soc/fsl/fsl_mqs.c | 4 ++-- sound/soc/fsl/fsl_sai.c | 10 +++++----- sound/soc/fsl/fsl_ssi.c | 24 ++++++++++++------------ sound/soc/fsl/imx-audmix.c | 4 ++-- sound/soc/fsl/imx-card.c | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c index 6dbb8c99f6268..c580dcb9a4cfe 100644 --- a/sound/soc/fsl/fsl_audmix.c +++ b/sound/soc/fsl/fsl_audmix.c @@ -259,8 +259,8 @@ static int fsl_audmix_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* For playback the AUDMIX is consumer, and for record is provider */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BP_FP: break; default: return -EINVAL; @@ -317,7 +317,7 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd, } static const struct snd_soc_dai_ops fsl_audmix_dai_ops = { - .set_fmt = fsl_audmix_dai_set_fmt, + .set_fmt_new = fsl_audmix_dai_set_fmt, .trigger = fsl_audmix_dai_trigger, }; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 1a2bdf8e76f00..572bdaee73eb6 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -480,16 +480,16 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* DAI clock provider masks */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: esai_priv->consumer_mode = true; break; - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BP_FC: xccr |= ESAI_xCCR_xCKD; break; - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BC_FP: xccr |= ESAI_xCCR_xFSD; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD; break; default: @@ -790,7 +790,7 @@ static const struct snd_soc_dai_ops fsl_esai_dai_ops = { .trigger = fsl_esai_trigger, .hw_params = fsl_esai_hw_params, .set_sysclk = fsl_esai_set_dai_sysclk, - .set_fmt = fsl_esai_set_dai_fmt, + .set_fmt_new = fsl_esai_set_dai_fmt, .set_tdm_slot = fsl_esai_set_dai_tdm_slot, }; diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index ceaecbe3a25e4..371d441b1dbef 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -103,7 +103,7 @@ static int fsl_mqs_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: break; default: return -EINVAL; @@ -152,7 +152,7 @@ static const struct snd_soc_dai_ops fsl_mqs_dai_ops = { .startup = fsl_mqs_startup, .shutdown = fsl_mqs_shutdown, .hw_params = fsl_mqs_hw_params, - .set_fmt = fsl_mqs_set_dai_fmt, + .set_fmt_new = fsl_mqs_set_dai_fmt, }; static struct snd_soc_dai_driver fsl_mqs_dai = { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index fa950dde53109..3edd302eb5c22 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -292,19 +292,19 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, /* DAI clock provider masks */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; val_cr4 |= FSL_SAI_CR4_FSD_MSTR; sai->is_consumer_mode = false; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: sai->is_consumer_mode = true; break; - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BP_FC: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; sai->is_consumer_mode = false; break; - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BC_FP: val_cr4 |= FSL_SAI_CR4_FSD_MSTR; sai->is_consumer_mode = true; break; @@ -704,7 +704,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, .set_sysclk = fsl_sai_set_dai_sysclk, - .set_fmt = fsl_sai_set_dai_fmt, + .set_fmt_new = fsl_sai_set_dai_fmt, .set_tdm_slot = fsl_sai_set_dai_tdm_slot, .hw_params = fsl_sai_hw_params, .hw_free = fsl_sai_hw_free, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 84cb36d9dfea9..32e4cf37c2029 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -93,7 +93,7 @@ */ #define FSLSSI_AC97_DAIFMT \ (SND_SOC_DAIFMT_AC97 | \ - SND_SOC_DAIFMT_CBM_CFS | \ + SND_SOC_DAIFMT_BC_FP | \ SND_SOC_DAIFMT_NB_NF) #define FSLSSI_SIER_DBG_RX_FLAGS \ @@ -358,13 +358,13 @@ static bool fsl_ssi_is_ac97(struct fsl_ssi *ssi) static bool fsl_ssi_is_i2s_clock_provider(struct fsl_ssi *ssi) { return (ssi->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == - SND_SOC_DAIFMT_CBC_CFC; + SND_SOC_DAIFMT_BP_FP; } -static bool fsl_ssi_is_i2s_cbp_cfc(struct fsl_ssi *ssi) +static bool fsl_ssi_is_i2s_bc_fp(struct fsl_ssi *ssi) { return (ssi->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == - SND_SOC_DAIFMT_CBP_CFC; + SND_SOC_DAIFMT_BC_FP; } /** @@ -847,7 +847,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, u8 i2s_net = ssi->i2s_net; /* Normal + Network mode to send 16-bit data in 32-bit frames */ - if (fsl_ssi_is_i2s_cbp_cfc(ssi) && sample_size == 16) + if (fsl_ssi_is_i2s_bc_fp(ssi) && sample_size == 16) i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; /* Use Normal mode to send mono data at 1st slot of 2 slots */ @@ -920,17 +920,17 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: if (IS_ERR(ssi->baudclk)) { dev_err(ssi->dev, "missing baudclk for master mode\n"); return -EINVAL; } fallthrough; - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BC_FP: ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE; break; default: @@ -992,15 +992,15 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi *ssi, unsigned int fmt) /* DAI clock provider masks */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: /* Output bit and frame sync clocks */ strcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR; scr |= SSI_SCR_SYS_CLK_EN; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: /* Input bit or frame sync clocks */ break; - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BC_FP: /* Input bit clock but output frame sync clock */ strcr |= SSI_STCR_TFDIR; break; @@ -1156,7 +1156,7 @@ static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { .shutdown = fsl_ssi_shutdown, .hw_params = fsl_ssi_hw_params, .hw_free = fsl_ssi_hw_free, - .set_fmt = fsl_ssi_set_dai_fmt, + .set_fmt_new = fsl_ssi_set_dai_fmt, .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, .trigger = fsl_ssi_trigger, }; diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c index 502fe1b522aba..1292a845c4244 100644 --- a/sound/soc/fsl/imx-audmix.c +++ b/sound/soc/fsl/imx-audmix.c @@ -81,7 +81,7 @@ static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream, int ret, dir; /* For playback the AUDMIX is consumer, and for record is provider */ - fmt |= tx ? SND_SOC_DAIFMT_CBC_CFC : SND_SOC_DAIFMT_CBP_CFP; + fmt |= tx ? SND_SOC_DAIFMT_BP_FP : SND_SOC_DAIFMT_BC_FC; dir = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN; /* set DAI configuration */ @@ -122,7 +122,7 @@ static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream, return 0; /* For playback the AUDMIX is consumer */ - fmt |= SND_SOC_DAIFMT_CBP_CFP; + fmt |= SND_SOC_DAIFMT_BC_FC; /* set AUDMIX DAI configuration */ ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index 6f8efd838fcc8..1797d777b1b87 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -317,7 +317,7 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream, } } - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + ret = snd_soc_dai_set_fmt(cpu_dai, snd_soc_daifmt_clock_provider_flipped(fmt)); if (ret && ret != -ENOTSUPP) { dev_err(dev, "failed to set cpu dai fmt: %d\n", ret); return ret; -- GitLab From 0f362524dd3face4865077a4f7e7e640a95702aa Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:31 +0100 Subject: [PATCH 092/942] ASoC: hisilicon: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/hisilicon/hi6210-i2s.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index a297d4af5099f..51f98ae651a6b 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c @@ -227,9 +227,9 @@ static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) * We don't actually set the hardware until the hw_params * call, but we need to validate the user input here. */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BP_FP: break; default: return -EINVAL; @@ -245,8 +245,8 @@ static int hi6210_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) } i2s->format = fmt; - i2s->master = (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) == - SND_SOC_DAIFMT_CBS_CFS; + i2s->master = (i2s->format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == + SND_SOC_DAIFMT_BP_FP; return 0; } @@ -375,21 +375,21 @@ static int hi6210_i2s_hw_params(struct snd_pcm_substream *substream, hi6210_write_reg(i2s, HII2S_MUX_TOP_MODULE_CFG, val); - switch (i2s->format & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (i2s->format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: i2s->master = false; val = hi6210_read_reg(i2s, HII2S_I2S_CFG); val |= HII2S_I2S_CFG__S2_MST_SLV; hi6210_write_reg(i2s, HII2S_I2S_CFG, val); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: i2s->master = true; val = hi6210_read_reg(i2s, HII2S_I2S_CFG); val &= ~HII2S_I2S_CFG__S2_MST_SLV; hi6210_write_reg(i2s, HII2S_I2S_CFG, val); break; default: - WARN_ONCE(1, "Invalid i2s->fmt MASTER_MASK. This shouldn't happen\n"); + WARN_ONCE(1, "Invalid i2s->fmt CLOCK_PROVIDER_MASK. This shouldn't happen\n"); return -EINVAL; } @@ -513,7 +513,7 @@ static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = { .trigger = hi6210_i2s_trigger, .hw_params = hi6210_i2s_hw_params, - .set_fmt = hi6210_i2s_set_fmt, + .set_fmt_new = hi6210_i2s_set_fmt, .startup = hi6210_i2s_startup, .shutdown = hi6210_i2s_shutdown, }; -- GitLab From ed2b384082a678a0c4c8c56deff9e5f46d5e3fca Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:32 +0100 Subject: [PATCH 093/942] ASoC: img: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/img/img-i2s-in.c | 6 +++--- sound/soc/img/img-i2s-out.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 09d23b11621c4..79e733bc0ae69 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -333,8 +333,8 @@ static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: break; default: return -EINVAL; @@ -373,7 +373,7 @@ static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops img_i2s_in_dai_ops = { .trigger = img_i2s_in_trigger, .hw_params = img_i2s_in_hw_params, - .set_fmt = img_i2s_in_set_fmt + .set_fmt_new = img_i2s_in_set_fmt }; static int img_i2s_in_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 28f48ca1508a6..d92539603d6cb 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -302,10 +302,10 @@ static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) if (force_clk_active) control_set |= IMG_I2S_OUT_CTL_CLK_EN_MASK; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: control_set |= IMG_I2S_OUT_CTL_MASTER_MASK; break; default: @@ -381,7 +381,7 @@ static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops img_i2s_out_dai_ops = { .trigger = img_i2s_out_trigger, .hw_params = img_i2s_out_hw_params, - .set_fmt = img_i2s_out_set_fmt + .set_fmt_new = img_i2s_out_set_fmt }; static int img_i2s_out_dai_probe(struct snd_soc_dai *dai) -- GitLab From add9ee8c64c617f561a309cdda50104e9e2c12f6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:33 +0100 Subject: [PATCH 094/942] ASoC: Intel: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-12-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst-atom-controls.c | 4 ++-- sound/soc/intel/atom/sst-mfld-platform-pcm.c | 2 +- sound/soc/intel/boards/bytcht_cx2072x.c | 2 +- sound/soc/intel/boards/bytcht_da7213.c | 2 +- sound/soc/intel/boards/bytcht_es8316.c | 2 +- sound/soc/intel/boards/bytcht_nocodec.c | 2 +- sound/soc/intel/boards/bytcr_rt5640.c | 2 +- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- sound/soc/intel/boards/bytcr_wm5102.c | 2 +- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 3 +-- sound/soc/intel/boards/cht_bsw_rt5645.c | 6 +++--- sound/soc/intel/boards/cht_bsw_rt5672.c | 2 +- sound/soc/intel/keembay/kmb_platform.c | 6 +++--- 13 files changed, 18 insertions(+), 19 deletions(-) diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 335c327329945..406455ddcb96e 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c @@ -831,9 +831,9 @@ static int sst_get_ssp_mode(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(dai->dev, "Enter:%s, format=%x\n", __func__, format); switch (format) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: return SSP_MODE_PROVIDER; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: return SSP_MODE_CONSUMER; default: dev_err(dai->dev, "Invalid ssp protocol: %d\n", format); diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index a56dd48c045f3..339d9440c1501 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -473,7 +473,7 @@ static const struct snd_soc_dai_ops sst_compr_dai_ops = { static const struct snd_soc_dai_ops sst_be_dai_ops = { .startup = sst_enable_ssp, .hw_params = sst_be_hw_params, - .set_fmt = sst_set_format, + .set_fmt_new = sst_set_format, .set_tdm_slot = sst_platform_set_ssp_slot, .shutdown = sst_disable_ssp, }; diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index 0eed68a11f7e1..ae899866863e5 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -126,7 +126,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index eb19bf16afad4..a0c8f1d3f8cec 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c @@ -81,7 +81,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index a08507783e44a..6432b83f616f3 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -265,7 +265,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC + SND_SOC_DAIFMT_BP_FP ); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c index 115c2bcaabd4f..7fc03f2efd356 100644 --- a/sound/soc/intel/boards/bytcht_nocodec.c +++ b/sound/soc/intel/boards/bytcht_nocodec.c @@ -61,7 +61,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index ed9fa17287227..ce1f3eb5f83b6 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1413,7 +1413,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index d467fcaa48eaa..f72a597114bf5 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -706,7 +706,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC + SND_SOC_DAIFMT_BP_FP ); if (ret < 0) { diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 00384c6fbcaa5..fe79f6e5f2bb8 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -265,7 +265,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret) { dev_err(rtd->dev, "Error setting format to I2S: %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index a5160f27adea9..64eb73525ee37 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -264,8 +264,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBC_CFC; + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP; ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); if (ret < 0) { diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 45c301ea5e003..56ee53e7ed3f5 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -362,7 +362,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC + SND_SOC_DAIFMT_BP_FP ); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); @@ -372,7 +372,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC + SND_SOC_DAIFMT_BC_FC ); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); @@ -396,7 +396,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BC_FC); if (ret < 0) { dev_err(rtd->dev, "can't set format to TDM %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index c80324f34b1b2..ca47f6476b077 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -300,7 +300,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) { dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); return ret; diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index a6fb74ba1c424..a65f03884d9a5 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -497,11 +497,11 @@ static int kmb_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) int ret; switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: kmb_i2s->clock_provider = false; ret = 0; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: writel(CLOCK_PROVIDER_MODE, kmb_i2s->pss_base + I2S_GEN_CFG_0); ret = clk_prepare_enable(kmb_i2s->clk_i2s); @@ -736,7 +736,7 @@ static const struct snd_soc_dai_ops kmb_dai_ops = { .hw_params = kmb_dai_hw_params, .hw_free = kmb_dai_hw_free, .prepare = kmb_dai_prepare, - .set_fmt = kmb_set_dai_fmt, + .set_fmt_new = kmb_set_dai_fmt, }; static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = { -- GitLab From cbb3a19f090d5a41b822caf9ff2058e1c6bc7ea3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:34 +0100 Subject: [PATCH 095/942] ASoC: js4740-i2s: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/jz4740/jz4740-i2s.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 7ad5d9a924d80..2c9dee2417783 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -206,18 +206,18 @@ static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: conf |= JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER; format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: conf |= JZ_AIC_CONF_SYNC_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_BP_FC: conf |= JZ_AIC_CONF_BIT_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: break; default: return -EINVAL; @@ -433,7 +433,7 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = { .shutdown = jz4740_i2s_shutdown, .trigger = jz4740_i2s_trigger, .hw_params = jz4740_i2s_hw_params, - .set_fmt = jz4740_i2s_set_fmt, + .set_fmt_new = jz4740_i2s_set_fmt, .set_sysclk = jz4740_i2s_set_sysclk, }; -- GitLab From 3af99430f8d948a41556156155b0295dec274d41 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:35 +0100 Subject: [PATCH 096/942] ASoC: mediatek: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-14-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-dai-etdm.c | 10 +++++----- sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c index c02c10da36004..5f7c9516dfa18 100644 --- a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c +++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c @@ -2172,11 +2172,11 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: etdm_data->slave_mode = true; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: etdm_data->slave_mode = false; break; default: @@ -2346,7 +2346,7 @@ static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { .hw_params = mtk_dai_etdm_hw_params, .trigger = mtk_dai_etdm_trigger, .set_sysclk = mtk_dai_etdm_set_sysclk, - .set_fmt = mtk_dai_etdm_set_fmt, + .set_fmt_new = mtk_dai_etdm_set_fmt, .set_tdm_slot = mtk_dai_etdm_set_tdm_slot, }; @@ -2356,7 +2356,7 @@ static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = { .hw_params = mtk_dai_hdmitx_dptx_hw_params, .trigger = mtk_dai_hdmitx_dptx_trigger, .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk, - .set_fmt = mtk_dai_etdm_set_fmt, + .set_fmt_new = mtk_dai_etdm_set_fmt, }; /* dai driver */ diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c index 12644ded83d59..37a8968ac21dc 100644 --- a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c +++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c @@ -266,11 +266,11 @@ static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: pcmif_priv->slave_mode = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: pcmif_priv->slave_mode = 0; break; default: @@ -282,7 +282,7 @@ static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { .prepare = mtk_dai_pcm_prepare, - .set_fmt = mtk_dai_pcm_set_fmt, + .set_fmt_new = mtk_dai_pcm_set_fmt, }; /* dai driver */ -- GitLab From f60442bf6eab47aa4ab127aab88afdcc29a09a73 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:36 +0100 Subject: [PATCH 097/942] ASoC: meson: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-15-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/meson/aiu-encoder-i2s.c | 4 ++-- sound/soc/meson/axg-tdm-interface.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encoder-i2s.c index 67729de41a73e..0ab991230deec 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -229,7 +229,7 @@ static int aiu_encoder_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int skew; /* Only CPU Master / Codec Slave supported ATM */ - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) return -EINVAL; if (inv == SND_SOC_DAIFMT_NB_IF || @@ -323,7 +323,7 @@ static void aiu_encoder_i2s_shutdown(struct snd_pcm_substream *substream, const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = { .hw_params = aiu_encoder_i2s_hw_params, .hw_free = aiu_encoder_i2s_hw_free, - .set_fmt = aiu_encoder_i2s_set_fmt, + .set_fmt_new = aiu_encoder_i2s_set_fmt, .set_sysclk = aiu_encoder_i2s_set_sysclk, .startup = aiu_encoder_i2s_startup, .shutdown = aiu_encoder_i2s_shutdown, diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index e076ced300257..ffdb12d0e01e3 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -119,19 +119,19 @@ static int axg_tdm_iface_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: if (!iface->mclk) { dev_err(dai->dev, "cpu clock master: mclk missing\n"); return -ENODEV; } break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BP_FC: + case SND_SOC_DAIFMT_BC_FP: dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n"); fallthrough; default: @@ -326,8 +326,8 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - if ((iface->fmt & SND_SOC_DAIFMT_MASTER_MASK) == - SND_SOC_DAIFMT_CBS_CFS) { + if ((iface->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == + SND_SOC_DAIFMT_BP_FP) { ret = axg_tdm_iface_set_sclk(dai, params); if (ret) return ret; @@ -394,7 +394,7 @@ static int axg_tdm_iface_probe_dai(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops axg_tdm_iface_ops = { .set_sysclk = axg_tdm_iface_set_sysclk, - .set_fmt = axg_tdm_iface_set_fmt, + .set_fmt_new = axg_tdm_iface_set_fmt, .startup = axg_tdm_iface_startup, .hw_params = axg_tdm_iface_hw_params, .prepare = axg_tdm_iface_prepare, -- GitLab From f3c0064f1f8e358799c70c7905a09d15c5ec5e5a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:37 +0100 Subject: [PATCH 098/942] ASoC: mxs-saif: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-16-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 7afe1a1acc568..38de46ba1583a 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -358,8 +358,8 @@ static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) * Saif internally could be slave when working on EXTMASTER mode. * We just hide this to machine driver. */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: if (saif->id == saif->master_id) scr &= ~BM_SAIF_CTRL_SLAVE_MODE; else @@ -642,7 +642,7 @@ static const struct snd_soc_dai_ops mxs_saif_dai_ops = { .prepare = mxs_saif_prepare, .hw_params = mxs_saif_hw_params, .set_sysclk = mxs_saif_set_dai_sysclk, - .set_fmt = mxs_saif_set_dai_fmt, + .set_fmt_new = mxs_saif_set_dai_fmt, }; static struct snd_soc_dai_driver mxs_saif_dai = { -- GitLab From 84c5b47c8ce4d5059d5e7539d3b44922cc0390e9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:38 +0100 Subject: [PATCH 099/942] ASoC: pxa: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-17-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/pxa/magician.c | 8 ++++---- sound/soc/pxa/mmp-sspa.c | 8 ++++---- sound/soc/pxa/pxa-ssp.c | 24 ++++++++++++------------ sound/soc/pxa/pxa2xx-i2s.c | 8 ++++---- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 9433cc9277552..b791a2ba5ce51 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c @@ -91,13 +91,13 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BC_FC); if (ret < 0) return ret; /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS); + SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_BP_FP); if (ret < 0) return ret; @@ -129,14 +129,14 @@ static int magician_capture_hw_params(struct snd_pcm_substream *substream, /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); + SND_SOC_DAIFMT_BC_FC); if (ret < 0) return ret; /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); + SND_SOC_DAIFMT_BP_FP); if (ret < 0) return ret; diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 7e39210a0b384..b746e52aaf85f 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -171,11 +171,11 @@ static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai, sspa->sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH; sspa->ctrl = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: sspa->sp |= SSPA_SP_MSL; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: break; default: return -EINVAL; @@ -346,7 +346,7 @@ static const struct snd_soc_dai_ops mmp_sspa_dai_ops = { .hw_params = mmp_sspa_hw_params, .set_sysclk = mmp_sspa_set_dai_sysclk, .set_pll = mmp_sspa_set_dai_pll, - .set_fmt = mmp_sspa_set_dai_fmt, + .set_fmt_new = mmp_sspa_set_dai_fmt, }; static struct snd_soc_dai_driver mmp_sspa_dai = { diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 7f13a35e9cc14..52124be1778eb 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -372,10 +372,10 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, { struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBM_CFS: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BC_FP: + case SND_SOC_DAIFMT_BP_FP: break; default: return -EINVAL; @@ -432,14 +432,14 @@ static int pxa_ssp_configure_dai_fmt(struct ssp_priv *priv) sscr1 |= SSCR1_RxTresh(8) | SSCR1_TxTresh(7); - switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (priv->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR | SSCR1_SCFR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: sscr1 |= SSCR1_SCLKDIR | SSCR1_SCFR; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: break; default: return -EINVAL; @@ -484,9 +484,9 @@ static int pxa_ssp_configure_dai_fmt(struct ssp_priv *priv) pxa_ssp_write_reg(ssp, SSCR1, sscr1); pxa_ssp_write_reg(ssp, SSPSP, sspsp); - switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBM_CFS: + switch (priv->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BC_FP: scfr = pxa_ssp_read_reg(ssp, SSCR1) | SSCR1_SCFR; pxa_ssp_write_reg(ssp, SSCR1, scfr); @@ -824,7 +824,7 @@ static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { .trigger = pxa_ssp_trigger, .hw_params = pxa_ssp_hw_params, .set_sysclk = pxa_ssp_set_dai_sysclk, - .set_fmt = pxa_ssp_set_dai_fmt, + .set_fmt_new = pxa_ssp_set_dai_fmt, .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, .set_tristate = pxa_ssp_set_dai_tristate, }; diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 746e6ec9198b0..9f12fc3615b65 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -129,11 +129,11 @@ static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, break; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: pxa_i2s.master = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: pxa_i2s.master = 0; break; default: @@ -333,7 +333,7 @@ static const struct snd_soc_dai_ops pxa_i2s_dai_ops = { .shutdown = pxa2xx_i2s_shutdown, .trigger = pxa2xx_i2s_trigger, .hw_params = pxa2xx_i2s_hw_params, - .set_fmt = pxa2xx_i2s_set_dai_fmt, + .set_fmt_new = pxa2xx_i2s_set_dai_fmt, .set_sysclk = pxa2xx_i2s_set_dai_sysclk, }; -- GitLab From 1148e16b335f341f36475b646c692b4a71a1855e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:39 +0100 Subject: [PATCH 100/942] ASoC: qcom: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-18-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/qcom/apq8016_sbc.c | 2 +- sound/soc/qcom/qdsp6/audioreach.c | 4 ++-- sound/soc/qcom/qdsp6/q6afe-dai.c | 2 +- sound/soc/qcom/qdsp6/q6afe.c | 6 +++--- sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 2 +- sound/soc/qcom/sc7180.c | 2 +- sound/soc/qcom/sdm845.c | 6 +++--- sound/soc/qcom/sm8250.c | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index b0a4f7ca27515..e54b8961112f3 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -172,7 +172,7 @@ static int msm8916_qdsp6_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP); return apq8016_dai_init(rtd, qdsp6_dai_get_lpass_id(cpu_dai)); } diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c index 98c0efa1d0fec..01dac32c50fda 100644 --- a/sound/soc/qcom/qdsp6/audioreach.c +++ b/sound/soc/qcom/qdsp6/audioreach.c @@ -732,10 +732,10 @@ static int audioreach_i2s_set_media_format(struct q6apm_graph *graph, intf_cfg->cfg.sd_line_idx = module->sd_line_idx; switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: intf_cfg->cfg.ws_src = CONFIG_I2S_WS_SRC_INTERNAL; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: /* CPU is slave */ intf_cfg->cfg.ws_src = CONFIG_I2S_WS_SRC_EXTERNAL; break; diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c index 8bb7452b8f18c..8f8794cffc1c5 100644 --- a/sound/soc/qcom/qdsp6/q6afe-dai.c +++ b/sound/soc/qcom/qdsp6/q6afe-dai.c @@ -648,7 +648,7 @@ static const struct snd_soc_dai_ops q6hdmi_ops = { static const struct snd_soc_dai_ops q6i2s_ops = { .prepare = q6afe_dai_prepare, .hw_params = q6i2s_hw_params, - .set_fmt = q6i2s_set_fmt, + .set_fmt_new = q6i2s_set_fmt, .shutdown = q6afe_dai_shutdown, .set_sysclk = q6afe_mi2s_set_sysclk, }; diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 625724852a7fb..919e326b9462b 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -1328,11 +1328,11 @@ int q6afe_i2s_port_prepare(struct q6afe_port *port, struct q6afe_i2s_cfg *cfg) pcfg->i2s_cfg.bit_width = cfg->bit_width; pcfg->i2s_cfg.data_format = AFE_LINEAR_PCM_DATA; - switch (cfg->fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (cfg->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_INTERNAL; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* CPU is slave */ pcfg->i2s_cfg.ws_src = AFE_PORT_CONFIG_I2S_WS_SRC_EXTERNAL; break; diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c index ce9e5646d8f3a..82ee52051f831 100644 --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c @@ -207,7 +207,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = { .shutdown = q6apm_lpass_dai_shutdown, .set_channel_map = q6dma_set_channel_map, .hw_params = q6dma_hw_params, - .set_fmt = q6i2s_set_fmt, + .set_fmt_new = q6i2s_set_fmt, }; static const struct snd_soc_component_driver q6apm_lpass_dai_component = { diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c index efccb5c0b3e00..f5f7c64b23a27 100644 --- a/sound/soc/qcom/sc7180.c +++ b/sound/soc/qcom/sc7180.c @@ -155,7 +155,7 @@ static int sc7180_snd_startup(struct snd_pcm_substream *substream) } snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_CBS_CFS | + SND_SOC_DAIFMT_BC_FC | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S); diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c index 61fda790f3756..d8d35563af00f 100644 --- a/sound/soc/qcom/sdm845.c +++ b/sound/soc/qcom/sdm845.c @@ -316,8 +316,8 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd) static int sdm845_snd_startup(struct snd_pcm_substream *substream) { - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; + unsigned int fmt = SND_SOC_DAIFMT_BP_FP; + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); @@ -356,7 +356,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream) snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); - snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBS_CFS); + snd_soc_dai_set_fmt(cpu_dai, fmt); break; diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 6e1184c8b672a..ce4a5713386a3 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -96,8 +96,8 @@ static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int sm8250_snd_startup(struct snd_pcm_substream *substream) { - unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; - unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; + unsigned int fmt = SND_SOC_DAIFMT_BP_FP; + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); -- GitLab From 27646d265da1745b2d1d10fec18465631cb1135f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:40 +0100 Subject: [PATCH 101/942] ASoC: rockchip: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Tested-by: Nicolas Frattaroli Link: https://lore.kernel.org/r/20220519154318.2153729-19-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 8 ++++---- sound/soc/rockchip/rockchip_i2s_tdm.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 4ce5d25793875..0a66c7df323dc 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -199,13 +199,13 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, pm_runtime_get_sync(cpu_dai->dev); mask = I2S_CKR_MSS_MASK; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* Set source clock in Master mode */ val = I2S_CKR_MSS_MASTER; i2s->is_master_mode = true; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: val = I2S_CKR_MSS_SLAVE; i2s->is_master_mode = false; break; @@ -486,7 +486,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = { .hw_params = rockchip_i2s_hw_params, .set_bclk_ratio = rockchip_i2s_set_bclk_ratio, .set_sysclk = rockchip_i2s_set_sysclk, - .set_fmt = rockchip_i2s_set_fmt, + .set_fmt_new = rockchip_i2s_set_fmt, .trigger = rockchip_i2s_trigger, }; diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 98700e75b82a1..c90afccdae362 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -411,12 +411,12 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai, } mask = I2S_CKR_MSS_MASK; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: val = I2S_CKR_MSS_MASTER; i2s_tdm->is_master_mode = true; break; - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: val = I2S_CKR_MSS_SLAVE; i2s_tdm->is_master_mode = false; break; @@ -1113,7 +1113,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { .hw_params = rockchip_i2s_tdm_hw_params, .set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio, .set_sysclk = rockchip_i2s_tdm_set_sysclk, - .set_fmt = rockchip_i2s_tdm_set_fmt, + .set_fmt_new = rockchip_i2s_tdm_set_fmt, .set_tdm_slot = rockchip_dai_tdm_slot, .trigger = rockchip_i2s_tdm_trigger, }; -- GitLab From 0b491c7c1b2555ef08285fd49a8567f2f9f34ff8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:41 +0100 Subject: [PATCH 102/942] ASoC: samsung: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-20-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 8 ++++---- sound/soc/samsung/pcm.c | 6 +++--- sound/soc/samsung/s3c-i2s-v2.c | 8 ++++---- sound/soc/samsung/s3c24xx-i2s.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 70c827162be4d..9ed275ebd744e 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -671,11 +671,11 @@ static int i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: tmp |= mod_slave; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: /* * Set default source clock in Master mode, only when the * CLK_I2S_RCLK_SRC clock is not exposed so we ensure any @@ -1107,7 +1107,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { .trigger = i2s_trigger, .hw_params = i2s_hw_params, - .set_fmt = i2s_set_fmt, + .set_fmt_new = i2s_set_fmt, .set_clkdiv = i2s_set_clkdiv, .set_sysclk = i2s_set_sysclk, .startup = i2s_startup, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 4c4dfde0568fe..818172d8832d2 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -340,8 +340,8 @@ static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, goto exit; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* Nothing to do, Master by default */ break; default: @@ -437,7 +437,7 @@ static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_clkdiv = s3c_pcm_set_clkdiv, .trigger = s3c_pcm_trigger, .hw_params = s3c_pcm_hw_params, - .set_fmt = s3c_pcm_set_fmt, + .set_fmt_new = s3c_pcm_set_fmt, }; static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index de66cc422e6ea..9c8a0697849d7 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -252,12 +252,12 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod = readl(i2s->regs + S3C2412_IISMOD); pr_debug("hw_params r: IISMOD: %x \n", iismod); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: i2s->master = 0; iismod |= S3C2412_IISMOD_SLAVE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: i2s->master = 1; iismod &= ~S3C2412_IISMOD_SLAVE; break; @@ -666,7 +666,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id, ops->trigger = s3c2412_i2s_trigger; if (!ops->hw_params) ops->hw_params = s3c_i2sv2_hw_params; - ops->set_fmt = s3c2412_i2s_set_fmt; + ops->set_fmt_new = s3c2412_i2s_set_fmt; ops->set_clkdiv = s3c2412_i2s_set_clkdiv; ops->set_sysclk = s3c_i2sv2_set_sysclk; diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 0f46304eaa4f3..6226b3b585e54 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -169,11 +169,11 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); pr_debug("hw_params r: IISMOD: %x \n", iismod); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_CFC: iismod |= S3C2410_IISMOD_SLAVE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: iismod &= ~S3C2410_IISMOD_SLAVE; break; default: @@ -394,7 +394,7 @@ static int s3c24xx_i2s_resume(struct snd_soc_component *component) static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { .trigger = s3c24xx_i2s_trigger, .hw_params = s3c24xx_i2s_hw_params, - .set_fmt = s3c24xx_i2s_set_fmt, + .set_fmt_new = s3c24xx_i2s_set_fmt, .set_clkdiv = s3c24xx_i2s_set_clkdiv, .set_sysclk = s3c24xx_i2s_set_sysclk, }; -- GitLab From 2d4dd776e902546389f2d7808ece7fd815aa829c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:42 +0100 Subject: [PATCH 103/942] ASoC: sh: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/20220519154318.2153729-21-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 8 ++++---- sound/soc/sh/rcar/core.c | 6 +++--- sound/soc/sh/rz-ssi.c | 4 ++-- sound/soc/sh/ssi.c | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index e9a1eb6bdf66a..4058d60b7e931 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1646,10 +1646,10 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) int ret; /* set clock master audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: fsi->clk_master = 1; /* cpu is master */ break; default: @@ -1724,7 +1724,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = { .startup = fsi_dai_startup, .shutdown = fsi_dai_shutdown, .trigger = fsi_dai_trigger, - .set_fmt = fsi_dai_set_fmt, + .set_fmt_new = fsi_dai_set_fmt, .hw_params = fsi_dai_hw_params, .auto_selectable_formats = &fsi_dai_formats, .num_auto_selectable_formats = 1, diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index eb762ab94d3ed..0ac15b74c58a8 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -756,10 +756,10 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* set clock master for audio interface */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BC_FC: rdai->clk_master = 0; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: rdai->clk_master = 1; /* cpu is master */ break; default: @@ -1068,7 +1068,7 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .startup = rsnd_soc_dai_startup, .shutdown = rsnd_soc_dai_shutdown, .trigger = rsnd_soc_dai_trigger, - .set_fmt = rsnd_soc_dai_set_fmt, + .set_fmt_new = rsnd_soc_dai_set_fmt, .set_tdm_slot = rsnd_soc_set_dai_tdm_slot, .prepare = rsnd_soc_dai_prepare, .auto_selectable_formats = rsnd_soc_dai_formats, diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index e392de7a262ef..0557d22a089f3 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -767,7 +767,7 @@ static int rz_ssi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BP_FP: break; default: dev_err(ssi->dev, "Codec should be clk and frame consumer\n"); @@ -840,7 +840,7 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rz_ssi_dai_ops = { .trigger = rz_ssi_dai_trigger, - .set_fmt = rz_ssi_dai_set_fmt, + .set_fmt_new = rz_ssi_dai_set_fmt, .hw_params = rz_ssi_dai_hw_params, }; diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index 15b01bcefca5c..95571cbeae296 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -291,16 +291,16 @@ static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_BP_FC: ssicr |= CR_SCK_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: ssicr |= CR_SWS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; break; default: @@ -336,7 +336,7 @@ static const struct snd_soc_dai_ops ssi_dai_ops = { .hw_params = ssi_hw_params, .set_sysclk = ssi_set_sysclk, .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, + .set_fmt_new = ssi_set_fmt, }; static struct snd_soc_dai_driver sh4_ssi_dai[] = { -- GitLab From 0092dac91ec1c404787841bdd9ecbf3404d1a41c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:43 +0100 Subject: [PATCH 104/942] ASoC: stm: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-22-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 10 +++++----- sound/soc/stm/stm32_sai_sub.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index ac5dff4d1677a..30c04f96ef1d6 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -593,16 +593,16 @@ static int stm32_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) } /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: i2s->ms_flg = I2S_MS_SLAVE; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: i2s->ms_flg = I2S_MS_MASTER; break; default: dev_err(cpu_dai->dev, "Unsupported mode %#x\n", - fmt & SND_SOC_DAIFMT_MASTER_MASK); + fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); return -EINVAL; } @@ -954,7 +954,7 @@ static const struct regmap_config stm32_h7_i2s_regmap_conf = { static const struct snd_soc_dai_ops stm32_i2s_pcm_dai_ops = { .set_sysclk = stm32_i2s_set_sysclk, - .set_fmt = stm32_i2s_set_dai_fmt, + .set_fmt_new = stm32_i2s_set_dai_fmt, .startup = stm32_i2s_startup, .hw_params = stm32_i2s_hw_params, .trigger = stm32_i2s_trigger, diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index dd636af81c9bd..9f169b93fa740 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -719,18 +719,18 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr); /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: /* codec is master */ cr1 |= SAI_XCR1_SLAVE; sai->master = false; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: sai->master = true; break; default: dev_err(cpu_dai->dev, "Unsupported mode %#x\n", - fmt & SND_SOC_DAIFMT_MASTER_MASK); + fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); return -EINVAL; } @@ -1225,7 +1225,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = { .set_sysclk = stm32_sai_set_sysclk, - .set_fmt = stm32_sai_set_dai_fmt, + .set_fmt_new = stm32_sai_set_dai_fmt, .set_tdm_slot = stm32_sai_set_dai_tdm_slot, .startup = stm32_sai_startup, .hw_params = stm32_sai_hw_params, -- GitLab From 7cc3965fde74c9c725ed01de4ac35bc7d562d16a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:44 +0100 Subject: [PATCH 105/942] ASoC: sunxi: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-23-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 20 ++++++++++---------- sound/soc/sunxi/sun8i-codec.c | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 7047f71629ab3..872838d3e0a94 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -702,13 +702,13 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, SUN4I_I2S_FMT0_FMT_MASK, val); /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* BCLK and LRCLK master */ val = SUN4I_I2S_CTRL_MODE_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* BCLK and LRCLK slave */ val = SUN4I_I2S_CTRL_MODE_SLAVE; break; @@ -802,13 +802,13 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, SUN8I_I2S_TX_CHAN_OFFSET(offset)); /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* BCLK and LRCLK master */ val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* BCLK and LRCLK slave */ val = 0; break; @@ -909,13 +909,13 @@ static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset)); /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* BCLK and LRCLK master */ val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* BCLK and LRCLK slave */ val = 0; break; @@ -1081,7 +1081,7 @@ static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { .hw_params = sun4i_i2s_hw_params, - .set_fmt = sun4i_i2s_set_fmt, + .set_fmt_new = sun4i_i2s_set_fmt, .set_sysclk = sun4i_i2s_set_sysclk, .set_tdm_slot = sun4i_i2s_set_tdm_slot, .trigger = sun4i_i2s_trigger, diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 0bea2162f68d9..6e9ef948d6621 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -286,11 +286,11 @@ static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) u32 dsp_format, format, invert, value; /* clock masters */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* Codec slave, DAI master */ value = 0x1; break; - case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */ + case SND_SOC_DAIFMT_BC_FC: /* Codec Master, DAI slave */ value = 0x0; break; default: @@ -630,7 +630,7 @@ static int sun8i_codec_hw_free(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops sun8i_codec_dai_ops = { - .set_fmt = sun8i_codec_set_fmt, + .set_fmt_new = sun8i_codec_set_fmt, .set_tdm_slot = sun8i_codec_set_tdm_slot, .startup = sun8i_codec_startup, .hw_params = sun8i_codec_hw_params, -- GitLab From d92ad6633fa77f9496840b77c8effeaa13ac78dc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:45 +0100 Subject: [PATCH 106/942] ASoC: tegra: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-24-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 8 ++++---- sound/soc/tegra/tegra210_i2s.c | 8 ++++---- sound/soc/tegra/tegra30_i2s.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 27365a877e471..9abb0e3536d82 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -95,11 +95,11 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai, } mask |= TEGRA20_I2S_CTRL_MASTER_ENABLE; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: val |= TEGRA20_I2S_CTRL_MASTER_ENABLE; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: break; default: return -EINVAL; @@ -311,7 +311,7 @@ static int tegra20_i2s_startup(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = { - .set_fmt = tegra20_i2s_set_fmt, + .set_fmt_new = tegra20_i2s_set_fmt, .hw_params = tegra20_i2s_hw_params, .trigger = tegra20_i2s_trigger, .startup = tegra20_i2s_startup, diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 9552bbb939dd1..a304948ee3935 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -214,11 +214,11 @@ static int tegra210_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int mask, val; mask = I2S_CTRL_MASTER_EN_MASK; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: val = 0; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: val = I2S_CTRL_MASTER_EN; break; default: @@ -678,7 +678,7 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops tegra210_i2s_dai_ops = { - .set_fmt = tegra210_i2s_set_fmt, + .set_fmt_new = tegra210_i2s_set_fmt, .hw_params = tegra210_i2s_hw_params, .set_bclk_ratio = tegra210_i2s_set_dai_bclk_ratio, .set_tdm_slot = tegra210_i2s_set_tdm_slot, diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 084a533bf4f2c..a4ea5221de6b4 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -87,11 +87,11 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, } mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: val |= TEGRA30_I2S_CTRL_MASTER_ENABLE; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: break; default: return -EINVAL; @@ -304,7 +304,7 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) } static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = { - .set_fmt = tegra30_i2s_set_fmt, + .set_fmt_new = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, .set_tdm_slot = tegra30_i2s_set_tdm, -- GitLab From d444c8d246a62392c0d249b1030c3ca271d47649 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:46 +0100 Subject: [PATCH 107/942] ASoC: test-component: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/20220519154318.2153729-25-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/generic/test-component.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c index 5da4725d9e16c..3a992a6eba9bb 100644 --- a/sound/soc/generic/test-component.c +++ b/sound/soc/generic/test-component.c @@ -66,7 +66,7 @@ static int test_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; unsigned int clock = fmt & SND_SOC_DAIFMT_CLOCK_MASK; unsigned int inv = fmt & SND_SOC_DAIFMT_INV_MASK; - unsigned int master = fmt & SND_SOC_DAIFMT_MASTER_MASK; + unsigned int master = fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; char *str; dev_info(dai->dev, "name : %s", dai->name); @@ -105,16 +105,16 @@ static int test_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) str = "unknown"; switch (master) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BP_FP: str = "clk provider, frame provider"; break; - case SND_SOC_DAIFMT_CBC_CFP: + case SND_SOC_DAIFMT_BC_FP: str = "clk consumer, frame provider"; break; - case SND_SOC_DAIFMT_CBP_CFC: + case SND_SOC_DAIFMT_BP_FC: str = "clk provider, frame consumer"; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BC_FC: str = "clk consumer, frame consumer"; break; } @@ -192,10 +192,10 @@ static int test_dai_bespoke_trigger(struct snd_pcm_substream *substream, static u64 test_dai_formats = /* * Select below from Sound Card, not auto - * SND_SOC_POSSIBLE_DAIFMT_CBP_CFP - * SND_SOC_POSSIBLE_DAIFMT_CBC_CFP - * SND_SOC_POSSIBLE_DAIFMT_CBP_CFC - * SND_SOC_POSSIBLE_DAIFMT_CBC_CFC + * SND_SOC_POSSIBLE_DAIFMT_BP_FP + * SND_SOC_POSSIBLE_DAIFMT_BC_FP + * SND_SOC_POSSIBLE_DAIFMT_BP_FC + * SND_SOC_POSSIBLE_DAIFMT_BC_FC */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | @@ -210,7 +210,7 @@ static u64 test_dai_formats = SND_SOC_POSSIBLE_DAIFMT_IB_IF; static const struct snd_soc_dai_ops test_ops = { - .set_fmt = test_dai_set_fmt, + .set_fmt_new = test_dai_set_fmt, .startup = test_dai_startup, .shutdown = test_dai_shutdown, .auto_selectable_formats = &test_dai_formats, @@ -221,7 +221,7 @@ static const struct snd_soc_dai_ops test_verbose_ops = { .set_sysclk = test_dai_set_sysclk, .set_pll = test_dai_set_pll, .set_clkdiv = test_dai_set_clkdiv, - .set_fmt = test_dai_set_fmt, + .set_fmt_new = test_dai_set_fmt, .mute_stream = test_dai_mute_stream, .startup = test_dai_startup, .shutdown = test_dai_shutdown, -- GitLab From 563ff63dc9fbb8ef4b8f145a53c84a5489bbd789 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:47 +0100 Subject: [PATCH 108/942] ASoC: ti: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update these CPU side drivers to use the new direct callback. Signed-off-by: Charles Keepax Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220519154318.2153729-26-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-i2s.c | 34 +++++++++++++++++----------------- sound/soc/ti/davinci-mcasp.c | 12 ++++++------ sound/soc/ti/omap-mcbsp.c | 14 +++++++------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c index 0363a088d2e00..c7368d5296688 100644 --- a/sound/soc/ti/davinci-i2s.c +++ b/sound/soc/ti/davinci-i2s.c @@ -230,15 +230,15 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, dev->fmt = fmt; /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* cpu is master */ pcr = DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: pcr = DAVINCI_MCBSP_PCR_FSRM | DAVINCI_MCBSP_PCR_FSXM; /* * Selection of the clock input pin that is the @@ -260,7 +260,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, } break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* codec is master */ pcr = 0; break; @@ -395,12 +395,12 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr); } - master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; + master = dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; fmt = params_format(params); mcbsp_word_length = asp_word_length[fmt]; switch (master) { - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: freq = clk_get_rate(dev->clk); srgr = DAVINCI_MCBSP_SRGR_FSGM | DAVINCI_MCBSP_SRGR_CLKSM; @@ -426,7 +426,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, clk_div &= 0xFF; srgr |= clk_div; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: srgr = DAVINCI_MCBSP_SRGR_FSGM; clk_div = dev->clk_div - 1; srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1); @@ -434,7 +434,7 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, clk_div &= 0xFF; srgr |= clk_div; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* Clock and frame sync given from external sources */ i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); srgr = DAVINCI_MCBSP_SRGR_FSGM; @@ -473,15 +473,15 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, fmt = double_fmt[fmt]; } switch (master) { - case SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BP_FC: rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(0); xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(0); rcr |= DAVINCI_MCBSP_RCR_RPHASE; xcr |= DAVINCI_MCBSP_XCR_XPHASE; break; - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BC_FP: rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1); xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1); break; @@ -492,13 +492,13 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, mcbsp_word_length = asp_word_length[fmt]; switch (master) { - case SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BP_FC: rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(0); xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(0); break; - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BC_FP: rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1); xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1); break; @@ -606,7 +606,7 @@ static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { .prepare = davinci_i2s_prepare, .trigger = davinci_i2s_trigger, .hw_params = davinci_i2s_hw_params, - .set_fmt = davinci_i2s_set_dai_fmt, + .set_fmt_new = davinci_i2s_set_dai_fmt, .set_clkdiv = davinci_i2s_dai_set_clkdiv, }; diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 377be2e2b6ee7..961bac6963652 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -492,8 +492,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay), FSRDLY(3)); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* codec is clock and frame slave */ mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); @@ -510,7 +510,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp->bclk_master = 1; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_BP_FC: /* codec is clock slave and frame master */ mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); @@ -527,7 +527,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp->bclk_master = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: /* codec is clock master and frame slave */ mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); @@ -544,7 +544,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp->bclk_master = 0; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* codec is clock and frame master */ mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); @@ -1620,7 +1620,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .trigger = davinci_mcasp_trigger, .delay = davinci_mcasp_delay, .hw_params = davinci_mcasp_hw_params, - .set_fmt = davinci_mcasp_set_dai_fmt, + .set_fmt_new = davinci_mcasp_set_dai_fmt, .set_clkdiv = davinci_mcasp_set_clkdiv, .set_sysclk = davinci_mcasp_set_sysclk, .set_tdm_slot = davinci_mcasp_set_tdm_slot, diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c index 4479d74f0a458..5bfb56d4ff844 100644 --- a/sound/soc/ti/omap-mcbsp.c +++ b/sound/soc/ti/omap-mcbsp.c @@ -1036,8 +1036,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, /* In McBSP master modes, FRAME (i.e. sample rate) is generated * by _counting_ BCLKs. Calculate frame size in BCLKs */ - master = mcbsp->fmt & SND_SOC_DAIFMT_MASTER_MASK; - if (master == SND_SOC_DAIFMT_CBS_CFS) { + master = mcbsp->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; + if (master == SND_SOC_DAIFMT_BP_FP) { div = mcbsp->clk_div ? mcbsp->clk_div : 1; framesize = (mcbsp->in_freq / div) / params_rate(params); @@ -1136,20 +1136,20 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: /* McBSP master. Set FS and bit clocks as outputs */ regs->pcr0 |= FSXM | FSRM | CLKXM | CLKRM; /* Sample rate generator drives the FS */ regs->srgr2 |= FSGM; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_BC_FP: /* McBSP slave. FS clock as output */ regs->srgr2 |= FSGM; regs->pcr0 |= FSXM | FSRM; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_BC_FC: /* McBSP slave */ break; default: @@ -1271,7 +1271,7 @@ static const struct snd_soc_dai_ops mcbsp_dai_ops = { .trigger = omap_mcbsp_dai_trigger, .delay = omap_mcbsp_dai_delay, .hw_params = omap_mcbsp_dai_hw_params, - .set_fmt = omap_mcbsp_dai_set_dai_fmt, + .set_fmt_new = omap_mcbsp_dai_set_dai_fmt, .set_clkdiv = omap_mcbsp_dai_set_clkdiv, .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, }; -- GitLab From ce3467c78478e33927aea9043bf20f46fa4d5688 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:48 +0100 Subject: [PATCH 109/942] ASoC: ux500: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-27-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_msp_dai.c | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 21052378a32eb..cd6c4bdf5041d 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -191,8 +191,8 @@ static int setup_clocking(struct snd_soc_dai *dai, return -EINVAL; } - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BC_FC: dev_dbg(dai->dev, "%s: Codec is master.\n", __func__); msp_config->iodelay = 0x20; @@ -204,7 +204,7 @@ static int setup_clocking(struct snd_soc_dai *dai, break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_BP_FP: dev_dbg(dai->dev, "%s: Codec is slave.\n", __func__); msp_config->tx_clk_sel = TX_CLK_SEL_SRG; @@ -328,15 +328,15 @@ static int setup_msp_config(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "%s: rate: %u, channels: %d.\n", __func__, runtime->rate, runtime->channels); switch (fmt & - (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: + (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) { + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BP_FP: dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__); msp_config->default_protdesc = 1; msp_config->protocol = MSP_I2S_PROTOCOL; break; - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BC_FC: dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__); msp_config->data_size = MSP_DATA_BITS_16; @@ -348,10 +348,10 @@ static int setup_msp_config(struct snd_pcm_substream *substream, break; - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BC_FC: dev_dbg(dai->dev, "%s: PCM format.\n", __func__); msp_config->data_size = MSP_DATA_BITS_16; @@ -477,7 +477,7 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream, } /* Set OPP-level */ - if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) && + if ((drvdata->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) && (drvdata->msp->f_bitclk > 19200000)) { /* If the bit-clock is higher than 19.2MHz, Vape should be * run in 100% OPP. Only when bit-clock is used (MSP master) @@ -544,13 +544,13 @@ static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai, dev_dbg(dai->dev, "%s: MSP %d: Enter.\n", __func__, dai->id); switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | - SND_SOC_DAIFMT_MASTER_MASK)) { - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: + SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) { + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_BC_FC: break; default: @@ -707,7 +707,7 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops ux500_msp_dai_ops[] = { { .set_sysclk = ux500_msp_dai_set_dai_sysclk, - .set_fmt = ux500_msp_dai_set_dai_fmt, + .set_fmt_new = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, .shutdown = ux500_msp_dai_shutdown, -- GitLab From e945206a0a448ac81dde0609578508368946f7a6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:49 +0100 Subject: [PATCH 110/942] ASoC: xtensa: Update to use set_fmt_new callback As part of updating the core to directly tell drivers if they are clock provider or consumer update this CPU side driver to use the new direct callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-28-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/xtensa/xtfpga-i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c index aeb4b2c4d1d35..72935f491901f 100644 --- a/sound/soc/xtensa/xtfpga-i2s.c +++ b/sound/soc/xtensa/xtfpga-i2s.c @@ -339,7 +339,7 @@ static int xtfpga_i2s_set_fmt(struct snd_soc_dai *cpu_dai, { if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) return -EINVAL; - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) return -EINVAL; if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) return -EINVAL; @@ -487,7 +487,7 @@ static const struct snd_soc_component_driver xtfpga_i2s_component = { static const struct snd_soc_dai_ops xtfpga_i2s_dai_ops = { .startup = xtfpga_i2s_startup, .hw_params = xtfpga_i2s_hw_params, - .set_fmt = xtfpga_i2s_set_fmt, + .set_fmt_new = xtfpga_i2s_set_fmt, }; static struct snd_soc_dai_driver xtfpga_i2s_dai[] = { -- GitLab From 6c076273a326cc5b5162451aacf7b7744bb03c66 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:50 +0100 Subject: [PATCH 111/942] ASoC: core: Always send the CPU DAI a direct clock specifier All CPU drivers are now updated to accept a direct indication of whether they are clock provider or consumer, rather than being told if the CODEC is clock provider. As such update the core to always pass this direct indication rather than only if the new set_fmt_new callback is defined. Note this makes no difference to the CODEC side of the DAI link as it was already being directly told if it was clock provider under the old system. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-29-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 90f4265bea501..227540851dedf 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1214,7 +1214,6 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, { struct snd_soc_dai *cpu_dai; struct snd_soc_dai *codec_dai; - unsigned int inv_dai_fmt; unsigned int i; int ret; @@ -1227,19 +1226,11 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, return ret; } - /* - * Flip the polarity for the "CPU" end of a CODEC<->CODEC link - */ - inv_dai_fmt = snd_soc_daifmt_clock_provider_flipped(dai_fmt); + /* Flip the polarity for the "CPU" end of link */ + dai_fmt = snd_soc_daifmt_clock_provider_flipped(dai_fmt); for_each_rtd_cpu_dais(rtd, i, cpu_dai) { - unsigned int fmt = dai_fmt; - - if (cpu_dai->driver->ops->set_fmt_new || - snd_soc_component_is_codec(cpu_dai->component)) - fmt = inv_dai_fmt; - - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt); if (ret != 0 && ret != -ENOTSUPP) return ret; } -- GitLab From 346f47e784cd48b456f267a66e0daf1ef10d21b3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:51 +0100 Subject: [PATCH 112/942] ASoC: amd: vangogh: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-30-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/amd/vangogh/acp5x-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c index 40fbd0bc77fde..72c8c68e59336 100644 --- a/sound/soc/amd/vangogh/acp5x-i2s.c +++ b/sound/soc/amd/vangogh/acp5x-i2s.c @@ -339,7 +339,7 @@ static int acp5x_i2s_trigger(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops acp5x_i2s_dai_ops = { .hw_params = acp5x_i2s_hwparams, .trigger = acp5x_i2s_trigger, - .set_fmt_new = acp5x_i2s_set_fmt, + .set_fmt = acp5x_i2s_set_fmt, .set_tdm_slot = acp5x_i2s_set_tdm_slot, }; -- GitLab From a839a53b9dc70f94032a671ee019599884612d4a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:52 +0100 Subject: [PATCH 113/942] ASoC: atmel: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-31-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-i2s.c | 2 +- sound/soc/atmel/atmel_ssc_dai.c | 2 +- sound/soc/atmel/mchp-i2s-mcc.c | 2 +- sound/soc/atmel/mchp-pdmc.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c index c5ce695da5866..ba56d6ac7e571 100644 --- a/sound/soc/atmel/atmel-i2s.c +++ b/sound/soc/atmel/atmel-i2s.c @@ -533,7 +533,7 @@ static const struct snd_soc_dai_ops atmel_i2s_dai_ops = { .prepare = atmel_i2s_prepare, .trigger = atmel_i2s_trigger, .hw_params = atmel_i2s_hw_params, - .set_fmt_new = atmel_i2s_set_dai_fmt, + .set_fmt = atmel_i2s_set_dai_fmt, }; static int atmel_i2s_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index da094762dc994..c92905e343e7e 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -835,7 +835,7 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { .prepare = atmel_ssc_prepare, .trigger = atmel_ssc_trigger, .hw_params = atmel_ssc_hw_params, - .set_fmt_new = atmel_ssc_set_dai_fmt, + .set_fmt = atmel_ssc_set_dai_fmt, .set_clkdiv = atmel_ssc_set_dai_clkdiv, }; diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c index 48d434e0c3318..269eab56b6dd9 100644 --- a/sound/soc/atmel/mchp-i2s-mcc.c +++ b/sound/soc/atmel/mchp-i2s-mcc.c @@ -877,7 +877,7 @@ static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = { .trigger = mchp_i2s_mcc_trigger, .hw_params = mchp_i2s_mcc_hw_params, .hw_free = mchp_i2s_mcc_hw_free, - .set_fmt_new = mchp_i2s_mcc_set_dai_fmt, + .set_fmt = mchp_i2s_mcc_set_dai_fmt, .set_tdm_slot = mchp_i2s_mcc_set_dai_tdm_slot, }; diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index b3f04fa2f6089..b9f6370594482 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -708,7 +708,7 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = { - .set_fmt_new = mchp_pdmc_set_fmt, + .set_fmt = mchp_pdmc_set_fmt, .startup = mchp_pdmc_startup, .shutdown = mchp_pdmc_shutdown, .hw_params = mchp_pdmc_hw_params, -- GitLab From 2c73f5fd20a845fcb48173578b7c83dbcbacdeda Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:53 +0100 Subject: [PATCH 114/942] ASoC: au1x: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-32-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/au1x/i2sc.c | 2 +- sound/soc/au1x/psc-i2s.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 72f16b7fda3e9..45bb7851e75d7 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -206,7 +206,7 @@ static const struct snd_soc_dai_ops au1xi2s_dai_ops = { .startup = au1xi2s_startup, .trigger = au1xi2s_trigger, .hw_params = au1xi2s_hw_params, - .set_fmt_new = au1xi2s_set_fmt, + .set_fmt = au1xi2s_set_fmt, }; static struct snd_soc_dai_driver au1xi2s_dai_driver = { diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index d82c1353f2f09..530a072d74274 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -266,7 +266,7 @@ static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { .startup = au1xpsc_i2s_startup, .trigger = au1xpsc_i2s_trigger, .hw_params = au1xpsc_i2s_hw_params, - .set_fmt_new = au1xpsc_i2s_set_fmt, + .set_fmt = au1xpsc_i2s_set_fmt, }; static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { -- GitLab From 1a267dd98c246237be00587b6e71f969bf75f10d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:54 +0100 Subject: [PATCH 115/942] ASoC: bcm: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-33-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/bcm/bcm2835-i2s.c | 2 +- sound/soc/bcm/cygnus-ssp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index aa7d8e081f89a..e39c8d9f40995 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -743,7 +743,7 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { .prepare = bcm2835_i2s_prepare, .trigger = bcm2835_i2s_trigger, .hw_params = bcm2835_i2s_hw_params, - .set_fmt_new = bcm2835_i2s_set_dai_fmt, + .set_fmt = bcm2835_i2s_set_dai_fmt, .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio, .set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot, }; diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c index 257f3657bcd6e..4bfa2d715ff4d 100644 --- a/sound/soc/bcm/cygnus-ssp.c +++ b/sound/soc/bcm/cygnus-ssp.c @@ -1148,7 +1148,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .shutdown = cygnus_ssp_shutdown, .trigger = cygnus_ssp_trigger, .hw_params = cygnus_ssp_hw_params, - .set_fmt_new = cygnus_ssp_set_fmt, + .set_fmt = cygnus_ssp_set_fmt, .set_sysclk = cygnus_ssp_set_sysclk, .set_tdm_slot = cygnus_set_dai_tdm_slot, }; -- GitLab From 324a4db8de05290237793dc3d7da887846ae90c1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:55 +0100 Subject: [PATCH 116/942] ASoC: ep93xx: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-34-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 2c8b1c76b834c..47959794353a7 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -398,7 +398,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { .shutdown = ep93xx_i2s_shutdown, .hw_params = ep93xx_i2s_hw_params, .set_sysclk = ep93xx_i2s_set_sysclk, - .set_fmt_new = ep93xx_i2s_set_dai_fmt, + .set_fmt = ep93xx_i2s_set_dai_fmt, }; #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) -- GitLab From 765fb623a2cd925c550370f73efe2137c52a1b25 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:56 +0100 Subject: [PATCH 117/942] ASoC: dwc: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-35-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/dwc/dwc-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index d3778d2d739d8..e794e020052ef 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -387,7 +387,7 @@ static const struct snd_soc_dai_ops dw_i2s_dai_ops = { .hw_params = dw_i2s_hw_params, .prepare = dw_i2s_prepare, .trigger = dw_i2s_trigger, - .set_fmt_new = dw_i2s_set_fmt, + .set_fmt = dw_i2s_set_fmt, }; #ifdef CONFIG_PM -- GitLab From 00778276cf4c611882219ab7aba9664c48981f1a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:57 +0100 Subject: [PATCH 118/942] ASoC: fsl: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-36-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_audmix.c | 2 +- sound/soc/fsl/fsl_esai.c | 2 +- sound/soc/fsl/fsl_mqs.c | 2 +- sound/soc/fsl/fsl_sai.c | 2 +- sound/soc/fsl/fsl_ssi.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c index c580dcb9a4cfe..43857b7a81c94 100644 --- a/sound/soc/fsl/fsl_audmix.c +++ b/sound/soc/fsl/fsl_audmix.c @@ -317,7 +317,7 @@ static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd, } static const struct snd_soc_dai_ops fsl_audmix_dai_ops = { - .set_fmt_new = fsl_audmix_dai_set_fmt, + .set_fmt = fsl_audmix_dai_set_fmt, .trigger = fsl_audmix_dai_trigger, }; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 572bdaee73eb6..75f7807df29af 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -790,7 +790,7 @@ static const struct snd_soc_dai_ops fsl_esai_dai_ops = { .trigger = fsl_esai_trigger, .hw_params = fsl_esai_hw_params, .set_sysclk = fsl_esai_set_dai_sysclk, - .set_fmt_new = fsl_esai_set_dai_fmt, + .set_fmt = fsl_esai_set_dai_fmt, .set_tdm_slot = fsl_esai_set_dai_tdm_slot, }; diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index 371d441b1dbef..fc539a1392509 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -152,7 +152,7 @@ static const struct snd_soc_dai_ops fsl_mqs_dai_ops = { .startup = fsl_mqs_startup, .shutdown = fsl_mqs_shutdown, .hw_params = fsl_mqs_hw_params, - .set_fmt_new = fsl_mqs_set_dai_fmt, + .set_fmt = fsl_mqs_set_dai_fmt, }; static struct snd_soc_dai_driver fsl_mqs_dai = { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 3edd302eb5c22..f67d8527876e7 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -704,7 +704,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, .set_sysclk = fsl_sai_set_dai_sysclk, - .set_fmt_new = fsl_sai_set_dai_fmt, + .set_fmt = fsl_sai_set_dai_fmt, .set_tdm_slot = fsl_sai_set_dai_tdm_slot, .hw_params = fsl_sai_hw_params, .hw_free = fsl_sai_hw_free, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 32e4cf37c2029..7dd0c48cd9ae4 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1156,7 +1156,7 @@ static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { .shutdown = fsl_ssi_shutdown, .hw_params = fsl_ssi_hw_params, .hw_free = fsl_ssi_hw_free, - .set_fmt_new = fsl_ssi_set_dai_fmt, + .set_fmt = fsl_ssi_set_dai_fmt, .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, .trigger = fsl_ssi_trigger, }; -- GitLab From b9a7972818b84a15d46505df7808fd86c3fba5bb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:58 +0100 Subject: [PATCH 119/942] ASoC: hisilicon: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-37-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/hisilicon/hi6210-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index 51f98ae651a6b..689ae13f34f5b 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c @@ -513,7 +513,7 @@ static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = { .trigger = hi6210_i2s_trigger, .hw_params = hi6210_i2s_hw_params, - .set_fmt_new = hi6210_i2s_set_fmt, + .set_fmt = hi6210_i2s_set_fmt, .startup = hi6210_i2s_startup, .shutdown = hi6210_i2s_shutdown, }; -- GitLab From 1830a30ec4cf1642a429e80dbbeb86aa7825c71a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:42:59 +0100 Subject: [PATCH 120/942] ASoC: img: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-38-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/img/img-i2s-in.c | 2 +- sound/soc/img/img-i2s-out.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 79e733bc0ae69..97cab6d95b169 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -373,7 +373,7 @@ static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops img_i2s_in_dai_ops = { .trigger = img_i2s_in_trigger, .hw_params = img_i2s_in_hw_params, - .set_fmt_new = img_i2s_in_set_fmt + .set_fmt = img_i2s_in_set_fmt }; static int img_i2s_in_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index d92539603d6cb..9ec6fc528e2b4 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -381,7 +381,7 @@ static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops img_i2s_out_dai_ops = { .trigger = img_i2s_out_trigger, .hw_params = img_i2s_out_hw_params, - .set_fmt_new = img_i2s_out_set_fmt + .set_fmt = img_i2s_out_set_fmt }; static int img_i2s_out_dai_probe(struct snd_soc_dai *dai) -- GitLab From c14a6ce9848571cf67faff206b02e212bec82761 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:00 +0100 Subject: [PATCH 121/942] ASoC: Intel: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-39-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst-mfld-platform-pcm.c | 2 +- sound/soc/intel/keembay/kmb_platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 339d9440c1501..a56dd48c045f3 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -473,7 +473,7 @@ static const struct snd_soc_dai_ops sst_compr_dai_ops = { static const struct snd_soc_dai_ops sst_be_dai_ops = { .startup = sst_enable_ssp, .hw_params = sst_be_hw_params, - .set_fmt_new = sst_set_format, + .set_fmt = sst_set_format, .set_tdm_slot = sst_platform_set_ssp_slot, .shutdown = sst_disable_ssp, }; diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index a65f03884d9a5..d10881fedc8bb 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -736,7 +736,7 @@ static const struct snd_soc_dai_ops kmb_dai_ops = { .hw_params = kmb_dai_hw_params, .hw_free = kmb_dai_hw_free, .prepare = kmb_dai_prepare, - .set_fmt_new = kmb_set_dai_fmt, + .set_fmt = kmb_set_dai_fmt, }; static struct snd_soc_dai_driver intel_kmb_hdmi_dai[] = { -- GitLab From 1724cc38e7685ad8b01413acd70a4a731fc105ae Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:01 +0100 Subject: [PATCH 122/942] ASoC: jz4740-i2s: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-40-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/jz4740/jz4740-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 2c9dee2417783..446c5e0615649 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -433,7 +433,7 @@ static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = { .shutdown = jz4740_i2s_shutdown, .trigger = jz4740_i2s_trigger, .hw_params = jz4740_i2s_hw_params, - .set_fmt_new = jz4740_i2s_set_fmt, + .set_fmt = jz4740_i2s_set_fmt, .set_sysclk = jz4740_i2s_set_sysclk, }; -- GitLab From 00ca2d152ef0fa9f4beb2a590e176499440de8fe Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:02 +0100 Subject: [PATCH 123/942] ASoC: mediatek: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-41-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-dai-etdm.c | 4 ++-- sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c index 5f7c9516dfa18..c2e268054773d 100644 --- a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c +++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c @@ -2346,7 +2346,7 @@ static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { .hw_params = mtk_dai_etdm_hw_params, .trigger = mtk_dai_etdm_trigger, .set_sysclk = mtk_dai_etdm_set_sysclk, - .set_fmt_new = mtk_dai_etdm_set_fmt, + .set_fmt = mtk_dai_etdm_set_fmt, .set_tdm_slot = mtk_dai_etdm_set_tdm_slot, }; @@ -2356,7 +2356,7 @@ static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = { .hw_params = mtk_dai_hdmitx_dptx_hw_params, .trigger = mtk_dai_hdmitx_dptx_trigger, .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk, - .set_fmt_new = mtk_dai_etdm_set_fmt, + .set_fmt = mtk_dai_etdm_set_fmt, }; /* dai driver */ diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c index 37a8968ac21dc..caceb0deb467f 100644 --- a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c +++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c @@ -282,7 +282,7 @@ static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { .prepare = mtk_dai_pcm_prepare, - .set_fmt_new = mtk_dai_pcm_set_fmt, + .set_fmt = mtk_dai_pcm_set_fmt, }; /* dai driver */ -- GitLab From eee6b5b9f3af0e906085022713ef41e56d03eca8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:03 +0100 Subject: [PATCH 124/942] ASoC: meson: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-42-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/meson/aiu-encoder-i2s.c | 2 +- sound/soc/meson/axg-tdm-interface.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encoder-i2s.c index 0ab991230deec..a0dd914c8ed13 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -323,7 +323,7 @@ static void aiu_encoder_i2s_shutdown(struct snd_pcm_substream *substream, const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops = { .hw_params = aiu_encoder_i2s_hw_params, .hw_free = aiu_encoder_i2s_hw_free, - .set_fmt_new = aiu_encoder_i2s_set_fmt, + .set_fmt = aiu_encoder_i2s_set_fmt, .set_sysclk = aiu_encoder_i2s_set_sysclk, .startup = aiu_encoder_i2s_startup, .shutdown = aiu_encoder_i2s_shutdown, diff --git a/sound/soc/meson/axg-tdm-interface.c b/sound/soc/meson/axg-tdm-interface.c index ffdb12d0e01e3..c040c83637e02 100644 --- a/sound/soc/meson/axg-tdm-interface.c +++ b/sound/soc/meson/axg-tdm-interface.c @@ -394,7 +394,7 @@ static int axg_tdm_iface_probe_dai(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops axg_tdm_iface_ops = { .set_sysclk = axg_tdm_iface_set_sysclk, - .set_fmt_new = axg_tdm_iface_set_fmt, + .set_fmt = axg_tdm_iface_set_fmt, .startup = axg_tdm_iface_startup, .hw_params = axg_tdm_iface_hw_params, .prepare = axg_tdm_iface_prepare, -- GitLab From 1a805faeb4915496671cd24bd2a75cc97a85dfc8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:04 +0100 Subject: [PATCH 125/942] ASoC: mxs-saif: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-43-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 38de46ba1583a..467b0f2ce0bb1 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -642,7 +642,7 @@ static const struct snd_soc_dai_ops mxs_saif_dai_ops = { .prepare = mxs_saif_prepare, .hw_params = mxs_saif_hw_params, .set_sysclk = mxs_saif_set_dai_sysclk, - .set_fmt_new = mxs_saif_set_dai_fmt, + .set_fmt = mxs_saif_set_dai_fmt, }; static struct snd_soc_dai_driver mxs_saif_dai = { -- GitLab From 8e2cc2b241bc0bb905231f301e6dfc80dc79f8a8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:05 +0100 Subject: [PATCH 126/942] ASoC: pxa: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-44-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/pxa/mmp-sspa.c | 2 +- sound/soc/pxa/pxa-ssp.c | 2 +- sound/soc/pxa/pxa2xx-i2s.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index b746e52aaf85f..382e9d8608a3f 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -346,7 +346,7 @@ static const struct snd_soc_dai_ops mmp_sspa_dai_ops = { .hw_params = mmp_sspa_hw_params, .set_sysclk = mmp_sspa_set_dai_sysclk, .set_pll = mmp_sspa_set_dai_pll, - .set_fmt_new = mmp_sspa_set_dai_fmt, + .set_fmt = mmp_sspa_set_dai_fmt, }; static struct snd_soc_dai_driver mmp_sspa_dai = { diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 52124be1778eb..0f504a9f4983d 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -824,7 +824,7 @@ static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { .trigger = pxa_ssp_trigger, .hw_params = pxa_ssp_hw_params, .set_sysclk = pxa_ssp_set_dai_sysclk, - .set_fmt_new = pxa_ssp_set_dai_fmt, + .set_fmt = pxa_ssp_set_dai_fmt, .set_tdm_slot = pxa_ssp_set_dai_tdm_slot, .set_tristate = pxa_ssp_set_dai_tristate, }; diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 9f12fc3615b65..ffcf44e4dc8c0 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -333,7 +333,7 @@ static const struct snd_soc_dai_ops pxa_i2s_dai_ops = { .shutdown = pxa2xx_i2s_shutdown, .trigger = pxa2xx_i2s_trigger, .hw_params = pxa2xx_i2s_hw_params, - .set_fmt_new = pxa2xx_i2s_set_dai_fmt, + .set_fmt = pxa2xx_i2s_set_dai_fmt, .set_sysclk = pxa2xx_i2s_set_dai_sysclk, }; -- GitLab From f1bd2fae856384f9377ca3faed0583d929002640 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:06 +0100 Subject: [PATCH 127/942] ASoC: qcom: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-45-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6afe-dai.c | 2 +- sound/soc/qcom/qdsp6/q6apm-lpass-dais.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c index 8f8794cffc1c5..8bb7452b8f18c 100644 --- a/sound/soc/qcom/qdsp6/q6afe-dai.c +++ b/sound/soc/qcom/qdsp6/q6afe-dai.c @@ -648,7 +648,7 @@ static const struct snd_soc_dai_ops q6hdmi_ops = { static const struct snd_soc_dai_ops q6i2s_ops = { .prepare = q6afe_dai_prepare, .hw_params = q6i2s_hw_params, - .set_fmt_new = q6i2s_set_fmt, + .set_fmt = q6i2s_set_fmt, .shutdown = q6afe_dai_shutdown, .set_sysclk = q6afe_mi2s_set_sysclk, }; diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c index 82ee52051f831..ce9e5646d8f3a 100644 --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c @@ -207,7 +207,7 @@ static const struct snd_soc_dai_ops q6i2s_ops = { .shutdown = q6apm_lpass_dai_shutdown, .set_channel_map = q6dma_set_channel_map, .hw_params = q6dma_hw_params, - .set_fmt_new = q6i2s_set_fmt, + .set_fmt = q6i2s_set_fmt, }; static const struct snd_soc_component_driver q6apm_lpass_dai_component = { -- GitLab From 059f16bc0e02164617312435c31dffdc419f113f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:07 +0100 Subject: [PATCH 128/942] ASoC: rockchip: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-46-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 2 +- sound/soc/rockchip/rockchip_i2s_tdm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 0a66c7df323dc..47a3971a9ce14 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -486,7 +486,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = { .hw_params = rockchip_i2s_hw_params, .set_bclk_ratio = rockchip_i2s_set_bclk_ratio, .set_sysclk = rockchip_i2s_set_sysclk, - .set_fmt_new = rockchip_i2s_set_fmt, + .set_fmt = rockchip_i2s_set_fmt, .trigger = rockchip_i2s_trigger, }; diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index c90afccdae362..48b3ecfa58b46 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -1113,7 +1113,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { .hw_params = rockchip_i2s_tdm_hw_params, .set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio, .set_sysclk = rockchip_i2s_tdm_set_sysclk, - .set_fmt_new = rockchip_i2s_tdm_set_fmt, + .set_fmt = rockchip_i2s_tdm_set_fmt, .set_tdm_slot = rockchip_dai_tdm_slot, .trigger = rockchip_i2s_tdm_trigger, }; -- GitLab From b99d00c724bcf395558cb3028e823bd8f554fee6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:08 +0100 Subject: [PATCH 129/942] ASoC: samsung: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220519154318.2153729-47-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 2 +- sound/soc/samsung/pcm.c | 2 +- sound/soc/samsung/s3c-i2s-v2.c | 2 +- sound/soc/samsung/s3c24xx-i2s.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 9ed275ebd744e..fdd9561c6a9f3 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1107,7 +1107,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { .trigger = i2s_trigger, .hw_params = i2s_hw_params, - .set_fmt_new = i2s_set_fmt, + .set_fmt = i2s_set_fmt, .set_clkdiv = i2s_set_clkdiv, .set_sysclk = i2s_set_sysclk, .startup = i2s_startup, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 818172d8832d2..c2eb3534bfccb 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -437,7 +437,7 @@ static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_clkdiv = s3c_pcm_set_clkdiv, .trigger = s3c_pcm_trigger, .hw_params = s3c_pcm_hw_params, - .set_fmt_new = s3c_pcm_set_fmt, + .set_fmt = s3c_pcm_set_fmt, }; static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 9c8a0697849d7..1bec72246ed0c 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -666,7 +666,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id, ops->trigger = s3c2412_i2s_trigger; if (!ops->hw_params) ops->hw_params = s3c_i2sv2_hw_params; - ops->set_fmt_new = s3c2412_i2s_set_fmt; + ops->set_fmt = s3c2412_i2s_set_fmt; ops->set_clkdiv = s3c2412_i2s_set_clkdiv; ops->set_sysclk = s3c_i2sv2_set_sysclk; diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 6226b3b585e54..4082ad7cbcc11 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -394,7 +394,7 @@ static int s3c24xx_i2s_resume(struct snd_soc_component *component) static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { .trigger = s3c24xx_i2s_trigger, .hw_params = s3c24xx_i2s_hw_params, - .set_fmt_new = s3c24xx_i2s_set_fmt, + .set_fmt = s3c24xx_i2s_set_fmt, .set_clkdiv = s3c24xx_i2s_set_clkdiv, .set_sysclk = s3c24xx_i2s_set_sysclk, }; -- GitLab From adced68031f96642272fae4e8c36d45d13797306 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:09 +0100 Subject: [PATCH 130/942] ASoC: sh: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-48-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 2 +- sound/soc/sh/rcar/core.c | 2 +- sound/soc/sh/rz-ssi.c | 2 +- sound/soc/sh/ssi.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 4058d60b7e931..f3edc2e3d9d7c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1724,7 +1724,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = { .startup = fsi_dai_startup, .shutdown = fsi_dai_shutdown, .trigger = fsi_dai_trigger, - .set_fmt_new = fsi_dai_set_fmt, + .set_fmt = fsi_dai_set_fmt, .hw_params = fsi_dai_hw_params, .auto_selectable_formats = &fsi_dai_formats, .num_auto_selectable_formats = 1, diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 0ac15b74c58a8..a4180dc5a59ba 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1068,7 +1068,7 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { .startup = rsnd_soc_dai_startup, .shutdown = rsnd_soc_dai_shutdown, .trigger = rsnd_soc_dai_trigger, - .set_fmt_new = rsnd_soc_dai_set_fmt, + .set_fmt = rsnd_soc_dai_set_fmt, .set_tdm_slot = rsnd_soc_set_dai_tdm_slot, .prepare = rsnd_soc_dai_prepare, .auto_selectable_formats = rsnd_soc_dai_formats, diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index 0557d22a089f3..beaf1a8d6da10 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -840,7 +840,7 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, static const struct snd_soc_dai_ops rz_ssi_dai_ops = { .trigger = rz_ssi_dai_trigger, - .set_fmt_new = rz_ssi_dai_set_fmt, + .set_fmt = rz_ssi_dai_set_fmt, .hw_params = rz_ssi_dai_hw_params, }; diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index 95571cbeae296..bf7a3c69920a6 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -336,7 +336,7 @@ static const struct snd_soc_dai_ops ssi_dai_ops = { .hw_params = ssi_hw_params, .set_sysclk = ssi_set_sysclk, .set_clkdiv = ssi_set_clkdiv, - .set_fmt_new = ssi_set_fmt, + .set_fmt = ssi_set_fmt, }; static struct snd_soc_dai_driver sh4_ssi_dai[] = { -- GitLab From 02ba0d9680feee645a321d65012f38d0a368b559 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:10 +0100 Subject: [PATCH 131/942] ASoC: stm: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-49-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 2 +- sound/soc/stm/stm32_sai_sub.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 30c04f96ef1d6..32d885f84a922 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -954,7 +954,7 @@ static const struct regmap_config stm32_h7_i2s_regmap_conf = { static const struct snd_soc_dai_ops stm32_i2s_pcm_dai_ops = { .set_sysclk = stm32_i2s_set_sysclk, - .set_fmt_new = stm32_i2s_set_dai_fmt, + .set_fmt = stm32_i2s_set_dai_fmt, .startup = stm32_i2s_startup, .hw_params = stm32_i2s_hw_params, .trigger = stm32_i2s_trigger, diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 9f169b93fa740..e09221b5f1f3a 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1225,7 +1225,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai) static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = { .set_sysclk = stm32_sai_set_sysclk, - .set_fmt_new = stm32_sai_set_dai_fmt, + .set_fmt = stm32_sai_set_dai_fmt, .set_tdm_slot = stm32_sai_set_dai_tdm_slot, .startup = stm32_sai_startup, .hw_params = stm32_sai_hw_params, -- GitLab From 15011b2388d020a6cdb323539fc69c31b04d9f21 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:11 +0100 Subject: [PATCH 132/942] ASoC: sunxi: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-50-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 2 +- sound/soc/sunxi/sun8i-codec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 872838d3e0a94..f58aa6406a874 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1081,7 +1081,7 @@ static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai *dai, static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { .hw_params = sun4i_i2s_hw_params, - .set_fmt_new = sun4i_i2s_set_fmt, + .set_fmt = sun4i_i2s_set_fmt, .set_sysclk = sun4i_i2s_set_sysclk, .set_tdm_slot = sun4i_i2s_set_tdm_slot, .trigger = sun4i_i2s_trigger, diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 6e9ef948d6621..90d74a2d53f38 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -630,7 +630,7 @@ static int sun8i_codec_hw_free(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops sun8i_codec_dai_ops = { - .set_fmt_new = sun8i_codec_set_fmt, + .set_fmt = sun8i_codec_set_fmt, .set_tdm_slot = sun8i_codec_set_tdm_slot, .startup = sun8i_codec_startup, .hw_params = sun8i_codec_hw_params, -- GitLab From 475f2af6a2ff33e828900601a162e324b9986f9a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:12 +0100 Subject: [PATCH 133/942] ASoC: tegra: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-51-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 2 +- sound/soc/tegra/tegra210_i2s.c | 2 +- sound/soc/tegra/tegra30_i2s.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 9abb0e3536d82..2e1a726602f02 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -311,7 +311,7 @@ static int tegra20_i2s_startup(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = { - .set_fmt_new = tegra20_i2s_set_fmt, + .set_fmt = tegra20_i2s_set_fmt, .hw_params = tegra20_i2s_hw_params, .trigger = tegra20_i2s_trigger, .startup = tegra20_i2s_startup, diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index a304948ee3935..a28945895466b 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -678,7 +678,7 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops tegra210_i2s_dai_ops = { - .set_fmt_new = tegra210_i2s_set_fmt, + .set_fmt = tegra210_i2s_set_fmt, .hw_params = tegra210_i2s_hw_params, .set_bclk_ratio = tegra210_i2s_set_dai_bclk_ratio, .set_tdm_slot = tegra210_i2s_set_tdm_slot, diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index a4ea5221de6b4..3aa157c82ae23 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -304,7 +304,7 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) } static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = { - .set_fmt_new = tegra30_i2s_set_fmt, + .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, .set_tdm_slot = tegra30_i2s_set_tdm, -- GitLab From 408c122ef9de99220f7919594ab8af98194a19e8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:13 +0100 Subject: [PATCH 134/942] ASoC: test-component: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-52-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/generic/test-component.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c index 3a992a6eba9bb..d28712fabe3f6 100644 --- a/sound/soc/generic/test-component.c +++ b/sound/soc/generic/test-component.c @@ -210,7 +210,7 @@ static u64 test_dai_formats = SND_SOC_POSSIBLE_DAIFMT_IB_IF; static const struct snd_soc_dai_ops test_ops = { - .set_fmt_new = test_dai_set_fmt, + .set_fmt = test_dai_set_fmt, .startup = test_dai_startup, .shutdown = test_dai_shutdown, .auto_selectable_formats = &test_dai_formats, @@ -221,7 +221,7 @@ static const struct snd_soc_dai_ops test_verbose_ops = { .set_sysclk = test_dai_set_sysclk, .set_pll = test_dai_set_pll, .set_clkdiv = test_dai_set_clkdiv, - .set_fmt_new = test_dai_set_fmt, + .set_fmt = test_dai_set_fmt, .mute_stream = test_dai_mute_stream, .startup = test_dai_startup, .shutdown = test_dai_shutdown, -- GitLab From 9ff1836023ae19013c01f230e6a091fad6835213 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:14 +0100 Subject: [PATCH 135/942] ASoC: ti: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220519154318.2153729-53-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-i2s.c | 2 +- sound/soc/ti/davinci-mcasp.c | 2 +- sound/soc/ti/omap-mcbsp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c index c7368d5296688..fe572b720b094 100644 --- a/sound/soc/ti/davinci-i2s.c +++ b/sound/soc/ti/davinci-i2s.c @@ -606,7 +606,7 @@ static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { .prepare = davinci_i2s_prepare, .trigger = davinci_i2s_trigger, .hw_params = davinci_i2s_hw_params, - .set_fmt_new = davinci_i2s_set_dai_fmt, + .set_fmt = davinci_i2s_set_dai_fmt, .set_clkdiv = davinci_i2s_dai_set_clkdiv, }; diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index 961bac6963652..e2aab4729f3ab 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -1620,7 +1620,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .trigger = davinci_mcasp_trigger, .delay = davinci_mcasp_delay, .hw_params = davinci_mcasp_hw_params, - .set_fmt_new = davinci_mcasp_set_dai_fmt, + .set_fmt = davinci_mcasp_set_dai_fmt, .set_clkdiv = davinci_mcasp_set_clkdiv, .set_sysclk = davinci_mcasp_set_sysclk, .set_tdm_slot = davinci_mcasp_set_tdm_slot, diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c index 5bfb56d4ff844..58d8e200a7b97 100644 --- a/sound/soc/ti/omap-mcbsp.c +++ b/sound/soc/ti/omap-mcbsp.c @@ -1271,7 +1271,7 @@ static const struct snd_soc_dai_ops mcbsp_dai_ops = { .trigger = omap_mcbsp_dai_trigger, .delay = omap_mcbsp_dai_delay, .hw_params = omap_mcbsp_dai_hw_params, - .set_fmt_new = omap_mcbsp_dai_set_dai_fmt, + .set_fmt = omap_mcbsp_dai_set_dai_fmt, .set_clkdiv = omap_mcbsp_dai_set_clkdiv, .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, }; -- GitLab From e24ba1a21e244e7174e75ca0c4020beaff0ad369 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:15 +0100 Subject: [PATCH 136/942] ASoC: ux500: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-54-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_msp_dai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index cd6c4bdf5041d..851c3b8473fd7 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -707,7 +707,7 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops ux500_msp_dai_ops[] = { { .set_sysclk = ux500_msp_dai_set_dai_sysclk, - .set_fmt_new = ux500_msp_dai_set_dai_fmt, + .set_fmt = ux500_msp_dai_set_dai_fmt, .set_tdm_slot = ux500_msp_dai_set_tdm_slot, .startup = ux500_msp_dai_startup, .shutdown = ux500_msp_dai_shutdown, -- GitLab From 58e23e21d18532aaa404e1db87ec92762e1fecd5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:16 +0100 Subject: [PATCH 137/942] ASoC: xtensa: Rename set_fmt_new back to set_fmt Now the core has been migrated across to the new direct clock specification we can move the drivers back to the normal set_fmt callback. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-55-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/xtensa/xtfpga-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c index 72935f491901f..8bd1215460327 100644 --- a/sound/soc/xtensa/xtfpga-i2s.c +++ b/sound/soc/xtensa/xtfpga-i2s.c @@ -487,7 +487,7 @@ static const struct snd_soc_component_driver xtfpga_i2s_component = { static const struct snd_soc_dai_ops xtfpga_i2s_dai_ops = { .startup = xtfpga_i2s_startup, .hw_params = xtfpga_i2s_hw_params, - .set_fmt_new = xtfpga_i2s_set_fmt, + .set_fmt = xtfpga_i2s_set_fmt, }; static struct snd_soc_dai_driver xtfpga_i2s_dai[] = { -- GitLab From 19423951a4b5c4f0ca107d6a4bed23f3f63718ca Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:17 +0100 Subject: [PATCH 138/942] ASoC: soc-dai: Remove set_fmt_new callback Now the behaviour of the core and all drivers is updated to the new direct clock specification the temporary set_fmt_new callback can be completely removed. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-56-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 1 - sound/soc/soc-dai.c | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 9c1d92d5a3738..ea75096720864 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -288,7 +288,6 @@ struct snd_soc_dai_ops { * Called by soc_card drivers, normally in their hw_params. */ int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); - int (*set_fmt_new)(struct snd_soc_dai *dai, unsigned int fmt); int (*xlate_tdm_slot_mask)(unsigned int slots, unsigned int *tx_mask, unsigned int *rx_mask); int (*set_tdm_slot)(struct snd_soc_dai *dai, diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 996712f4d9bfd..d530e8c2b77b1 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -208,11 +208,7 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { int ret = -ENOTSUPP; - if (dai->driver->ops && - dai->driver->ops->set_fmt_new) - ret = dai->driver->ops->set_fmt_new(dai, fmt); - else if (dai->driver->ops && - dai->driver->ops->set_fmt) + if (dai->driver->ops && dai->driver->ops->set_fmt) ret = dai->driver->ops->set_fmt(dai, fmt); return soc_dai_ret(dai, ret); -- GitLab From 28086d05ada6d03daa886aad0e469854b811311c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 19 May 2022 16:43:18 +0100 Subject: [PATCH 139/942] ASoC: simple-card-utils: Move snd_soc_component_is_codec to be local The helper function snd_soc_component_is_codec is based off the presence of the non_legacy_dai_naming flag. This isn't super robust as CPU side components may also specify this flag, and indeed the kernel already contains a couple that do. After componentisation there isn't really a totally robust solution to identifying what is a CODEC driver, without introducing a flag specifically for that purpose, and really the desirable direction to move in is that the distinction doesn't matter. This patch does two things to try to mitigate these problems. Firstly, now that all the other users of the helper function have been removed, it makes the helper function local to the driver rather, than being part of the core. This should help to discourage any new code from being created that depends on the CODEC driver distinction. Secondly, it updates the helper function itself to use the endianness flag rather than the non_legacy_dai_naming flag. The endianness flag is definitely invalid on a CPU side component, so it a more reliable indicator that the device is definitely a CODEC. The vast majority of buses require the CODEC to set the endianness flag, so the number of corner cases should be fairly minimal. It is worth noting that CODECs sending audio over SPI, or built into the CPU CODECs are potential corner cases, however the hope is that in most cases those types of devices do not consitute a simple audio card. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220519154318.2153729-57-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 5 ----- sound/soc/generic/simple-card-utils.c | 7 ++++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 5a764c3099d3e..5c4cfa70b018c 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -348,11 +348,6 @@ static inline int snd_soc_component_cache_sync( return regcache_sync(component->regmap); } -static inline int snd_soc_component_is_codec(struct snd_soc_component *component) -{ - return component->driver->non_legacy_dai_naming; -} - void snd_soc_component_set_aux(struct snd_soc_component *component, struct snd_soc_aux_dev *aux); int snd_soc_component_init(struct snd_soc_component *component); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 539d7f081bd79..50a9827089335 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -513,6 +513,11 @@ static int asoc_simple_init_dai(struct snd_soc_dai *dai, return 0; } +static inline int asoc_simple_component_is_codec(struct snd_soc_component *component) +{ + return component->driver->endianness; +} + static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd, struct simple_dai_props *dai_props) { @@ -524,7 +529,7 @@ static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd, /* Only Codecs */ for_each_rtd_components(rtd, i, component) { - if (!snd_soc_component_is_codec(component)) + if (!asoc_simple_component_is_codec(component)) return 0; } -- GitLab From 60391d788a221f1866492a71929483790b772676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 3 Jun 2022 16:05:10 +0200 Subject: [PATCH 140/942] ASoC: ak4642: Drop no-op remove function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remove callback that just returns 0 is equivalent to no callback at all as can be seen in i2c_device_remove(). So simplify accordingly. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220603140513.131142-2-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/ak4613.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 55e773f921228..648208d40d060 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -919,18 +919,12 @@ static int ak4613_i2c_probe(struct i2c_client *i2c) &ak4613_dai, 1); } -static int ak4613_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static struct i2c_driver ak4613_i2c_driver = { .driver = { .name = "ak4613-codec", .of_match_table = ak4613_of_match, }, .probe_new = ak4613_i2c_probe, - .remove = ak4613_i2c_remove, .id_table = ak4613_i2c_id, }; -- GitLab From 8a291eebeb633316edad2e80537a3c7df83ee8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 3 Jun 2022 16:05:11 +0200 Subject: [PATCH 141/942] ASoC: da7219: Drop no-op remove function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remove callback that just returns 0 is equivalent to no callback at all as can be seen in i2c_device_remove(). So simplify accordingly. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220603140513.131142-3-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/da7219.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 7fdef38ed8cd3..c18f76f370fc4 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2693,11 +2693,6 @@ static int da7219_i2c_probe(struct i2c_client *i2c) return ret; } -static int da7219_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id da7219_i2c_id[] = { { "da7219", }, { } @@ -2711,7 +2706,6 @@ static struct i2c_driver da7219_i2c_driver = { .acpi_match_table = ACPI_PTR(da7219_acpi_match), }, .probe_new = da7219_i2c_probe, - .remove = da7219_i2c_remove, .id_table = da7219_i2c_id, }; -- GitLab From 3cce931a5e4487f7339be559e2ea032478be021a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 3 Jun 2022 16:05:12 +0200 Subject: [PATCH 142/942] ASoC: lm49453: Drop no-op remove function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remove callback that just returns 0 is equivalent to no callback at all as can be seen in i2c_device_remove(). So simplify accordingly. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220603140513.131142-4-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/lm49453.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index bd0078e4499bb..c4900ada86184 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1442,11 +1442,6 @@ static int lm49453_i2c_probe(struct i2c_client *i2c) return ret; } -static int lm49453_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id lm49453_i2c_id[] = { { "lm49453", 0 }, { } @@ -1458,7 +1453,6 @@ static struct i2c_driver lm49453_i2c_driver = { .name = "lm49453", }, .probe_new = lm49453_i2c_probe, - .remove = lm49453_i2c_remove, .id_table = lm49453_i2c_id, }; -- GitLab From fb68cb963bb78380166a98beea593d20b956e4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 3 Jun 2022 16:05:13 +0200 Subject: [PATCH 143/942] ASoC: da732x: Drop no-op remove function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A remove callback that just returns 0 is equivalent to no callback at all as can be seen in i2c_device_remove(). So simplify accordingly. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220603140513.131142-5-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/da732x.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index f14cddf23f427..3f1cfee10df3f 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1546,11 +1546,6 @@ static int da732x_i2c_probe(struct i2c_client *i2c) return ret; } -static int da732x_i2c_remove(struct i2c_client *client) -{ - return 0; -} - static const struct i2c_device_id da732x_i2c_id[] = { { "da7320", 0}, { } @@ -1562,7 +1557,6 @@ static struct i2c_driver da732x_i2c_driver = { .name = "da7320", }, .probe_new = da732x_i2c_probe, - .remove = da732x_i2c_remove, .id_table = da732x_i2c_id, }; -- GitLab From 94e0bc317ad241c022a6bb311b3a28b4d51ea8b6 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Wed, 25 May 2022 14:16:30 +0100 Subject: [PATCH 144/942] ASoC: cs35l41: Move cs35l41 exit hibernate function into shared code CS35L41 HDA Driver will support hibernation using DSP firmware, move the exit hibernate function into shared code so this can be reused. Acked-by: Charles Keepax Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220525131638.5512-10-vitalyr@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l41.h | 1 + sound/soc/codecs/cs35l41-lib.c | 60 +++++++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 61 +--------------------------------- 3 files changed, 62 insertions(+), 60 deletions(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 8972fa6976227..7759f2e14d96d 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -881,6 +881,7 @@ void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, enum cs35l41_cspl_mbox_cmd cmd); int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); +int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); int cs35l41_init_boost(struct device *dev, struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 6d3070ea9e06d..cc5366c8bdd61 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1321,6 +1321,66 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) } EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); +static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap) +{ + const int pwrmgt_retries = 10; + unsigned int sts; + int i, ret; + + for (i = 0; i < pwrmgt_retries; i++) { + ret = regmap_read(regmap, CS35L41_PWRMGT_STS, &sts); + if (ret) + dev_err(dev, "Failed to read PWRMGT_STS: %d\n", ret); + else if (!(sts & CS35L41_WR_PEND_STS_MASK)) + return; + + udelay(20); + } + + dev_err(dev, "Timed out reading PWRMGT_STS\n"); +} + +int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap) +{ + const int wake_retries = 20; + const int sleep_retries = 5; + int ret, i, j; + + for (i = 0; i < sleep_retries; i++) { + dev_dbg(dev, "Exit hibernate\n"); + + for (j = 0; j < wake_retries; j++) { + ret = cs35l41_set_cspl_mbox_cmd(dev, regmap, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE); + if (!ret) + break; + + usleep_range(100, 200); + } + + if (j < wake_retries) { + dev_dbg(dev, "Wake success at cycle: %d\n", j); + return 0; + } + + dev_err(dev, "Wake failed, re-enter hibernate: %d\n", ret); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); + + cs35l41_wait_for_pwrmgt_sts(dev, regmap); + regmap_write(regmap, CS35L41_PWRMGT_CTL, 0x3); + } + + dev_err(dev, "Timed out waking device\n"); + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(cs35l41_exit_hibernate); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, "); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 3e68a07a3c8e0..be7d025177396 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -1351,65 +1351,6 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) return 0; } -static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) -{ - const int pwrmgt_retries = 10; - unsigned int sts; - int i, ret; - - for (i = 0; i < pwrmgt_retries; i++) { - ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts); - if (ret) - dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret); - else if (!(sts & CS35L41_WR_PEND_STS_MASK)) - return; - - udelay(20); - } - - dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n"); -} - -static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) -{ - const int wake_retries = 20; - const int sleep_retries = 5; - int ret, i, j; - - for (i = 0; i < sleep_retries; i++) { - dev_dbg(cs35l41->dev, "Exit hibernate\n"); - - for (j = 0; j < wake_retries; j++) { - ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, - CSPL_MBOX_CMD_OUT_OF_HIBERNATE); - if (!ret) - break; - - usleep_range(100, 200); - } - - if (j < wake_retries) { - dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j); - return 0; - } - - dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); - - cs35l41_wait_for_pwrmgt_sts(cs35l41); - regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); - } - - dev_err(cs35l41->dev, "Timed out waking device\n"); - - return -ETIMEDOUT; -} - static int __maybe_unused cs35l41_runtime_resume(struct device *dev) { struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); @@ -1422,7 +1363,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev) regcache_cache_only(cs35l41->regmap, false); - ret = cs35l41_exit_hibernate(cs35l41); + ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); if (ret) return ret; -- GitLab From e341efc308e5374ded6b471f9e1ec01450bcc93e Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Wed, 25 May 2022 14:16:32 +0100 Subject: [PATCH 145/942] ASoC: cs35l41: Add common cs35l41 enter hibernate function Since the CS35L41 HDA driver also support hibernation, it makes sense to move code from the ASoC driver to enter hibernation into common code. Since HDA must support laptops which do not support hibernation due to lack of external boost GPIO it is necessary to ensure the function returns an error when an unsupported boost type is in use. Acked-by: Charles Keepax Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220525131638.5512-12-vitalyr@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l41.h | 2 ++ sound/soc/codecs/cs35l41-lib.c | 19 +++++++++++++++++++ sound/soc/codecs/cs35l41.c | 10 +--------- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 7759f2e14d96d..a66ef37184fd5 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -881,6 +881,8 @@ void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, enum cs35l41_cspl_mbox_cmd cmd); int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap); +int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap, + enum cs35l41_boost_type b_type); int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); int cs35l41_init_boost(struct device *dev, struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index cc5366c8bdd61..10b754481ca2a 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1321,6 +1321,25 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap) } EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata); +int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap, + enum cs35l41_boost_type b_type) +{ + if (!cs35l41_safe_reset(regmap, b_type)) { + dev_dbg(dev, "System does not support Suspend\n"); + return -EINVAL; + } + + dev_dbg(dev, "Enter hibernate\n"); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088); + regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188); + + // Don't wait for ACK since bus activity would wake the device + regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE); + + return 0; +} +EXPORT_SYMBOL_GPL(cs35l41_enter_hibernate); + static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap) { const int pwrmgt_retries = 10; diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index be7d025177396..a115ea35b92d4 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -1335,15 +1335,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) return 0; - dev_dbg(cs35l41->dev, "Enter hibernate\n"); - - cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); - regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); - - // Don't wait for ACK since bus activity would wake the device - regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, - CSPL_MBOX_CMD_HIBERNATE); + cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type); regcache_cache_only(cs35l41->regmap, true); regcache_mark_dirty(cs35l41->regmap); -- GitLab From 97076475e2fdf471348b9ce73215cdbceeb4390f Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Wed, 25 May 2022 14:16:31 +0100 Subject: [PATCH 146/942] ASoC: cs35l41: Do not print error when waking from hibernation When waking from hibernation, it is possible for the function which sends the wake command to fail initially, but after a retry it will succeed. There is no need to print an error if the initial attempts fail. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Acked-by: Charles Keepax Link: https://lore.kernel.org/r/20220525131638.5512-11-vitalyr@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 10b754481ca2a..0c7d1c7912798 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1302,7 +1302,8 @@ int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, return 0; } - dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); + if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) + dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); return -ENOMSG; } -- GitLab From 0439eb4d94e0fc17c6dd3829fabd88c11773381d Mon Sep 17 00:00:00 2001 From: V sujith kumar Reddy Date: Tue, 31 May 2022 17:38:11 +0530 Subject: [PATCH 147/942] ASoC: amd: acp: Add support for nau8825 and max98360 card We have new platform with nau8825 as a primary codec and max98360 as an amp codec. Add machine struct to register sof audio based sound card on such Chrome machine. Signed-off-by: V sujith kumar Reddy Reviewed-by: Akihiko Odaki Link: https://lore.kernel.org/r/20220531120813.47116-2-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-config.c | 21 ++++ sound/soc/amd/acp/Kconfig | 1 + sound/soc/amd/acp/acp-mach-common.c | 166 +++++++++++++++++++++++++++- sound/soc/amd/acp/acp-mach.h | 3 + sound/soc/amd/acp/acp-sof-mach.c | 15 +++ sound/soc/amd/mach-config.h | 1 + 6 files changed, 201 insertions(+), 6 deletions(-) diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c index 5cbc82eca4c9a..3b9f851bf50d8 100644 --- a/sound/soc/amd/acp-config.c +++ b/sound/soc/amd/acp-config.c @@ -130,4 +130,25 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = { }; EXPORT_SYMBOL(snd_soc_acpi_amd_sof_machines); +struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[] = { + { + .id = "AMDI1019", + .drv_name = "rmb-dsp", + .pdata = &acp_quirk_data, + .fw_filename = "sof-rmb.ri", + .sof_tplg_filename = "sof-acp-rmb.tplg", + }, + { + .id = "10508825", + .drv_name = "nau8825-max", + .pdata = &acp_quirk_data, + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + .fw_filename = "sof-rmb.ri", + .sof_tplg_filename = "sof-rmb-nau8825-max98360.tplg", + }, + {}, +}; +EXPORT_SYMBOL(snd_soc_acpi_amd_rmb_sof_machines); + MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 9dae2719084ce..7e56d26441058 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -49,6 +49,7 @@ config SND_SOC_AMD_MACH_COMMON select SND_SOC_RT1019 select SND_SOC_MAX98357A select SND_SOC_RT5682S + select SND_SOC_NAU8825 help This option enables common Machine driver module for ACP. diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index 6ae454bf60afa..a03b396d96bbc 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -24,6 +24,7 @@ #include "../../codecs/rt5682.h" #include "../../codecs/rt1019.h" #include "../../codecs/rt5682s.h" +#include "../../codecs/nau8825.h" #include "acp-mach.h" #define PCO_PLAT_CLK 48000000 @@ -175,7 +176,8 @@ static void acp_card_shutdown(struct snd_pcm_substream *substream) struct snd_soc_card *card = rtd->card; struct acp_card_drvdata *drvdata = card->drvdata; - clk_disable_unprepare(drvdata->wclk); + if (!drvdata->soc_mclk) + clk_disable_unprepare(drvdata->wclk); } static const struct snd_soc_ops acp_card_rt5682_ops = { @@ -363,7 +365,7 @@ static int acp_card_amp_startup(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct acp_card_drvdata *drvdata = card->drvdata; - int ret; + int ret = 0; runtime->hw.channels_max = DUAL_CHANNEL; snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, @@ -371,10 +373,13 @@ static int acp_card_amp_startup(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - ret = acp_clk_enable(drvdata); - if (ret < 0) - dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret); - + if (!drvdata->soc_mclk) { + ret = acp_clk_enable(drvdata); + if (ret < 0) { + dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret); + return ret; + } + } return ret; } @@ -409,6 +414,104 @@ static const struct snd_soc_ops acp_card_maxim_ops = { .shutdown = acp_card_shutdown, }; +/* Declare nau8825 codec components */ +SND_SOC_DAILINK_DEF(nau8825, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi"))); + +static const struct snd_soc_dapm_route nau8825_map[] = { + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, +}; + +static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct acp_card_drvdata *drvdata = card->drvdata; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = codec_dai->component; + unsigned int fmt; + int ret; + + dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); + + if (drvdata->hs_codec_id != NAU8825) + return -EINVAL; + + if (drvdata->soc_mclk) + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + else + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) { + dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); + return ret; + } + ret = snd_soc_card_jack_new(card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_LINEOUT | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + &pco_jack); + if (ret) { + dev_err(card->dev, "HP jack creation failed %d\n", ret); + return ret; + } + + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(component, &pco_jack, NULL); + if (ret) { + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + + return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8825_map, ARRAY_SIZE(nau8825_map)); +} + +static int acp_nau8825_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + int ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS, + (48000 * 256), SND_SOC_CLOCK_IN); + if (ret < 0) + dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); + + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params), + params_rate(params) * 256); + if (ret < 0) { + dev_err(rtd->dev, "can't set FLL: %d\n", ret); + return ret; + } + + return ret; +} + +static int acp_nau8825_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.channels_max = 2; + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + + runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE; + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); + return 0; +} + +static const struct snd_soc_ops acp_card_nau8825_ops = { + .startup = acp_nau8825_startup, + .hw_params = acp_nau8825_hw_params, +}; + /* Declare DMIC codec components */ SND_SOC_DAILINK_DEF(dmic_codec, DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); @@ -437,6 +540,8 @@ SND_SOC_DAILINK_DEF(i2s_sp, DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp"))); SND_SOC_DAILINK_DEF(sof_sp, DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp"))); +SND_SOC_DAILINK_DEF(sof_hs, + DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs"))); SND_SOC_DAILINK_DEF(sof_dmic, DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic"))); SND_SOC_DAILINK_DEF(pdm_dmic, @@ -491,6 +596,31 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) i++; } + if (drv_data->hs_cpu_id == I2S_HS) { + links[i].name = "acp-headset-codec"; + links[i].id = HEADSET_BE_ID; + links[i].cpus = sof_hs; + links[i].num_cpus = ARRAY_SIZE(sof_hs); + links[i].platforms = sof_component; + links[i].num_platforms = ARRAY_SIZE(sof_component); + links[i].dpcm_playback = 1; + links[i].dpcm_capture = 1; + links[i].nonatomic = true; + links[i].no_pcm = 1; + if (!drv_data->hs_codec_id) { + /* Use dummy codec if codec id not specified */ + links[i].codecs = dummy_codec; + links[i].num_codecs = ARRAY_SIZE(dummy_codec); + } + if (drv_data->hs_codec_id == NAU8825) { + links[i].codecs = nau8825; + links[i].num_codecs = ARRAY_SIZE(nau8825); + links[i].init = acp_card_nau8825_init; + links[i].ops = &acp_card_nau8825_ops; + } + i++; + } + if (drv_data->amp_cpu_id == I2S_SP) { links[i].name = "acp-amp-codec"; links[i].id = AMP_BE_ID; @@ -523,6 +653,30 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) i++; } + if (drv_data->amp_cpu_id == I2S_HS) { + links[i].name = "acp-amp-codec"; + links[i].id = AMP_BE_ID; + links[i].cpus = sof_hs; + links[i].num_cpus = ARRAY_SIZE(sof_hs); + links[i].platforms = sof_component; + links[i].num_platforms = ARRAY_SIZE(sof_component); + links[i].dpcm_playback = 1; + links[i].nonatomic = true; + links[i].no_pcm = 1; + if (!drv_data->amp_codec_id) { + /* Use dummy codec if codec id not specified */ + links[i].codecs = dummy_codec; + links[i].num_codecs = ARRAY_SIZE(dummy_codec); + } + if (drv_data->amp_codec_id == MAX98360A) { + links[i].codecs = max98360a; + links[i].num_codecs = ARRAY_SIZE(max98360a); + links[i].ops = &acp_card_maxim_ops; + links[i].init = acp_card_maxim_init; + } + i++; + } + if (drv_data->dmic_cpu_id == DMIC) { links[i].name = "acp-dmic-codec"; links[i].id = DMIC_BE_ID; diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h index 5dc47cfbff10e..c95ee1c52eb1b 100644 --- a/sound/soc/amd/acp/acp-mach.h +++ b/sound/soc/amd/acp/acp-mach.h @@ -26,6 +26,7 @@ enum be_id { enum cpu_endpoints { NONE = 0, + I2S_HS, I2S_SP, I2S_BT, DMIC, @@ -37,6 +38,7 @@ enum codec_endpoints { RT1019, MAX98360A, RT5682S, + NAU8825, }; struct acp_card_drvdata { @@ -49,6 +51,7 @@ struct acp_card_drvdata { unsigned int dai_fmt; struct clk *wclk; struct clk *bclk; + bool soc_mclk; }; int acp_sofdsp_dai_links_create(struct snd_soc_card *card); diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c index d1531cdab1102..adbae809f2aa5 100644 --- a/sound/soc/amd/acp/acp-sof-mach.c +++ b/sound/soc/amd/acp/acp-sof-mach.c @@ -56,6 +56,16 @@ static struct acp_card_drvdata sof_rt5682s_max_data = { .dmic_codec_id = DMIC, }; +static struct acp_card_drvdata sof_nau8825_data = { + .hs_cpu_id = I2S_HS, + .amp_cpu_id = I2S_HS, + .dmic_cpu_id = DMIC, + .hs_codec_id = NAU8825, + .amp_codec_id = MAX98360A, + .dmic_codec_id = DMIC, + .soc_mclk = true, +}; + static const struct snd_kcontrol_new acp_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -124,6 +134,10 @@ static const struct platform_device_id board_ids[] = { .name = "rt5682s-rt1019", .driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data }, + { + .name = "nau8825-max", + .driver_data = (kernel_ulong_t)&sof_nau8825_data + }, { } }; static struct platform_driver acp_asoc_audio = { @@ -143,4 +157,5 @@ MODULE_ALIAS("platform:rt5682-rt1019"); MODULE_ALIAS("platform:rt5682-max"); MODULE_ALIAS("platform:rt5682s-max"); MODULE_ALIAS("platform:rt5682s-rt1019"); +MODULE_ALIAS("platform:nau8825-max"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/mach-config.h b/sound/soc/amd/mach-config.h index 0a54567a28415..7b4c625da40d8 100644 --- a/sound/soc/amd/mach-config.h +++ b/sound/soc/amd/mach-config.h @@ -19,6 +19,7 @@ #define ACP_PCI_DEV_ID 0x15E2 extern struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[]; struct config_entry { u32 flags; -- GitLab From 4dc6737cfe882765d914fcb88b5eaa14551ffddd Mon Sep 17 00:00:00 2001 From: V sujith kumar Reddy Date: Tue, 31 May 2022 17:38:12 +0530 Subject: [PATCH 148/942] ASoC: amd: acp: Add support for rt5682s and rt1019 card with hs instance We have new platform with rt5682s as a primary codec and rt1019 as an amp codec. Add machine struct to register sof audio based sound card on such Chrome machine. Here we are configuring as a soc mclk master and codec slave. Signed-off-by: V sujith kumar Reddy Link: https://lore.kernel.org/r/20220531120813.47116-3-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-config.c | 9 ++++ sound/soc/amd/acp/acp-mach-common.c | 67 ++++++++++++++++++++++++----- sound/soc/amd/acp/acp-sof-mach.c | 15 +++++++ 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c index 3b9f851bf50d8..0932473b63945 100644 --- a/sound/soc/amd/acp-config.c +++ b/sound/soc/amd/acp-config.c @@ -147,6 +147,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[] = { .fw_filename = "sof-rmb.ri", .sof_tplg_filename = "sof-rmb-nau8825-max98360.tplg", }, + { + .id = "RTL5682", + .drv_name = "rt5682s-hs-rt1019", + .pdata = &acp_quirk_data, + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + .fw_filename = "sof-rmb.ri", + .sof_tplg_filename = "sof-rmb-rt5682s-rt1019.tplg", + }, {}, }; EXPORT_SYMBOL(snd_soc_acpi_amd_rmb_sof_machines); diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index a03b396d96bbc..7530cab24bc8b 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -149,9 +149,14 @@ static int acp_card_hs_startup(struct snd_pcm_substream *substream) struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int ret; + unsigned int fmt; - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBP_CFP); + if (drvdata->soc_mclk) + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + else + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); if (ret < 0) { dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); return ret; @@ -162,10 +167,13 @@ static int acp_card_hs_startup(struct snd_pcm_substream *substream) &constraints_channels); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &constraints_rates); - - ret = acp_clk_enable(drvdata); - if (ret < 0) - dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret); + if (!drvdata->soc_mclk) { + ret = acp_clk_enable(drvdata); + if (ret < 0) { + dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret); + return ret; + } + } return ret; } @@ -201,6 +209,7 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) struct acp_card_drvdata *drvdata = card->drvdata; struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; + unsigned int fmt; int ret; dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name); @@ -208,8 +217,12 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) if (drvdata->hs_codec_id != RT5682S) return -EINVAL; - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBP_CFP); + if (drvdata->soc_mclk) + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + else + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP; + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); if (ret < 0) { dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret); return ret; @@ -236,8 +249,10 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) return ret; } - drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); - drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); + if (!drvdata->soc_mclk) { + drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); + drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); + } ret = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_LINEOUT | @@ -298,6 +313,9 @@ static const struct snd_soc_ops acp_card_dmic_ops = { SND_SOC_DAILINK_DEF(rt1019, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); +SND_SOC_DAILINK_DEF(rt1019_1, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:02", "rt1019-aif"), + COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); static const struct snd_soc_dapm_route rt1019_map_lr[] = { { "Left Spk", NULL, "Left SPO" }, @@ -315,6 +333,17 @@ static struct snd_soc_codec_conf rt1019_conf[] = { }, }; +static struct snd_soc_codec_conf rt1019_1_conf[] = { + { + .dlc = COMP_CODEC_CONF("i2c-10EC1019:02"), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"), + .name_prefix = "Right", + }, +}; + static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -618,6 +647,12 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) links[i].init = acp_card_nau8825_init; links[i].ops = &acp_card_nau8825_ops; } + if (drv_data->hs_codec_id == RT5682S) { + links[i].codecs = rt5682s; + links[i].num_codecs = ARRAY_SIZE(rt5682s); + links[i].init = acp_card_rt5682s_init; + links[i].ops = &acp_card_rt5682s_ops; + } i++; } @@ -674,6 +709,18 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) links[i].ops = &acp_card_maxim_ops; links[i].init = acp_card_maxim_init; } + if (drv_data->amp_codec_id == RT1019) { + links[i].codecs = rt1019; + links[i].num_codecs = ARRAY_SIZE(rt1019); + links[i].ops = &acp_card_rt1019_ops; + links[i].init = acp_card_rt1019_init; + card->codec_conf = rt1019_conf; + card->num_configs = ARRAY_SIZE(rt1019_conf); + links[i].codecs = rt1019_1; + links[i].num_codecs = ARRAY_SIZE(rt1019_1); + card->codec_conf = rt1019_1_conf; + card->num_configs = ARRAY_SIZE(rt1019_1_conf); + } i++; } diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c index adbae809f2aa5..f19f064a75272 100644 --- a/sound/soc/amd/acp/acp-sof-mach.c +++ b/sound/soc/amd/acp/acp-sof-mach.c @@ -66,6 +66,16 @@ static struct acp_card_drvdata sof_nau8825_data = { .soc_mclk = true, }; +static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { + .hs_cpu_id = I2S_HS, + .amp_cpu_id = I2S_HS, + .dmic_cpu_id = DMIC, + .hs_codec_id = RT5682S, + .amp_codec_id = RT1019, + .dmic_codec_id = DMIC, + .soc_mclk = true, +}; + static const struct snd_kcontrol_new acp_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -138,6 +148,10 @@ static const struct platform_device_id board_ids[] = { .name = "nau8825-max", .driver_data = (kernel_ulong_t)&sof_nau8825_data }, + { + .name = "rt5682s-hs-rt1019", + .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data + }, { } }; static struct platform_driver acp_asoc_audio = { @@ -158,4 +172,5 @@ MODULE_ALIAS("platform:rt5682-max"); MODULE_ALIAS("platform:rt5682s-max"); MODULE_ALIAS("platform:rt5682s-rt1019"); MODULE_ALIAS("platform:nau8825-max"); +MODULE_ALIAS("platform:rt5682s-hs-rt1019"); MODULE_LICENSE("GPL v2"); -- GitLab From 8dc51d009fad7aba0575e0eb4b684d25c0f01f37 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:05:29 +0200 Subject: [PATCH 149/942] ASoC: ssm2518: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the ssm2518 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602130531.3552275-2-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2518.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 83acbdbb8e0da..012f209e76e90 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -409,8 +409,8 @@ static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) bool invert_fclk; int ret; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From 0160e8835fab4d4a15abefe7509d0397890c0ffd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:05:30 +0200 Subject: [PATCH 150/942] ASoC: ssm2602: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the ssm2602 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602130531.3552275-3-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2602.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 7964e922b07f6..1821854ca0f37 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -411,11 +411,11 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int iface = 0; /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface |= 0x0040; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From 627a18149250e13409079ffb6936e472c3766f44 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:05:31 +0200 Subject: [PATCH 151/942] ASoC: ssm4567: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the ssm4567 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602130531.3552275-4-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/ssm4567.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index 08ced09ef001d..b47321c597d0e 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -278,8 +278,8 @@ static int ssm4567_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int ctrl1 = 0; bool invert_fclk; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From 0511e2ac4e848ceac14b3ac4b476f0e26b48ddb2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:04 -0500 Subject: [PATCH 152/942] ASoC: cs35l45: typo in argument definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/codecs/cs35l45-tables.c:36:49: style:inconclusive: Function 'cs35l45_apply_patch' argument 1 names different: declaration 'cs43l45' definition 'cs35l45'. [funcArgNamesDifferent] Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l45.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h index 4e266d19cd1cd..8f98cbbf6209f 100644 --- a/sound/soc/codecs/cs35l45.h +++ b/sound/soc/codecs/cs35l45.h @@ -209,7 +209,7 @@ struct cs35l45_private { extern const struct dev_pm_ops cs35l45_pm_ops; extern const struct regmap_config cs35l45_i2c_regmap; extern const struct regmap_config cs35l45_spi_regmap; -int cs35l45_apply_patch(struct cs35l45_private *cs43l45); +int cs35l45_apply_patch(struct cs35l45_private *cs35l45); unsigned int cs35l45_get_clk_freq_id(unsigned int freq); int cs35l45_probe(struct cs35l45_private *cs35l45); int cs35l45_remove(struct cs35l45_private *cs35l45); -- GitLab From 94f8f2068ed0e3a5e367029f64ed76e6e65d5eb3 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:05 -0500 Subject: [PATCH 153/942] ASoC: cs42l42: remove redundant test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/codecs/cs42l42.c:1704:28: style: The statement 'if (cs42l42->plug_state!=CS42L42_TS_TRANS) cs42l42->plug_state=CS42L42_TS_TRANS' is logically equivalent to 'cs42l42->plug_state=CS42L42_TS_TRANS'. [duplicateConditionalAssign] if (cs42l42->plug_state != CS42L42_TS_TRANS) ^ sound/soc/codecs/cs42l42.c:1705:25: note: Assignment 'cs42l42->plug_state=CS42L42_TS_TRANS' cs42l42->plug_state = CS42L42_TS_TRANS; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l42.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 4fade23887972..6ca74c0d46eaa 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1701,8 +1701,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) break; default: - if (cs42l42->plug_state != CS42L42_TS_TRANS) - cs42l42->plug_state = CS42L42_TS_TRANS; + cs42l42->plug_state = CS42L42_TS_TRANS; } } -- GitLab From cac24a360a6b948ffb75c3d7ccc819064300454c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:06 -0500 Subject: [PATCH 154/942] ASoC: wcd-mbhc-v2: remove useless initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/codecs/wcd-mbhc-v2.c:1309:17: style: Variable 'clamp_state' is assigned a value that is never used. [unreadVariable] u8 clamp_state = 0; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd-mbhc-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index c53c2ef33e1a2..31009283e7d4a 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1306,7 +1306,7 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) static irqreturn_t wcd_mbhc_adc_hs_ins_irq(int irq, void *data) { struct wcd_mbhc *mbhc = data; - u8 clamp_state = 0; + u8 clamp_state; u8 clamp_retry = WCD_MBHC_FAKE_INS_RETRY; /* -- GitLab From 0016361dfcc93a70850c6909fb76f15305dda5ae Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:07 -0500 Subject: [PATCH 155/942] ASoC: wcd9335: remove redundant tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/codecs/wcd9335.c:1810:23: style: Condition 'tx_port>=4' is always true [knownConditionTrueFalse] } else if ((tx_port >= 4) && (tx_port < 8)) { ^ sound/soc/codecs/wcd9335.c:1806:15: note: Assuming that condition 'tx_port<4' is not redundant if (tx_port < 4) { ^ sound/soc/codecs/wcd9335.c:1810:23: note: Condition 'tx_port>=4' is always true } else if ((tx_port >= 4) && (tx_port < 8)) { ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 617a36a89dfed..e1b6930480842 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1807,11 +1807,11 @@ static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai, tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0; shift = (tx_port << 1); shift_val = 0x03; - } else if ((tx_port >= 4) && (tx_port < 8)) { + } else if (tx_port < 8) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1; shift = ((tx_port - 4) << 1); shift_val = 0x03; - } else if ((tx_port >= 8) && (tx_port < 11)) { + } else if (tx_port < 11) { tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2; shift = ((tx_port - 8) << 1); shift_val = 0x03; -- GitLab From fb6ed937aaa0703bcdacfe013897d583a6eba365 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:08 -0500 Subject: [PATCH 156/942] ASoC: Intel: atom: sst: remove useless initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck reports an invalid null pointer dereference but there's indeed no need to initialize a loop variable. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst/sst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index 3a42d68c0247b..160b50f479fb4 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c @@ -114,7 +114,7 @@ static irqreturn_t intel_sst_interrupt_mrfld(int irq, void *context) static irqreturn_t intel_sst_irq_thread_mrfld(int irq, void *context) { struct intel_sst_drv *drv = (struct intel_sst_drv *) context; - struct ipc_post *__msg, *msg = NULL; + struct ipc_post *__msg, *msg; unsigned long irq_flags; spin_lock_irqsave(&drv->rx_msg_lock, irq_flags); -- GitLab From d8af541139fa135a250c5ae743bfec3b49e97c3a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:09 -0500 Subject: [PATCH 157/942] ASoC: Intel: atom: sst_ipc: remove redundant test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/intel/atom/sst/sst_ipc.c:344:30: style: Condition 'drv_id' is always true [knownConditionTrueFalse] if (msg_high.part.result && drv_id && !msg_high.part.large) { ^ sound/soc/intel/atom/sst/sst_ipc.c:337:13: note: Assuming that condition 'drv_id==0' is not redundant if (drv_id == SST_ASYNC_DRV_ID) { ^ sound/soc/intel/atom/sst/sst_ipc.c:344:30: note: Condition 'drv_id' is always true if (msg_high.part.result && drv_id && !msg_high.part.large) { ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst/sst_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 4e8382097e618..78ea67c7a1281 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c @@ -341,7 +341,7 @@ void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx, } /* FW sent short error response for an IPC */ - if (msg_high.part.result && drv_id && !msg_high.part.large) { + if (msg_high.part.result && !msg_high.part.large) { /* 32-bit FW error code in msg_low */ dev_err(sst_drv_ctx->dev, "FW sent error response 0x%x", msg_low); sst_wake_up_block(sst_drv_ctx, msg_high.part.result, -- GitLab From a140785b701d286374ea1b26762f333e4f5e9ee3 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:10 -0500 Subject: [PATCH 158/942] ASoC: Intel: atom: sst_ipc: remove useless initializations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck throws invalid NULL dereference warnings but there's indeed no need to initialize a loop variable or initialize to NULL before allocating memory. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst/sst_ipc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 78ea67c7a1281..4e039c7173d8c 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c @@ -28,7 +28,7 @@ struct sst_block *sst_create_block(struct intel_sst_drv *ctx, u32 msg_id, u32 drv_id) { - struct sst_block *msg = NULL; + struct sst_block *msg; dev_dbg(ctx->dev, "Enter\n"); msg = kzalloc(sizeof(*msg), GFP_KERNEL); @@ -63,7 +63,7 @@ struct sst_block *sst_create_block(struct intel_sst_drv *ctx, int sst_wake_up_block(struct intel_sst_drv *ctx, int result, u32 drv_id, u32 ipc, void *data, u32 size) { - struct sst_block *block = NULL; + struct sst_block *block; dev_dbg(ctx->dev, "Enter\n"); @@ -91,7 +91,7 @@ int sst_wake_up_block(struct intel_sst_drv *ctx, int result, int sst_free_block(struct intel_sst_drv *ctx, struct sst_block *freed) { - struct sst_block *block = NULL, *__block; + struct sst_block *block, *__block; dev_dbg(ctx->dev, "Enter\n"); spin_lock_bh(&ctx->block_lock); -- GitLab From f6cd55a19f3f46e3d36b1121f844956128c60b6a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:11 -0500 Subject: [PATCH 159/942] ASoC: Intel: atom: controls: remove useless initializations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck complains about invalid NULL dereferences but there's indeed no need to initialize loop variables or before allocating memory. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/atom/sst-atom-controls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c index 335c327329945..34d63252debfd 100644 --- a/sound/soc/intel/atom/sst-atom-controls.c +++ b/sound/soc/intel/atom/sst-atom-controls.c @@ -1328,7 +1328,7 @@ int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute) { struct sst_data *drv = snd_soc_dai_get_drvdata(dai); struct snd_soc_dapm_widget *w; - struct snd_soc_dapm_path *p = NULL; + struct snd_soc_dapm_path *p; dev_dbg(dai->dev, "enter, dai-name=%s dir=%d\n", dai->name, stream); @@ -1392,7 +1392,7 @@ int sst_send_pipe_gains(struct snd_soc_dai *dai, int stream, int mute) static int sst_fill_module_list(struct snd_kcontrol *kctl, struct snd_soc_dapm_widget *w, int type) { - struct sst_module *module = NULL; + struct sst_module *module; struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); struct sst_ids *ids = w->priv; int ret = 0; -- GitLab From 9972773c26125242b467f0062c1fee874c87ae68 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:12 -0500 Subject: [PATCH 160/942] ASoC: Intel: boards: reset acpi_chan_package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck complains about possible tests of uninitialized 'aif_value' members. This isn't really possible but static analysis cannot know what ACPICA does, so make sure the acpi_chan_package structure is reset prior to use to make the warning go away. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_rt5640.c | 2 +- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- sound/soc/intel/boards/cht_bsw_rt5645.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index ed9fa17287227..2371927fe8365 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1636,7 +1636,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) * with the codec driver/pdata are non-existent */ - struct acpi_chan_package chan_package; + struct acpi_chan_package chan_package = { 0 }; /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index d467fcaa48eaa..03a52b1069a92 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -952,7 +952,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) * with the codec driver/pdata are non-existent */ - struct acpi_chan_package chan_package; + struct acpi_chan_package chan_package = { 0 }; /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 45c301ea5e003..453281326c831 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -603,7 +603,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) * with the codec driver/pdata are non-existent */ - struct acpi_chan_package chan_package; + struct acpi_chan_package chan_package = { 0 }; /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; -- GitLab From f057852fd351741d1efaadc48aa59ea49c79a087 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:13 -0500 Subject: [PATCH 161/942] ASoC: Intel: sof_pcm512x: remove unnecessary init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck complains about an invalid NULL dereference but indeed there is no need to initialize a loop variable. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_pcm512x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 6815204e58d58..d4c67d5340a92 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -419,7 +419,7 @@ static int sof_audio_probe(struct platform_device *pdev) static int sof_pcm512x_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct snd_soc_component *component = NULL; + struct snd_soc_component *component; for_each_card_components(card, component) { if (!strcmp(component->name, pcm512x_component[0].name)) { -- GitLab From 9e9fb5d3f387788d50f5eae4c01ff60429691e71 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:14 -0500 Subject: [PATCH 162/942] ASoC: mediatek: mt8195: simplify error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warnings: sound/soc/mediatek/mt8195/mt8195-afe-clk.c:311:9: warning: Identical condition and return expression 'ret', return value is always 0 [identicalConditionAfterEarlyExit] return ret; ^ sound/soc/mediatek/mt8195/mt8195-afe-clk.c:297:6: note: If condition 'ret' is true, the function will return/exit if (ret) ^ sound/soc/mediatek/mt8195/mt8195-afe-clk.c:311:9: note: Returning identical expression 'ret' return ret; ^ sound/soc/mediatek/mt8195/mt8195-afe-clk.c:341:9: warning: Identical condition and return expression 'ret', return value is always 0 [identicalConditionAfterEarlyExit] return ret; ^ sound/soc/mediatek/mt8195/mt8195-afe-clk.c:338:6: note: If condition 'ret' is true, the function will return/exit if (ret) ^ sound/soc/mediatek/mt8195/mt8195-afe-clk.c:341:9: note: Returning identical expression 'ret' return ret; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8195/mt8195-afe-clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c index efd5cc364a351..2ee3872c83c36 100644 --- a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c @@ -284,7 +284,7 @@ static int mt8195_afe_enable_apll_tuner(struct mtk_base_afe *afe, { struct mt8195_afe_tuner_cfg *cfg = mt8195_afe_found_apll_tuner(id); unsigned long flags; - int ret = 0; + int ret; if (!cfg) return -EINVAL; @@ -308,7 +308,7 @@ static int mt8195_afe_enable_apll_tuner(struct mtk_base_afe *afe, spin_unlock_irqrestore(&cfg->ctrl_lock, flags); - return ret; + return 0; } static int mt8195_afe_disable_apll_tuner(struct mtk_base_afe *afe, @@ -316,7 +316,7 @@ static int mt8195_afe_disable_apll_tuner(struct mtk_base_afe *afe, { struct mt8195_afe_tuner_cfg *cfg = mt8195_afe_found_apll_tuner(id); unsigned long flags; - int ret = 0; + int ret; if (!cfg) return -EINVAL; @@ -338,7 +338,7 @@ static int mt8195_afe_disable_apll_tuner(struct mtk_base_afe *afe, if (ret) return ret; - return ret; + return 0; } int mt8195_afe_get_mclk_source_clk_id(int sel) -- GitLab From 015d9ab7805fb1b3766d1dc487ed34dbc03bd4da Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:15 -0500 Subject: [PATCH 163/942] ASoC: qcom: q6dsp: q6adm: remove useless initializations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck complains about invalid NULL dereferences but there's indeed no need to initialize loop variables. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-13-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6adm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c index 72c5719f1d253..22b408c3794e0 100644 --- a/sound/soc/qcom/qdsp6/q6adm.c +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -90,7 +90,7 @@ struct q6adm_session_map_node_v5 { static struct q6copp *q6adm_find_copp(struct q6adm *adm, int port_idx, int copp_idx) { - struct q6copp *c = NULL; + struct q6copp *c; struct q6copp *ret = NULL; unsigned long flags; @@ -299,7 +299,7 @@ static struct q6copp *q6adm_find_matching_copp(struct q6adm *adm, int channel_mode, int bit_width, int app_type) { - struct q6copp *c = NULL; + struct q6copp *c; struct q6copp *ret = NULL; unsigned long flags; -- GitLab From 7518be0cc120d7617a8985787196cd5776b93688 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:16 -0500 Subject: [PATCH 164/942] ASoC: qcom: q6dsp: remove spurious space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/qcom/qdsp6/q6adm.c:183:14: warning:inconclusive: Found suspicious oper ator '*' [constStatement] } __packed * open = data->payload; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6adm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c index 22b408c3794e0..01f383888b622 100644 --- a/sound/soc/qcom/qdsp6/q6adm.c +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -180,7 +180,7 @@ static int q6adm_callback(struct apr_device *adev, struct apr_resp_pkt *data) u32 status; u16 copp_id; u16 reserved; - } __packed * open = data->payload; + } __packed *open = data->payload; copp = q6adm_find_copp(adm, port_idx, copp_idx); if (!copp) -- GitLab From 59a6cc5c5d64ca20461fec46e450e0639b1e6410 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:17 -0500 Subject: [PATCH 165/942] ASoC: rockchip: simplify error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/rockchip/rk3288_hdmi_analog.c:256:9: warning: Identical condition and return expression 'ret', return value is always 0 [identicalConditionAfterEarlyExit] return ret; ^ sound/soc/rockchip/rk3288_hdmi_analog.c:252:6: note: If condition 'ret' is true, the function will return/exit if (ret) ^ sound/soc/rockchip/rk3288_hdmi_analog.c:256:9: note: Returning identical expression 'ret' return ret; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-15-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rk3288_hdmi_analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index bcdeddeba80c9..0c6bd9a019dbe 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -169,7 +169,7 @@ static struct snd_soc_card snd_soc_card_rk = { static int snd_rk_mc_probe(struct platform_device *pdev) { - int ret = 0; + int ret; struct snd_soc_card *card = &snd_soc_card_rk; struct device_node *np = pdev->dev.of_node; struct rk_drvdata *machine; @@ -253,7 +253,7 @@ static int snd_rk_mc_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, ret, "Soc register card failed\n"); - return ret; + return 0; } static const struct of_device_id rockchip_sound_of_match[] = { -- GitLab From 0c57064e3fdba9bb76086b9a6e318eb0cef24b69 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:18 -0500 Subject: [PATCH 166/942] ASoC: samsung: snow: simplify error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck warning: sound/soc/samsung/snow.c:219:9: warning: Identical condition and return expression 'ret', return value is always 0 [identicalConditionAfterEarlyExit] return ret; ^ sound/soc/samsung/snow.c:215:6: note: If condition 'ret' is true, the function will return/exit if (ret) ^ sound/soc/samsung/snow.c:219:9: note: Returning identical expression 'ret' return ret; ^ Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-16-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/samsung/snow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c index 02372109c251e..da342da038804 100644 --- a/sound/soc/samsung/snow.c +++ b/sound/soc/samsung/snow.c @@ -216,7 +216,7 @@ static int snow_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n"); - return ret; + return 0; } static int snow_remove(struct platform_device *pdev) -- GitLab From 7188b28f6686af0bc4aa1f96d720de782769a0a9 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 20 May 2022 16:17:19 -0500 Subject: [PATCH 167/942] ASoC: meson: remove useless initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cppcheck complains about invalid NULL dereferences but there's indeed no need to initialize a loop variable. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220520211719.607543-17-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/meson/meson-codec-glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/meson/meson-codec-glue.c b/sound/soc/meson/meson-codec-glue.c index 2870cfad813ac..80c5ed196961d 100644 --- a/sound/soc/meson/meson-codec-glue.c +++ b/sound/soc/meson/meson-codec-glue.c @@ -13,7 +13,7 @@ static struct snd_soc_dapm_widget * meson_codec_glue_get_input(struct snd_soc_dapm_widget *w) { - struct snd_soc_dapm_path *p = NULL; + struct snd_soc_dapm_path *p; struct snd_soc_dapm_widget *in; snd_soc_dapm_widget_for_each_source_path(w, p) { -- GitLab From 0a034d93ee929a9ea89f3fa5f1d8492435b9ee6e Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 3 Jun 2022 17:10:43 +0400 Subject: [PATCH 168/942] ASoC: cros_ec_codec: Fix refcount leak in cros_ec_codec_platform_probe of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: b6bc07d4360d ("ASoC: cros_ec_codec: support WoV") Signed-off-by: Miaoqian Lin Reviewed-by: Tzung-Bi Shih Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20220603131043.38907-1-linmq006@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/cros_ec_codec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 8b0a9c788a264..11e7b3f6d410b 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -995,6 +995,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", priv->ap_shm_phys_addr, priv->ap_shm_len); } + of_node_put(node); } #endif -- GitLab From 3e2649c5e8643bea0867bb1dd970fedadb0eb7f3 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 3 Jun 2022 17:06:39 +0400 Subject: [PATCH 169/942] ASoC: samsung: Fix error handling in aries_audio_probe of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. This function is missing of_node_put(cpu) in the error path. Fix this by goto out label. of_node_put() will check NULL pointer. Fixes: 7a3a7671fa6c ("ASoC: samsung: Add driver for Aries boards") Signed-off-by: Miaoqian Lin Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220603130640.37624-1-linmq006@gmail.com Signed-off-by: Mark Brown --- sound/soc/samsung/aries_wm8994.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index bb0cf4244e007..edee02d7f100a 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -628,8 +628,10 @@ static int aries_audio_probe(struct platform_device *pdev) return -EINVAL; codec = of_get_child_by_name(dev->of_node, "codec"); - if (!codec) - return -EINVAL; + if (!codec) { + ret = -EINVAL; + goto out; + } for_each_card_prelinks(card, i, dai_link) { dai_link->codecs->of_node = of_parse_phandle(codec, -- GitLab From 8466579b63cc9aa957b7b4f273087512f989d2a1 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 28 May 2022 09:59:22 +0200 Subject: [PATCH 170/942] ASoC: ux500: Remove some leftover from the "Replace GPLv2 boilerplate/reference with SPDX" rules The "Replace GPLv2 boilerplate/reference with SPDX" has left some empty "License terms" paragraphs. Remove them as well. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/84d94977c57deee9e85249f18394ebf8d72497bc.1653724723.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- sound/soc/ux500/mop500.c | 2 -- sound/soc/ux500/mop500_ab8500.c | 2 -- sound/soc/ux500/mop500_ab8500.h | 2 -- sound/soc/ux500/ux500_msp_dai.c | 2 -- sound/soc/ux500/ux500_msp_dai.h | 2 -- sound/soc/ux500/ux500_msp_i2s.c | 2 -- sound/soc/ux500/ux500_msp_i2s.h | 2 -- sound/soc/ux500/ux500_pcm.c | 2 -- sound/soc/ux500/ux500_pcm.h | 2 -- 9 files changed, 18 deletions(-) diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 4f41bb0ab2b00..fdd55d772b8e2 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -4,8 +4,6 @@ * * Author: Ola Lilja (ola.o.lilja@stericsson.com) * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index 1ea1729984a9a..e5e73a2bd9fe4 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c @@ -5,8 +5,6 @@ * Author: Ola Lilja , * Kristoffer Karlsson * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/ux500/mop500_ab8500.h b/sound/soc/ux500/mop500_ab8500.h index 087ef246d87da..98de80a9cc4fe 100644 --- a/sound/soc/ux500/mop500_ab8500.h +++ b/sound/soc/ux500/mop500_ab8500.h @@ -4,8 +4,6 @@ * * Author: Ola Lilja * for ST-Ericsson. - * - * License terms: */ #ifndef MOP500_AB8500_H diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 21052378a32eb..56532b62faf3f 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -5,8 +5,6 @@ * Author: Ola Lilja , * Roger Nilsson * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index fcd4b26f5d2de..30bf708381961 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h @@ -5,8 +5,6 @@ * Author: Ola Lilja , * Roger Nilsson * for ST-Ericsson. - * - * License terms: */ #ifndef UX500_msp_dai_H diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index fd0b88bb79212..d113411a19f82 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -6,8 +6,6 @@ * Roger Nilsson , * Sandeep Kaushik * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 756b3973af9af..d45b5e2831cc0 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h @@ -4,8 +4,6 @@ * * Author: Ola Lilja , * for ST-Ericsson. - * - * License terms: */ diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 18191084b8b84..d3802e5ef196e 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -5,8 +5,6 @@ * Author: Ola Lilja , * Roger Nilsson * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h index ff3ef7223db69..bd4348ebf9a13 100644 --- a/sound/soc/ux500/ux500_pcm.h +++ b/sound/soc/ux500/ux500_pcm.h @@ -5,8 +5,6 @@ * Author: Ola Lilja , * Roger Nilsson * for ST-Ericsson. - * - * License terms: */ #ifndef UX500_PCM_H #define UX500_PCM_H -- GitLab From 2f4a8171da06609bb6a063630ed546ee3d93dad7 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 25 May 2022 22:05:43 -0300 Subject: [PATCH 171/942] ASoC: imx-audmux: Silence a clang warning Change the of_device_get_match_data() cast to (uintptr_t) to silence the following clang warning: sound/soc/fsl/imx-audmux.c:301:16: warning: cast to smaller integer type 'enum imx_audmux_type' from 'const void *' [-Wvoid-pointer-to-enum-cast] Reported-by: kernel test robot Fixes: 6a8b8b582db1 ("ASoC: imx-audmux: Remove unused .id_table") Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20220526010543.1164793-1-festevam@gmail.com Signed-off-by: Mark Brown --- sound/soc/fsl/imx-audmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index dfa05d40b2764..a8e5e0f57faf9 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -298,7 +298,7 @@ static int imx_audmux_probe(struct platform_device *pdev) audmux_clk = NULL; } - audmux_type = (enum imx_audmux_type)of_device_get_match_data(&pdev->dev); + audmux_type = (uintptr_t)of_device_get_match_data(&pdev->dev); switch (audmux_type) { case IMX31_AUDMUX: -- GitLab From b521e85eefa384a5c31984b1a7e0d71b762c9663 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 28 May 2022 10:00:53 +0200 Subject: [PATCH 172/942] ASoC: ab8500: Remove some leftover from the "Replace GPLv2 boilerplate/reference with SPDX" rules The "Replace GPLv2 boilerplate/reference with SPDX" has left some empty "License terms" paragraphs. Remove them as well. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/28c0833d4a11f8f75f385e5aad93c23721b06c7e.1653724847.git.christophe.jaillet@wanadoo.fr Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 2 -- sound/soc/codecs/ab8500-codec.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index aefafb0b7b974..cbd4a92cb06ce 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -12,8 +12,6 @@ * Mikko Sarmanne , * Jarmo K. Kuronen , * for ST-Ericsson. - * - * License terms: */ #include diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h index 0ac87d0446c2a..2a6f6409f1f85 100644 --- a/sound/soc/codecs/ab8500-codec.h +++ b/sound/soc/codecs/ab8500-codec.h @@ -11,8 +11,6 @@ * Mikko J. Lehto , * Mikko Sarmanne , * for ST-Ericsson. - * - * License terms: */ #ifndef AB8500_CODEC_REGISTERS_H -- GitLab From b661a848a50c0cc3e0b79795c74469d7b50ff4ac Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 May 2022 13:11:29 +0200 Subject: [PATCH 173/942] ASoC: amd: acp: fix typo in comment Spelling mistake (triple letters) in comment. Detected with the help of Coccinelle. Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/20220521111145.81697-79-Julia.Lawall@inria.fr Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-pdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 424c6e0bb9d6d..7a0b26a30051c 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -174,7 +174,7 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream, struct acp_dev_data *adata = dev_get_drvdata(dev); u32 ext_int_ctrl; - /* Disable DMIC interrrupts */ + /* Disable DMIC interrupts */ ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL); ext_int_ctrl |= ~PDM_DMA_INTR_MASK; writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL); -- GitLab From 99b5c107506c728b8a7d25742cf13f6c9c89d6ea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 11:29:20 +0200 Subject: [PATCH 174/942] ASoC: ops: Clarify snd_soc_info_volsw_sx() Currently snd_soc_info_volsw_sx() is implemented indirectly, wrapping snd_soc_info_volsw() and modifying the values it sets up rather than directly setting up the values reported to userspace. This makes it much harder to follow what the intended behaviour of these controls is. Let's rewrite the function to be self contained with a clarifying comment at the top in an effort to help maintainability. Signed-off-by: Mark Brown Reviewed-by: Charles Keepax Tested-by: Charles Keepax Link: https://lore.kernel.org/r/20220602092921.3302713-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index e693070f51fe8..8c0e669fe92dd 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -203,7 +203,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw); * Callback to provide information about a single mixer control, or a double * mixer control that spans 2 registers of the SX TLV type. SX TLV controls * have a range that represents both positive and negative values either side - * of zero but without a sign bit. + * of zero but without a sign bit. min is the minimum register value, max is + * the number of steps. * * Returns 0 for success. */ @@ -212,12 +213,21 @@ int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + int max; - snd_soc_info_volsw(kcontrol, uinfo); - /* Max represents the number of levels in an SX control not the - * maximum value, so add the minimum value back on - */ - uinfo->value.integer.max += mc->min; + if (mc->platform_max) + max = mc->platform_max; + else + max = mc->max; + + if (max == 1 && !strstr(kcontrol->id.name, " Volume")) + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + + uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = max; return 0; } -- GitLab From f53f50ee21d46094a8c48970e95e38a4deaa128e Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 1 Jun 2022 11:23:40 +0200 Subject: [PATCH 175/942] ASoC: fsl_sai: use local device pointer Use a local variable to dereference the device pointer once and use the local variable in further calls. No functional changes. Signed-off-by: Marco Felsch Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20220601092342.3328644-1-m.felsch@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index fa950dde53109..a7637d602f3cc 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1004,6 +1004,7 @@ static int fsl_sai_runtime_resume(struct device *dev); static int fsl_sai_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; struct fsl_sai *sai; struct regmap *gpr; struct resource *res; @@ -1012,12 +1013,12 @@ static int fsl_sai_probe(struct platform_device *pdev) int irq, ret, i; int index; - sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); + sai = devm_kzalloc(dev, sizeof(*sai), GFP_KERNEL); if (!sai) return -ENOMEM; sai->pdev = pdev; - sai->soc_data = of_device_get_match_data(&pdev->dev); + sai->soc_data = of_device_get_match_data(dev); sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); @@ -1032,18 +1033,18 @@ static int fsl_sai_probe(struct platform_device *pdev) ARRAY_SIZE(fsl_sai_reg_defaults_ofs8); } - sai->regmap = devm_regmap_init_mmio(&pdev->dev, base, &fsl_sai_regmap_config); + sai->regmap = devm_regmap_init_mmio(dev, base, &fsl_sai_regmap_config); if (IS_ERR(sai->regmap)) { - dev_err(&pdev->dev, "regmap init failed\n"); + dev_err(dev, "regmap init failed\n"); return PTR_ERR(sai->regmap); } - sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); + sai->bus_clk = devm_clk_get(dev, "bus"); /* Compatible with old DTB cases */ if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER) - sai->bus_clk = devm_clk_get(&pdev->dev, "sai"); + sai->bus_clk = devm_clk_get(dev, "sai"); if (IS_ERR(sai->bus_clk)) { - dev_err(&pdev->dev, "failed to get bus clock: %ld\n", + dev_err(dev, "failed to get bus clock: %ld\n", PTR_ERR(sai->bus_clk)); /* -EPROBE_DEFER */ return PTR_ERR(sai->bus_clk); @@ -1051,9 +1052,9 @@ static int fsl_sai_probe(struct platform_device *pdev) for (i = 1; i < FSL_SAI_MCLK_MAX; i++) { sprintf(tmp, "mclk%d", i); - sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); + sai->mclk_clk[i] = devm_clk_get(dev, tmp); if (IS_ERR(sai->mclk_clk[i])) { - dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", + dev_err(dev, "failed to get mclk%d clock: %ld\n", i + 1, PTR_ERR(sai->mclk_clk[i])); sai->mclk_clk[i] = NULL; } @@ -1068,10 +1069,10 @@ static int fsl_sai_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, IRQF_SHARED, + ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED, np->name, sai); if (ret) { - dev_err(&pdev->dev, "failed to claim irq %u\n", irq); + dev_err(dev, "failed to claim irq %u\n", irq); return ret; } @@ -1088,7 +1089,7 @@ static int fsl_sai_probe(struct platform_device *pdev) if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && of_find_property(np, "fsl,sai-asynchronous", NULL)) { /* error out if both synchronous and asynchronous are present */ - dev_err(&pdev->dev, "invalid binding for synchronous mode\n"); + dev_err(dev, "invalid binding for synchronous mode\n"); return -EINVAL; } @@ -1109,7 +1110,7 @@ static int fsl_sai_probe(struct platform_device *pdev) of_device_is_compatible(np, "fsl,imx6ul-sai")) { gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); if (IS_ERR(gpr)) { - dev_err(&pdev->dev, "cannot find iomuxc registers\n"); + dev_err(dev, "cannot find iomuxc registers\n"); return PTR_ERR(gpr); } @@ -1127,23 +1128,23 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; platform_set_drvdata(pdev, sai); - pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { - ret = fsl_sai_runtime_resume(&pdev->dev); + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) { + ret = fsl_sai_runtime_resume(dev); if (ret) goto err_pm_disable; } - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_get_sync(dev); if (ret < 0) { - pm_runtime_put_noidle(&pdev->dev); + pm_runtime_put_noidle(dev); goto err_pm_get_sync; } /* Get sai version */ - ret = fsl_sai_check_version(&pdev->dev); + ret = fsl_sai_check_version(dev); if (ret < 0) - dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret); + dev_warn(dev, "Error reading SAI version: %d\n", ret); /* Select MCLK direction */ if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) && @@ -1152,7 +1153,7 @@ static int fsl_sai_probe(struct platform_device *pdev) FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); } - ret = pm_runtime_put_sync(&pdev->dev); + ret = pm_runtime_put_sync(dev); if (ret < 0) goto err_pm_get_sync; @@ -1165,12 +1166,12 @@ static int fsl_sai_probe(struct platform_device *pdev) if (ret) goto err_pm_get_sync; } else { - ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0); if (ret) goto err_pm_get_sync; } - ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, + ret = devm_snd_soc_register_component(dev, &fsl_component, &sai->cpu_dai_drv, 1); if (ret) goto err_pm_get_sync; @@ -1178,10 +1179,10 @@ static int fsl_sai_probe(struct platform_device *pdev) return ret; err_pm_get_sync: - if (!pm_runtime_status_suspended(&pdev->dev)) - fsl_sai_runtime_suspend(&pdev->dev); + if (!pm_runtime_status_suspended(dev)) + fsl_sai_runtime_suspend(dev); err_pm_disable: - pm_runtime_disable(&pdev->dev); + pm_runtime_disable(dev); return ret; } -- GitLab From 22205521770ee740f64a3ec90301f50e34738cfd Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 1 Jun 2022 11:23:42 +0200 Subject: [PATCH 176/942] ASoC: fsl_sai: add error message in case of missing imx-pcm-dma support If the imx-pcm-dma is required we need to have the module enabled. For all NXP/FSL sound cards using the ASoC architecture this is the case but in case of using the simple-audio-card sound card this isn't the case. In such case the driver probe fails silently and the card isn't available. It took a while to find the missing Kconfig. Make this easier for others by printing a error if this the module isn't available but required by the HW. Signed-off-by: Marco Felsch Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20220601092342.3328644-3-m.felsch@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a7637d602f3cc..b65c9c7cf54a4 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1163,8 +1163,11 @@ static int fsl_sai_probe(struct platform_device *pdev) */ if (sai->soc_data->use_imx_pcm) { ret = imx_pcm_dma_init(pdev); - if (ret) + if (ret) { + if (!IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)) + dev_err(dev, "Error: You must enable the imx-pcm-dma support!\n"); goto err_pm_get_sync; + } } else { ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0); if (ret) -- GitLab From ae4f11c1ed2d67192fdf3d89db719ee439827c11 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 2 Jun 2022 07:41:42 +0400 Subject: [PATCH 177/942] ASoC: mediatek: mt8173: Fix refcount leak in mt8173_rt5650_rt5676_dev_probe of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Fix missing of_node_put() in error paths. Fixes: 94319ba10eca ("ASoC: mediatek: Use platform_of_node for machine drivers") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220602034144.60159-1-linmq006@gmail.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index 70bf312e855f6..8794720cea3a0 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -256,14 +256,16 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } mt8173_rt5650_rt5676_codec_conf[0].dlc.of_node = mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node; @@ -276,13 +278,15 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } card->dev = &pdev->dev; ret = devm_snd_soc_register_card(&pdev->dev, card); +put_node: of_node_put(platform_node); return ret; } -- GitLab From aa7407f807b250eca7697e5fe9a699bc6c2fab71 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 5 Jun 2022 09:31:23 -0700 Subject: [PATCH 178/942] ASoC: max98390: use linux/gpio/consumer.h to fix build Change the header file to fix build errors in max98390.c: ../sound/soc/codecs/max98390.c: In function 'max98390_i2c_probe': ../sound/soc/codecs/max98390.c:1076:22: error: implicit declaration of function 'devm_gpiod_get_optional'; did you mean 'devm_regulator_get_optional'? [-Werror=implicit-function-declaration] 1076 | reset_gpio = devm_gpiod_get_optional(&i2c->dev, ../sound/soc/codecs/max98390.c:1077:55: error: 'GPIOD_OUT_HIGH' undeclared (first use in this function); did you mean 'GPIOF_INIT_HIGH'? 1077 | "reset", GPIOD_OUT_HIGH); ../sound/soc/codecs/max98390.c:1077:55: note: each undeclared identifier is reported only once for each function it appears in ../sound/soc/codecs/max98390.c:1083:17: error: implicit declaration of function 'gpiod_set_value_cansleep'; did you mean 'gpio_set_value_cansleep'? [-Werror=implicit-function-declaration] 1083 | gpiod_set_value_cansleep(reset_gpio, 0); Fixes: 397ff0249606 ("ASoC: max98390: Add reset gpio control") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Steve Lee Cc: Mark Brown Cc: Liam Girdwood Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: alsa-devel@alsa-project.org Link: https://lore.kernel.org/r/20220605163123.23537-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98390.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 2a6b1648c8844..d83f81d9ff4ea 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include -- GitLab From ef6c320942a2f057204702d769d507186fd7f0b7 Mon Sep 17 00:00:00 2001 From: Alexander Martinz Date: Thu, 2 Jun 2022 18:45:03 +0200 Subject: [PATCH 179/942] ASoC: codecs: tfa989x: Add support for tfa9890 The initialization sequence is taken from the version provided by the supplier [1]. This allows speakers using the TFA9890 amplifier to work, which are used by various mobile phones such as the SHIFT6mq. [1]: https://source.codeaurora.org/external/mas/tfa98xx/tree/src/tfa_init.c?id=d2cd12931fbc48df988b62931fb9960d4e9dc05d#n1827 Signed-off-by: Alexander Martinz Reviewed-by: Stephan Gerhold Link: https://lore.kernel.org/r/20220602164504.261361-1-amartinz@shiftphones.com Signed-off-by: Mark Brown --- sound/soc/codecs/tfa989x.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/soc/codecs/tfa989x.c b/sound/soc/codecs/tfa989x.c index dc86852752c50..8ab2656de7505 100644 --- a/sound/soc/codecs/tfa989x.c +++ b/sound/soc/codecs/tfa989x.c @@ -40,12 +40,14 @@ #define TFA989X_I2S_SEL_REG 0x0a #define TFA989X_I2S_SEL_REG_SPKR_MSK GENMASK(10, 9) /* speaker impedance */ #define TFA989X_I2S_SEL_REG_DCFG_MSK GENMASK(14, 11) /* DCDC compensation */ +#define TFA989X_HIDE_UNHIDE_KEY 0x40 #define TFA989X_PWM_CONTROL 0x41 #define TFA989X_CURRENTSENSE1 0x46 #define TFA989X_CURRENTSENSE2 0x47 #define TFA989X_CURRENTSENSE3 0x48 #define TFA989X_CURRENTSENSE4 0x49 +#define TFA9890_REVISION 0x80 #define TFA9895_REVISION 0x12 #define TFA9897_REVISION 0x97 @@ -188,6 +190,33 @@ static struct snd_soc_dai_driver tfa989x_dai = { .ops = &tfa989x_dai_ops, }; +static int tfa9890_init(struct regmap *regmap) +{ + int ret; + + /* unhide keys to allow updating them */ + ret = regmap_write(regmap, TFA989X_HIDE_UNHIDE_KEY, 0x5a6b); + if (ret) + return ret; + + /* update PLL registers */ + ret = regmap_set_bits(regmap, 0x59, 0x3); + if (ret) + return ret; + + /* hide keys again */ + ret = regmap_write(regmap, TFA989X_HIDE_UNHIDE_KEY, 0x0000); + if (ret) + return ret; + + return regmap_write(regmap, TFA989X_CURRENTSENSE2, 0x7BE1); +} + +static const struct tfa989x_rev tfa9890_rev = { + .rev = TFA9890_REVISION, + .init = tfa9890_init, +}; + static const struct reg_sequence tfa9895_reg_init[] = { /* some other registers must be set for optimal amplifier behaviour */ { TFA989X_BAT_PROT, 0x13ab }, @@ -376,6 +405,7 @@ static int tfa989x_i2c_probe(struct i2c_client *i2c) } static const struct of_device_id tfa989x_of_match[] = { + { .compatible = "nxp,tfa9890", .data = &tfa9890_rev }, { .compatible = "nxp,tfa9895", .data = &tfa9895_rev }, { .compatible = "nxp,tfa9897", .data = &tfa9897_rev }, { } -- GitLab From d0da7c8668dc19df157d927a67721ca00e29ff2b Mon Sep 17 00:00:00 2001 From: Alexander Martinz Date: Thu, 2 Jun 2022 18:45:04 +0200 Subject: [PATCH 180/942] ASoC: dt-bindings: nxp,tfa989x: Add tfa9890 support Document TFA9890 binding for tfa989x. Signed-off-by: Alexander Martinz Reviewed-by: Stephan Gerhold Acked-by: Rob Herring Link: https://lore.kernel.org/r/20220602164504.261361-2-amartinz@shiftphones.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml b/Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml index b9b1dba40856d..7f2e68ff6d342 100644 --- a/Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml +++ b/Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml @@ -15,6 +15,7 @@ allOf: properties: compatible: enum: + - nxp,tfa9890 - nxp,tfa9895 - nxp,tfa9897 -- GitLab From 6398b004cfcce38626f3ba6fa5853177a3501aae Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 20 May 2022 11:06:00 +0800 Subject: [PATCH 181/942] ASoC: fsl_asrc_dma: enable dual fifo for ASRC P2P The SSI and SPDIF has dual fifos, enhance P2P for these case with using the sdma_peripheral_config struct Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1653015960-15474-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_asrc_dma.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 5038faf035cba..aaf7993935b74 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -129,6 +129,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, struct snd_pcm_hw_params *params) { enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; + enum sdma_peripheral_type be_peripheral_type = IMX_DMATYPE_SSI; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL; @@ -139,6 +140,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, struct snd_soc_component *component_be = NULL; struct fsl_asrc *asrc = pair->asrc; struct dma_slave_config config_fe, config_be; + struct sdma_peripheral_config audio_config; enum asrc_pair_index index = pair->index; struct device *dev = component->dev; struct device_node *of_dma_node; @@ -221,6 +223,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, /* Get DMA request of Back-End */ tmp_data = tmp_chan->private; pair->dma_data.dma_request = tmp_data->dma_request; + be_peripheral_type = tmp_data->peripheral_type; if (!be_chan) dma_release_channel(tmp_chan); @@ -268,6 +271,17 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, config_be.dst_addr_width = buswidth; config_be.dst_maxburst = dma_params_be->maxburst; + memset(&audio_config, 0, sizeof(audio_config)); + config_be.peripheral_config = &audio_config; + config_be.peripheral_size = sizeof(audio_config); + + if (tx && (be_peripheral_type == IMX_DMATYPE_SSI_DUAL || + be_peripheral_type == IMX_DMATYPE_SPDIF)) + audio_config.n_fifos_dst = 2; + if (!tx && (be_peripheral_type == IMX_DMATYPE_SSI_DUAL || + be_peripheral_type == IMX_DMATYPE_SPDIF)) + audio_config.n_fifos_src = 2; + if (tx) { config_be.src_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index); config_be.dst_addr = dma_params_be->addr; -- GitLab From ff31753fcb061b90bd8c356d5b27a6eb5f8ade15 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 30 May 2022 04:28:44 +0000 Subject: [PATCH 182/942] ASoC: simple-card-utils: rename asoc_simple_init_dai_link_params() to asoc_simple_init_for_codec2codec() commit 95cfc0a0aaf5752071 ("ASoC: simple-card: Add support for codec2codec DAI links") added the function asoc_simple_init_dai_link_params() to initialize dai_link "params". It is very straight naming, but difficult to noticed that it is for Codec2Codec support. Handling Codec2Codec is one of very tricky part on ALSA SoC, thus it is very important to clarify it. This patch renames the function name. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87o7zflk3n.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 539d7f081bd79..fa080f166345c 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -513,7 +513,7 @@ static int asoc_simple_init_dai(struct snd_soc_dai *dai, return 0; } -static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd, +static int asoc_simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, struct simple_dai_props *dai_props) { struct snd_soc_dai_link *dai_link = rtd->dai_link; @@ -575,7 +575,7 @@ int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd) return ret; } - ret = asoc_simple_init_dai_link_params(rtd, props); + ret = asoc_simple_init_for_codec2codec(rtd, props); if (ret < 0) return ret; -- GitLab From 3ae190edc5f6f64f296f8dd15f4b511f529ab402 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 12:35:30 +0200 Subject: [PATCH 183/942] ASoC: nau8822: Don't reconfigure PLL to the same values When we configure the PLL record the input and output frequency, then if we get asked to configure the same values again just skip reprogramming the hardware. This makes things a bit easier to use for machine drivers since it means they don't need to keep track of if they've programmed the PLL so much. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220603103530.3844527-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/nau8822.c | 7 +++++++ sound/soc/codecs/nau8822.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 08f6c56dc387f..f4f68b549e1ae 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -726,6 +726,10 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, struct nau8822_pll *pll_param = &nau8822->pll; int ret, fs; + if (freq_in == pll_param->freq_in && + freq_out == pll_param->freq_out) + return 0; + fs = freq_out / 256; ret = nau8822_calc_pll(freq_in, fs, pll_param); @@ -762,6 +766,9 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, snd_soc_component_update_bits(component, NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_ON); + pll_param->freq_in = freq_in; + pll_param->freq_out = freq_out; + return 0; } diff --git a/sound/soc/codecs/nau8822.h b/sound/soc/codecs/nau8822.h index b45d42c15de6b..547ec057f853b 100644 --- a/sound/soc/codecs/nau8822.h +++ b/sound/soc/codecs/nau8822.h @@ -198,6 +198,8 @@ struct nau8822_pll { int mclk_scaler; int pll_frac; int pll_int; + int freq_in; + int freq_out; }; /* Codec Private Data */ -- GitLab From 84965cc60e643db7049eb75bb9a6cc5cd66ee3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 20 May 2022 19:33:49 +0200 Subject: [PATCH 184/942] ASoC: cs35l45: Make cs35l45_remove() return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cs35l45_remove() always returns zero. Make it return no value which makes it easier to see in the callers that there is no error to handle. Also the return value of i2c driver remove callbacks is ignored anyway. This prepares making i2c remove callbacks return void, too. Signed-off-by: Uwe Kleine-König Acked-by: Charles Keepax Reviewed-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20220520173349.774366-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l45-i2c.c | 4 +++- sound/soc/codecs/cs35l45.c | 4 +--- sound/soc/codecs/cs35l45.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs35l45-i2c.c b/sound/soc/codecs/cs35l45-i2c.c index 38a4dbc9e9fea..06c2ddffb9c53 100644 --- a/sound/soc/codecs/cs35l45-i2c.c +++ b/sound/soc/codecs/cs35l45-i2c.c @@ -40,7 +40,9 @@ static int cs35l45_i2c_remove(struct i2c_client *client) { struct cs35l45_private *cs35l45 = i2c_get_clientdata(client); - return cs35l45_remove(cs35l45); + cs35l45_remove(cs35l45); + + return 0; } static const struct of_device_id cs35l45_of_match[] = { diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 2367c1a4c10eb..c94edfce4b720 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -665,7 +665,7 @@ int cs35l45_probe(struct cs35l45_private *cs35l45) } EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); -int cs35l45_remove(struct cs35l45_private *cs35l45) +void cs35l45_remove(struct cs35l45_private *cs35l45) { pm_runtime_disable(cs35l45->dev); @@ -673,8 +673,6 @@ int cs35l45_remove(struct cs35l45_private *cs35l45) regulator_disable(cs35l45->vdd_a); /* VDD_BATT must be the last to power-off */ regulator_disable(cs35l45->vdd_batt); - - return 0; } EXPORT_SYMBOL_NS_GPL(cs35l45_remove, SND_SOC_CS35L45); diff --git a/sound/soc/codecs/cs35l45.h b/sound/soc/codecs/cs35l45.h index 4e266d19cd1cd..680891bcfce9a 100644 --- a/sound/soc/codecs/cs35l45.h +++ b/sound/soc/codecs/cs35l45.h @@ -212,6 +212,6 @@ extern const struct regmap_config cs35l45_spi_regmap; int cs35l45_apply_patch(struct cs35l45_private *cs43l45); unsigned int cs35l45_get_clk_freq_id(unsigned int freq); int cs35l45_probe(struct cs35l45_private *cs35l45); -int cs35l45_remove(struct cs35l45_private *cs35l45); +void cs35l45_remove(struct cs35l45_private *cs35l45); #endif /* CS35L45_H */ -- GitLab From 9c3148dec7d2d40ef727b8789d3e9410ad6d4a1f Mon Sep 17 00:00:00 2001 From: zhangqilong Date: Thu, 2 Jun 2022 15:20:24 +0800 Subject: [PATCH 185/942] ASoC: fsl_xcvr:Fix unbalanced pm_runtime_enable in fsl_xcvr_probe a) Add missing pm_runtime_disable() when probe error out. It could avoid pm_runtime implementation complains when removing and probing again the driver. b) Add remove for missing pm_runtime_disable(). Fix:c590fa80b3928 ("ASoC: fsl_xcvr: register platform component before registering cpu dai") Signed-off-by: Zhang Qilong Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20220602072024.33236-1-zhangqilong3@huawei.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_xcvr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index d0556c79fdb15..55e640cba87d0 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -1228,6 +1228,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev) */ ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0); if (ret) { + pm_runtime_disable(dev); dev_err(dev, "failed to pcm register\n"); return ret; } @@ -1235,6 +1236,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev) ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp, &fsl_xcvr_dai, 1); if (ret) { + pm_runtime_disable(dev); dev_err(dev, "failed to register component %s\n", fsl_xcvr_comp.name); } @@ -1242,6 +1244,12 @@ static int fsl_xcvr_probe(struct platform_device *pdev) return ret; } +static int fsl_xcvr_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + return 0; +} + static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev) { struct fsl_xcvr *xcvr = dev_get_drvdata(dev); @@ -1370,6 +1378,7 @@ static struct platform_driver fsl_xcvr_driver = { .pm = &fsl_xcvr_pm_ops, .of_match_table = fsl_xcvr_dt_ids, }, + .remove = fsl_xcvr_remove, }; module_platform_driver(fsl_xcvr_driver); -- GitLab From bf1ebcddcb19a1b6d6d8b75b75626197a5a76d4f Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Wed, 25 May 2022 21:50:23 +0800 Subject: [PATCH 186/942] ASoC: stm32: sai: Remove useless define STM_SAI_IS_SUB_B(x) and STM_SAI_BLOCK_NAME(x) are not being used, so remove them. Signed-off-by: Tang Bin Acked-by: Olivier Moysan Link: https://lore.kernel.org/r/20220525135023.6792-1-tangbin@cmss.chinamobile.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_sai_sub.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index dd636af81c9bd..4296fcb245c94 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -45,8 +45,6 @@ #define STM_SAI_B_ID 0x1 #define STM_SAI_IS_SUB_A(x) ((x)->id == STM_SAI_A_ID) -#define STM_SAI_IS_SUB_B(x) ((x)->id == STM_SAI_B_ID) -#define STM_SAI_BLOCK_NAME(x) (((x)->id == STM_SAI_A_ID) ? "A" : "B") #define SAI_SYNC_NONE 0x0 #define SAI_SYNC_INTERNAL 0x1 -- GitLab From fef94875a72bc63ba60d2e12421d7f49d31523f0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 12:18:33 +0200 Subject: [PATCH 187/942] ASoC: ops: Remove unneeded delay.h inclusion The ops code does not do any sleeps or delays so does not need delay.h. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602101833.3481641-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 8c0e669fe92dd..2d5910b6ca54d 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include -- GitLab From 32882881078bd8f8fae47ff69c102d9e691f5bb9 Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Mandadapu Date: Wed, 18 May 2022 18:12:35 +0530 Subject: [PATCH 188/942] ASoC: qcom: soundwire: Add support for controlling audio CGCR from HLOS Add support for controlling soundwire audio CGCR interface using clock framework to make hclk ungating with software. As per new hardware changes, software has to always ungate hclk if soundwire is operational and keep it running. This requirement is for latest LPASS chipsets for RX, TX and WSA path to work. Signed-off-by: Srinivasa Rao Mandadapu Link: https://lore.kernel.org/r/1652877755-25120-1-git-send-email-quic_srivasam@quicinc.com Signed-off-by: Mark Brown --- drivers/soundwire/qcom.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 22b706350ead3..a3fccf051e076 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -142,6 +143,7 @@ struct qcom_swrm_ctrl { struct device *dev; struct regmap *regmap; void __iomem *mmio; + struct reset_control *audio_cgcr; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs; #endif @@ -656,6 +658,8 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl) val = FIELD_PREP(SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK, ctrl->rows_index); val |= FIELD_PREP(SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK, ctrl->cols_index); + reset_control_reset(ctrl->audio_cgcr); + ctrl->reg_write(ctrl, SWRM_MCP_FRAME_CTRL_BANK_ADDR(0), val); /* Enable Auto enumeration */ @@ -1332,6 +1336,10 @@ static int qcom_swrm_probe(struct platform_device *pdev) ctrl->bus.compute_params = &qcom_swrm_compute_params; ctrl->bus.clk_stop_timeout = 300; + ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr"); + if (IS_ERR(ctrl->audio_cgcr)) + dev_err(dev, "Failed to get audio_cgcr reset required for soundwire-v1.6.0\n"); + ret = qcom_swrm_get_port_config(ctrl); if (ret) goto err_clk; @@ -1485,6 +1493,8 @@ static int __maybe_unused swrm_runtime_resume(struct device *dev) qcom_swrm_get_device_status(ctrl); sdw_handle_slave_status(&ctrl->bus, ctrl->status); } else { + reset_control_reset(ctrl->audio_cgcr); + ctrl->reg_write(ctrl, SWRM_MCP_BUS_CTRL, SWRM_MCP_BUS_CLK_START); ctrl->reg_write(ctrl, SWRM_INTERRUPT_CLEAR, SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET); -- GitLab From 4f8ed19593872b710f27bbc3b7a9ce03310efc57 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:10:58 +0200 Subject: [PATCH 189/942] ASoC: tfa9879: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tfa9879 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Acked-by: Peter Rosin Link: https://lore.kernel.org/r/20220602131058.3552621-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tfa9879.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index 3d8e8c2276f08..41a9b1b76e629 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c @@ -111,8 +111,8 @@ static int tfa9879_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) int i2s_set; int sck_pol; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From 7472eb8d7dd12b6b9b1a4f4527719cc9c7f5965f Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 3 Jun 2022 12:34:15 +0400 Subject: [PATCH 190/942] ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: f0ab0bf250da ("ASoC: add mt6797-mt6351 driver and config option") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220603083417.9011-1-linmq006@gmail.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt6797/mt6797-mt6351.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/mediatek/mt6797/mt6797-mt6351.c b/sound/soc/mediatek/mt6797/mt6797-mt6351.c index 496f32bcfb5e3..d2f6213a6bfcc 100644 --- a/sound/soc/mediatek/mt6797/mt6797-mt6351.c +++ b/sound/soc/mediatek/mt6797/mt6797-mt6351.c @@ -217,7 +217,8 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev) if (!codec_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } for_each_card_prelinks(card, i, dai_link) { if (dai_link->codecs->name) @@ -230,6 +231,9 @@ static int mt6797_mt6351_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret); + of_node_put(codec_node); +put_platform_node: + of_node_put(platform_node); return ret; } -- GitLab From 82fa8f581a954ddeec1602bed9f8b4a09d100e6e Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 31 May 2022 17:47:12 +0800 Subject: [PATCH 191/942] ASoC: codecs: da7210: add check for i2c_add_driver As i2c_add_driver could return error if fails, it should be better to check the return value. However, if the CONFIG_I2C and CONFIG_SPI_MASTER are both true, the return value of i2c_add_driver will be covered by spi_register_driver. Therefore, it is necessary to add check and return error if fails. Fixes: aa0e25caafb7 ("ASoC: da7210: Add support for spi regmap") Signed-off-by: Jiasheng Jiang Link: https://lore.kernel.org/r/20220531094712.2376759-1-jiasheng@iscas.ac.cn Signed-off-by: Mark Brown --- sound/soc/codecs/da7210.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 3fa3042e44242..76a21976ccddb 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1335,6 +1335,8 @@ static int __init da7210_modinit(void) int ret = 0; #if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&da7210_i2c_driver); + if (ret) + return ret; #endif #if defined(CONFIG_SPI_MASTER) ret = spi_register_driver(&da7210_spi_driver); -- GitLab From 12ba5ceb4a08d5ea776d3eaf83c0cee63fafe952 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Thu, 2 Jun 2022 07:18:09 +0000 Subject: [PATCH 192/942] ASoC: mediatek: remove unnecessary check of clk_disable_unprepare Because clk_disable_unprepare already checked NULL clock parameter, so the additional checks are unnecessary, just remove them. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Link: https://lore.kernel.org/r/20220602071809.278134-1-chi.minghao@zte.com.cn Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c index 31494930433f7..dcaeeeb8aac70 100644 --- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c @@ -286,10 +286,8 @@ static int mt8173_afe_dais_set_clks(struct mtk_base_afe *afe, static void mt8173_afe_dais_disable_clks(struct mtk_base_afe *afe, struct clk *m_ck, struct clk *b_ck) { - if (m_ck) - clk_disable_unprepare(m_ck); - if (b_ck) - clk_disable_unprepare(b_ck); + clk_disable_unprepare(m_ck); + clk_disable_unprepare(b_ck); } static int mt8173_afe_i2s_startup(struct snd_pcm_substream *substream, -- GitLab From 8366d8ca0f7805be6cffe1e242822565aed509ae Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 14:58:12 +0200 Subject: [PATCH 193/942] ASoC: max9860: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the max9860 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Acked-by: Peter Rosin Link: https://lore.kernel.org/r/20220602125812.3551947-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/max9860.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 82f20a8e27ad5..a1d0179e12c76 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -448,9 +448,9 @@ static int max9860_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct snd_soc_component *component = dai->component; struct max9860_priv *max9860 = snd_soc_component_get_drvdata(component); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_CBC_CFC: max9860->fmt = fmt; return 0; -- GitLab From 063c915502b914a5a621458c763dfc28286f7606 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 25 May 2022 13:23:41 +0800 Subject: [PATCH 194/942] ASoC: fsl_mqs: simplify the code with adding fsl_mqs_soc_data Add soc specific data struct fsl_mqs_soc_data, move the definition of control register, each function bits to it, then the code can be simplified. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1653456221-21613-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_mqs.c | 119 ++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 48 deletions(-) diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index ceaecbe3a25e4..8a8d727319d6b 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -29,15 +30,41 @@ #define MQS_CLK_DIV_MASK (0xFF << 0) #define MQS_CLK_DIV_SHIFT (0) +/** + * struct fsl_mqs_soc_data - soc specific data + * + * @use_gpr: control register is in General Purpose Register group + * @ctrl_off: control register offset + * @en_mask: enable bit mask + * @en_shift: enable bit shift + * @rst_mask: reset bit mask + * @rst_shift: reset bit shift + * @osr_mask: oversample bit mask + * @osr_shift: oversample bit shift + * @div_mask: clock divider mask + * @div_shift: clock divider bit shift + */ +struct fsl_mqs_soc_data { + bool use_gpr; + int ctrl_off; + int en_mask; + int en_shift; + int rst_mask; + int rst_shift; + int osr_mask; + int osr_shift; + int div_mask; + int div_shift; +}; + /* codec private data */ struct fsl_mqs { struct regmap *regmap; struct clk *mclk; struct clk *ipg; + const struct fsl_mqs_soc_data *soc; - unsigned int reg_iomuxc_gpr2; unsigned int reg_mqs_ctrl; - bool use_gpr; }; #define FSL_MQS_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) @@ -65,19 +92,11 @@ static int fsl_mqs_hw_params(struct snd_pcm_substream *substream, res = mclk_rate % (32 * lrclk * 2 * 8); if (res == 0 && div > 0 && div <= 256) { - if (mqs_priv->use_gpr) { - regmap_update_bits(mqs_priv->regmap, IOMUXC_GPR2, - IMX6SX_GPR2_MQS_CLK_DIV_MASK, - (div - 1) << IMX6SX_GPR2_MQS_CLK_DIV_SHIFT); - regmap_update_bits(mqs_priv->regmap, IOMUXC_GPR2, - IMX6SX_GPR2_MQS_OVERSAMPLE_MASK, 0); - } else { - regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL, - MQS_CLK_DIV_MASK, - (div - 1) << MQS_CLK_DIV_SHIFT); - regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL, - MQS_OVERSAMPLE_MASK, 0); - } + regmap_update_bits(mqs_priv->regmap, mqs_priv->soc->ctrl_off, + mqs_priv->soc->div_mask, + (div - 1) << mqs_priv->soc->div_shift); + regmap_update_bits(mqs_priv->regmap, mqs_priv->soc->ctrl_off, + mqs_priv->soc->osr_mask, 0); } else { dev_err(component->dev, "can't get proper divider\n"); } @@ -118,14 +137,9 @@ static int fsl_mqs_startup(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct fsl_mqs *mqs_priv = snd_soc_component_get_drvdata(component); - if (mqs_priv->use_gpr) - regmap_update_bits(mqs_priv->regmap, IOMUXC_GPR2, - IMX6SX_GPR2_MQS_EN_MASK, - 1 << IMX6SX_GPR2_MQS_EN_SHIFT); - else - regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL, - MQS_EN_MASK, - 1 << MQS_EN_SHIFT); + regmap_update_bits(mqs_priv->regmap, mqs_priv->soc->ctrl_off, + mqs_priv->soc->en_mask, + 1 << mqs_priv->soc->en_shift); return 0; } @@ -135,12 +149,8 @@ static void fsl_mqs_shutdown(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct fsl_mqs *mqs_priv = snd_soc_component_get_drvdata(component); - if (mqs_priv->use_gpr) - regmap_update_bits(mqs_priv->regmap, IOMUXC_GPR2, - IMX6SX_GPR2_MQS_EN_MASK, 0); - else - regmap_update_bits(mqs_priv->regmap, REG_MQS_CTRL, - MQS_EN_MASK, 0); + regmap_update_bits(mqs_priv->regmap, mqs_priv->soc->ctrl_off, + mqs_priv->soc->en_mask, 0); } static const struct snd_soc_component_driver soc_codec_fsl_mqs = { @@ -191,12 +201,9 @@ static int fsl_mqs_probe(struct platform_device *pdev) * But in i.MX8QM/i.MX8QXP the control register is moved * to its own domain. */ - if (of_device_is_compatible(np, "fsl,imx8qm-mqs")) - mqs_priv->use_gpr = false; - else - mqs_priv->use_gpr = true; + mqs_priv->soc = of_device_get_match_data(&pdev->dev); - if (mqs_priv->use_gpr) { + if (mqs_priv->soc->use_gpr) { gpr_np = of_parse_phandle(np, "gpr", 0); if (!gpr_np) { dev_err(&pdev->dev, "failed to get gpr node by phandle\n"); @@ -280,12 +287,7 @@ static int fsl_mqs_runtime_resume(struct device *dev) return ret; } - if (mqs_priv->use_gpr) - regmap_write(mqs_priv->regmap, IOMUXC_GPR2, - mqs_priv->reg_iomuxc_gpr2); - else - regmap_write(mqs_priv->regmap, REG_MQS_CTRL, - mqs_priv->reg_mqs_ctrl); + regmap_write(mqs_priv->regmap, mqs_priv->soc->ctrl_off, mqs_priv->reg_mqs_ctrl); return 0; } @@ -293,12 +295,7 @@ static int fsl_mqs_runtime_suspend(struct device *dev) { struct fsl_mqs *mqs_priv = dev_get_drvdata(dev); - if (mqs_priv->use_gpr) - regmap_read(mqs_priv->regmap, IOMUXC_GPR2, - &mqs_priv->reg_iomuxc_gpr2); - else - regmap_read(mqs_priv->regmap, REG_MQS_CTRL, - &mqs_priv->reg_mqs_ctrl); + regmap_read(mqs_priv->regmap, mqs_priv->soc->ctrl_off, &mqs_priv->reg_mqs_ctrl); clk_disable_unprepare(mqs_priv->mclk); clk_disable_unprepare(mqs_priv->ipg); @@ -315,9 +312,35 @@ static const struct dev_pm_ops fsl_mqs_pm_ops = { pm_runtime_force_resume) }; +static const struct fsl_mqs_soc_data fsl_mqs_imx8qm_data = { + .use_gpr = false, + .ctrl_off = REG_MQS_CTRL, + .en_mask = MQS_EN_MASK, + .en_shift = MQS_EN_SHIFT, + .rst_mask = MQS_SW_RST_MASK, + .rst_shift = MQS_SW_RST_SHIFT, + .osr_mask = MQS_OVERSAMPLE_MASK, + .osr_shift = MQS_OVERSAMPLE_SHIFT, + .div_mask = MQS_CLK_DIV_MASK, + .div_shift = MQS_CLK_DIV_SHIFT, +}; + +static const struct fsl_mqs_soc_data fsl_mqs_imx6sx_data = { + .use_gpr = true, + .ctrl_off = IOMUXC_GPR2, + .en_mask = IMX6SX_GPR2_MQS_EN_MASK, + .en_shift = IMX6SX_GPR2_MQS_EN_SHIFT, + .rst_mask = IMX6SX_GPR2_MQS_SW_RST_MASK, + .rst_shift = IMX6SX_GPR2_MQS_SW_RST_SHIFT, + .osr_mask = IMX6SX_GPR2_MQS_OVERSAMPLE_MASK, + .osr_shift = IMX6SX_GPR2_MQS_OVERSAMPLE_SHIFT, + .div_mask = IMX6SX_GPR2_MQS_CLK_DIV_MASK, + .div_shift = IMX6SX_GPR2_MQS_CLK_DIV_SHIFT, +}; + static const struct of_device_id fsl_mqs_dt_ids[] = { - { .compatible = "fsl,imx8qm-mqs", }, - { .compatible = "fsl,imx6sx-mqs", }, + { .compatible = "fsl,imx8qm-mqs", .data = &fsl_mqs_imx8qm_data }, + { .compatible = "fsl,imx6sx-mqs", .data = &fsl_mqs_imx6sx_data }, {} }; MODULE_DEVICE_TABLE(of, fsl_mqs_dt_ids); -- GitLab From 2685d5046962f018b1a155b3eef316562414638b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 May 2022 13:11:26 +0200 Subject: [PATCH 195/942] ASoC: stm32: dfsdm: fix typo in comment Spelling mistake (triple letters) in comment. Detected with the help of Coccinelle. Signed-off-by: Julia Lawall Link: https://lore.kernel.org/r/20220521111145.81697-76-Julia.Lawall@inria.fr Signed-off-by: Mark Brown --- sound/soc/stm/stm32_adfsdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c index 6ee714542b84a..122805160e70b 100644 --- a/sound/soc/stm/stm32_adfsdm.c +++ b/sound/soc/stm/stm32_adfsdm.c @@ -296,7 +296,7 @@ static int stm32_adfsdm_pcm_new(struct snd_soc_component *component, static int stm32_adfsdm_dummy_cb(const void *data, void *private) { /* - * This dummmy callback is requested by iio_channel_get_all_cb() API, + * This dummy callback is requested by iio_channel_get_all_cb() API, * but the stm32_dfsdm_get_buff_cb() API is used instead, to optimize * DMA transfers. */ -- GitLab From ac8a2ea48001a4c336fbaaa977642d5ad79cdbd8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 13:50:03 +0200 Subject: [PATCH 196/942] ASoC: wm_adsp: Fix event generation for wm_adsp_fw_put() Currently wm_adsp_fw_put() returns 0 rather than 1 when updating the value of the control, meaning that no event is generated to userspace. Fix this by setting the default return value to 1, the code already exits early with a return value of 0 if the value is unchanged. Signed-off-by: Mark Brown Reviewed-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20220603115003.3865834-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 7973a75cac059..6d7fd88243aa8 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -333,7 +333,7 @@ int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); - int ret = 0; + int ret = 1; if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw) return 0; -- GitLab From 3929ead38d61abe6c5302adce1d490f5c041d4b3 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 30 May 2022 12:01:50 +0800 Subject: [PATCH 197/942] ASoC: nau8822: Add operation for internal PLL off and on We tried to enable the audio on an imx6sx EVB with the codec nau8822, after setting the internal PLL fractional parameters, the audio still couldn't work and the there was no sdma irq at all. After checking with the section "8.1.1 Phase Locked Loop (PLL) Design Example" of "NAU88C22 Datasheet Rev 0.6", we found we need to turn off the PLL before programming fractional parameters and turn on the PLL after programming. After this change, the audio driver could record and play sound and the sdma's irq is triggered when playing or recording. Cc: David Lin Cc: John Hsu Cc: Seven Li Signed-off-by: Hui Wang Link: https://lore.kernel.org/r/20220530040151.95221-2-hui.wang@canonical.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8822.c | 4 ++++ sound/soc/codecs/nau8822.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 66bbd8f4f1ad8..08f6c56dc387f 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -740,6 +740,8 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, pll_param->pll_int, pll_param->pll_frac, pll_param->mclk_scaler, pll_param->pre_factor); + snd_soc_component_update_bits(component, + NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF); snd_soc_component_update_bits(component, NAU8822_REG_PLL_N, NAU8822_PLLMCLK_DIV2 | NAU8822_PLLN_MASK, (pll_param->pre_factor ? NAU8822_PLLMCLK_DIV2 : 0) | @@ -757,6 +759,8 @@ static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source, pll_param->mclk_scaler << NAU8822_MCLKSEL_SFT); snd_soc_component_update_bits(component, NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK, NAU8822_CLKM_PLL); + snd_soc_component_update_bits(component, + NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_ON); return 0; } diff --git a/sound/soc/codecs/nau8822.h b/sound/soc/codecs/nau8822.h index 489191ff187ec..b45d42c15de6b 100644 --- a/sound/soc/codecs/nau8822.h +++ b/sound/soc/codecs/nau8822.h @@ -90,6 +90,9 @@ #define NAU8822_REFIMP_3K 0x3 #define NAU8822_IOBUF_EN (0x1 << 2) #define NAU8822_ABIAS_EN (0x1 << 3) +#define NAU8822_PLL_EN_MASK (0x1 << 5) +#define NAU8822_PLL_ON (0x1 << 5) +#define NAU8822_PLL_OFF (0x0 << 5) /* NAU8822_REG_AUDIO_INTERFACE (0x4) */ #define NAU8822_AIFMT_MASK (0x3 << 3) -- GitLab From dd58365d43efccd87dbfc8f93eb3e61b9b4d64f8 Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Mandadapu Date: Fri, 27 May 2022 19:40:08 +0530 Subject: [PATCH 198/942] ASoC: qcom: lpass-platform: Update VMA access permissions in mmap callback Replace page protection permissions from noncashed to writecombine, in lpass codec DMA path mmp callabck, to support 64 bit chromeOS. Avoid SIGBUS error in userspace caused by noncached permissions in 64 bit chromeOS. Signed-off-by: Srinivasa Rao Mandadapu Link: https://lore.kernel.org/r/1653660608-27245-1-git-send-email-quic_srivasam@quicinc.com Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index f03a7ae49d505..b41ab7a321ae9 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -898,7 +898,7 @@ static int lpass_platform_cdc_dma_mmap(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; unsigned long size, offset; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); size = vma->vm_end - vma->vm_start; offset = vma->vm_pgoff << PAGE_SHIFT; return io_remap_pfn_range(vma, vma->vm_start, -- GitLab From 33dbf3fc6942b53920296395bb4c81fb3cc5ebfd Mon Sep 17 00:00:00 2001 From: xliu Date: Thu, 2 Jun 2022 13:19:22 +0800 Subject: [PATCH 199/942] ASoC: Intel: cirrus-common: fix incorrect channel mapping The default mapping of ASPRX1 (DAC source) is slot 0. Change the slot mapping of right amplifiers (WR and TR) to slot 1 to receive right channel data. Also update the ACPI instance ID mapping according to HW configuration. Signed-off-by: xliu Signed-off-by: Brent Lu Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220602051922.1232457-1-brent.lu@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cirrus_common.c | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index e71d74ec1b0b8..f4192df962d60 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -54,22 +54,29 @@ static struct snd_soc_dai_link_component cs35l41_components[] = { }, }; +/* + * Mapping between ACPI instance id and speaker position. + * + * Four speakers: + * 0: Tweeter left, 1: Woofer left + * 2: Tweeter right, 3: Woofer right + */ static struct snd_soc_codec_conf cs35l41_codec_conf[] = { { .dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME), - .name_prefix = "WL", + .name_prefix = "TL", }, { .dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME), - .name_prefix = "WR", + .name_prefix = "WL", }, { .dlc = COMP_CODEC_CONF(CS35L41_DEV2_NAME), - .name_prefix = "TL", + .name_prefix = "TR", }, { .dlc = COMP_CODEC_CONF(CS35L41_DEV3_NAME), - .name_prefix = "TR", + .name_prefix = "WR", }, }; @@ -101,6 +108,21 @@ static int cs35l41_init(struct snd_soc_pcm_runtime *rtd) return ret; } +/* + * Channel map: + * + * TL/WL: ASPRX1 on slot 0, ASPRX2 on slot 1 (default) + * TR/WR: ASPRX1 on slot 1, ASPRX2 on slot 0 + */ +static const struct { + unsigned int rx[2]; +} cs35l41_channel_map[] = { + {.rx = {0, 1}}, /* TL */ + {.rx = {0, 1}}, /* WL */ + {.rx = {1, 0}}, /* TR */ + {.rx = {1, 0}}, /* WR */ +}; + static int cs35l41_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -134,6 +156,16 @@ static int cs35l41_hw_params(struct snd_pcm_substream *substream, ret); return ret; } + + /* setup channel map */ + ret = snd_soc_dai_set_channel_map(codec_dai, 0, NULL, + ARRAY_SIZE(cs35l41_channel_map[i].rx), + (unsigned int *)cs35l41_channel_map[i].rx); + if (ret < 0) { + dev_err(codec_dai->dev, "fail to set channel map, ret %d\n", + ret); + return ret; + } } return 0; -- GitLab From 07c2307ce8b420e351e0635c690397ad7a9fab77 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:14 +0100 Subject: [PATCH 200/942] ASoC: cs42l52: Fix TLV scales for mixer controls The datasheet specifies the range of the mixer volumes as between -51.5dB and 12dB with a 0.5dB step. Update the TLVs for this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 9b182b585be4c..02c25399cf8a2 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -137,7 +137,7 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0); static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); -static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0); +static DECLARE_TLV_DB_SCALE(mix_tlv, -5150, 50, 0); static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0); @@ -364,7 +364,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { CS42L52_ADCB_VOL, 0, 0xA0, 0x78, ipd_tlv), SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL, - 0, 0x19, 0x7F, ipd_tlv), + 0, 0x19, 0x7F, mix_tlv), SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0), -- GitLab From e9dad4de223ee5a4bd5e8b11931a2af8558da0bc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:15 +0100 Subject: [PATCH 201/942] ASoC: cs35l36: Update digital volume TLV The digital volume TLV specifies the step as 0.25dB but the actual step of the control is 0.125dB. Update the TLV to correct this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l36.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index 920190daa4d1b..dfe85dc2cd20f 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -444,7 +444,8 @@ static bool cs35l36_volatile_reg(struct device *dev, unsigned int reg) } } -static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 25, 0); +static const DECLARE_TLV_DB_RANGE(dig_vol_tlv, 0, 912, + TLV_DB_MINMAX_ITEM(-10200, 1200)); static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1); static const char * const cs35l36_pcm_sftramp_text[] = { -- GitLab From 5a7f6cdd402e3da891d2768f1da1f3ea1664a2a2 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:16 +0100 Subject: [PATCH 202/942] ASoC: cs53l30: Correct number of volume levels on SX controls This driver specified the maximum value rather than the number of volume levels on the SX controls, this is incorrect, so correct them. Reported-by: David Rhodes Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs53l30.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 703545273900f..360ca2ffd5069 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -348,22 +348,22 @@ static const struct snd_kcontrol_new cs53l30_snd_controls[] = { SOC_ENUM("ADC2 NG Delay", adc2_ng_delay_enum), SOC_SINGLE_SX_TLV("ADC1A PGA Volume", - CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + CS53L30_ADC1A_AFE_CTL, 0, 0x34, 0x24, pga_tlv), SOC_SINGLE_SX_TLV("ADC1B PGA Volume", - CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + CS53L30_ADC1B_AFE_CTL, 0, 0x34, 0x24, pga_tlv), SOC_SINGLE_SX_TLV("ADC2A PGA Volume", - CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + CS53L30_ADC2A_AFE_CTL, 0, 0x34, 0x24, pga_tlv), SOC_SINGLE_SX_TLV("ADC2B PGA Volume", - CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x18, pga_tlv), + CS53L30_ADC2B_AFE_CTL, 0, 0x34, 0x24, pga_tlv), SOC_SINGLE_SX_TLV("ADC1A Digital Volume", - CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + CS53L30_ADC1A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv), SOC_SINGLE_SX_TLV("ADC1B Digital Volume", - CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + CS53L30_ADC1B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv), SOC_SINGLE_SX_TLV("ADC2A Digital Volume", - CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + CS53L30_ADC2A_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv), SOC_SINGLE_SX_TLV("ADC2B Digital Volume", - CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x0C, dig_tlv), + CS53L30_ADC2B_DIG_VOL, 0, 0xA0, 0x6C, dig_tlv), }; static const struct snd_soc_dapm_widget cs53l30_dapm_widgets[] = { -- GitLab From cd6c0895b9d30b47d22293b9cddab3a8366e4a76 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:17 +0100 Subject: [PATCH 203/942] ASoC: cs42l52: Correct TLV for Bypass Volume The Bypass Volume is accidentally using a -6dB minimum TLV rather than the correct -60dB minimum. Add a new TLV to correct this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 02c25399cf8a2..10e696406a71b 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -137,6 +137,8 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0); static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); +static DECLARE_TLV_DB_SCALE(pass_tlv, -6000, 50, 0); + static DECLARE_TLV_DB_SCALE(mix_tlv, -5150, 50, 0); static DECLARE_TLV_DB_SCALE(beep_tlv, -56, 200, 0); @@ -351,7 +353,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { CS42L52_SPKB_VOL, 0, 0x40, 0xC0, hl_tlv), SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL, - CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pga_tlv), + CS42L52_PASSTHRUB_VOL, 0, 0x88, 0x90, pass_tlv), SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0), -- GitLab From 0c9495ee315e13cce3e3eb588efdcb107b566aab Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:18 +0100 Subject: [PATCH 204/942] ASoC: cs42l56: Correct typo in minimum level for SX volume controls A couple of the SX volume controls specify 0x84 as the lowest volume value, however the correct value from the datasheet is 0x44. The datasheet don't include spaces in the value it displays as binary so this was almost certainly just a typo reading 1000100. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l56.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index dc23007336c58..510c94265b1f0 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -391,9 +391,9 @@ static const struct snd_kcontrol_new cs42l56_snd_controls[] = { SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, - CS42L56_HPB_VOLUME, 0, 0x84, 0x48, hl_tlv), + CS42L56_HPB_VOLUME, 0, 0x44, 0x48, hl_tlv), SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, - CS42L56_LOB_VOLUME, 0, 0x84, 0x48, hl_tlv), + CS42L56_LOB_VOLUME, 0, 0x44, 0x48, hl_tlv), SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, 0, 0x00, 1, tone_tlv), -- GitLab From 513abe2460de2feaa56a66270efda5fa7a788459 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 2 Jun 2022 17:21:19 +0100 Subject: [PATCH 205/942] ASoC: cs42l51: Correct minimum value for SX volume control The minimum value for the PGA Volume is given as 0x1A, however the values from there to 0x19 are all the same volume and this is not represented in the TLV structure. The number of volumes given is correct so this leads to all the volumes being shifted. Move the minimum value up to 0x19 to fix this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220602162119.3393857-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index aff618513c753..0e933181b5dbb 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 0, 0xA0, 96, adc_att_tlv), SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL, - 0, 0x1A, 30, pga_tlv), + 0, 0x19, 30, pga_tlv), SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0), SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0), -- GitLab From eff8f2aeaf0c1b529d918c9f9569577dff600dc5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:52:57 +0200 Subject: [PATCH 206/942] ASoC: cx2072x: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the cx2072x driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-2-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/cx2072x.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/cx2072x.c b/sound/soc/codecs/cx2072x.c index b35debb5818db..b6667e8a60999 100644 --- a/sound/soc/codecs/cx2072x.c +++ b/sound/soc/codecs/cx2072x.c @@ -710,22 +710,19 @@ static int cx2072x_config_i2spcm(struct cx2072x_priv *cx2072x) regdbt2.ulval = 0xac; - /* set master/slave */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: reg2.r.tx_master = 1; reg3.r.rx_master = 1; - dev_dbg(dev, "Sets Master mode\n"); break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg2.r.tx_master = 0; reg3.r.rx_master = 0; - dev_dbg(dev, "Sets Slave mode\n"); break; default: - dev_err(dev, "Unsupported DAI master mode\n"); + dev_err(dev, "Unsupported DAI clocking mode\n"); return -EINVAL; } @@ -1009,9 +1006,9 @@ static int cx2072x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(dev, "set_dai_fmt- %08x\n", fmt); /* set master/slave */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_CBC_CFC: break; default: -- GitLab From 573a9a37b6fcef6dc3977ca11a671f82b1c1b606 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:52:58 +0200 Subject: [PATCH 207/942] ASoC: max98090: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the max98090 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-3-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 576277a82d41a..72471cdb22292 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1591,9 +1591,9 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, cdata->fmt = fmt; regval = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Set to slave mode PLL - MAS mode off */ + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: + /* Set to consumer mode PLL - MAS mode off */ snd_soc_component_write(component, M98090_REG_CLOCK_RATIO_NI_MSB, 0x00); snd_soc_component_write(component, @@ -1602,8 +1602,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, M98090_USE_M1_MASK, 0); max98090->master = false; break; - case SND_SOC_DAIFMT_CBM_CFM: - /* Set to master mode */ + case SND_SOC_DAIFMT_CBP_CFP: + /* Set to provider mode */ if (max98090->tdm_slots == 4) { /* TDM */ regval |= M98090_MAS_MASK | @@ -1619,8 +1619,6 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, } max98090->master = true; break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: dev_err(component->dev, "DAI clock mode unsupported"); return -EINVAL; -- GitLab From cd0df1706d181bf103d0f02e6c008c2386772eb1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:52:59 +0200 Subject: [PATCH 208/942] ASoC: rk3328: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the rk3328 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-4-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/rk3328_codec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c index 86b679cf7aef9..1d523bfd9d84f 100644 --- a/sound/soc/codecs/rk3328_codec.c +++ b/sound/soc/codecs/rk3328_codec.c @@ -69,11 +69,11 @@ static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) snd_soc_component_get_drvdata(dai->component); unsigned int val; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: val = PIN_DIRECTION_IN | DAC_I2S_MODE_SLAVE; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: val = PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER; break; default: -- GitLab From ef08b481ae78eb89672bdf67ed306a43065253b3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:00 +0200 Subject: [PATCH 209/942] ASoC: sta32x: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the sta32x driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-5-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/sta32x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 8585cbef4c9be..17e5077f26b00 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -601,8 +601,8 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai, struct sta32x_priv *sta32x = snd_soc_component_get_drvdata(component); u8 confb = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From def5b3774a48ed06e69b56af8317cb563bbd9ceb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:01 +0200 Subject: [PATCH 210/942] ASoC: sta350: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the sta350 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-6-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/sta350.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index 9189fb3648f7d..b2d15d20fe63d 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -630,8 +630,8 @@ static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai, struct sta350_priv *sta350 = snd_soc_component_get_drvdata(component); unsigned int confb = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From d7e98b570e801375130ed4796bcbb35a39669d44 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:02 +0200 Subject: [PATCH 211/942] ASoC: sti-sas: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the sti-sas driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-7-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/sti-sas.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 3be4940e3c77d..10a6a112f4b47 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -199,10 +199,10 @@ static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream) static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { dev_err(dai->component->dev, - "%s: ERROR: Unsupporter master mask 0x%x\n", - __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK); + "%s: ERROR: Unsupported clocking mask 0x%x\n", + __func__, fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); return -EINVAL; } -- GitLab From 6b486af2ab946cbcad5c95f8daa1f4a8a53f25c5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:03 +0200 Subject: [PATCH 212/942] ASoC: tas2552: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tas2552 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-8-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2552.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index b5c9c61ff5a8e..c98a9332dcc0e 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -347,17 +347,17 @@ static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) struct tas2552_data *tas2552 = dev_get_drvdata(component->dev); u8 serial_format; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: serial_format = 0x00; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: serial_format = TAS2552_WCLKDIR; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: serial_format = TAS2552_BCLKDIR; break; - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR); break; default: -- GitLab From f8a4018c826fde6137425bbdbe524d5973feb173 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:04 +0200 Subject: [PATCH 213/942] ASoC: tas2770: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tas2770 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-9-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas2770.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index c1dbd978d5502..f6037a148cb60 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -340,11 +340,11 @@ static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; int ret; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(tas2770->dev, "ASI format master is not found\n"); + dev_err(tas2770->dev, "ASI invalid DAI clocking\n"); return -EINVAL; } -- GitLab From 7c5c399fb97e3f7a88d1b154f610cab4d9253955 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:05 +0200 Subject: [PATCH 214/942] ASoC: tas5086: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tas5086 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-10-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas5086.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 5c0df3cd48320..05b57bb1aea04 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -318,7 +318,7 @@ static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai, struct tas5086_private *priv = snd_soc_component_get_drvdata(component); /* The TAS5086 can only be slave to all clocks */ - if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + if ((format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { dev_err(component->dev, "Invalid clocking mode\n"); return -EINVAL; } -- GitLab From 9f6654c3162a4e64265c62bea433550fce4beffd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:06 +0200 Subject: [PATCH 215/942] ASoC: tas5720: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tas5720 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-11-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas5720.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index 17034abef5689..2ee06a95f3e4f 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -89,8 +89,8 @@ static int tas5720_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) u8 serial_format; int ret; - if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { - dev_vdbg(component->dev, "DAI Format master is not found\n"); + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { + dev_vdbg(component->dev, "DAI clocking invalid\n"); return -EINVAL; } -- GitLab From f025fcc466cc03fa4f5ae245b6848629b846edff Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:07 +0200 Subject: [PATCH 216/942] ASoC: tas6424: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tas6424 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-12-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tas6424.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 22b53856e6918..9c9a6ec4d9779 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -160,11 +160,11 @@ static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) dev_dbg(component->dev, "%s() fmt=0x%0x\n", __func__, fmt); /* clock masters */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clocking\n"); return -EINVAL; } -- GitLab From 5fc4ed4bda465fb826bea7c6a7b15657154787ce Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:08 +0200 Subject: [PATCH 217/942] ASoC: uda1334: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the uda1334 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-13-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/uda1334.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/uda1334.c b/sound/soc/codecs/uda1334.c index 8670a2a05a560..9d5ed34e54204 100644 --- a/sound/soc/codecs/uda1334.c +++ b/sound/soc/codecs/uda1334.c @@ -169,7 +169,7 @@ static int uda1334_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int uda1334_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | - SND_SOC_DAIFMT_MASTER_MASK); + SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK); if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC)) { -- GitLab From ad60ff09801fa1841dcdcf1f6ad1fa0e09ad0693 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:09 +0200 Subject: [PATCH 218/942] ASoC: tlv320adc3xxx: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic3xxx driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-14-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adc3xxx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c index 82532ad00c3c8..748998e48af97 100644 --- a/sound/soc/codecs/tlv320adc3xxx.c +++ b/sound/soc/codecs/tlv320adc3xxx.c @@ -1252,8 +1252,7 @@ static int adc3xxx_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) int master = 0; int ret; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { case SND_SOC_DAIFMT_CBP_CFP: master = 1; clkdir = ADC3XXX_BCLK_MASTER | ADC3XXX_WCLK_MASTER; -- GitLab From 10649fa392c9abb6e9b258f7af9577596339fbe2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:10 +0200 Subject: [PATCH 219/942] ASoC: tlv320adcx140: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320adcx140 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-15-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index b55f0b836932b..de5b184a701ef 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -713,16 +713,14 @@ static int adcx140_set_dai_fmt(struct snd_soc_dai *codec_dai, bool inverted_bclk = false; /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg2 |= ADCX140_BCLK_FSYNC_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clock provider\n"); return -EINVAL; } -- GitLab From b9ff35c7afc6ae1bddca3f84fb23a3d903a62a23 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:11 +0200 Subject: [PATCH 220/942] ASoC: tlv320aic23: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic23 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220602135316.3554400-16-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 2400093e2c990..c86ca793a2b66 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -429,12 +429,11 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_reg = snd_soc_component_read(component, TLV320AIC23_DIGT_FMT) & (~0x03); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg |= TLV320AIC23_MS_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: iface_reg &= ~TLV320AIC23_MS_MASTER; break; default: -- GitLab From 8d322f170b09989f47614c1a663371647f03176f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:12 +0200 Subject: [PATCH 221/942] ASoC: tlv320aic26: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic26 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220602135316.3554400-17-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic26.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 077415a572255..f85f8061639f3 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -32,7 +32,7 @@ struct aic26 { struct spi_device *spi; struct regmap *regmap; struct snd_soc_component *component; - int master; + int clock_provider; int datfm; int mclk; @@ -117,8 +117,8 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, reg = dval << 2; snd_soc_component_write(component, AIC26_REG_PLL_PROG2, reg); - /* Audio Control 3 (master mode, fsref rate) */ - if (aic26->master) + /* Audio Control 3 (clock provider mode, fsref rate) */ + if (aic26->clock_provider) reg = 0x0800; if (fsref == 48000) reg = 0x2000; @@ -178,10 +178,9 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n", codec_dai, fmt); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: aic26->master = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: aic26->master = 0; break; + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aic26->clock_provider = 1; break; + case SND_SOC_DAIFMT_CBC_CFC: aic26->clock_provider = 0; break; default: dev_dbg(&aic26->spi->dev, "bad master\n"); return -EINVAL; } @@ -363,7 +362,7 @@ static int aic26_spi_probe(struct spi_device *spi) /* Initialize the driver data */ aic26->spi = spi; dev_set_drvdata(&spi->dev, aic26); - aic26->master = 1; + aic26->clock_provider = 1; ret = devm_snd_soc_register_component(&spi->dev, &aic26_soc_component_dev, &aic26_dai, 1); -- GitLab From 2fd8298aed2228b8c6b94edf820121da25b3f5e2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:13 +0200 Subject: [PATCH 222/942] ASoC: tlv320aic31xx: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic31xx driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-18-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic31xx.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index b2e59581c17a2..aacee23679924 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1033,8 +1033,8 @@ static int aic31xx_clock_master_routes(struct snd_soc_component *component, struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component); int ret; - fmt &= SND_SOC_DAIFMT_MASTER_MASK; - if (fmt == SND_SOC_DAIFMT_CBS_CFS && + fmt &= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; + if (fmt == SND_SOC_DAIFMT_CBC_CFC && aic31xx->master_dapm_route_applied) { /* * Remove the DAPM route(s) for codec clock master modes, @@ -1051,7 +1051,7 @@ static int aic31xx_clock_master_routes(struct snd_soc_component *component, return ret; aic31xx->master_dapm_route_applied = false; - } else if (fmt != SND_SOC_DAIFMT_CBS_CFS && + } else if (fmt != SND_SOC_DAIFMT_CBC_CFC && !aic31xx->master_dapm_route_applied) { /* * Add the needed DAPM route(s) for codec clock master modes, @@ -1083,21 +1083,20 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, dev_dbg(component->dev, "## %s: fmt = 0x%x\n", __func__, fmt); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: iface_reg1 |= AIC31XX_WCLK_MASTER; break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: iface_reg1 |= AIC31XX_BCLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: - dev_err(component->dev, "Invalid DAI master/slave interface\n"); + dev_err(component->dev, "Invalid DAI clock provider\n"); return -EINVAL; } -- GitLab From 0cc5a137f7a3ba6fec069d8d222020f0927a18ef Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:14 +0200 Subject: [PATCH 223/942] ASoC: tlv320aic32x4: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic32x4 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-19-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic32x4.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 8f42fd7bc0539..a8e6adf62ac82 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -615,15 +615,14 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) u8 iface_reg_2 = 0; u8 iface_reg_3 = 0; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: - printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); + printk(KERN_ERR "aic32x4: invalid clock provider\n"); return -EINVAL; } -- GitLab From 83a5f86903fbaf9c47c13975eb6f2fbd16d7f865 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:15 +0200 Subject: [PATCH 224/942] ASoC: tlv320aic33: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320aic33 driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-20-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index d53037b1509d0..610e41bbf388c 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1253,22 +1253,21 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, iface_areg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLA) & 0x3f; iface_breg = snd_soc_component_read(component, AIC3X_ASD_INTF_CTRLB) & 0x3f; - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aic3x->master = 1; iface_areg |= BIT_CLK_MASTER | WORD_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: aic3x->master = 0; iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); break; - case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBP_CFC: aic3x->master = 1; iface_areg |= BIT_CLK_MASTER; iface_areg &= ~WORD_CLK_MASTER; break; - case SND_SOC_DAIFMT_CBS_CFM: + case SND_SOC_DAIFMT_CBC_CFP: aic3x->master = 1; iface_areg |= WORD_CLK_MASTER; iface_areg &= ~BIT_CLK_MASTER; -- GitLab From 894bf75bb1f6c274cdd877879d9215abd6ed4b1b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 15:53:16 +0200 Subject: [PATCH 225/942] ASoC: tlv320dac3x: Use modern ASoC DAI format terminology As part of moving to remove the old style defines for the bus clocks update the tlv320dac3x driver to use more modern terminology for clocking. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602135316.3554400-21-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320dac33.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 66f1d1cd6cf00..371026eb8f41b 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1317,16 +1317,14 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, aictrl_a = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_A); aictrl_b = dac33_read_reg_cache(component, DAC33_SER_AUDIOIF_CTRL_B); - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - /* Codec Master */ + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK); break; - case SND_SOC_DAIFMT_CBS_CFS: - /* Codec Slave */ + case SND_SOC_DAIFMT_CBC_CFC: if (dac33->fifo_mode) { - dev_err(component->dev, "FIFO mode requires master mode\n"); + dev_err(component->dev, "FIFO mode requires provider mode\n"); return -EINVAL; } else aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK); -- GitLab From e059da384ffdc93778e69a5f212c2ac7357ec09a Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 2 Jun 2022 19:14:32 -0700 Subject: [PATCH 226/942] dt-bindings: Update QCOM USB subsystem maintainer information Update devicetree binding files with the proper maintainer, and updated contact email. Signed-off-by: Wesley Cheng Acked-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220603021432.13365-1-quic_wcheng@quicinc.com --- Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml | 2 +- Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml | 2 +- .../devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml | 2 +- .../devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml | 2 +- Documentation/devicetree/bindings/usb/qcom,dwc3.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml index 60dc27834e1df..b078009ed509d 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml @@ -8,7 +8,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#" title: Qualcomm QMP USB3 DP PHY controller maintainers: - - Manu Gautam + - Wesley Cheng properties: compatible: diff --git a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml index 0ab3dad3f1213..d68ab49345b8f 100644 --- a/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml @@ -8,7 +8,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#" title: Qualcomm QUSB2 phy controller maintainers: - - Manu Gautam + - Wesley Cheng description: QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets. diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml index 1ce251de08557..7a0e6a9854da2 100644 --- a/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml @@ -7,7 +7,7 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#" title: Qualcomm Synopsys Femto High-Speed USB PHY V2 maintainers: - - Wesley Cheng + - Wesley Cheng description: | Qualcomm High-Speed USB PHY diff --git a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml index 12ed98c28aaa5..dbe78cd4adba5 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,usb-vbus-regulator.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: The Qualcomm PMIC VBUS output regulator driver maintainers: - - Wesley Cheng + - Wesley Cheng description: | This regulator driver controls the VBUS output by the Qualcomm PMIC. This diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml index e336fe2e03cca..749e1963ddbb8 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm SuperSpeed DWC3 USB SoC controller maintainers: - - Manu Gautam + - Wesley Cheng properties: compatible: -- GitLab From 0a884eadc428b9e7070d86e8b22c278bdb52a422 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 1 Jun 2022 15:52:22 +0200 Subject: [PATCH 227/942] dt-bindings: vendor-prefixes: document deprecated Atheros Two old boards use "atheros" prefix instead of already documented "qca". Document it as deprecated to fix warnings like: at91-gatwick.dtb: atheros@0: 'atheros,board-id' does not match any of the regexes Signed-off-by: Krzysztof Kozlowski Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220601135222.205035-1-krzysztof.kozlowski@linaro.org --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 6bb20b4554d7e..0496773a3c4d8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -143,6 +143,9 @@ patternProperties: description: ASPEED Technology Inc. "^asus,.*": description: AsusTek Computer Inc. + "^atheros,.*": + description: Qualcomm Atheros, Inc. (deprecated, use qca) + deprecated: true "^atlas,.*": description: Atlas Scientific LLC "^atmel,.*": -- GitLab From cce65bb2c36dd32d7bb413636b89a80d85b94196 Mon Sep 17 00:00:00 2001 From: Krishna Manikandan Date: Thu, 2 Jun 2022 16:19:58 +0530 Subject: [PATCH 228/942] dt-bindings: msm: update maintainers list with proper id Use quic id instead of codeaurora id in maintainers list for display devicetree bindings. Signed-off-by: Krishna Manikandan Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/1654166998-14907-1-git-send-email-quic_mkrishn@quicinc.com --- Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml | 2 +- .../devicetree/bindings/display/msm/dsi-controller-main.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml | 2 +- Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml | 2 +- .../devicetree/bindings/display/msm/dsi-phy-common.yaml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml index b41991eaa454a..d3c3e4b078971 100644 --- a/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml +++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7180.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DPU dt properties for SC7180 target maintainers: - - Krishna Manikandan + - Krishna Manikandan description: | Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml index 6e417d06fc790..f427eec3d3a45 100644 --- a/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml +++ b/Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DPU dt properties for SC7280 maintainers: - - Krishna Manikandan + - Krishna Manikandan description: | Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates diff --git a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml index 1a42491efdbcb..2bb8896beffc6 100644 --- a/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml +++ b/Documentation/devicetree/bindings/display/msm/dpu-sdm845.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DPU dt properties for SDM845 target maintainers: - - Krishna Manikandan + - Krishna Manikandan description: | Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml index 7095ec3c890da..880bfe930830c 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DSI controller maintainers: - - Krishna Manikandan + - Krishna Manikandan allOf: - $ref: "../dsi-controller.yaml#" diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml index 2d5a766d028f1..716f921e3532e 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-10nm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DSI 10nm PHY maintainers: - - Krishna Manikandan + - Krishna Manikandan allOf: - $ref: dsi-phy-common.yaml# diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml index 81dbee4803c0b..1342d74ecfe0f 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DSI 14nm PHY maintainers: - - Krishna Manikandan + - Krishna Manikandan allOf: - $ref: dsi-phy-common.yaml# diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml index b8de785ce8156..9c1f9140c731b 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-20nm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DSI 20nm PHY maintainers: - - Krishna Manikandan + - Krishna Manikandan allOf: - $ref: dsi-phy-common.yaml# diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml index 69eecaa64b187..3d8540a06fe22 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-28nm.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Display DSI 28nm PHY maintainers: - - Krishna Manikandan + - Krishna Manikandan allOf: - $ref: dsi-phy-common.yaml# diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-common.yaml b/Documentation/devicetree/bindings/display/msm/dsi-phy-common.yaml index 502bdda902354..76d40f7933dde 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi-phy-common.yaml +++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-common.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Description of Qualcomm Display DSI PHY common dt properties maintainers: - - Krishna Manikandan + - Krishna Manikandan description: | This defines the DSI PHY dt properties which are common for all -- GitLab From 216d1a8013433bacb2001d492a467e3a58db91bc Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 3 Jun 2022 17:57:23 +0200 Subject: [PATCH 229/942] dt-bindings: update Luca Ceresoli's e-mail address My Bootlin address is preferred from now on. Signed-off-by: Luca Ceresoli Signed-off-by: Luca Ceresoli Acked-by: Rob Herring Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220603155727.1232061-2-luca@lucaceresoli.net --- Documentation/devicetree/bindings/clock/idt,versaclock5.yaml | 2 +- Documentation/devicetree/bindings/mfd/maxim,max77714.yaml | 2 +- .../devicetree/bindings/power/supply/maxim,max77976.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml index be66f1e8b5476..7c331bfbe370e 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.yaml @@ -45,7 +45,7 @@ description: | The case where SH and SP are both 1 is likely not very interesting. maintainers: - - Luca Ceresoli + - Luca Ceresoli properties: compatible: diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml index 74a6867d3c826..edac14af101e5 100644 --- a/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml +++ b/Documentation/devicetree/bindings/mfd/maxim,max77714.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: MAX77714 PMIC with GPIO, RTC and watchdog from Maxim Integrated. maintainers: - - Luca Ceresoli + - Luca Ceresoli description: | MAX77714 is a Power Management IC with 4 buck regulators, 9 diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml index 675b9b26d2337..f23dcc50793e0 100644 --- a/Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml +++ b/Documentation/devicetree/bindings/power/supply/maxim,max77976.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Maxim Integrated MAX77976 Battery charger maintainers: - - Luca Ceresoli + - Luca Ceresoli description: | The Maxim MAX77976 is a 19Vin / 5.5A, 1-Cell Li+ battery charger -- GitLab From fa1f57421e0b1c57843902c89728f823abc32f02 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 2 Jun 2022 22:23:49 +0300 Subject: [PATCH 230/942] xen/virtio: Enable restricted memory access using Xen grant mappings In order to support virtio in Xen guests add a config option XEN_VIRTIO enabling the user to specify whether in all Xen guests virtio should be able to access memory via Xen grant mappings only on the host side. Also set PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS feature from the guest initialization code on Arm and x86 if CONFIG_XEN_VIRTIO is enabled. Signed-off-by: Juergen Gross Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Reviewed-by: Boris Ostrovsky Link: https://lore.kernel.org/r/1654197833-25362-5-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- arch/arm/xen/enlighten.c | 2 ++ arch/x86/xen/enlighten_hvm.c | 2 ++ arch/x86/xen/enlighten_pv.c | 2 ++ drivers/xen/Kconfig | 11 +++++++++++ include/xen/xen.h | 8 ++++++++ 5 files changed, 25 insertions(+) diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 07eb69f9e7df3..1f9c3ba328333 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -443,6 +443,8 @@ static int __init xen_guest_init(void) if (!xen_domain()) return 0; + xen_set_restricted_virtio_memory_access(); + if (!acpi_disabled) xen_acpi_guest_init(); else diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 517a9d8d8f94d..8b71b1dd76396 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -195,6 +195,8 @@ static void __init xen_hvm_guest_init(void) if (xen_pv_domain()) return; + xen_set_restricted_virtio_memory_access(); + init_hvm_pv_info(); reserve_shared_info(); diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index f33a4421e7cd6..e3297b15701c6 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -109,6 +109,8 @@ static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc); static void __init xen_pv_init_platform(void) { + xen_set_restricted_virtio_memory_access(); + populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP)); set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info); diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 313a9127fd5c3..a7bd8ce7a1d2a 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -339,4 +339,15 @@ config XEN_GRANT_DMA_OPS bool select DMA_OPS +config XEN_VIRTIO + bool "Xen virtio support" + depends on VIRTIO + select XEN_GRANT_DMA_OPS + help + Enable virtio support for running as Xen guest. Depending on the + guest type this will require special support on the backend side + (qemu or kernel, depending on the virtio device types used). + + If in doubt, say n. + endmenu diff --git a/include/xen/xen.h b/include/xen/xen.h index a99bab8175234..0780a81e140de 100644 --- a/include/xen/xen.h +++ b/include/xen/xen.h @@ -52,6 +52,14 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, extern u64 xen_saved_max_mem_size; #endif +#include + +static inline void xen_set_restricted_virtio_memory_access(void) +{ + if (IS_ENABLED(CONFIG_XEN_VIRTIO) && xen_domain()) + platform_set(PLATFORM_VIRTIO_RESTRICTED_MEM_ACCESS); +} + #ifdef CONFIG_XEN_UNPOPULATED_ALLOC int xen_alloc_unpopulated_pages(unsigned int nr_pages, struct page **pages); void xen_free_unpopulated_pages(unsigned int nr_pages, struct page **pages); -- GitLab From add413a1d966d8458571a2571881903d234a9f8e Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Thu, 2 Jun 2022 22:23:50 +0300 Subject: [PATCH 231/942] dt-bindings: Add xen,grant-dma IOMMU description for xen-grant DMA ops The main purpose of this binding is to communicate Xen specific information using generic IOMMU device tree bindings (which is a good fit here) rather than introducing a custom property. Introduce Xen specific IOMMU for the virtualized device (e.g. virtio) to be used by Xen grant DMA-mapping layer in the subsequent commit. The reference to Xen specific IOMMU node using "iommus" property indicates that Xen grant mappings need to be enabled for the device, and it specifies the ID of the domain where the corresponding backend resides. The domid (domain ID) is used as an argument to the Xen grant mapping APIs. This is needed for the option to restrict memory access using Xen grant mappings to work which primary goal is to enable using virtio devices in Xen guests. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1654197833-25362-6-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- .../bindings/iommu/xen,grant-dma.yaml | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml diff --git a/Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml b/Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml new file mode 100644 index 0000000000000..be1539d234f96 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/xen,grant-dma.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iommu/xen,grant-dma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xen specific IOMMU for virtualized devices (e.g. virtio) + +maintainers: + - Stefano Stabellini + +description: + The Xen IOMMU represents the Xen grant table interface. Grant mappings + are to be used with devices connected to the Xen IOMMU using the "iommus" + property, which also specifies the ID of the backend domain. + The binding is required to restrict memory access using Xen grant mappings. + +properties: + compatible: + const: xen,grant-dma + + '#iommu-cells': + const: 1 + description: + The single cell is the domid (domain ID) of the domain where the backend + is running. + +required: + - compatible + - "#iommu-cells" + +additionalProperties: false + +examples: + - | + iommu { + compatible = "xen,grant-dma"; + #iommu-cells = <1>; + }; -- GitLab From 1ca55d50e50c74747a7b8846dac306fbe5ac4cf5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Thu, 2 Jun 2022 22:23:51 +0300 Subject: [PATCH 232/942] xen/grant-dma-iommu: Introduce stub IOMMU driver In order to reuse generic IOMMU device tree bindings by Xen grant DMA-mapping layer we need to add this stub driver from a fw_devlink perspective (grant-dma-ops cannot be converted into the proper IOMMU driver). Otherwise, just reusing IOMMU bindings (without having a corresponding driver) leads to the deferred probe timeout afterwards, because the IOMMU device never becomes available. This stub driver does nothing except registering empty iommu_ops, the upper layer "of_iommu" will treat this as NO_IOMMU condition and won't return -EPROBE_DEFER. As this driver is quite different from the most hardware IOMMU implementations and only needed in Xen guests, place it in drivers/xen directory. The subsequent commit will make use of it. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Link: https://lore.kernel.org/r/1654197833-25362-7-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- drivers/xen/Kconfig | 4 ++ drivers/xen/Makefile | 1 + drivers/xen/grant-dma-iommu.c | 78 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 drivers/xen/grant-dma-iommu.c diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index a7bd8ce7a1d2a..35d20d90390bc 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -335,6 +335,10 @@ config XEN_UNPOPULATED_ALLOC having to balloon out RAM regions in order to obtain physical memory space to create such mappings. +config XEN_GRANT_DMA_IOMMU + bool + select IOMMU_API + config XEN_GRANT_DMA_OPS bool select DMA_OPS diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 1a23cb0dc1889..c0503f1c7d5b2 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -40,3 +40,4 @@ xen-privcmd-y := privcmd.o privcmd-buf.o obj-$(CONFIG_XEN_FRONT_PGDIR_SHBUF) += xen-front-pgdir-shbuf.o obj-$(CONFIG_XEN_UNPOPULATED_ALLOC) += unpopulated-alloc.o obj-$(CONFIG_XEN_GRANT_DMA_OPS) += grant-dma-ops.o +obj-$(CONFIG_XEN_GRANT_DMA_IOMMU) += grant-dma-iommu.o diff --git a/drivers/xen/grant-dma-iommu.c b/drivers/xen/grant-dma-iommu.c new file mode 100644 index 0000000000000..16b8bc0c0b33d --- /dev/null +++ b/drivers/xen/grant-dma-iommu.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Stub IOMMU driver which does nothing. + * The main purpose of it being present is to reuse generic IOMMU device tree + * bindings by Xen grant DMA-mapping layer. + * + * Copyright (C) 2022 EPAM Systems Inc. + */ + +#include +#include +#include + +struct grant_dma_iommu_device { + struct device *dev; + struct iommu_device iommu; +}; + +/* Nothing is really needed here */ +static const struct iommu_ops grant_dma_iommu_ops; + +static const struct of_device_id grant_dma_iommu_of_match[] = { + { .compatible = "xen,grant-dma" }, + { }, +}; + +static int grant_dma_iommu_probe(struct platform_device *pdev) +{ + struct grant_dma_iommu_device *mmu; + int ret; + + mmu = devm_kzalloc(&pdev->dev, sizeof(*mmu), GFP_KERNEL); + if (!mmu) + return -ENOMEM; + + mmu->dev = &pdev->dev; + + ret = iommu_device_register(&mmu->iommu, &grant_dma_iommu_ops, &pdev->dev); + if (ret) + return ret; + + platform_set_drvdata(pdev, mmu); + + return 0; +} + +static int grant_dma_iommu_remove(struct platform_device *pdev) +{ + struct grant_dma_iommu_device *mmu = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + iommu_device_unregister(&mmu->iommu); + + return 0; +} + +static struct platform_driver grant_dma_iommu_driver = { + .driver = { + .name = "grant-dma-iommu", + .of_match_table = grant_dma_iommu_of_match, + }, + .probe = grant_dma_iommu_probe, + .remove = grant_dma_iommu_remove, +}; + +static int __init grant_dma_iommu_init(void) +{ + struct device_node *iommu_np; + + iommu_np = of_find_matching_node(NULL, grant_dma_iommu_of_match); + if (!iommu_np) + return 0; + + of_node_put(iommu_np); + + return platform_driver_register(&grant_dma_iommu_driver); +} +subsys_initcall(grant_dma_iommu_init); -- GitLab From 625ab90ecdf7770bda7ae21c4d5c938aa9b43bb4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Thu, 2 Jun 2022 22:23:52 +0300 Subject: [PATCH 233/942] xen/grant-dma-ops: Retrieve the ID of backend's domain for DT devices Use the presence of "iommus" property pointed to the IOMMU node with recently introduced "xen,grant-dma" compatible as a clear indicator of enabling Xen grant mappings scheme for that device and read the ID of Xen domain where the corresponding backend is running. The domid (domain ID) is used as an argument to the Xen grant mapping APIs. To avoid the deferred probe timeout which takes place after reusing generic IOMMU device tree bindings (because the IOMMU device never becomes available) enable recently introduced stub IOMMU driver by selecting XEN_GRANT_DMA_IOMMU. Also introduce xen_is_grant_dma_device() to check whether xen-grant DMA ops need to be set for a passed device. Remove the hardcoded domid 0 in xen_grant_setup_dma_ops(). Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Link: https://lore.kernel.org/r/1654197833-25362-8-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- drivers/xen/Kconfig | 1 + drivers/xen/grant-dma-ops.c | 48 +++++++++++++++++++++++++++++++------ include/xen/xen-ops.h | 5 ++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 35d20d90390bc..bfd5f4f706bcc 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -347,6 +347,7 @@ config XEN_VIRTIO bool "Xen virtio support" depends on VIRTIO select XEN_GRANT_DMA_OPS + select XEN_GRANT_DMA_IOMMU if OF help Enable virtio support for running as Xen guest. Depending on the guest type this will require special support on the backend side diff --git a/drivers/xen/grant-dma-ops.c b/drivers/xen/grant-dma-ops.c index aaff35cda5175..fc01424840017 100644 --- a/drivers/xen/grant-dma-ops.c +++ b/drivers/xen/grant-dma-ops.c @@ -56,11 +56,6 @@ static struct xen_grant_dma_data *find_xen_grant_dma_data(struct device *dev) * Such a DMA address is formed by using the grant reference as a frame * number and setting the highest address bit (this bit is for the backend * to be able to distinguish it from e.g. a mmio address). - * - * Note that for now we hard wire dom0 to be the backend domain. In order - * to support any domain as backend we'd need to add a way to communicate - * the domid of this backend, e.g. via Xenstore, via the PCI-device's - * config space or DT/ACPI. */ static void *xen_grant_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, @@ -276,9 +271,26 @@ static const struct dma_map_ops xen_grant_dma_ops = { .dma_supported = xen_grant_dma_supported, }; +bool xen_is_grant_dma_device(struct device *dev) +{ + struct device_node *iommu_np; + bool has_iommu; + + /* XXX Handle only DT devices for now */ + if (!dev->of_node) + return false; + + iommu_np = of_parse_phandle(dev->of_node, "iommus", 0); + has_iommu = iommu_np && of_device_is_compatible(iommu_np, "xen,grant-dma"); + of_node_put(iommu_np); + + return has_iommu; +} + void xen_grant_setup_dma_ops(struct device *dev) { struct xen_grant_dma_data *data; + struct of_phandle_args iommu_spec; data = find_xen_grant_dma_data(dev); if (data) { @@ -286,12 +298,34 @@ void xen_grant_setup_dma_ops(struct device *dev) return; } + /* XXX ACPI device unsupported for now */ + if (!dev->of_node) + goto err; + + if (of_parse_phandle_with_args(dev->of_node, "iommus", "#iommu-cells", + 0, &iommu_spec)) { + dev_err(dev, "Cannot parse iommus property\n"); + goto err; + } + + if (!of_device_is_compatible(iommu_spec.np, "xen,grant-dma") || + iommu_spec.args_count != 1) { + dev_err(dev, "Incompatible IOMMU node\n"); + of_node_put(iommu_spec.np); + goto err; + } + + of_node_put(iommu_spec.np); + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) goto err; - /* XXX The dom0 is hardcoded as the backend domain for now */ - data->backend_domid = 0; + /* + * The endpoint ID here means the ID of the domain where the corresponding + * backend is running + */ + data->backend_domid = iommu_spec.args[0]; if (xa_err(xa_store(&xen_grant_dma_devices, (unsigned long)dev, data, GFP_KERNEL))) { diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h index afd586d717a45..80546960f8b77 100644 --- a/include/xen/xen-ops.h +++ b/include/xen/xen-ops.h @@ -216,10 +216,15 @@ static inline void xen_preemptible_hcall_end(void) { } #ifdef CONFIG_XEN_GRANT_DMA_OPS void xen_grant_setup_dma_ops(struct device *dev); +bool xen_is_grant_dma_device(struct device *dev); #else static inline void xen_grant_setup_dma_ops(struct device *dev) { } +static inline bool xen_is_grant_dma_device(struct device *dev) +{ + return false; +} #endif /* CONFIG_XEN_GRANT_DMA_OPS */ #endif /* INCLUDE_XEN_OPS_H */ -- GitLab From fea981610c25173e6e5d63ccd4fce49739663ab0 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Thu, 2 Jun 2022 22:23:53 +0300 Subject: [PATCH 234/942] arm/xen: Assign xen-grant DMA ops for xen-grant DMA devices By assigning xen-grant DMA ops we will restrict memory access for passed device using Xen grant mappings. This is needed for using any virtualized device (e.g. virtio) in Xen guests in a safe manner. Please note, for the virtio devices the XEN_VIRTIO config should be enabled (it forces ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS). Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Link: https://lore.kernel.org/r/1654197833-25362-9-git-send-email-olekstysh@gmail.com Signed-off-by: Juergen Gross --- include/xen/arm/xen-ops.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/xen/arm/xen-ops.h b/include/xen/arm/xen-ops.h index 288deb1c3ac96..b0766a660338f 100644 --- a/include/xen/arm/xen-ops.h +++ b/include/xen/arm/xen-ops.h @@ -3,11 +3,14 @@ #define _ASM_ARM_XEN_OPS_H #include +#include static inline void xen_setup_dma_ops(struct device *dev) { #ifdef CONFIG_XEN - if (xen_swiotlb_detect()) + if (xen_is_grant_dma_device(dev)) + xen_grant_setup_dma_ops(dev); + else if (xen_swiotlb_detect()) dev->dma_ops = &xen_swiotlb_dma_ops; #endif } -- GitLab From 612c4695e312c753a8b06f6b052cea3d8338e3c3 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:39 +0800 Subject: [PATCH 235/942] ASoC: mediatek: mt6366: support for mt6366 codec Mt6366 is a new version of mt6358, and they are same about audio part. So we can reuse the driver of mt6358 that add a new compatible string inside of the mt6358 driver. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-2-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6358.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index 60b209efe52d1..93f35e8d26fce 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -2479,6 +2479,7 @@ static int mt6358_platform_driver_probe(struct platform_device *pdev) static const struct of_device_id mt6358_of_match[] = { {.compatible = "mediatek,mt6358-sound",}, + {.compatible = "mediatek,mt6366-sound",}, {} }; MODULE_DEVICE_TABLE(of, mt6358_of_match); -- GitLab From 58949aa35c0f74a98b03864817354d85f452a51c Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:41 +0800 Subject: [PATCH 236/942] ASoC: mediatek: mt8186: support audsys clock control Add mt8186 audio cg control. Audio clock gates are registered to CCF for reference count and clock parent management. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-4-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-audsys-clk.c | 150 ++++++++++++++++++ sound/soc/mediatek/mt8186/mt8186-audsys-clk.h | 15 ++ .../soc/mediatek/mt8186/mt8186-audsys-clkid.h | 45 ++++++ 3 files changed, 210 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clk.c create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clk.h create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clkid.h diff --git a/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c new file mode 100644 index 0000000000000..578969ca91c8e --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mt8186-audsys-clk.h -- Mediatek 8186 audsys clock control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include +#include "mt8186-afe-common.h" +#include "mt8186-audsys-clk.h" +#include "mt8186-audsys-clkid.h" +#include "mt8186-reg.h" + +struct afe_gate { + int id; + const char *name; + const char *parent_name; + int reg; + u8 bit; + const struct clk_ops *ops; + unsigned long flags; + u8 cg_flags; +}; + +#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .reg = _reg, \ + .bit = _bit, \ + .flags = _flags, \ + .cg_flags = _cgflags, \ + } + +#define GATE_AFE(_id, _name, _parent, _reg, _bit) \ + GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, \ + CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE) + +#define GATE_AUD0(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit) + +#define GATE_AUD1(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit) + +#define GATE_AUD2(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON2, _bit) + +static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = { + /* AUD0 */ + GATE_AUD0(CLK_AUD_AFE, "aud_afe_clk", "top_audio", 2), + GATE_AUD0(CLK_AUD_22M, "aud_apll22m_clk", "top_aud_engen1", 8), + GATE_AUD0(CLK_AUD_24M, "aud_apll24m_clk", "top_aud_engen2", 9), + GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner_clk", "top_aud_engen2", 18), + GATE_AUD0(CLK_AUD_APLL_TUNER, "aud_apll_tuner_clk", "top_aud_engen1", 19), + GATE_AUD0(CLK_AUD_TDM, "aud_tdm_clk", "top_aud_1", 20), + GATE_AUD0(CLK_AUD_ADC, "aud_adc_clk", "top_audio", 24), + GATE_AUD0(CLK_AUD_DAC, "aud_dac_clk", "top_audio", 25), + GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis_clk", "top_audio", 26), + GATE_AUD0(CLK_AUD_TML, "aud_tml_clk", "top_audio", 27), + GATE_AUD0(CLK_AUD_NLE, "aud_nle_clk", "top_audio", 28), + + /* AUD1 */ + GATE_AUD1(CLK_AUD_I2S1_BCLK, "aud_i2s1_bclk", "top_audio", 4), + GATE_AUD1(CLK_AUD_I2S2_BCLK, "aud_i2s2_bclk", "top_audio", 5), + GATE_AUD1(CLK_AUD_I2S3_BCLK, "aud_i2s3_bclk", "top_audio", 6), + GATE_AUD1(CLK_AUD_I2S4_BCLK, "aud_i2s4_bclk", "top_audio", 7), + GATE_AUD1(CLK_AUD_CONNSYS_I2S_ASRC, "aud_connsys_i2s_asrc", "top_audio", 12), + GATE_AUD1(CLK_AUD_GENERAL1_ASRC, "aud_general1_asrc", "top_audio", 13), + GATE_AUD1(CLK_AUD_GENERAL2_ASRC, "aud_general2_asrc", "top_audio", 14), + GATE_AUD1(CLK_AUD_DAC_HIRES, "aud_dac_hires_clk", "top_audio_h", 15), + GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires_clk", "top_audio_h", 16), + GATE_AUD1(CLK_AUD_ADC_HIRES_TML, "aud_adc_hires_tml", "top_audio_h", 17), + GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "top_audio", 20), + GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "top_audio_h", 21), + GATE_AUD1(CLK_AUD_3RD_DAC, "aud_3rd_dac", "top_audio", 28), + GATE_AUD1(CLK_AUD_3RD_DAC_PREDIS, "aud_3rd_dac_predis", "top_audio", 29), + GATE_AUD1(CLK_AUD_3RD_DAC_TML, "aud_3rd_dac_tml", "top_audio", 30), + GATE_AUD1(CLK_AUD_3RD_DAC_HIRES, "aud_3rd_dac_hires", "top_audio_h", 31), + + /* AUD2 */ + GATE_AUD2(CLK_AUD_ETDM_IN1_BCLK, "aud_etdm_in1_bclk", "top_audio", 23), + GATE_AUD2(CLK_AUD_ETDM_OUT1_BCLK, "aud_etdm_out1_bclk", "top_audio", 24), +}; + +int mt8186_audsys_clk_register(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct clk *clk; + struct clk_lookup *cl; + int i; + + afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK, + sizeof(*afe_priv->lookup), + GFP_KERNEL); + + if (!afe_priv->lookup) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(aud_clks); i++) { + const struct afe_gate *gate = &aud_clks[i]; + + clk = clk_register_gate(afe->dev, gate->name, gate->parent_name, + gate->flags, afe->base_addr + gate->reg, + gate->bit, gate->cg_flags, NULL); + + if (IS_ERR(clk)) { + dev_err(afe->dev, "Failed to register clk %s: %ld\n", + gate->name, PTR_ERR(clk)); + continue; + } + + /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */ + cl = kzalloc(sizeof(*cl), GFP_KERNEL); + if (!cl) + return -ENOMEM; + + cl->clk = clk; + cl->con_id = gate->name; + cl->dev_id = dev_name(afe->dev); + clkdev_add(cl); + + afe_priv->lookup[i] = cl; + } + + return 0; +} + +void mt8186_audsys_clk_unregister(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct clk *clk; + struct clk_lookup *cl; + int i; + + if (!afe_priv) + return; + + for (i = 0; i < CLK_AUD_NR_CLK; i++) { + cl = afe_priv->lookup[i]; + if (!cl) + continue; + + clk = cl->clk; + clk_unregister_gate(clk); + + clkdev_drop(cl); + } +} diff --git a/sound/soc/mediatek/mt8186/mt8186-audsys-clk.h b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.h new file mode 100644 index 0000000000000..b8d6a06e11e8d --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * mt8186-audsys-clk.h -- Mediatek 8186 audsys clock definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Trevor Wu + */ + +#ifndef _MT8186_AUDSYS_CLK_H_ +#define _MT8186_AUDSYS_CLK_H_ + +int mt8186_audsys_clk_register(struct mtk_base_afe *afe); +void mt8186_audsys_clk_unregister(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8186/mt8186-audsys-clkid.h b/sound/soc/mediatek/mt8186/mt8186-audsys-clkid.h new file mode 100644 index 0000000000000..3ce5937c18237 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-audsys-clkid.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * mt8186-audsys-clkid.h -- Mediatek 8186 audsys clock id definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Jiaxin Yu + */ + +#ifndef _MT8186_AUDSYS_CLKID_H_ +#define _MT8186_AUDSYS_CLKID_H_ + +enum{ + CLK_AUD_AFE, + CLK_AUD_22M, + CLK_AUD_24M, + CLK_AUD_APLL2_TUNER, + CLK_AUD_APLL_TUNER, + CLK_AUD_TDM, + CLK_AUD_ADC, + CLK_AUD_DAC, + CLK_AUD_DAC_PREDIS, + CLK_AUD_TML, + CLK_AUD_NLE, + CLK_AUD_I2S1_BCLK, + CLK_AUD_I2S2_BCLK, + CLK_AUD_I2S3_BCLK, + CLK_AUD_I2S4_BCLK, + CLK_AUD_CONNSYS_I2S_ASRC, + CLK_AUD_GENERAL1_ASRC, + CLK_AUD_GENERAL2_ASRC, + CLK_AUD_DAC_HIRES, + CLK_AUD_ADC_HIRES, + CLK_AUD_ADC_HIRES_TML, + CLK_AUD_ADDA6_ADC, + CLK_AUD_ADDA6_ADC_HIRES, + CLK_AUD_3RD_DAC, + CLK_AUD_3RD_DAC_PREDIS, + CLK_AUD_3RD_DAC_TML, + CLK_AUD_3RD_DAC_HIRES, + CLK_AUD_ETDM_IN1_BCLK, + CLK_AUD_ETDM_OUT1_BCLK, + CLK_AUD_NR_CLK, +}; + +#endif -- GitLab From b65c466220b336f5044c1be75ebc771d087ee7ca Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:42 +0800 Subject: [PATCH 237/942] ASoC: mediatek: mt8186: support adda in platform driver Add mt8186 adda dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-5-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 873 ++++++++++++++++++++ 1 file changed, 873 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-adda.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c new file mode 100644 index 0000000000000..c66861fd197d3 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c @@ -0,0 +1,873 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI ADDA Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include "mt8186-afe-clk.h" +#include "mt8186-afe-common.h" +#include "mt8186-afe-gpio.h" +#include "mt8186-interconnection.h" + +enum { + UL_IIR_SW = 0, + UL_IIR_5HZ, + UL_IIR_10HZ, + UL_IIR_25HZ, + UL_IIR_50HZ, + UL_IIR_75HZ, +}; + +enum { + AUDIO_SDM_LEVEL_MUTE = 0, + AUDIO_SDM_LEVEL_NORMAL = 0x1d, + /* if you change level normal */ + /* you need to change formula of hp impedance and dc trim too */ +}; + +enum { + AUDIO_SDM_2ND = 0, + AUDIO_SDM_3RD, +}; + +enum { + DELAY_DATA_MISO1 = 0, + DELAY_DATA_MISO2, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K = 0, + MTK_AFE_ADDA_DL_RATE_11K = 1, + MTK_AFE_ADDA_DL_RATE_12K = 2, + MTK_AFE_ADDA_DL_RATE_16K = 3, + MTK_AFE_ADDA_DL_RATE_22K = 4, + MTK_AFE_ADDA_DL_RATE_24K = 5, + MTK_AFE_ADDA_DL_RATE_32K = 6, + MTK_AFE_ADDA_DL_RATE_44K = 7, + MTK_AFE_ADDA_DL_RATE_48K = 8, + MTK_AFE_ADDA_DL_RATE_96K = 9, + MTK_AFE_ADDA_DL_RATE_192K = 10, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K = 0, + MTK_AFE_ADDA_UL_RATE_16K = 1, + MTK_AFE_ADDA_UL_RATE_32K = 2, + MTK_AFE_ADDA_UL_RATE_48K = 3, + MTK_AFE_ADDA_UL_RATE_96K = 4, + MTK_AFE_ADDA_UL_RATE_192K = 5, + MTK_AFE_ADDA_UL_RATE_48K_HD = 6, +}; + +#define SDM_AUTO_RESET_THRESHOLD 0x190000 + +struct mtk_afe_adda_priv { + int dl_rate; + int ul_rate; +}; + +static struct mtk_afe_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id; + + if (strncmp(name, "aud_dac_hires_clk", 7) == 0 || + strncmp(name, "aud_adc_hires_clk", 7) == 0) + dai_id = MT8186_DAI_ADDA; + else + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_DL_RATE_8K; + case 11025: + return MTK_AFE_ADDA_DL_RATE_11K; + case 12000: + return MTK_AFE_ADDA_DL_RATE_12K; + case 16000: + return MTK_AFE_ADDA_DL_RATE_16K; + case 22050: + return MTK_AFE_ADDA_DL_RATE_22K; + case 24000: + return MTK_AFE_ADDA_DL_RATE_24K; + case 32000: + return MTK_AFE_ADDA_DL_RATE_32K; + case 44100: + return MTK_AFE_ADDA_DL_RATE_44K; + case 48000: + return MTK_AFE_ADDA_DL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_DL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_DL_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + } + + return MTK_AFE_ADDA_DL_RATE_48K; +} + +static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + } + + return MTK_AFE_ADDA_UL_RATE_48K; +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN3, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN3, I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN3, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN3, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN3_1, I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN3_1, I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN3_1, I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN3_1, I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN3, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN3, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN3, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN3, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1 Switch", AFE_CONN3, + I_PCM_2_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN3_1, + I_SRC_1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH1 Switch", AFE_CONN3_1, + I_SRC_2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN4, I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN4, I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN4, I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN4, I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN4, I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN4, I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN4, I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN4_1, I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN4_1, I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN4_1, I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN4_1, I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN4, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN4, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN4, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN4, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN4, + I_PCM_2_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN4_1, + I_SRC_1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_2_OUT_CH2 Switch", AFE_CONN4_1, + I_SRC_2_OUT_CH2, 1, 0), +}; + +enum { + SUPPLY_SEQ_ADDA_AFE_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_FIFO, + SUPPLY_SEQ_ADDA_AP_DMIC, + SUPPLY_SEQ_ADDA_UL_ON, +}; + +static int mtk_adda_ul_src_dmic(struct mtk_base_afe *afe, int id) +{ + unsigned int reg; + + switch (id) { + case MT8186_DAI_ADDA: + case MT8186_DAI_AP_DMIC: + reg = AFE_ADDA_UL_SRC_CON0; + break; + default: + return -EINVAL; + } + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, reg, + DIGMIC_3P25M_1P625M_SEL_MASK_SFT, 0); + regmap_update_bits(afe->regmap, reg, + DMIC_LOW_POWER_CTL_MASK_SFT, 0); + + /* turn on dmic, ch1, ch2 */ + regmap_update_bits(afe->regmap, reg, + UL_SDM_3_LEVEL_MASK_SFT, + BIT(UL_SDM_3_LEVEL_SFT)); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH1_CTL_MASK_SFT, + BIT(UL_MODE_3P25M_CH1_CTL_SFT)); + regmap_update_bits(afe->regmap, reg, + UL_MODE_3P25M_CH2_CTL_MASK_SFT, + BIT(UL_MODE_3P25M_CH2_CTL_SFT)); + + return 0; +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int mtkaif_dmic = afe_priv->mtkaif_dmic; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x, mtkaif_dmic %d\n", + __func__, w->name, event, mtkaif_dmic); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_afe_gpio_request(afe->dev, true, MT8186_DAI_ADDA, 1); + + /* update setting to dmic */ + if (mtkaif_dmic) { + /* mtkaif_rxif_data_mode = 1, dmic */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + 0x1, 0x1); + + /* dmic mode, 3.25M*/ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, + MTKAIF_RXIF_VOICE_MODE_MASK_SFT, + 0x0); + mtk_adda_ul_src_dmic(afe, MT8186_DAI_ADDA); + } + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_ADDA, 1); + + /* reset dmic */ + afe_priv->mtkaif_dmic = 0; + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x39); + else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); + else + regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int delay_data; + int delay_cycle; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) { + /* set protocol 2 */ + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x10000); + /* mtkaif_rxif_clkinv_adc inverse */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, + MTKAIF_RXIF_CLKINV_ADC_MASK_SFT, + BIT(MTKAIF_RXIF_CLKINV_ADC_SFT)); + + if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0) { + if (afe_priv->mtkaif_chosen_phase[0] < 0 && + afe_priv->mtkaif_chosen_phase[1] < 0) { + dev_err(afe->dev, + "%s(), calib fail mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } + + if (afe_priv->mtkaif_chosen_phase[0] < 0 || + afe_priv->mtkaif_chosen_phase[1] < 0) { + dev_err(afe->dev, + "%s(), skip dealy setting mtkaif_chosen_phase[0/1]:%d/%d\n", + __func__, + afe_priv->mtkaif_chosen_phase[0], + afe_priv->mtkaif_chosen_phase[1]); + break; + } + } + + /* set delay for ch12 */ + if (afe_priv->mtkaif_phase_cycle[0] >= + afe_priv->mtkaif_phase_cycle[1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = afe_priv->mtkaif_phase_cycle[0] - + afe_priv->mtkaif_phase_cycle[1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = afe_priv->mtkaif_phase_cycle[1] - + afe_priv->mtkaif_phase_cycle[0]; + } + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_DATA_MASK_SFT, + delay_data << + MTKAIF_RXIF_DELAY_DATA_SFT); + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_RX_CFG2, + MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, + delay_cycle << + MTKAIF_RXIF_DELAY_CYCLE_SFT); + + } else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x10000); + } else { + regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0); + } + + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_afe_gpio_request(afe->dev, true, MT8186_DAI_ADDA, 0); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_ADDA, 0); + break; + default: + break; + } + + return 0; +} + +static int mt8186_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; + + return 0; +} + +static int mt8186_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dmic_on; + + dmic_on = ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + if (afe_priv->mtkaif_dmic == dmic_on) + return 0; + + afe_priv->mtkaif_dmic = dmic_on; + + return 1; +} + +static const struct snd_kcontrol_new mtk_adda_controls[] = { + SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1, + DL_2_GAIN_CTL_PRE_SFT, DL_2_GAIN_CTL_PRE_MASK, 0), + SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0, + mt8186_adda_dmic_get, mt8186_adda_dmic_set), +}; + +/* ADDA UL MUX */ +enum { + ADDA_UL_MUX_MTKAIF = 0, + ADDA_UL_MUX_AP_DMIC, + ADDA_UL_MUX_MASK = 0x1, +}; + +static const char * const adda_ul_mux_map[] = { + "MTKAIF", "AP_DMIC" +}; + +static int adda_ul_map_value[] = { + ADDA_UL_MUX_MTKAIF, + ADDA_UL_MUX_AP_DMIC, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(adda_ul_mux_map_enum, + SND_SOC_NOPM, + 0, + ADDA_UL_MUX_MASK, + adda_ul_mux_map, + adda_ul_map_value); + +static const struct snd_kcontrol_new adda_ul_mux_control = + SOC_DAPM_ENUM("ADDA_UL_MUX Select", adda_ul_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch1_mix, + ARRAY_SIZE(mtk_adda_dl_ch1_mix)), + SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, + mtk_adda_dl_ch2_mix, + ARRAY_SIZE(mtk_adda_dl_ch2_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_DL_SRC2_CON0, + DL_2_SRC_ON_CTL_PRE_SFT, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL_SRC_CON0, + UL_SRC_ON_CTL_SFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUD_PAD_TOP", SUPPLY_SEQ_ADDA_AUD_PAD_TOP, + 0, 0, 0, + mtk_adda_pad_top_event, + SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY_S("AP_DMIC_EN", SUPPLY_SEQ_ADDA_AP_DMIC, + AFE_ADDA_UL_SRC_CON0, + UL_AP_DMIC_ON_SFT, 0, + NULL, 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA_FIFO", SUPPLY_SEQ_ADDA_FIFO, + AFE_ADDA_UL_DL_CON0, + AFE_ADDA_FIFO_AUTO_RST_SFT, 1, + NULL, 0), + + SND_SOC_DAPM_MUX("ADDA_UL_Mux", SND_SOC_NOPM, 0, 0, + &adda_ul_mux_control), + + SND_SOC_DAPM_INPUT("AP_DMIC_INPUT"), + + /* clock */ + SND_SOC_DAPM_CLOCK_SUPPLY("top_mux_audio_h"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_predis_clk"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_clk"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires_clk"), +}; + +#define HIRES_THRESHOLD 48000 +static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_adda_priv *adda_priv; + + adda_priv = get_adda_priv_by_name(afe, w->name); + + if (!adda_priv) { + dev_err(afe->dev, "%s(), adda_priv == NULL", __func__); + return 0; + } + + return (adda_priv->dl_rate > HIRES_THRESHOLD) ? 1 : 0; +} + +static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_adda_priv *adda_priv; + + adda_priv = get_adda_priv_by_name(afe, w->name); + + if (!adda_priv) { + dev_err(afe->dev, "%s(), adda_priv == NULL", __func__); + return 0; + } + + return (adda_priv->ul_rate > HIRES_THRESHOLD) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + /* playback */ + {"ADDA_DL_CH1", "DL1_CH1 Switch", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH1 Switch", "DL1"}, + {"ADDA_DL_CH2", "DL1_CH2 Switch", "DL1"}, + + {"ADDA_DL_CH1", "DL12_CH1 Switch", "DL12"}, + {"ADDA_DL_CH2", "DL12_CH2 Switch", "DL12"}, + + {"ADDA_DL_CH1", "DL6_CH1 Switch", "DL6"}, + {"ADDA_DL_CH2", "DL6_CH2 Switch", "DL6"}, + + {"ADDA_DL_CH1", "DL8_CH1 Switch", "DL8"}, + {"ADDA_DL_CH2", "DL8_CH2 Switch", "DL8"}, + + {"ADDA_DL_CH1", "DL2_CH1 Switch", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH1 Switch", "DL2"}, + {"ADDA_DL_CH2", "DL2_CH2 Switch", "DL2"}, + + {"ADDA_DL_CH1", "DL3_CH1 Switch", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH1 Switch", "DL3"}, + {"ADDA_DL_CH2", "DL3_CH2 Switch", "DL3"}, + + {"ADDA_DL_CH1", "DL4_CH1 Switch", "DL4"}, + {"ADDA_DL_CH2", "DL4_CH2 Switch", "DL4"}, + + {"ADDA_DL_CH1", "DL5_CH1 Switch", "DL5"}, + {"ADDA_DL_CH2", "DL5_CH2 Switch", "DL5"}, + + {"ADDA Playback", NULL, "ADDA_DL_CH1"}, + {"ADDA Playback", NULL, "ADDA_DL_CH2"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + + /* capture */ + {"ADDA_UL_Mux", "MTKAIF", "ADDA Capture"}, + {"ADDA_UL_Mux", "AP_DMIC", "AP DMIC Capture"}, + + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "AUD_PAD_TOP"}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + + {"AP DMIC Capture", NULL, "ADDA Enable"}, + {"AP DMIC Capture", NULL, "ADDA Capture Enable"}, + {"AP DMIC Capture", NULL, "ADDA_FIFO"}, + {"AP DMIC Capture", NULL, "AP_DMIC_EN"}, + + {"AP DMIC Capture", NULL, "AP_DMIC_INPUT"}, + + /* clk */ + {"ADDA Playback", NULL, "aud_dac_clk"}, + {"ADDA Playback", NULL, "aud_dac_predis_clk"}, + {"ADDA Playback", NULL, "aud_dac_hires_clk", mtk_afe_dac_hires_connect}, + + {"ADDA Capture Enable", NULL, "aud_adc_clk"}, + {"ADDA Capture Enable", NULL, "aud_adc_hires_clk", + mtk_afe_adc_hires_connect}, + + /* hires source from apll1 */ + {"top_mux_audio_h", NULL, APLL2_W_NAME}, + + {"aud_dac_hires_clk", NULL, "top_mux_audio_h"}, + {"aud_adc_hires_clk", NULL, "top_mux_audio_h"}, +}; + +/* dai ops */ +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + unsigned int rate = params_rate(params); + int id = dai->id; + struct mtk_afe_adda_priv *adda_priv = afe_priv->dai_priv[id]; + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, id, substream->stream, rate); + + if (!adda_priv) { + dev_err(afe->dev, "%s(), adda_priv == NULL", __func__); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + unsigned int dl_src2_con0; + unsigned int dl_src2_con1; + + adda_priv->dl_rate = rate; + + /* set sampling rate */ + dl_src2_con0 = adda_dl_rate_transform(afe, rate) << + DL_2_INPUT_MODE_CTL_SFT; + + /* set output mode, UP_SAMPLING_RATE_X8 */ + dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT); + + /* turn off mute function */ + dl_src2_con0 |= BIT(DL_2_MUTE_CH2_OFF_CTL_PRE_SFT); + dl_src2_con0 |= BIT(DL_2_MUTE_CH1_OFF_CTL_PRE_SFT); + + /* set voice input data if input sample rate is 8k or 16k */ + if (rate == 8000 || rate == 16000) + dl_src2_con0 |= BIT(DL_2_VOICE_MODE_CTL_PRE_SFT); + + /* SA suggest apply -0.3db to audio/speech path */ + dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL << + DL_2_GAIN_CTL_PRE_SFT; + + /* turn on down-link gain */ + dl_src2_con0 |= BIT(DL_2_GAIN_ON_CTL_PRE_SFT); + + if (id == MT8186_DAI_ADDA) { + /* clean predistortion */ + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); + regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); + + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); + regmap_write(afe->regmap, + AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); + + /* set sdm gain */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + ATTGAIN_CTL_MASK_SFT, + AUDIO_SDM_LEVEL_NORMAL << + ATTGAIN_CTL_SFT); + + /* Use new 2nd sdm */ + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DITHER_CON, + AFE_DL_SDM_DITHER_64TAP_EN_MASK_SFT, + BIT(AFE_DL_SDM_DITHER_64TAP_EN_SFT)); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + AFE_DL_USE_NEW_2ND_SDM_MASK_SFT, + BIT(AFE_DL_USE_NEW_2ND_SDM_SFT)); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_DCCOMP_CON, + USE_3RD_SDM_MASK_SFT, + AUDIO_SDM_2ND << USE_3RD_SDM_SFT); + + /* sdm auto reset */ + regmap_write(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_THRESHOLD); + regmap_update_bits(afe->regmap, + AFE_ADDA_DL_SDM_AUTO_RESET_CON, + SDM_AUTO_RESET_TEST_ON_MASK_SFT, + BIT(SDM_AUTO_RESET_TEST_ON_SFT)); + } + } else { + unsigned int ul_src_con0 = 0; + unsigned int voice_mode = adda_ul_rate_transform(afe, rate); + + adda_priv->ul_rate = rate; + ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); + + /* enable iir */ + ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & + UL_IIR_ON_TMP_CTL_MASK_SFT; + ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) & + UL_IIRMODE_CTL_MASK_SFT; + switch (id) { + case MT8186_DAI_ADDA: + case MT8186_DAI_AP_DMIC: + /* 35Hz @ 48k */ + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_02_01, 0); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_04_03, 0x3fb8); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_06_05, 0x3fb80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_08_07, 0x3fb80000); + regmap_write(afe->regmap, + AFE_ADDA_IIR_COEF_10_09, 0xc048); + + regmap_write(afe->regmap, + AFE_ADDA_UL_SRC_CON0, ul_src_con0); + + /* Using Internal ADC */ + regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, BIT(0), 0); + + /* mtkaif_rxif_data_mode = 0, amic */ + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, BIT(0), 0); + break; + default: + break; + } + + /* ap dmic */ + switch (id) { + case MT8186_DAI_AP_DMIC: + mtk_adda_ul_src_dmic(afe, id); + break; + default: + break; + } + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "ADDA", + .id = MT8186_DAI_ADDA, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "AP_DMIC", + .id = MT8186_DAI_AP_DMIC, + .capture = { + .stream_name = "AP DMIC Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +int mt8186_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + + dai->controls = mtk_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_adda_controls); + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + + /* set dai priv */ + ret = mt8186_dai_set_priv(afe, MT8186_DAI_ADDA, + sizeof(struct mtk_afe_adda_priv), NULL); + if (ret) + return ret; + + /* ap dmic priv share with adda */ + afe_priv->dai_priv[MT8186_DAI_AP_DMIC] = + afe_priv->dai_priv[MT8186_DAI_ADDA]; + + return 0; +} -- GitLab From 55cac93d271166a2aa431d453bf31fdcb19bd5e6 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:43 +0800 Subject: [PATCH 238/942] ASoC: mediatek: mt8186: support hostless in platform driver Add mt8186 hostless dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-6-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- .../soc/mediatek/mt8186/mt8186-dai-hostless.c | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hostless.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c b/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c new file mode 100644 index 0000000000000..bf0d83840cf4d --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI Hostless Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include "mt8186-afe-common.h" + +static const struct snd_pcm_hardware mt8186_hostless_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .period_bytes_min = 256, + .period_bytes_max = 4 * 48 * 1024, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 4 * 48 * 1024, + .fifo_size = 0, +}; + +/* dai component */ +static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = { + /* Hostless ADDA Loopback */ + {"ADDA_DL_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"ADDA_DL_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S1_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S1_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S3_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S3_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"I2S3_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"}, + {"I2S3_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"}, + {"Hostless LPBK UL", NULL, "ADDA_UL_Mux"}, + + /* Hostelss FM */ + /* connsys_i2s to hw gain 1*/ + {"Hostless FM UL", NULL, "Connsys I2S"}, + + {"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1 Switch", "Hostless FM DL"}, + {"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2 Switch", "Hostless FM DL"}, + /* hw gain to adda dl */ + {"Hostless FM UL", NULL, "HW Gain 1 Out"}, + + {"ADDA_DL_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"ADDA_DL_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + /* hw gain to i2s3 */ + {"I2S3_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"I2S3_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + /* hw gain to i2s1 */ + {"I2S1_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"}, + {"I2S1_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"}, + + /* Hostless_SRC */ + {"ADDA_DL_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"ADDA_DL_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"I2S1_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"I2S1_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"I2S3_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"}, + {"I2S3_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"}, + {"Hostless_SRC_1_UL", NULL, "HW_SRC_1_Out"}, + + /* Hostless_SRC_bargein */ + {"HW_SRC_1_IN_CH1", "I2S0_CH1 Switch", "Hostless_SRC_Bargein_DL"}, + {"HW_SRC_1_IN_CH2", "I2S0_CH2 Switch", "Hostless_SRC_Bargein_DL"}, + {"Hostless_SRC_Bargein_UL", NULL, "I2S0"}, + + /* Hostless AAudio */ + {"Hostless HW Gain AAudio In", NULL, "HW Gain 2 In"}, + {"Hostless SRC AAudio UL", NULL, "HW Gain 2 Out"}, + {"HW_SRC_2_IN_CH1", "HW_GAIN2_OUT_CH1 Switch", "Hostless SRC AAudio DL"}, + {"HW_SRC_2_IN_CH2", "HW_GAIN2_OUT_CH2 Switch", "Hostless SRC AAudio DL"}, +}; + +/* dai ops */ +static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + snd_soc_set_runtime_hwparams(substream, &mt8186_hostless_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_hostless_ops = { + .startup = mtk_dai_hostless_startup, +}; + +/* dai driver */ +#define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_hostless_driver[] = { + { + .name = "Hostless LPBK DAI", + .id = MT8186_DAI_HOSTLESS_LPBK, + .playback = { + .stream_name = "Hostless LPBK DL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .capture = { + .stream_name = "Hostless LPBK UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless FM DAI", + .id = MT8186_DAI_HOSTLESS_FM, + .playback = { + .stream_name = "Hostless FM DL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .capture = { + .stream_name = "Hostless FM UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_SRC_1_DAI", + .id = MT8186_DAI_HOSTLESS_SRC_1, + .playback = { + .stream_name = "Hostless_SRC_1_DL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .capture = { + .stream_name = "Hostless_SRC_1_UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_SRC_Bargein_DAI", + .id = MT8186_DAI_HOSTLESS_SRC_BARGEIN, + .playback = { + .stream_name = "Hostless_SRC_Bargein_DL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .capture = { + .stream_name = "Hostless_SRC_Bargein_UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + /* BE dai */ + { + .name = "Hostless_UL1 DAI", + .id = MT8186_DAI_HOSTLESS_UL1, + .capture = { + .stream_name = "Hostless_UL1 UL", + .channels_min = 1, + .channels_max = 4, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_UL2 DAI", + .id = MT8186_DAI_HOSTLESS_UL2, + .capture = { + .stream_name = "Hostless_UL2 UL", + .channels_min = 1, + .channels_max = 4, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_UL3 DAI", + .id = MT8186_DAI_HOSTLESS_UL3, + .capture = { + .stream_name = "Hostless_UL3 UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_UL5 DAI", + .id = MT8186_DAI_HOSTLESS_UL5, + .capture = { + .stream_name = "Hostless_UL5 UL", + .channels_min = 1, + .channels_max = 12, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless_UL6 DAI", + .id = MT8186_DAI_HOSTLESS_UL6, + .capture = { + .stream_name = "Hostless_UL6 UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless HW Gain AAudio DAI", + .id = MT8186_DAI_HOSTLESS_HW_GAIN_AAUDIO, + .capture = { + .stream_name = "Hostless HW Gain AAudio In", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, + { + .name = "Hostless SRC AAudio DAI", + .id = MT8186_DAI_HOSTLESS_SRC_AAUDIO, + .playback = { + .stream_name = "Hostless SRC AAudio DL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .capture = { + .stream_name = "Hostless SRC AAudio UL", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HOSTLESS_RATES, + .formats = MTK_HOSTLESS_FORMATS, + }, + .ops = &mtk_dai_hostless_ops, + }, +}; + +int mt8186_dai_hostless_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_hostless_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_hostless_driver); + + dai->dapm_routes = mtk_dai_hostless_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_hostless_routes); + + return 0; +} -- GitLab From 2567ccae9105cbc881828f2ea09954c1b5fd975d Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:44 +0800 Subject: [PATCH 239/942] ASoC: mediatek: mt8186: support hw gain in platform driver Add mt8186 hw gain dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-7-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- .../soc/mediatek/mt8186/mt8186-dai-hw-gain.c | 236 ++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c b/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c new file mode 100644 index 0000000000000..33edd6cbde128 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI HW Gain Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include "mt8186-afe-common.h" +#include "mt8186-interconnection.h" + +#define HW_GAIN_1_EN_W_NAME "HW GAIN 1 Enable" +#define HW_GAIN_2_EN_W_NAME "HW GAIN 2 Enable" + +/* dai component */ +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1 Switch", AFE_CONN13_1, + I_CONNSYS_I2S_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2 Switch", AFE_CONN14_1, + I_CONNSYS_I2S_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_gain2_in_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN15, + I_ADDA_UL_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_gain2_in_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN16, + I_ADDA_UL_CH2, 1, 0), +}; + +static int mtk_hw_gain_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + unsigned int gain_cur; + unsigned int gain_con1; + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strcmp(w->name, HW_GAIN_1_EN_W_NAME) == 0) { + gain_cur = AFE_GAIN1_CUR; + gain_con1 = AFE_GAIN1_CON1; + } else { + gain_cur = AFE_GAIN2_CUR; + gain_con1 = AFE_GAIN2_CON1; + } + + /* let hw gain ramp up, set cur gain to 0 */ + regmap_update_bits(afe->regmap, gain_cur, AFE_GAIN1_CUR_MASK_SFT, 0); + + /* set target gain to 0 */ + regmap_update_bits(afe->regmap, gain_con1, GAIN1_TARGET_MASK_SFT, 0); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_hw_gain_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH1", SND_SOC_NOPM, 0, 0, + mtk_hw_gain1_in_ch1_mix, + ARRAY_SIZE(mtk_hw_gain1_in_ch1_mix)), + SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH2", SND_SOC_NOPM, 0, 0, + mtk_hw_gain1_in_ch2_mix, + ARRAY_SIZE(mtk_hw_gain1_in_ch2_mix)), + SND_SOC_DAPM_MIXER("HW_GAIN2_IN_CH1", SND_SOC_NOPM, 0, 0, + mtk_hw_gain2_in_ch1_mix, + ARRAY_SIZE(mtk_hw_gain2_in_ch1_mix)), + SND_SOC_DAPM_MIXER("HW_GAIN2_IN_CH2", SND_SOC_NOPM, 0, 0, + mtk_hw_gain2_in_ch2_mix, + ARRAY_SIZE(mtk_hw_gain2_in_ch2_mix)), + + SND_SOC_DAPM_SUPPLY(HW_GAIN_1_EN_W_NAME, + AFE_GAIN1_CON0, GAIN1_ON_SFT, 0, + mtk_hw_gain_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_SUPPLY(HW_GAIN_2_EN_W_NAME, + AFE_GAIN2_CON0, GAIN2_ON_SFT, 0, + mtk_hw_gain_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_INPUT("HW Gain 1 Out Endpoint"), + SND_SOC_DAPM_INPUT("HW Gain 2 Out Endpoint"), + SND_SOC_DAPM_OUTPUT("HW Gain 1 In Endpoint"), +}; + +static const struct snd_soc_dapm_route mtk_dai_hw_gain_routes[] = { + {"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH1"}, + {"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH2"}, + {"HW Gain 2 In", NULL, "HW_GAIN2_IN_CH1"}, + {"HW Gain 2 In", NULL, "HW_GAIN2_IN_CH2"}, + + {"HW Gain 1 In", NULL, HW_GAIN_1_EN_W_NAME}, + {"HW Gain 1 Out", NULL, HW_GAIN_1_EN_W_NAME}, + {"HW Gain 2 In", NULL, HW_GAIN_2_EN_W_NAME}, + {"HW Gain 2 Out", NULL, HW_GAIN_2_EN_W_NAME}, + + {"HW Gain 1 In Endpoint", NULL, "HW Gain 1 In"}, + {"HW Gain 1 Out", NULL, "HW Gain 1 Out Endpoint"}, + {"HW Gain 2 Out", NULL, "HW Gain 2 Out Endpoint"}, +}; + +static const struct snd_kcontrol_new mtk_hw_gain_controls[] = { + SOC_SINGLE("HW Gain 1 Volume", AFE_GAIN1_CON1, + GAIN1_TARGET_SFT, GAIN1_TARGET_MASK, 0), + SOC_SINGLE("HW Gain 2 Volume", AFE_GAIN2_CON1, + GAIN2_TARGET_SFT, GAIN2_TARGET_MASK, 0), +}; + +/* dai ops */ +static int mtk_dai_gain_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, dai->id); + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, dai->id, substream->stream, rate); + + /* rate */ + regmap_update_bits(afe->regmap, + dai->id == MT8186_DAI_HW_GAIN_1 ? + AFE_GAIN1_CON0 : AFE_GAIN2_CON0, + GAIN1_MODE_MASK_SFT, + rate_reg << GAIN1_MODE_SFT); + + /* sample per step */ + regmap_update_bits(afe->regmap, + dai->id == MT8186_DAI_HW_GAIN_1 ? + AFE_GAIN1_CON0 : AFE_GAIN2_CON0, + GAIN1_SAMPLE_PER_STEP_MASK_SFT, + (dai->id == MT8186_DAI_HW_GAIN_1 ? 0x40 : 0x0) << + GAIN1_SAMPLE_PER_STEP_SFT); + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_gain_ops = { + .hw_params = mtk_dai_gain_hw_params, +}; + +/* dai driver */ +#define MTK_HW_GAIN_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_HW_GAIN_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_gain_driver[] = { + { + .name = "HW Gain 1", + .id = MT8186_DAI_HW_GAIN_1, + .playback = { + .stream_name = "HW Gain 1 In", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HW_GAIN_RATES, + .formats = MTK_HW_GAIN_FORMATS, + }, + .capture = { + .stream_name = "HW Gain 1 Out", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HW_GAIN_RATES, + .formats = MTK_HW_GAIN_FORMATS, + }, + .ops = &mtk_dai_gain_ops, + .symmetric_rate = 1, + .symmetric_channels = 1, + .symmetric_sample_bits = 1, + }, + { + .name = "HW Gain 2", + .id = MT8186_DAI_HW_GAIN_2, + .playback = { + .stream_name = "HW Gain 2 In", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HW_GAIN_RATES, + .formats = MTK_HW_GAIN_FORMATS, + }, + .capture = { + .stream_name = "HW Gain 2 Out", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_HW_GAIN_RATES, + .formats = MTK_HW_GAIN_FORMATS, + }, + .ops = &mtk_dai_gain_ops, + .symmetric_rate = 1, + .symmetric_channels = 1, + .symmetric_sample_bits = 1, + }, +}; + +int mt8186_dai_hw_gain_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_gain_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_gain_driver); + + dai->controls = mtk_hw_gain_controls; + dai->num_controls = ARRAY_SIZE(mtk_hw_gain_controls); + dai->dapm_widgets = mtk_dai_hw_gain_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_hw_gain_widgets); + dai->dapm_routes = mtk_dai_hw_gain_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_hw_gain_routes); + return 0; +} -- GitLab From 2907d261276e09bd84fdc8bad35930a046a99d4d Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:45 +0800 Subject: [PATCH 240/942] ASoC: mediatek: mt8186: support i2s in platform driver Add mt8186 i2s dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-8-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-i2s.c | 1286 ++++++++++++++++++++ 1 file changed, 1286 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-i2s.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c new file mode 100644 index 0000000000000..5c1290b950e8b --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c @@ -0,0 +1,1286 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI I2S Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include +#include "mt8186-afe-clk.h" +#include "mt8186-afe-common.h" +#include "mt8186-afe-gpio.h" +#include "mt8186-interconnection.h" + +enum { + I2S_FMT_EIAJ = 0, + I2S_FMT_I2S = 1, +}; + +enum { + I2S_WLEN_16_BIT = 0, + I2S_WLEN_32_BIT = 1, +}; + +enum { + I2S_HD_NORMAL = 0, + I2S_HD_LOW_JITTER = 1, +}; + +enum { + I2S1_SEL_O28_O29 = 0, + I2S1_SEL_O03_O04 = 1, +}; + +enum { + I2S_IN_PAD_CONNSYS = 0, + I2S_IN_PAD_IO_MUX = 1, +}; + +struct mtk_afe_i2s_priv { + int id; + int rate; /* for determine which apll to use */ + int low_jitter_en; + int master; /* only i2s0 has slave mode*/ + + const char *share_property_name; + int share_i2s_id; + + int mclk_id; + int mclk_rate; + int mclk_apll; +}; + +static unsigned int get_i2s_wlen(snd_pcm_format_t format) +{ + return snd_pcm_format_physical_width(format) <= 16 ? + I2S_WLEN_16_BIT : I2S_WLEN_32_BIT; +} + +#define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux" +#define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux" +#define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux" +#define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux" +#define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux" + +#define I2S0_HD_EN_W_NAME "I2S0_HD_EN" +#define I2S1_HD_EN_W_NAME "I2S1_HD_EN" +#define I2S2_HD_EN_W_NAME "I2S2_HD_EN" +#define I2S3_HD_EN_W_NAME "I2S3_HD_EN" + +#define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN" +#define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN" +#define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN" +#define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN" + +static int get_i2s_id_by_name(struct mtk_base_afe *afe, + const char *name) +{ + if (strncmp(name, "I2S0", 4) == 0) + return MT8186_DAI_I2S_0; + else if (strncmp(name, "I2S1", 4) == 0) + return MT8186_DAI_I2S_1; + else if (strncmp(name, "I2S2", 4) == 0) + return MT8186_DAI_I2S_2; + else if (strncmp(name, "I2S3", 4) == 0) + return MT8186_DAI_I2S_3; + + return -EINVAL; +} + +static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_i2s_id_by_name(afe, name); + + if (dai_id < 0) + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +/* low jitter control */ +static const char * const mt8186_i2s_hd_str[] = { + "Normal", "Low_Jitter" +}; + +static const struct soc_enum mt8186_i2s_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str), + mt8186_i2s_hd_str), +}; + +static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en; + + return 0; +} + +static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int hd_en; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + hd_en = ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", + __func__, kcontrol->id.name, hd_en); + + i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + if (i2s_priv->low_jitter_en == hd_en) + return 0; + + i2s_priv->low_jitter_en = hd_en; + + return 1; +} + +static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = { + SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0], + mt8186_i2s_hd_get, mt8186_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0], + mt8186_i2s_hd_get, mt8186_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0], + mt8186_i2s_hd_get, mt8186_i2s_hd_set), + SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0], + mt8186_i2s_hd_get, mt8186_i2s_hd_set), +}; + +/* dai component */ +/* i2s virtual mux to output widget */ +static const char * const i2s_mux_map[] = { + "Normal", "Dummy_Widget", +}; + +static int i2s_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + i2s_mux_map, + i2s_mux_map_value); + +static const struct snd_kcontrol_new i2s0_in_mux_control = + SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum); + +static const struct snd_kcontrol_new i2s1_out_mux_control = + SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum); + +static const struct snd_kcontrol_new i2s2_in_mux_control = + SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum); + +static const struct snd_kcontrol_new i2s3_out_mux_control = + SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum); + +/* i2s in lpbk */ +static const char * const i2s_lpbk_mux_map[] = { + "Normal", "Lpbk", +}; + +static int i2s_lpbk_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum, + AFE_I2S_CON, + I2S_LOOPBACK_SFT, + 1, + i2s_lpbk_mux_map, + i2s_lpbk_mux_map_value); + +static const struct snd_kcontrol_new i2s0_lpbk_mux_control = + SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum, + AFE_I2S_CON2, + I2S3_LOOPBACK_SFT, + 1, + i2s_lpbk_mux_map, + i2s_lpbk_mux_map_value); + +static const struct snd_kcontrol_new i2s2_lpbk_mux_control = + SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum); + +/* interconnection */ +static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0, + I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0, + I_DL12_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1, + I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1, + I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1, + I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1, + I_DL12_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1, + I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1, + I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1, + I_ADDA_UL_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1, + I_PCM_2_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1, + I_SRC_1_OUT_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28, + I_DL12_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28, + I_DL12_CH3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1, + I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1, + I_DL8_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28, + I_GAIN1_OUT_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28, + I_PCM_1_CAP_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1, + I_SRC_1_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29, + I_DL12_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29, + I_DL12_CH4, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1, + I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1, + I_DL8_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29, + I_GAIN1_OUT_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29, + I_PCM_1_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29, + I_PCM_2_CAP_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1, + I_SRC_1_OUT_CH2, 1, 0), +}; + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_I2S_MCLK_EN, + SUPPLY_SEQ_I2S_HD_EN, + SUPPLY_SEQ_I2S_EN, +}; + +static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0); + break; + case SND_SOC_DAPM_POST_PMD: + mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0); + break; + default: + break; + } + + return 0; +} + +static int mtk_apll_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8186_apll1_enable(afe); + else + mt8186_apll2_enable(afe); + break; + case SND_SOC_DAPM_POST_PMD: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8186_apll1_disable(afe); + else + mt8186_apll2_disable(afe); + break; + default: + break; + } + + return 0; +} + +static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + i2s_priv->mclk_rate = 0; + mt8186_mck_disable(afe, i2s_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = { + SND_SOC_DAPM_INPUT("CONNSYS"), + + SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2s1_ch1_mix, + ARRAY_SIZE(mtk_i2s1_ch1_mix)), + SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2s1_ch2_mix, + ARRAY_SIZE(mtk_i2s1_ch2_mix)), + + SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0, + mtk_i2s3_ch1_mix, + ARRAY_SIZE(mtk_i2s3_ch1_mix)), + SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0, + mtk_i2s3_ch2_mix, + ARRAY_SIZE(mtk_i2s3_ch2_mix)), + + /* i2s en*/ + SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN, + AFE_I2S_CON, I2S_EN_SFT, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN, + AFE_I2S_CON1, I2S_EN_SFT, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN, + AFE_I2S_CON2, I2S_EN_SFT, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN, + AFE_I2S_CON3, I2S_EN_SFT, 0, + mtk_i2s_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + /* i2s hd en */ + SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN, + AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* i2s mclk en */ + SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN, + SND_SOC_NOPM, 0, 0, + mtk_mclk_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* apll */ + SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* allow i2s on without codec on */ + SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"), + SND_SOC_DAPM_MUX("I2S1_Out_Mux", + SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control), + SND_SOC_DAPM_MUX("I2S3_Out_Mux", + SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control), + SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"), + SND_SOC_DAPM_MUX("I2S0_In_Mux", + SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control), + SND_SOC_DAPM_MUX("I2S2_In_Mux", + SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control), + + /* i2s in lpbk */ + SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux", + SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control), + SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux", + SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control), +}; + +static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return 0; + } + + if (i2s_priv->share_i2s_id < 0) + return 0; + + return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name); +} + +static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return 0; + } + + if (get_i2s_id_by_name(afe, sink->name) == + get_i2s_id_by_name(afe, source->name)) + return i2s_priv->low_jitter_en; + + /* check if share i2s need hd en */ + if (i2s_priv->share_i2s_id < 0) + return 0; + + if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) + return i2s_priv->low_jitter_en; + + return 0; +} + +static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + int i2s_need_apll; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return 0; + } + + /* which apll */ + cur_apll = mt8186_get_apll_by_name(afe, source->name); + + /* choose APLL from i2s rate */ + i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate); + + return (i2s_need_apll == cur_apll) ? 1 : 0; +} + +static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + + i2s_priv = get_i2s_priv_by_name(afe, sink->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return 0; + } + + if (get_i2s_id_by_name(afe, sink->name) == + get_i2s_id_by_name(afe, source->name)) + return (i2s_priv->mclk_rate > 0) ? 1 : 0; + + /* check if share i2s need mclk */ + if (i2s_priv->share_i2s_id < 0) + return 0; + + if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name)) + return (i2s_priv->mclk_rate > 0) ? 1 : 0; + + return 0; +} + +static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_afe_i2s_priv *i2s_priv; + int cur_apll; + + i2s_priv = get_i2s_priv_by_name(afe, w->name); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return 0; + } + + /* which apll */ + cur_apll = mt8186_get_apll_by_name(afe, source->name); + + return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { + {"Connsys I2S", NULL, "CONNSYS"}, + + /* i2s0 */ + {"I2S0", NULL, "I2S0_EN"}, + {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, + {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, + {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, + + {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2s1 */ + {"I2S1_CH1", "DL1_CH1 Switch", "DL1"}, + {"I2S1_CH2", "DL1_CH2 Switch", "DL1"}, + + {"I2S1_CH1", "DL2_CH1 Switch", "DL2"}, + {"I2S1_CH2", "DL2_CH2 Switch", "DL2"}, + + {"I2S1_CH1", "DL3_CH1 Switch", "DL3"}, + {"I2S1_CH2", "DL3_CH2 Switch", "DL3"}, + + {"I2S1_CH1", "DL12_CH1 Switch", "DL12"}, + {"I2S1_CH2", "DL12_CH2 Switch", "DL12"}, + + {"I2S1_CH1", "DL12_CH3 Switch", "DL12"}, + {"I2S1_CH2", "DL12_CH4 Switch", "DL12"}, + + {"I2S1_CH1", "DL6_CH1 Switch", "DL6"}, + {"I2S1_CH2", "DL6_CH2 Switch", "DL6"}, + + {"I2S1_CH1", "DL4_CH1 Switch", "DL4"}, + {"I2S1_CH2", "DL4_CH2 Switch", "DL4"}, + + {"I2S1_CH1", "DL5_CH1 Switch", "DL5"}, + {"I2S1_CH2", "DL5_CH2 Switch", "DL5"}, + + {"I2S1_CH1", "DL8_CH1 Switch", "DL8"}, + {"I2S1_CH2", "DL8_CH2 Switch", "DL8"}, + + {"I2S1", NULL, "I2S1_CH1"}, + {"I2S1", NULL, "I2S1_CH2"}, + + {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, + {"I2S1", NULL, "I2S1_EN"}, + {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, + {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, + + {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2s2 */ + {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, + {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, + {"I2S2", NULL, "I2S2_EN"}, + {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect}, + + {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* i2s3 */ + {"I2S3_CH1", "DL1_CH1 Switch", "DL1"}, + {"I2S3_CH2", "DL1_CH2 Switch", "DL1"}, + + {"I2S3_CH1", "DL2_CH1 Switch", "DL2"}, + {"I2S3_CH2", "DL2_CH2 Switch", "DL2"}, + + {"I2S3_CH1", "DL3_CH1 Switch", "DL3"}, + {"I2S3_CH2", "DL3_CH2 Switch", "DL3"}, + + {"I2S3_CH1", "DL12_CH1 Switch", "DL12"}, + {"I2S3_CH2", "DL12_CH2 Switch", "DL12"}, + + {"I2S3_CH1", "DL12_CH3 Switch", "DL12"}, + {"I2S3_CH2", "DL12_CH4 Switch", "DL12"}, + + {"I2S3_CH1", "DL6_CH1 Switch", "DL6"}, + {"I2S3_CH2", "DL6_CH2 Switch", "DL6"}, + + {"I2S3_CH1", "DL4_CH1 Switch", "DL4"}, + {"I2S3_CH2", "DL4_CH2 Switch", "DL4"}, + + {"I2S3_CH1", "DL5_CH1 Switch", "DL5"}, + {"I2S3_CH2", "DL5_CH2 Switch", "DL5"}, + + {"I2S3_CH1", "DL8_CH1 Switch", "DL8"}, + {"I2S3_CH2", "DL8_CH2 Switch", "DL8"}, + + {"I2S3", NULL, "I2S3_CH1"}, + {"I2S3", NULL, "I2S3_CH2"}, + + {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect}, + {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect}, + {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect}, + {"I2S3", NULL, "I2S3_EN"}, + + {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect}, + {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect}, + {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect}, + + {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect}, + {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + /* allow i2s on without codec on */ + {"I2S0", NULL, "I2S0_In_Mux"}, + {"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2S1_Out_Mux", "Dummy_Widget", "I2S1"}, + {"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"}, + + {"I2S2", NULL, "I2S2_In_Mux"}, + {"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"}, + + {"I2S3_Out_Mux", "Dummy_Widget", "I2S3"}, + {"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"}, + + /* i2s in lpbk */ + {"I2S0_Lpbk_Mux", "Lpbk", "I2S3"}, + {"I2S2_Lpbk_Mux", "Lpbk", "I2S1"}, + {"I2S0", NULL, "I2S0_Lpbk_Mux"}, + {"I2S2", NULL, "I2S2_Lpbk_Mux"}, +}; + +/* dai ops */ +static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8186_rate_transform(afe->dev, + rate, dai->id); + unsigned int i2s_con = 0; + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, dai->id, substream->stream, rate); + + /* non-inverse, i2s mode, slave, 16bits, from connsys */ + i2s_con |= 0 << INV_PAD_CTRL_SFT; + i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT; + i2s_con |= 1 << I2S_SRC_SFT; + i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT; + i2s_con |= 0 << I2SIN_PAD_SEL_SFT; + regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con); + + /* use asrc */ + regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, + I2S_BYPSRC_MASK_SFT, 0); + + /* slave mode, set i2s for asrc */ + regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, + I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT); + + if (rate == 44100) + regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000); + else if (rate == 32000) + regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000); + else + regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000); + + /* Calibration setting */ + regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000); + regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000); + regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00); + regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4); + regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986); + + /* 0:Stereo 1:Mono */ + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2, + CHSET_IS_MONO_MASK_SFT, 0); + + return 0; +} + +static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n", + __func__, cmd, substream->stream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* i2s enable */ + regmap_update_bits(afe->regmap, + AFE_CONNSYS_I2S_CON, + I2S_EN_MASK_SFT, + BIT(I2S_EN_SFT)); + + /* calibrator enable */ + regmap_update_bits(afe->regmap, + AFE_ASRC_2CH_CON5, + CALI_EN_MASK_SFT, + BIT(CALI_EN_SFT)); + + /* asrc enable */ + regmap_update_bits(afe->regmap, + AFE_ASRC_2CH_CON0, + CON0_CHSET_STR_CLR_MASK_SFT, + BIT(CON0_CHSET_STR_CLR_SFT)); + regmap_update_bits(afe->regmap, + AFE_ASRC_2CH_CON0, + CON0_ASM_ON_MASK_SFT, + BIT(CON0_ASM_ON_SFT)); + + afe_priv->dai_on[dai->id] = true; + return 0; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0, + CON0_ASM_ON_MASK_SFT, 0); + regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5, + CALI_EN_MASK_SFT, 0); + + /* i2s disable */ + regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, + I2S_EN_MASK_SFT, 0); + + /* bypass asrc */ + regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, + I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT)); + + afe_priv->dai_on[dai->id] = false; + return 0; + default: + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = { + .hw_params = mtk_dai_connsys_i2s_hw_params, + .trigger = mtk_dai_connsys_i2s_trigger, +}; + +/* i2s */ +static int mtk_dai_i2s_config(struct mtk_base_afe *afe, + struct snd_pcm_hw_params *params, + int i2s_id) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id]; + + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8186_rate_transform(afe->dev, + rate, i2s_id); + snd_pcm_format_t format = params_format(params); + unsigned int i2s_con = 0; + int ret; + + dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n", + __func__, i2s_id, rate, format); + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + i2s_priv->rate = rate; + + switch (i2s_id) { + case MT8186_DAI_I2S_0: + i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT; + i2s_con |= rate_reg << I2S_OUT_MODE_SFT; + i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT; + i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT; + regmap_update_bits(afe->regmap, AFE_I2S_CON, + 0xffffeffa, i2s_con); + break; + case MT8186_DAI_I2S_1: + i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT; + i2s_con |= rate_reg << I2S2_OUT_MODE_SFT; + i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT; + i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT; + regmap_update_bits(afe->regmap, AFE_I2S_CON1, + 0xffffeffa, i2s_con); + break; + case MT8186_DAI_I2S_2: + i2s_con = 8 << I2S3_UPDATE_WORD_SFT; + i2s_con |= rate_reg << I2S3_OUT_MODE_SFT; + i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT; + i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT; + regmap_update_bits(afe->regmap, AFE_I2S_CON2, + 0xffffeffa, i2s_con); + break; + case MT8186_DAI_I2S_3: + i2s_con = rate_reg << I2S4_OUT_MODE_SFT; + i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT; + i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT; + regmap_update_bits(afe->regmap, AFE_I2S_CON3, + 0xffffeffa, i2s_con); + break; + default: + dev_err(afe->dev, "%s(), id %d not support\n", + __func__, i2s_id); + return -EINVAL; + } + + /* set share i2s */ + if (i2s_priv && i2s_priv->share_i2s_id >= 0) { + ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id); + if (ret) + return ret; + } + + return 0; +} + +static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + return mtk_dai_i2s_config(afe, params, dai->id); +} + +static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id]; + int apll; + int apll_rate; + + if (!i2s_priv) { + dev_err(afe->dev, "%s(), i2s_priv == NULL", __func__); + return -EINVAL; + } + + if (dir != SND_SOC_CLOCK_OUT) { + dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__); + return -EINVAL; + } + + dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); + + apll = mt8186_get_apll_by_rate(afe, freq); + apll_rate = mt8186_get_apll_rate(afe, apll); + + if (freq > apll_rate) { + dev_err(afe->dev, "%s(), freq > apll rate", __func__); + return -EINVAL; + } + + if (apll_rate % freq != 0) { + dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__); + return -EINVAL; + } + + i2s_priv->mclk_rate = freq; + i2s_priv->mclk_apll = apll; + + if (i2s_priv->share_i2s_id > 0) { + struct mtk_afe_i2s_priv *share_i2s_priv; + + share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id]; + if (!share_i2s_priv) { + dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__); + return -EINVAL; + } + + share_i2s_priv->mclk_rate = i2s_priv->mclk_rate; + share_i2s_priv->mclk_apll = i2s_priv->mclk_apll; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_i2s_ops = { + .hw_params = mtk_dai_i2s_hw_params, + .set_sysclk = mtk_dai_i2s_set_sysclk, +}; + +/* dai driver */ +#define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) + +#define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = { + { + .name = "CONNSYS_I2S", + .id = MT8186_DAI_CONNSYS_I2S, + .capture = { + .stream_name = "Connsys I2S", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_CONNSYS_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_connsys_i2s_ops, + }, + { + .name = "I2S0", + .id = MT8186_DAI_I2S_0, + .capture = { + .stream_name = "I2S0", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2S1", + .id = MT8186_DAI_I2S_1, + .playback = { + .stream_name = "I2S1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2S2", + .id = MT8186_DAI_I2S_2, + .capture = { + .stream_name = "I2S2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + }, + { + .name = "I2S3", + .id = MT8186_DAI_I2S_3, + .playback = { + .stream_name = "I2S3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_I2S_RATES, + .formats = MTK_I2S_FORMATS, + }, + .ops = &mtk_dai_i2s_ops, + } +}; + +/* this enum is merely for mtk_afe_i2s_priv declare */ +enum { + DAI_I2S0 = 0, + DAI_I2S1, + DAI_I2S2, + DAI_I2S3, + DAI_I2S_NUM, +}; + +static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = { + [DAI_I2S0] = { + .id = MT8186_DAI_I2S_0, + .mclk_id = MT8186_I2S0_MCK, + .share_property_name = "i2s0-share", + .share_i2s_id = -1, + }, + [DAI_I2S1] = { + .id = MT8186_DAI_I2S_1, + .mclk_id = MT8186_I2S1_MCK, + .share_property_name = "i2s1-share", + .share_i2s_id = -1, + }, + [DAI_I2S2] = { + .id = MT8186_DAI_I2S_2, + .mclk_id = MT8186_I2S2_MCK, + .share_property_name = "i2s2-share", + .share_i2s_id = -1, + }, + [DAI_I2S3] = { + .id = MT8186_DAI_I2S_3, + /* clock gate naming is hf_faud_i2s4_m_ck*/ + .mclk_id = MT8186_I2S4_MCK, + .share_property_name = "i2s3-share", + .share_i2s_id = -1, + } +}; + +static int mt8186_dai_i2s_get_share(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + const struct device_node *of_node = afe->dev->of_node; + const char *of_str; + const char *property_name; + struct mtk_afe_i2s_priv *i2s_priv; + int i; + + for (i = 0; i < DAI_I2S_NUM; i++) { + i2s_priv = afe_priv->dai_priv[mt8186_i2s_priv[i].id]; + property_name = mt8186_i2s_priv[i].share_property_name; + if (of_property_read_string(of_node, property_name, &of_str)) + continue; + i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str); + } + + return 0; +} + +static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe) +{ + int i; + int ret; + + for (i = 0; i < DAI_I2S_NUM; i++) { + ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id, + sizeof(struct mtk_afe_i2s_priv), + &mt8186_i2s_priv[i]); + if (ret) + return ret; + } + + return 0; +} + +int mt8186_dai_i2s_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + int ret; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_i2s_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver); + + dai->controls = mtk_dai_i2s_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls); + dai->dapm_widgets = mtk_dai_i2s_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets); + dai->dapm_routes = mtk_dai_i2s_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes); + + /* set all dai i2s private data */ + ret = mt8186_dai_i2s_set_priv(afe); + if (ret) + return ret; + + /* parse share i2s */ + ret = mt8186_dai_i2s_get_share(afe); + if (ret) + return ret; + + return 0; +} -- GitLab From 920508f9fe2fc90f19916d74f4c23088030d32e0 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:46 +0800 Subject: [PATCH 241/942] ASoC: mediatek: mt8186: support pcm in platform driver Add mt8186 pcm dai driver. Signed-off-by: Jiaxin Yu Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220523132858.22166-9-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-pcm.c | 423 +++++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-pcm.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c new file mode 100644 index 0000000000000..0b0032ecfe6d3 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c @@ -0,0 +1,423 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI I2S Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include "mt8186-afe-common.h" +#include "mt8186-afe-gpio.h" +#include "mt8186-interconnection.h" + +struct mtk_afe_pcm_priv { + unsigned int id; + unsigned int fmt; + unsigned int bck_invert; + unsigned int lck_invert; +}; + +enum aud_tx_lch_rpt { + AUD_TX_LCH_RPT_NO_REPEAT = 0, + AUD_TX_LCH_RPT_REPEAT = 1 +}; + +enum aud_vbt_16k_mode { + AUD_VBT_16K_MODE_DISABLE = 0, + AUD_VBT_16K_MODE_ENABLE = 1 +}; + +enum aud_ext_modem { + AUD_EXT_MODEM_SELECT_INTERNAL = 0, + AUD_EXT_MODEM_SELECT_EXTERNAL = 1 +}; + +enum aud_pcm_sync_type { + /* bck sync length = 1 */ + AUD_PCM_ONE_BCK_CYCLE_SYNC = 0, + /* bck sync length = PCM_INTF_CON1[9:13] */ + AUD_PCM_EXTENDED_BCK_CYCLE_SYNC = 1 +}; + +enum aud_bt_mode { + AUD_BT_MODE_DUAL_MIC_ON_TX = 0, + AUD_BT_MODE_SINGLE_MIC_ON_TX = 1 +}; + +enum aud_pcm_afifo_src { + /* slave mode & external modem uses different crystal */ + AUD_PCM_AFIFO_ASRC = 0, + /* slave mode & external modem uses the same crystal */ + AUD_PCM_AFIFO_AFIFO = 1 +}; + +enum aud_pcm_clock_source { + AUD_PCM_CLOCK_MASTER_MODE = 0, + AUD_PCM_CLOCK_SLAVE_MODE = 1 +}; + +enum aud_pcm_wlen { + AUD_PCM_WLEN_PCM_32_BCK_CYCLES = 0, + AUD_PCM_WLEN_PCM_64_BCK_CYCLES = 1 +}; + +enum aud_pcm_24bit { + AUD_PCM_24BIT_PCM_16_BITS = 0, + AUD_PCM_24BIT_PCM_24_BITS = 1 +}; + +enum aud_pcm_mode { + AUD_PCM_MODE_PCM_MODE_8K = 0, + AUD_PCM_MODE_PCM_MODE_16K = 1, + AUD_PCM_MODE_PCM_MODE_32K = 2, + AUD_PCM_MODE_PCM_MODE_48K = 3, +}; + +enum aud_pcm_fmt { + AUD_PCM_FMT_I2S = 0, + AUD_PCM_FMT_EIAJ = 1, + AUD_PCM_FMT_PCM_MODE_A = 2, + AUD_PCM_FMT_PCM_MODE_B = 3 +}; + +enum aud_bclk_out_inv { + AUD_BCLK_OUT_INV_NO_INVERSE = 0, + AUD_BCLK_OUT_INV_INVERSE = 1 +}; + +enum aud_lrclk_out_inv { + AUD_LRCLK_OUT_INV_NO_INVERSE = 0, + AUD_LRCLK_OUT_INV_INVERSE = 1 +}; + +enum aud_pcm_en { + AUD_PCM_EN_DISABLE = 0, + AUD_PCM_EN_ENABLE = 1 +}; + +/* dai component */ +static const struct snd_kcontrol_new mtk_pcm_1_playback_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN7, + I_ADDA_UL_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN7, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN7_1, + I_DL4_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_pcm_1_playback_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN8, + I_ADDA_UL_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN8, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN8_1, + I_DL4_CH2, 1, 0), +}; + +static int mtk_pcm_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_afe_gpio_request(afe->dev, true, MT8186_DAI_PCM, 0); + break; + case SND_SOC_DAPM_POST_PMD: + mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_PCM, 0); + break; + } + + return 0; +} + +/* pcm in/out lpbk */ +static const char * const pcm_lpbk_mux_map[] = { + "Normal", "Lpbk", +}; + +static int pcm_lpbk_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(pcm_in_lpbk_mux_map_enum, + PCM_INTF_CON1, + PCM_I2S_PCM_LOOPBACK_SFT, + 1, + pcm_lpbk_mux_map, + pcm_lpbk_mux_map_value); + +static const struct snd_kcontrol_new pcm_in_lpbk_mux_control = + SOC_DAPM_ENUM("PCM In Lpbk Select", pcm_in_lpbk_mux_map_enum); + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(pcm_out_lpbk_mux_map_enum, + PCM_INTF_CON1, + PCM_I2S_PCM_LOOPBACK_SFT, + 1, + pcm_lpbk_mux_map, + pcm_lpbk_mux_map_value); + +static const struct snd_kcontrol_new pcm_out_lpbk_mux_control = + SOC_DAPM_ENUM("PCM Out Lpbk Select", pcm_out_lpbk_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("PCM_1_PB_CH1", SND_SOC_NOPM, 0, 0, + mtk_pcm_1_playback_ch1_mix, + ARRAY_SIZE(mtk_pcm_1_playback_ch1_mix)), + SND_SOC_DAPM_MIXER("PCM_1_PB_CH2", SND_SOC_NOPM, 0, 0, + mtk_pcm_1_playback_ch2_mix, + ARRAY_SIZE(mtk_pcm_1_playback_ch2_mix)), + + SND_SOC_DAPM_SUPPLY("PCM_1_EN", + PCM_INTF_CON1, PCM_EN_SFT, 0, + mtk_pcm_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* pcm in lpbk */ + SND_SOC_DAPM_MUX("PCM_In_Lpbk_Mux", + SND_SOC_NOPM, 0, 0, &pcm_in_lpbk_mux_control), + + /* pcm out lpbk */ + SND_SOC_DAPM_MUX("PCM_Out_Lpbk_Mux", + SND_SOC_NOPM, 0, 0, &pcm_out_lpbk_mux_control), +}; + +static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { + {"PCM 1 Playback", NULL, "PCM_1_PB_CH1"}, + {"PCM 1 Playback", NULL, "PCM_1_PB_CH2"}, + + {"PCM 1 Playback", NULL, "PCM_1_EN"}, + {"PCM 1 Capture", NULL, "PCM_1_EN"}, + + {"PCM_1_PB_CH1", "DL2_CH1 Switch", "DL2"}, + {"PCM_1_PB_CH2", "DL2_CH2 Switch", "DL2"}, + + {"PCM_1_PB_CH1", "DL4_CH1 Switch", "DL4"}, + {"PCM_1_PB_CH2", "DL4_CH2 Switch", "DL4"}, + + /* pcm out lpbk */ + {"PCM_Out_Lpbk_Mux", "Lpbk", "PCM 1 Playback"}, + {"I2S0", NULL, "PCM_Out_Lpbk_Mux"}, + + /* pcm in lpbk */ + {"PCM_In_Lpbk_Mux", "Lpbk", "PCM 1 Capture"}, + {"I2S3", NULL, "PCM_In_Lpbk_Mux"}, +}; + +/* dai ops */ +static int mtk_dai_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int pcm_id = dai->id; + struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[pcm_id]; + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, dai->id); + snd_pcm_format_t format = params_format(params); + unsigned int data_width = + snd_pcm_format_width(format); + unsigned int wlen_width = + snd_pcm_format_physical_width(format); + unsigned int pcm_con = 0; + + dev_dbg(afe->dev, "%s(), id %d, stream %d, widget active p %d, c %d\n", + __func__, dai->id, substream->stream, dai->playback_widget->active, + dai->capture_widget->active); + dev_dbg(afe->dev, "%s(), rate %d, rate_reg %d, data_width %d, wlen_width %d\n", + __func__, rate, rate_reg, data_width, wlen_width); + + if (dai->playback_widget->active || dai->capture_widget->active) + return 0; + + switch (dai->id) { + case MT8186_DAI_PCM: + pcm_con |= AUD_TX_LCH_RPT_NO_REPEAT << PCM_TX_LCH_RPT_SFT; + pcm_con |= AUD_VBT_16K_MODE_DISABLE << PCM_VBT_16K_MODE_SFT; + pcm_con |= AUD_EXT_MODEM_SELECT_EXTERNAL << PCM_EXT_MODEM_SFT; + pcm_con |= AUD_PCM_ONE_BCK_CYCLE_SYNC << PCM_SYNC_TYPE_SFT; + pcm_con |= AUD_BT_MODE_DUAL_MIC_ON_TX << PCM_BT_MODE_SFT; + pcm_con |= AUD_PCM_AFIFO_AFIFO << PCM_BYP_ASRC_SFT; + pcm_con |= AUD_PCM_CLOCK_MASTER_MODE << PCM_SLAVE_SFT; + pcm_con |= 0 << PCM_SYNC_LENGTH_SFT; + + /* sampling rate */ + pcm_con |= rate_reg << PCM_MODE_SFT; + + /* format */ + pcm_con |= pcm_priv->fmt << PCM_FMT_SFT; + + /* 24bit data width */ + if (data_width > 16) + pcm_con |= AUD_PCM_24BIT_PCM_24_BITS << PCM_24BIT_SFT; + else + pcm_con |= AUD_PCM_24BIT_PCM_16_BITS << PCM_24BIT_SFT; + + /* wlen width*/ + if (wlen_width > 16) + pcm_con |= AUD_PCM_WLEN_PCM_64_BCK_CYCLES << PCM_WLEN_SFT; + else + pcm_con |= AUD_PCM_WLEN_PCM_32_BCK_CYCLES << PCM_WLEN_SFT; + + /* clock invert */ + pcm_con |= pcm_priv->lck_invert << PCM_SYNC_OUT_INV_SFT; + pcm_con |= pcm_priv->bck_invert << PCM_BCLK_OUT_INV_SFT; + + regmap_update_bits(afe->regmap, PCM_INTF_CON1, 0xfffffffe, pcm_con); + break; + default: + dev_err(afe->dev, "%s(), id %d not support\n", __func__, dai->id); + return -EINVAL; + } + + return 0; +} + +static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[dai->id]; + + if (!pcm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + /* DAI mode*/ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + pcm_priv->fmt = AUD_PCM_FMT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + pcm_priv->fmt = AUD_PCM_FMT_EIAJ; + break; + case SND_SOC_DAIFMT_DSP_A: + pcm_priv->fmt = AUD_PCM_FMT_PCM_MODE_A; + break; + case SND_SOC_DAIFMT_DSP_B: + pcm_priv->fmt = AUD_PCM_FMT_PCM_MODE_B; + break; + default: + pcm_priv->fmt = AUD_PCM_FMT_I2S; + } + + /* DAI clock inversion*/ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_NO_INVERSE; + pcm_priv->lck_invert = AUD_LRCLK_OUT_INV_NO_INVERSE; + break; + case SND_SOC_DAIFMT_NB_IF: + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_NO_INVERSE; + pcm_priv->lck_invert = AUD_BCLK_OUT_INV_INVERSE; + break; + case SND_SOC_DAIFMT_IB_NF: + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_INVERSE; + pcm_priv->lck_invert = AUD_LRCLK_OUT_INV_NO_INVERSE; + break; + case SND_SOC_DAIFMT_IB_IF: + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_INVERSE; + pcm_priv->lck_invert = AUD_BCLK_OUT_INV_INVERSE; + break; + default: + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_NO_INVERSE; + pcm_priv->lck_invert = AUD_LRCLK_OUT_INV_NO_INVERSE; + break; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { + .hw_params = mtk_dai_pcm_hw_params, + .set_fmt = mtk_dai_pcm_set_fmt, +}; + +/* dai driver */ +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000) + +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { + { + .name = "PCM 1", + .id = MT8186_DAI_PCM, + .playback = { + .stream_name = "PCM 1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .capture = { + .stream_name = "PCM 1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mtk_dai_pcm_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, + }, +}; + +static struct mtk_afe_pcm_priv *init_pcm_priv_data(struct mtk_base_afe *afe) +{ + struct mtk_afe_pcm_priv *pcm_priv; + + pcm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_pcm_priv), + GFP_KERNEL); + if (!pcm_priv) + return NULL; + + pcm_priv->id = MT8186_DAI_PCM; + pcm_priv->fmt = AUD_PCM_FMT_I2S; + pcm_priv->bck_invert = AUD_BCLK_OUT_INV_NO_INVERSE; + pcm_priv->lck_invert = AUD_LRCLK_OUT_INV_NO_INVERSE; + + return pcm_priv; +} + +int mt8186_dai_pcm_register(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_pcm_priv *pcm_priv; + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_pcm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver); + + dai->dapm_widgets = mtk_dai_pcm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets); + dai->dapm_routes = mtk_dai_pcm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes); + + pcm_priv = init_pcm_priv_data(afe); + if (!pcm_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8186_DAI_PCM] = pcm_priv; + + return 0; +} -- GitLab From e118015db7bd0dad1744221d0fe18333ebf9c622 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:47 +0800 Subject: [PATCH 242/942] ASoC: mediatek: mt8186: support src in platform driver Add mt8186 src dai driver Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-10-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-src.c | 695 +++++++++++++++++++++ 1 file changed, 695 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-src.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-src.c b/sound/soc/mediatek/mt8186/mt8186-dai-src.c new file mode 100644 index 0000000000000..67989ffd67ca9 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-src.c @@ -0,0 +1,695 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI SRC Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include "mt8186-afe-common.h" +#include "mt8186-interconnection.h" + +struct mtk_afe_src_priv { + int dl_rate; + int ul_rate; +}; + +static const unsigned int src_iir_coeff_32_to_16[] = { + 0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002, + 0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002, + 0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002, + 0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002, + 0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002, + 0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002, + 0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002, + 0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001 +}; + +static const unsigned int src_iir_coeff_44_to_16[] = { + 0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002, + 0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002, + 0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002, + 0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002, + 0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002, + 0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002, + 0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001 +}; + +static const unsigned int src_iir_coeff_44_to_32[] = { + 0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003, + 0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002, + 0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002, + 0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002, + 0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002, + 0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002, + 0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001 +}; + +static const unsigned int src_iir_coeff_48_to_16[] = { + 0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002, + 0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002, + 0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002, + 0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002, + 0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002, + 0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002, + 0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001, + 0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004 +}; + +static const unsigned int src_iir_coeff_48_to_32[] = { + 0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002, + 0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002, + 0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002, + 0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002, + 0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002, + 0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002, + 0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001 +}; + +static const unsigned int src_iir_coeff_48_to_44[] = { + 0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003, + 0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003, + 0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003, + 0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003, + 0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001 +}; + +static const unsigned int src_iir_coeff_96_to_16[] = { + 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002, + 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003, + 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003, + 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003, + 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002, + 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002, + 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002, + 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001, +}; + +static const unsigned int src_iir_coeff_96_to_44[] = { + 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002, + 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002, + 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002, + 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002, + 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002, + 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002, + 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001, + 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001, +}; + +static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate) +{ + switch (rate) { + case 8000: + return 0x50000; + case 11025: + return 0x6e400; + case 12000: + return 0x78000; + case 16000: + return 0xa0000; + case 22050: + return 0xdc800; + case 24000: + return 0xf0000; + case 32000: + return 0x140000; + case 44100: + return 0x1b9000; + case 48000: + return 0x1e0000; + case 88200: + return 0x372000; + case 96000: + return 0x3c0000; + case 176400: + return 0x6e4000; + case 192000: + return 0x780000; + default: + dev_err(afe->dev, "%s(), rate %d invalid!!!\n", + __func__, rate); + return 0; + } +} + +static const unsigned int *get_iir_coeff(unsigned int rate_in, + unsigned int rate_out, + unsigned int *param_num) +{ + if (rate_in == 32000 && rate_out == 16000) { + *param_num = ARRAY_SIZE(src_iir_coeff_32_to_16); + return src_iir_coeff_32_to_16; + } else if (rate_in == 44100 && rate_out == 16000) { + *param_num = ARRAY_SIZE(src_iir_coeff_44_to_16); + return src_iir_coeff_44_to_16; + } else if (rate_in == 44100 && rate_out == 32000) { + *param_num = ARRAY_SIZE(src_iir_coeff_44_to_32); + return src_iir_coeff_44_to_32; + } else if ((rate_in == 48000 && rate_out == 16000) || + (rate_in == 96000 && rate_out == 32000)) { + *param_num = ARRAY_SIZE(src_iir_coeff_48_to_16); + return src_iir_coeff_48_to_16; + } else if (rate_in == 48000 && rate_out == 32000) { + *param_num = ARRAY_SIZE(src_iir_coeff_48_to_32); + return src_iir_coeff_48_to_32; + } else if (rate_in == 48000 && rate_out == 44100) { + *param_num = ARRAY_SIZE(src_iir_coeff_48_to_44); + return src_iir_coeff_48_to_44; + } else if (rate_in == 96000 && rate_out == 16000) { + *param_num = ARRAY_SIZE(src_iir_coeff_96_to_16); + return src_iir_coeff_96_to_16; + } else if ((rate_in == 96000 && rate_out == 44100) || + (rate_in == 48000 && rate_out == 22050)) { + *param_num = ARRAY_SIZE(src_iir_coeff_96_to_44); + return src_iir_coeff_96_to_44; + } + + *param_num = 0; + return NULL; +} + +static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; + unsigned int iir_coeff_num; + unsigned int iir_stage; + int rate_in = src_priv->dl_rate; + int rate_out = src_priv->ul_rate; + unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out); + unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in); + + /* set out freq mode */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3, + G_SRC_ASM_FREQ_4_MASK_SFT, + out_freq_mode << G_SRC_ASM_FREQ_4_SFT); + + /* set in freq mode */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4, + G_SRC_ASM_FREQ_5_MASK_SFT, + in_freq_mode << G_SRC_ASM_FREQ_5_SFT); + + regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986); + regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987); + regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd); + regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0); + + /* set iir if in_rate > out_rate */ + if (rate_in > rate_out) { + int i; + const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out, + &iir_coeff_num); + + if (iir_coeff_num == 0 || !iir_coeff) { + dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n", + __func__, iir_coeff_num, iir_coeff); + return -EINVAL; + } + + /* COEFF_SRAM_CTRL */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0, + G_SRC_COEFF_SRAM_CTRL_MASK_SFT, + BIT(G_SRC_COEFF_SRAM_CTRL_SFT)); + /* Clear coeff history to r/w coeff from the first position */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13, + G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0); + /* Write SRC coeff, should not read the reg during write */ + for (i = 0; i < iir_coeff_num; i++) + regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12, + iir_coeff[i]); + /* disable sram access */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0, + G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0); + /* CHSET_IIR_STAGE */ + iir_stage = (iir_coeff_num / 6) - 1; + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_STAGE_MASK_SFT, + iir_stage << G_SRC_CHSET_IIR_STAGE_SFT); + /* CHSET_IIR_EN */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_EN_MASK_SFT, + BIT(G_SRC_CHSET_IIR_EN_SFT)); + } else { + /* CHSET_IIR_EN off */ + regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_EN_MASK_SFT, 0); + } + + return 0; +} + +static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; + unsigned int iir_coeff_num; + unsigned int iir_stage; + int rate_in = src_priv->dl_rate; + int rate_out = src_priv->ul_rate; + unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out); + unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in); + + /* set out freq mode */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3, + G_SRC_ASM_FREQ_4_MASK_SFT, + out_freq_mode << G_SRC_ASM_FREQ_4_SFT); + + /* set in freq mode */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4, + G_SRC_ASM_FREQ_5_MASK_SFT, + in_freq_mode << G_SRC_ASM_FREQ_5_SFT); + + regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986); + regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987); + regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd); + regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0); + + /* set iir if in_rate > out_rate */ + if (rate_in > rate_out) { + int i; + const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out, + &iir_coeff_num); + + if (iir_coeff_num == 0 || !iir_coeff) { + dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n", + __func__, iir_coeff_num, iir_coeff); + return -EINVAL; + } + + /* COEFF_SRAM_CTRL */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0, + G_SRC_COEFF_SRAM_CTRL_MASK_SFT, + BIT(G_SRC_COEFF_SRAM_CTRL_SFT)); + /* Clear coeff history to r/w coeff from the first position */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13, + G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0); + /* Write SRC coeff, should not read the reg during write */ + for (i = 0; i < iir_coeff_num; i++) + regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12, + iir_coeff[i]); + /* disable sram access */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0, + G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0); + /* CHSET_IIR_STAGE */ + iir_stage = (iir_coeff_num / 6) - 1; + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_STAGE_MASK_SFT, + iir_stage << G_SRC_CHSET_IIR_STAGE_SFT); + /* CHSET_IIR_EN */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_EN_MASK_SFT, + BIT(G_SRC_CHSET_IIR_EN_SFT)); + } else { + /* CHSET_IIR_EN off */ + regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, + G_SRC_CHSET_IIR_EN_MASK_SFT, 0); + } + + return 0; +} + +#define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable" +#define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable" + +static int mtk_hw_src_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int id; + struct mtk_afe_src_priv *src_priv; + unsigned int reg; + + if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0) + id = MT8186_DAI_SRC_1; + else + id = MT8186_DAI_SRC_2; + + src_priv = afe_priv->dai_priv[id]; + + dev_dbg(afe->dev, + "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n", + __func__, w->name, event, id, src_priv, + src_priv->dl_rate, src_priv->ul_rate); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (id == MT8186_DAI_SRC_1) + mtk_set_src_1_param(afe, id); + else + mtk_set_src_2_param(afe, id); + break; + case SND_SOC_DAPM_POST_PMU: + reg = (id == MT8186_DAI_SRC_1) ? + AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0; + /* ASM_ON */ + regmap_update_bits(afe->regmap, reg, + G_SRC_ASM_ON_MASK_SFT, + BIT(G_SRC_ASM_ON_SFT)); + /* CHSET_ON */ + regmap_update_bits(afe->regmap, reg, + G_SRC_CHSET_ON_MASK_SFT, + BIT(G_SRC_CHSET_ON_SFT)); + /* CHSET_STR_CLR */ + regmap_update_bits(afe->regmap, reg, + G_SRC_CHSET_STR_CLR_MASK_SFT, + BIT(G_SRC_CHSET_STR_CLR_SFT)); + break; + case SND_SOC_DAPM_PRE_PMD: + reg = (id == MT8186_DAI_SRC_1) ? + AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0; + /* ASM_OFF */ + regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0); + /* CHSET_OFF */ + regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0); + /* CHSET_STR_CLR */ + regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0); + break; + default: + break; + } + + return 0; +} + +/* dai component */ +static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40, + I_I2S0_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1, + I_DL5_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41, + I_I2S0_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1, + I_DL5_CH2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42, + I_DL1_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42, + I_DL2_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42, + I_DL3_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42, + I_DL4_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1, + I_DL5_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1, + I_DL6_CH1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42, + I_GAIN2_OUT_CH1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43, + I_DL1_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43, + I_DL2_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43, + I_DL3_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43, + I_DL4_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1, + I_DL5_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1, + I_DL6_CH2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43, + I_GAIN2_OUT_CH2, 1, 0), +}; + +static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = { + /* inter-connections */ + SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0, + mtk_hw_src_1_in_ch1_mix, + ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)), + SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0, + mtk_hw_src_1_in_ch2_mix, + ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)), + SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0, + mtk_hw_src_2_in_ch1_mix, + ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)), + SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0, + mtk_hw_src_2_in_ch2_mix, + ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)), + + SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME, + GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0, + mtk_hw_src_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME, + GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0, + mtk_hw_src_event, + SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"), + SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"), + SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"), + SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"), +}; + +static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_src_priv *src_priv; + + if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0) + src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1]; + else + src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2]; + + dev_dbg(afe->dev, + "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n", + __func__, source->name, sink->name, + src_priv->dl_rate, src_priv->ul_rate); + + return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0; +} + +static const struct snd_soc_dapm_route mtk_dai_src_routes[] = { + {"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"}, + {"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"}, + {"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"}, + {"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"}, + {"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"}, + {"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"}, + {"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"}, + {"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"}, + {"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"}, + {"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"}, + {"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"}, + {"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"}, + {"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"}, + {"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"}, + {"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"}, + {"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"}, + {"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"}, + {"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"}, + {"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"}, + {"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"}, + {"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"}, + {"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"}, + {"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"}, + {"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"}, + + {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"}, + {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"}, + + {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"}, + {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"}, + + {"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect}, + {"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect}, + {"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect}, + {"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect}, + + {"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"}, + {"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"}, + {"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"}, + {"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"}, +}; + +/* dai ops */ +static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int id = dai->id; + struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; + unsigned int sft, mask; + unsigned int rate = params_rate(params); + unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id); + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, id, substream->stream, rate); + + /* rate */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + src_priv->dl_rate = rate; + if (id == MT8186_DAI_SRC_1) { + sft = GENERAL1_ASRCIN_MODE_SFT; + mask = GENERAL1_ASRCIN_MODE_MASK; + } else { + sft = GENERAL2_ASRCIN_MODE_SFT; + mask = GENERAL2_ASRCIN_MODE_MASK; + } + } else { + src_priv->ul_rate = rate; + if (id == MT8186_DAI_SRC_1) { + sft = GENERAL1_ASRCOUT_MODE_SFT; + mask = GENERAL1_ASRCOUT_MODE_MASK; + } else { + sft = GENERAL2_ASRCOUT_MODE_SFT; + mask = GENERAL2_ASRCOUT_MODE_MASK; + } + } + + regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft); + + return 0; +} + +static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int id = dai->id; + struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id]; + + dev_dbg(afe->dev, "%s(), id %d, stream %d\n", + __func__, id, substream->stream); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + src_priv->dl_rate = 0; + else + src_priv->ul_rate = 0; + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_src_ops = { + .hw_params = mtk_dai_src_hw_params, + .hw_free = mtk_dai_src_hw_free, +}; + +/* dai driver */ +#define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_src_driver[] = { + { + .name = "HW_SRC_1", + .id = MT8186_DAI_SRC_1, + .playback = { + .stream_name = "HW_SRC_1_In", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_SRC_RATES, + .formats = MTK_SRC_FORMATS, + }, + .capture = { + .stream_name = "HW_SRC_1_Out", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_SRC_RATES, + .formats = MTK_SRC_FORMATS, + }, + .ops = &mtk_dai_src_ops, + }, + { + .name = "HW_SRC_2", + .id = MT8186_DAI_SRC_2, + .playback = { + .stream_name = "HW_SRC_2_In", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_SRC_RATES, + .formats = MTK_SRC_FORMATS, + }, + .capture = { + .stream_name = "HW_SRC_2_Out", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_SRC_RATES, + .formats = MTK_SRC_FORMATS, + }, + .ops = &mtk_dai_src_ops, + }, +}; + +int mt8186_dai_src_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + int ret; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_src_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver); + + dai->dapm_widgets = mtk_dai_src_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets); + dai->dapm_routes = mtk_dai_src_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes); + + /* set dai priv */ + ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1, + sizeof(struct mtk_afe_src_priv), NULL); + if (ret) + return ret; + + ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2, + sizeof(struct mtk_afe_src_priv), NULL); + if (ret) + return ret; + + return 0; +} -- GitLab From ae92dcbee8b6a6f63198a2a6fea0fc9f6a0fe07b Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:48 +0800 Subject: [PATCH 243/942] ASoC: mediatek: mt8186: support tdm in platform driver Add mt8186 tdm dai driver. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-11-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 698 +++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c new file mode 100644 index 0000000000000..dfff209b60da4 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c @@ -0,0 +1,698 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio DAI TDM Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include + +#include "mt8186-afe-clk.h" +#include "mt8186-afe-common.h" +#include "mt8186-afe-gpio.h" +#include "mt8186-interconnection.h" + +#define TDM_HD_EN_W_NAME "TDM_HD_EN" +#define TDM_MCLK_EN_W_NAME "TDM_MCLK_EN" +#define MTK_AFE_TDM_KCONTROL_NAME "TDM_HD_Mux" + +struct mtk_afe_tdm_priv { + unsigned int id; + unsigned int rate; /* for determine which apll to use */ + unsigned int bck_invert; + unsigned int lck_invert; + unsigned int lrck_width; + unsigned int mclk_id; + unsigned int mclk_multiple; /* according to sample rate */ + unsigned int mclk_rate; + unsigned int mclk_apll; + unsigned int tdm_mode; + unsigned int data_mode; + unsigned int slave_mode; + unsigned int low_jitter_en; +}; + +enum { + TDM_IN_I2S = 0, + TDM_IN_LJ = 1, + TDM_IN_RJ = 2, + TDM_IN_DSP_A = 4, + TDM_IN_DSP_B = 5, +}; + +enum { + TDM_DATA_ONE_PIN = 0, + TDM_DATA_MULTI_PIN, +}; + +enum { + TDM_BCK_NON_INV = 0, + TDM_BCK_INV = 1, +}; + +enum { + TDM_LCK_NON_INV = 0, + TDM_LCK_INV = 1, +}; + +static unsigned int get_tdm_lrck_width(snd_pcm_format_t format, + unsigned int mode) +{ + if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B) + return 0; + + return snd_pcm_format_physical_width(format) - 1; +} + +static unsigned int get_tdm_ch_fixup(unsigned int channels) +{ + if (channels > 4) + return 8; + else if (channels > 2) + return 4; + + return 2; +} + +static unsigned int get_tdm_ch_per_sdata(unsigned int mode, + unsigned int channels) +{ + if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B) + return get_tdm_ch_fixup(channels); + + return 2; +} + +enum { + SUPPLY_SEQ_APLL, + SUPPLY_SEQ_TDM_MCK_EN, + SUPPLY_SEQ_TDM_HD_EN, + SUPPLY_SEQ_TDM_EN, +}; + +static int get_tdm_id_by_name(const char *name) +{ + return MT8186_DAI_TDM_IN; +} + +static int mtk_tdm_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_afe_gpio_request(afe->dev, true, tdm_priv->id, 0); + break; + case SND_SOC_DAPM_POST_PMD: + mt8186_afe_gpio_request(afe->dev, false, tdm_priv->id, 0); + break; + default: + break; + } + + return 0; +} + +static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n", + __func__, w->name, event, dai_id); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8186_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate); + break; + case SND_SOC_DAPM_POST_PMD: + tdm_priv->mclk_rate = 0; + mt8186_mck_disable(afe, tdm_priv->mclk_id); + break; + default: + break; + } + + return 0; +} + +/* dai component */ +/* tdm virtual mux to output widget */ +static const char * const tdm_mux_map[] = { + "Normal", "Dummy_Widget", +}; + +static int tdm_mux_map_value[] = { + 0, 1, +}; + +static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(tdm_mux_map_enum, + SND_SOC_NOPM, + 0, + 1, + tdm_mux_map, + tdm_mux_map_value); + +static const struct snd_kcontrol_new tdm_in_mux_control = + SOC_DAPM_ENUM("TDM In Select", tdm_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_tdm_widgets[] = { + SND_SOC_DAPM_CLOCK_SUPPLY("aud_tdm_clk"), + + SND_SOC_DAPM_SUPPLY_S("TDM_EN", SUPPLY_SEQ_TDM_EN, + ETDM_IN1_CON0, ETDM_IN1_CON0_REG_ETDM_IN_EN_SFT, + 0, mtk_tdm_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + /* tdm hd en */ + SND_SOC_DAPM_SUPPLY_S(TDM_HD_EN_W_NAME, SUPPLY_SEQ_TDM_HD_EN, + ETDM_IN1_CON2, ETDM_IN1_CON2_REG_CLOCK_SOURCE_SEL_SFT, + 0, NULL, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S(TDM_MCLK_EN_W_NAME, SUPPLY_SEQ_TDM_MCK_EN, + SND_SOC_NOPM, 0, 0, + mtk_tdm_mck_en_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_INPUT("TDM_DUMMY_IN"), + + SND_SOC_DAPM_MUX("TDM_In_Mux", + SND_SOC_NOPM, 0, 0, &tdm_in_mux_control), +}; + +static int mtk_afe_tdm_mclk_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return 0; + } + + return (tdm_priv->mclk_rate > 0) ? 1 : 0; +} + +static int mtk_afe_tdm_mclk_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + int cur_apll; + + /* which apll */ + cur_apll = mt8186_get_apll_by_name(afe, source->name); + + return (tdm_priv->mclk_apll == cur_apll) ? 1 : 0; +} + +static int mtk_afe_tdm_hd_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return 0; + } + + return tdm_priv->low_jitter_en; +} + +static int mtk_afe_tdm_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(w->name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + int cur_apll; + int tdm_need_apll; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return 0; + } + + /* which apll */ + cur_apll = mt8186_get_apll_by_name(afe, source->name); + + /* choose APLL from tdm rate */ + tdm_need_apll = mt8186_get_apll_by_rate(afe, tdm_priv->rate); + + return (tdm_need_apll == cur_apll) ? 1 : 0; +} + +/* low jitter control */ +static const char * const mt8186_tdm_hd_str[] = { + "Normal", "Low_Jitter" +}; + +static const struct soc_enum mt8186_tdm_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_tdm_hd_str), + mt8186_tdm_hd_str), +}; + +static int mt8186_tdm_hd_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(kcontrol->id.name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = tdm_priv->low_jitter_en; + + return 0; +} + +static int mt8186_tdm_hd_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_tdm_id_by_name(kcontrol->id.name); + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id]; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int hd_en; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + hd_en = ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n", + __func__, kcontrol->id.name, hd_en); + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + if (tdm_priv->low_jitter_en == hd_en) + return 0; + + tdm_priv->low_jitter_en = hd_en; + + return 1; +} + +static const struct snd_kcontrol_new mtk_dai_tdm_controls[] = { + SOC_ENUM_EXT(MTK_AFE_TDM_KCONTROL_NAME, mt8186_tdm_enum[0], + mt8186_tdm_hd_get, mt8186_tdm_hd_set), +}; + +static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = { + {"TDM IN", NULL, "aud_tdm_clk"}, + {"TDM IN", NULL, "TDM_EN"}, + {"TDM IN", NULL, TDM_HD_EN_W_NAME, mtk_afe_tdm_hd_connect}, + {TDM_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect}, + {TDM_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect}, + + {"TDM IN", NULL, TDM_MCLK_EN_W_NAME, mtk_afe_tdm_mclk_connect}, + {TDM_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_mclk_apll_connect}, + {TDM_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_mclk_apll_connect}, + + /* allow tdm on without codec on */ + {"TDM IN", NULL, "TDM_In_Mux"}, + {"TDM_In_Mux", "Dummy_Widget", "TDM_DUMMY_IN"}, +}; + +/* dai ops */ +static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe, + struct mtk_afe_tdm_priv *tdm_priv, + int freq) +{ + int apll; + int apll_rate; + + apll = mt8186_get_apll_by_rate(afe, freq); + apll_rate = mt8186_get_apll_rate(afe, apll); + + if (!freq || freq > apll_rate) { + dev_err(afe->dev, + "%s(), freq(%d Hz) invalid\n", __func__, freq); + return -EINVAL; + } + + if (apll_rate % freq != 0) { + dev_err(afe->dev, + "%s(), APLL cannot generate %d Hz", __func__, freq); + return -EINVAL; + } + + tdm_priv->mclk_rate = freq; + tdm_priv->mclk_apll = apll; + + return 0; +} + +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int tdm_id = dai->id; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id]; + unsigned int tdm_mode = tdm_priv->tdm_mode; + unsigned int data_mode = tdm_priv->data_mode; + unsigned int rate = params_rate(params); + unsigned int channels = params_channels(params); + snd_pcm_format_t format = params_format(params); + unsigned int bit_width = + snd_pcm_format_physical_width(format); + unsigned int tdm_channels = (data_mode == TDM_DATA_ONE_PIN) ? + get_tdm_ch_per_sdata(tdm_mode, channels) : 2; + unsigned int lrck_width = + get_tdm_lrck_width(format, tdm_mode); + unsigned int tdm_con = 0; + bool slave_mode = tdm_priv->slave_mode; + bool lrck_inv = tdm_priv->lck_invert; + bool bck_inv = tdm_priv->bck_invert; + unsigned int tran_rate; + unsigned int tran_relatch_rate; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + tdm_priv->rate = rate; + + tran_rate = mt8186_rate_transform(afe->dev, rate, dai->id); + tran_relatch_rate = mt8186_tdm_relatch_rate_transform(afe->dev, rate); + + /* calculate mclk_rate, if not set explicitly */ + if (!tdm_priv->mclk_rate) { + tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple; + mtk_dai_tdm_cal_mclk(afe, + tdm_priv, + tdm_priv->mclk_rate); + } + + /* ETDM_IN1_CON0 */ + tdm_con |= slave_mode << ETDM_IN1_CON0_REG_SLAVE_MODE_SFT; + tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT; + tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_BIT_LENGTH_SFT; + tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_WORD_LENGTH_SFT; + tdm_con |= (tdm_channels - 1) << ETDM_IN1_CON0_REG_CH_NUM_SFT; + /* need to disable sync mode otherwise this may cause latch data error */ + tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT; + /* relatch 1x en clock fix to h26m */ + tdm_con |= 0 << ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT; + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, ETDM_IN_CON0_CTRL_MASK, tdm_con); + + /* ETDM_IN1_CON1 */ + tdm_con = 0; + tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT; + tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT; + tdm_con |= (lrck_width - 1) << ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT; + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, ETDM_IN_CON1_CTRL_MASK, tdm_con); + + /* ETDM_IN1_CON3 */ + tdm_con = 0; + tdm_con = ETDM_IN_CON3_FS(tran_rate); + regmap_update_bits(afe->regmap, ETDM_IN1_CON3, ETDM_IN_CON3_CTRL_MASK, tdm_con); + + /* ETDM_IN1_CON4 */ + tdm_con = 0; + tdm_con = ETDM_IN_CON4_FS(tran_relatch_rate); + if (slave_mode) { + if (lrck_inv) + tdm_con |= ETDM_IN_CON4_CON0_SLAVE_LRCK_INV; + if (bck_inv) + tdm_con |= ETDM_IN_CON4_CON0_SLAVE_BCK_INV; + } else { + if (lrck_inv) + tdm_con |= ETDM_IN_CON4_CON0_MASTER_LRCK_INV; + if (bck_inv) + tdm_con |= ETDM_IN_CON4_CON0_MASTER_BCK_INV; + } + regmap_update_bits(afe->regmap, ETDM_IN1_CON4, ETDM_IN_CON4_CTRL_MASK, tdm_con); + + /* ETDM_IN1_CON2 */ + tdm_con = 0; + if (data_mode == TDM_DATA_MULTI_PIN) { + tdm_con |= ETDM_IN_CON2_MULTI_IP_2CH_MODE; + tdm_con |= ETDM_IN_CON2_MULTI_IP_CH(channels); + } + regmap_update_bits(afe->regmap, ETDM_IN1_CON2, ETDM_IN_CON2_CTRL_MASK, tdm_con); + + /* ETDM_IN1_CON8 */ + tdm_con = 0; + if (slave_mode) { + tdm_con |= 1 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT; + tdm_con |= 0 << ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT; + tdm_con |= ETDM_IN_CON8_FS(tran_relatch_rate); + } else { + tdm_con |= 0 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT; + } + regmap_update_bits(afe->regmap, ETDM_IN1_CON8, ETDM_IN_CON8_CTRL_MASK, tdm_con); + + return 0; +} + +static int mtk_dai_tdm_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + if (dir != SND_SOC_CLOCK_IN) { + dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__); + return -EINVAL; + } + + dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq); + + return mtk_dai_tdm_cal_mclk(afe, tdm_priv, freq); +} + +static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; + + if (!tdm_priv) { + dev_err(afe->dev, "%s(), tdm_priv == NULL", __func__); + return -EINVAL; + } + + /* DAI mode*/ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + tdm_priv->tdm_mode = TDM_IN_I2S; + tdm_priv->data_mode = TDM_DATA_MULTI_PIN; + break; + case SND_SOC_DAIFMT_LEFT_J: + tdm_priv->tdm_mode = TDM_IN_LJ; + tdm_priv->data_mode = TDM_DATA_MULTI_PIN; + break; + case SND_SOC_DAIFMT_RIGHT_J: + tdm_priv->tdm_mode = TDM_IN_RJ; + tdm_priv->data_mode = TDM_DATA_MULTI_PIN; + break; + case SND_SOC_DAIFMT_DSP_A: + tdm_priv->tdm_mode = TDM_IN_DSP_A; + tdm_priv->data_mode = TDM_DATA_ONE_PIN; + break; + case SND_SOC_DAIFMT_DSP_B: + tdm_priv->tdm_mode = TDM_IN_DSP_B; + tdm_priv->data_mode = TDM_DATA_ONE_PIN; + break; + default: + dev_err(afe->dev, "%s(), invalid DAIFMT_FORMAT_MASK", __func__); + return -EINVAL; + } + + /* DAI clock inversion*/ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + tdm_priv->bck_invert = TDM_BCK_NON_INV; + tdm_priv->lck_invert = TDM_LCK_NON_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + tdm_priv->bck_invert = TDM_BCK_NON_INV; + tdm_priv->lck_invert = TDM_LCK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + tdm_priv->bck_invert = TDM_BCK_INV; + tdm_priv->lck_invert = TDM_LCK_NON_INV; + break; + case SND_SOC_DAIFMT_IB_IF: + tdm_priv->bck_invert = TDM_BCK_INV; + tdm_priv->lck_invert = TDM_LCK_INV; + break; + default: + dev_err(afe->dev, "%s(), invalid DAIFMT_INV_MASK", __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + tdm_priv->slave_mode = false; + break; + case SND_SOC_DAIFMT_CBC_CFC: + tdm_priv->slave_mode = true; + break; + default: + dev_err(afe->dev, "%s(), invalid DAIFMT_CLOCK_PROVIDER_MASK", + __func__); + return -EINVAL; + } + + return 0; +} + +static int mtk_dai_tdm_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, + unsigned int rx_mask, + int slots, + int slot_width) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai->id]; + + dev_dbg(dai->dev, "%s %d slot_width %d\n", __func__, dai->id, slot_width); + + tdm_priv->lrck_width = slot_width; + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_tdm_ops = { + .hw_params = mtk_dai_tdm_hw_params, + .set_sysclk = mtk_dai_tdm_set_sysclk, + .set_fmt = mtk_dai_tdm_set_fmt, + .set_tdm_slot = mtk_dai_tdm_set_tdm_slot, +}; + +/* dai driver */ +#define MTK_TDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_tdm_driver[] = { + { + .name = "TDM IN", + .id = MT8186_DAI_TDM_IN, + .capture = { + .stream_name = "TDM IN", + .channels_min = 2, + .channels_max = 8, + .rates = MTK_TDM_RATES, + .formats = MTK_TDM_FORMATS, + }, + .ops = &mtk_dai_tdm_ops, + }, +}; + +static struct mtk_afe_tdm_priv *init_tdm_priv_data(struct mtk_base_afe *afe) +{ + struct mtk_afe_tdm_priv *tdm_priv; + + tdm_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_afe_tdm_priv), + GFP_KERNEL); + if (!tdm_priv) + return NULL; + + tdm_priv->mclk_multiple = 512; + tdm_priv->mclk_id = MT8186_TDM_MCK; + tdm_priv->id = MT8186_DAI_TDM_IN; + + return tdm_priv; +} + +int mt8186_dai_tdm_register(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct mtk_afe_tdm_priv *tdm_priv; + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_tdm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_tdm_driver); + + dai->controls = mtk_dai_tdm_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_tdm_controls); + dai->dapm_widgets = mtk_dai_tdm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_tdm_widgets); + dai->dapm_routes = mtk_dai_tdm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_tdm_routes); + + tdm_priv = init_tdm_priv_data(afe); + if (!tdm_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8186_DAI_TDM_IN] = tdm_priv; + + return 0; +} -- GitLab From 55b423d5623ccd6785429431c2cf5f3e073b73ba Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:49 +0800 Subject: [PATCH 244/942] ASoC: mediatek: mt8186: support audio clock control in platform driver Add audio clock control with CCF interface. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-12-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-clk.c | 651 +++++++++++++++++++++ sound/soc/mediatek/mt8186/mt8186-afe-clk.h | 106 ++++ 2 files changed, 757 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.c create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.h diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c new file mode 100644 index 0000000000000..0275f66ddc185 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c @@ -0,0 +1,651 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mt8186-afe-clk.c -- Mediatek 8186 afe clock ctrl +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include + +#include "mt8186-afe-common.h" +#include "mt8186-afe-clk.h" +#include "mt8186-audsys-clk.h" + +static DEFINE_MUTEX(mutex_request_dram); + +static const char *aud_clks[CLK_NUM] = { + [CLK_AFE] = "aud_afe_clk", + [CLK_DAC] = "aud_dac_clk", + [CLK_DAC_PREDIS] = "aud_dac_predis_clk", + [CLK_ADC] = "aud_adc_clk", + [CLK_TML] = "aud_tml_clk", + [CLK_APLL22M] = "aud_apll22m_clk", + [CLK_APLL24M] = "aud_apll24m_clk", + [CLK_APLL1_TUNER] = "aud_apll_tuner_clk", + [CLK_APLL2_TUNER] = "aud_apll2_tuner_clk", + [CLK_TDM] = "aud_tdm_clk", + [CLK_NLE] = "aud_nle_clk", + [CLK_DAC_HIRES] = "aud_dac_hires_clk", + [CLK_ADC_HIRES] = "aud_adc_hires_clk", + [CLK_I2S1_BCLK] = "aud_i2s1_bclk", + [CLK_I2S2_BCLK] = "aud_i2s2_bclk", + [CLK_I2S3_BCLK] = "aud_i2s3_bclk", + [CLK_I2S4_BCLK] = "aud_i2s4_bclk", + [CLK_CONNSYS_I2S_ASRC] = "aud_connsys_i2s_asrc", + [CLK_GENERAL1_ASRC] = "aud_general1_asrc", + [CLK_GENERAL2_ASRC] = "aud_general2_asrc", + [CLK_ADC_HIRES_TML] = "aud_adc_hires_tml", + [CLK_ADDA6_ADC] = "aud_adda6_adc", + [CLK_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires", + [CLK_3RD_DAC] = "aud_3rd_dac", + [CLK_3RD_DAC_PREDIS] = "aud_3rd_dac_predis", + [CLK_3RD_DAC_TML] = "aud_3rd_dac_tml", + [CLK_3RD_DAC_HIRES] = "aud_3rd_dac_hires", + [CLK_ETDM_IN1_BCLK] = "aud_etdm_in1_bclk", + [CLK_ETDM_OUT1_BCLK] = "aud_etdm_out1_bclk", + [CLK_INFRA_SYS_AUDIO] = "aud_infra_clk", + [CLK_INFRA_AUDIO_26M] = "mtkaif_26m_clk", + [CLK_MUX_AUDIO] = "top_mux_audio", + [CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int", + [CLK_TOP_MAINPLL_D2_D4] = "top_mainpll_d2_d4", + [CLK_TOP_MUX_AUD_1] = "top_mux_aud_1", + [CLK_TOP_APLL1_CK] = "top_apll1_ck", + [CLK_TOP_MUX_AUD_2] = "top_mux_aud_2", + [CLK_TOP_APLL2_CK] = "top_apll2_ck", + [CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1", + [CLK_TOP_APLL1_D8] = "top_apll1_d8", + [CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2", + [CLK_TOP_APLL2_D8] = "top_apll2_d8", + [CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h", + [CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel", + [CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel", + [CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel", + [CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel", + [CLK_TOP_TDM_M_SEL] = "top_tdm_m_sel", + [CLK_TOP_APLL12_DIV0] = "top_apll12_div0", + [CLK_TOP_APLL12_DIV1] = "top_apll12_div1", + [CLK_TOP_APLL12_DIV2] = "top_apll12_div2", + [CLK_TOP_APLL12_DIV4] = "top_apll12_div4", + [CLK_TOP_APLL12_DIV_TDM] = "top_apll12_div_tdm", + [CLK_CLK26M] = "top_clk26m_clk", +}; + +int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe, + int clk_id) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS], + afe_priv->clk[clk_id]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIOINTBUS], + aud_clks[clk_id], ret); + return ret; + } + + return 0; +} + +static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + if (enable) { + ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_1], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1], + afe_priv->clk[CLK_TOP_APLL1_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_1], + aud_clks[CLK_TOP_APLL1_CK], ret); + return ret; + } + + /* 180.6336 / 8 = 22.5792MHz */ + ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1], + afe_priv->clk[CLK_TOP_APLL1_D8]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], + aud_clks[CLK_TOP_APLL1_D8], ret); + return ret; + } + } else { + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], + aud_clks[CLK_CLK26M], ret); + return ret; + } + clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]); + + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_1], + aud_clks[CLK_CLK26M], ret); + return ret; + } + clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]); + } + + return 0; +} + +static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + if (enable) { + ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_2], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2], + afe_priv->clk[CLK_TOP_APLL2_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_2], + aud_clks[CLK_TOP_APLL2_CK], ret); + return ret; + } + + /* 196.608 / 8 = 24.576MHz */ + ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2], + afe_priv->clk[CLK_TOP_APLL2_D8]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], + aud_clks[CLK_TOP_APLL2_D8], ret); + return ret; + } + } else { + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], + aud_clks[CLK_CLK26M], ret); + return ret; + } + clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]); + + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUD_2], + aud_clks[CLK_CLK26M], ret); + return ret; + } + clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]); + } + + return 0; +} + +int mt8186_afe_enable_cgs(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + int i; + + for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) { + ret = clk_prepare_enable(afe_priv->clk[i]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[i], ret); + return ret; + } + } + + return 0; +} + +void mt8186_afe_disable_cgs(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int i; + + for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) + clk_disable_unprepare(afe_priv->clk[i]); +} + +int mt8186_afe_enable_clock(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret = 0; + + ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret); + goto clk_infra_sys_audio_err; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_INFRA_AUDIO_26M], ret); + goto clk_infra_audio_26m_err; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIO], ret); + goto clk_mux_audio_err; + } + ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO], + afe_priv->clk[CLK_CLK26M]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIO], + aud_clks[CLK_CLK26M], ret); + goto clk_mux_audio_err; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret); + goto clk_mux_audio_intbus_err; + } + ret = mt8186_set_audio_int_bus_parent(afe, + CLK_TOP_MAINPLL_D2_D4); + if (ret) + goto clk_mux_audio_intbus_parent_err; + + ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H], + afe_priv->clk[CLK_TOP_APLL2_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[CLK_TOP_MUX_AUDIO_H], + aud_clks[CLK_TOP_APLL2_CK], ret); + goto clk_mux_audio_h_parent_err; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_AFE], ret); + goto clk_afe_err; + } + + return 0; + +clk_afe_err: + clk_disable_unprepare(afe_priv->clk[CLK_AFE]); +clk_mux_audio_h_parent_err: +clk_mux_audio_intbus_parent_err: + mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); +clk_mux_audio_intbus_err: + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); +clk_mux_audio_err: + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]); +clk_infra_sys_audio_err: + clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]); +clk_infra_audio_26m_err: + clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]); + + return ret; +} + +void mt8186_afe_disable_clock(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + clk_disable_unprepare(afe_priv->clk[CLK_AFE]); + mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]); + clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]); + clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]); +} + +int mt8186_afe_suspend_clock(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* set audio int bus to 26M */ + ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + if (ret) { + dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret); + goto clk_mux_audio_intbus_err; + } + ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); + if (ret) + goto clk_mux_audio_intbus_parent_err; + + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + + return 0; + +clk_mux_audio_intbus_parent_err: + mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4); +clk_mux_audio_intbus_err: + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + return ret; +} + +int mt8186_afe_resume_clock(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* set audio int bus to normal working clock */ + ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + if (ret) { + dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret); + goto clk_mux_audio_intbus_err; + } + ret = mt8186_set_audio_int_bus_parent(afe, + CLK_TOP_MAINPLL_D2_D4); + if (ret) + goto clk_mux_audio_intbus_parent_err; + + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + + return 0; + +clk_mux_audio_intbus_parent_err: + mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M); +clk_mux_audio_intbus_err: + clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]); + return ret; +} + +int mt8186_apll1_enable(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* setting for APLL */ + apll1_mux_setting(afe, true); + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL22M], ret); + goto err_clk_apll22m; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL1_TUNER], ret); + goto err_clk_apll1_tuner; + } + + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0xfff7, 0x832); + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1); + + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_22M_ON_MASK_SFT, BIT(AFE_22M_ON_SFT)); + + return 0; + +err_clk_apll1_tuner: + clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]); +err_clk_apll22m: + clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]); + + return ret; +} + +void mt8186_apll1_disable(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_22M_ON_MASK_SFT, 0); + + regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0); + + clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]); + clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]); + + apll1_mux_setting(afe, false); +} + +int mt8186_apll2_enable(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int ret; + + /* setting for APLL */ + apll2_mux_setting(afe, true); + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL24M], ret); + goto err_clk_apll24m; + } + + ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CLK_APLL2_TUNER], ret); + goto err_clk_apll2_tuner; + } + + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0xfff7, 0x634); + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1); + + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_24M_ON_MASK_SFT, BIT(AFE_24M_ON_SFT)); + + return 0; + +err_clk_apll2_tuner: + clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]); +err_clk_apll24m: + clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]); + + return ret; +} + +void mt8186_apll2_disable(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE, + AFE_24M_ON_MASK_SFT, 0); + + regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0); + + clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]); + clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]); + + apll2_mux_setting(afe, false); +} + +int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll) +{ + return (apll == MT8186_APLL1) ? 180633600 : 196608000; +} + +int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate) +{ + return ((rate % 8000) == 0) ? MT8186_APLL2 : MT8186_APLL1; +} + +int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char *name) +{ + if (strcmp(name, APLL1_W_NAME) == 0) + return MT8186_APLL1; + + return MT8186_APLL2; +} + +/* mck */ +struct mt8186_mck_div { + u32 m_sel_id; + u32 div_clk_id; +}; + +static const struct mt8186_mck_div mck_div[MT8186_MCK_NUM] = { + [MT8186_I2S0_MCK] = { + .m_sel_id = CLK_TOP_I2S0_M_SEL, + .div_clk_id = CLK_TOP_APLL12_DIV0, + }, + [MT8186_I2S1_MCK] = { + .m_sel_id = CLK_TOP_I2S1_M_SEL, + .div_clk_id = CLK_TOP_APLL12_DIV1, + }, + [MT8186_I2S2_MCK] = { + .m_sel_id = CLK_TOP_I2S2_M_SEL, + .div_clk_id = CLK_TOP_APLL12_DIV2, + }, + [MT8186_I2S4_MCK] = { + .m_sel_id = CLK_TOP_I2S4_M_SEL, + .div_clk_id = CLK_TOP_APLL12_DIV4, + }, + [MT8186_TDM_MCK] = { + .m_sel_id = CLK_TOP_TDM_M_SEL, + .div_clk_id = CLK_TOP_APLL12_DIV_TDM, + }, +}; + +int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int apll = mt8186_get_apll_by_rate(afe, rate); + int apll_clk_id = apll == MT8186_APLL1 ? + CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2; + int m_sel_id = mck_div[mck_id].m_sel_id; + int div_clk_id = mck_div[mck_id].div_clk_id; + int ret; + + /* select apll */ + if (m_sel_id >= 0) { + ret = clk_prepare_enable(afe_priv->clk[m_sel_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[m_sel_id], ret); + return ret; + } + ret = clk_set_parent(afe_priv->clk[m_sel_id], + afe_priv->clk[apll_clk_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n", + __func__, aud_clks[m_sel_id], + aud_clks[apll_clk_id], ret); + return ret; + } + } + + /* enable div, set rate */ + ret = clk_prepare_enable(afe_priv->clk[div_clk_id]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[div_clk_id], ret); + return ret; + } + ret = clk_set_rate(afe_priv->clk[div_clk_id], rate); + if (ret) { + dev_err(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n", + __func__, aud_clks[div_clk_id], rate, ret); + return ret; + } + + return 0; +} + +void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + int m_sel_id = mck_div[mck_id].m_sel_id; + int div_clk_id = mck_div[mck_id].div_clk_id; + + clk_disable_unprepare(afe_priv->clk[div_clk_id]); + if (m_sel_id >= 0) + clk_disable_unprepare(afe_priv->clk[m_sel_id]); +} + +int mt8186_init_clock(struct mtk_base_afe *afe) +{ + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct device_node *of_node = afe->dev->of_node; + int i = 0; + + mt8186_audsys_clk_register(afe); + + afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk), + GFP_KERNEL); + if (!afe_priv->clk) + return -ENOMEM; + + for (i = 0; i < CLK_NUM; i++) { + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clk[i])) { + dev_err(afe->dev, "%s devm_clk_get %s fail, ret %ld\n", + __func__, + aud_clks[i], PTR_ERR(afe_priv->clk[i])); + afe_priv->clk[i] = NULL; + } + } + + afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node, + "mediatek,apmixedsys"); + if (IS_ERR(afe_priv->apmixedsys)) { + dev_err(afe->dev, "%s() Cannot find apmixedsys controller: %ld\n", + __func__, PTR_ERR(afe_priv->apmixedsys)); + return PTR_ERR(afe_priv->apmixedsys); + } + + afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node, + "mediatek,topckgen"); + if (IS_ERR(afe_priv->topckgen)) { + dev_err(afe->dev, "%s() Cannot find topckgen controller: %ld\n", + __func__, PTR_ERR(afe_priv->topckgen)); + return PTR_ERR(afe_priv->topckgen); + } + + afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node, + "mediatek,infracfg"); + if (IS_ERR(afe_priv->infracfg)) { + dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n", + __func__, PTR_ERR(afe_priv->infracfg)); + return PTR_ERR(afe_priv->infracfg); + } + + return 0; +} + +void mt8186_deinit_clock(struct mtk_base_afe *afe) +{ + mt8186_audsys_clk_unregister(afe); +} diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h new file mode 100644 index 0000000000000..c539557d7c78c --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * mt8186-afe-clk.h -- Mediatek 8186 afe clock ctrl definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Jiaxin Yu + */ + +#ifndef _MT8186_AFE_CLOCK_CTRL_H_ +#define _MT8186_AFE_CLOCK_CTRL_H_ + +#define PERI_BUS_DCM_CTRL 0x74 + +/* APLL */ +#define APLL1_W_NAME "APLL1" +#define APLL2_W_NAME "APLL2" +enum { + MT8186_APLL1 = 0, + MT8186_APLL2, +}; + +enum { + CLK_AFE = 0, + CLK_DAC, + CLK_DAC_PREDIS, + CLK_ADC, + CLK_TML, + CLK_APLL22M, + CLK_APLL24M, + CLK_APLL1_TUNER, + CLK_APLL2_TUNER, + CLK_TDM, + CLK_NLE, + CLK_DAC_HIRES, + CLK_ADC_HIRES, + CLK_I2S1_BCLK, + CLK_I2S2_BCLK, + CLK_I2S3_BCLK, + CLK_I2S4_BCLK, + CLK_CONNSYS_I2S_ASRC, + CLK_GENERAL1_ASRC, + CLK_GENERAL2_ASRC, + CLK_ADC_HIRES_TML, + CLK_ADDA6_ADC, + CLK_ADDA6_ADC_HIRES, + CLK_3RD_DAC, + CLK_3RD_DAC_PREDIS, + CLK_3RD_DAC_TML, + CLK_3RD_DAC_HIRES, + CLK_ETDM_IN1_BCLK, + CLK_ETDM_OUT1_BCLK, + CLK_INFRA_SYS_AUDIO, + CLK_INFRA_AUDIO_26M, + CLK_MUX_AUDIO, + CLK_MUX_AUDIOINTBUS, + CLK_TOP_MAINPLL_D2_D4, + /* apll related mux */ + CLK_TOP_MUX_AUD_1, + CLK_TOP_APLL1_CK, + CLK_TOP_MUX_AUD_2, + CLK_TOP_APLL2_CK, + CLK_TOP_MUX_AUD_ENG1, + CLK_TOP_APLL1_D8, + CLK_TOP_MUX_AUD_ENG2, + CLK_TOP_APLL2_D8, + CLK_TOP_MUX_AUDIO_H, + CLK_TOP_I2S0_M_SEL, + CLK_TOP_I2S1_M_SEL, + CLK_TOP_I2S2_M_SEL, + CLK_TOP_I2S4_M_SEL, + CLK_TOP_TDM_M_SEL, + CLK_TOP_APLL12_DIV0, + CLK_TOP_APLL12_DIV1, + CLK_TOP_APLL12_DIV2, + CLK_TOP_APLL12_DIV4, + CLK_TOP_APLL12_DIV_TDM, + CLK_CLK26M, + CLK_NUM +}; + +struct mtk_base_afe; +int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe, int clk_id); +int mt8186_init_clock(struct mtk_base_afe *afe); +void mt8186_deinit_clock(struct mtk_base_afe *afe); +int mt8186_afe_enable_cgs(struct mtk_base_afe *afe); +void mt8186_afe_disable_cgs(struct mtk_base_afe *afe); +int mt8186_afe_enable_clock(struct mtk_base_afe *afe); +void mt8186_afe_disable_clock(struct mtk_base_afe *afe); +int mt8186_afe_suspend_clock(struct mtk_base_afe *afe); +int mt8186_afe_resume_clock(struct mtk_base_afe *afe); + +int mt8186_apll1_enable(struct mtk_base_afe *afe); +void mt8186_apll1_disable(struct mtk_base_afe *afe); + +int mt8186_apll2_enable(struct mtk_base_afe *afe); +void mt8186_apll2_disable(struct mtk_base_afe *afe); + +int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll); +int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate); +int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char *name); + +/* these will be replaced by using CCF */ +int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate); +void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id); + +#endif -- GitLab From cfa9a966f12a91a269e50f1c3237c006ffe2ee9a Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:50 +0800 Subject: [PATCH 245/942] ASoC: mediatek: mt8186: support gpio control in platform driver Add gpio control for all audio interface separately. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-13-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-gpio.c | 244 ++++++++++++++++++++ sound/soc/mediatek/mt8186/mt8186-afe-gpio.h | 19 ++ 2 files changed, 263 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.c create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.h diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c new file mode 100644 index 0000000000000..5ba28095b7dad --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mt8186-afe-gpio.c -- Mediatek 8186 afe gpio ctrl +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include + +#include "mt8186-afe-common.h" +#include "mt8186-afe-gpio.h" + +struct pinctrl *aud_pinctrl; + +enum mt8186_afe_gpio { + MT8186_AFE_GPIO_CLK_MOSI_OFF, + MT8186_AFE_GPIO_CLK_MOSI_ON, + MT8186_AFE_GPIO_CLK_MISO_OFF, + MT8186_AFE_GPIO_CLK_MISO_ON, + MT8186_AFE_GPIO_DAT_MISO_OFF, + MT8186_AFE_GPIO_DAT_MISO_ON, + MT8186_AFE_GPIO_DAT_MOSI_OFF, + MT8186_AFE_GPIO_DAT_MOSI_ON, + MT8186_AFE_GPIO_I2S0_OFF, + MT8186_AFE_GPIO_I2S0_ON, + MT8186_AFE_GPIO_I2S1_OFF, + MT8186_AFE_GPIO_I2S1_ON, + MT8186_AFE_GPIO_I2S2_OFF, + MT8186_AFE_GPIO_I2S2_ON, + MT8186_AFE_GPIO_I2S3_OFF, + MT8186_AFE_GPIO_I2S3_ON, + MT8186_AFE_GPIO_TDM_OFF, + MT8186_AFE_GPIO_TDM_ON, + MT8186_AFE_GPIO_PCM_OFF, + MT8186_AFE_GPIO_PCM_ON, + MT8186_AFE_GPIO_GPIO_NUM +}; + +struct audio_gpio_attr { + const char *name; + bool gpio_prepare; + struct pinctrl_state *gpioctrl; +}; + +static struct audio_gpio_attr aud_gpios[MT8186_AFE_GPIO_GPIO_NUM] = { + [MT8186_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL}, + [MT8186_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL}, + [MT8186_AFE_GPIO_CLK_MISO_OFF] = {"aud_clk_miso_off", false, NULL}, + [MT8186_AFE_GPIO_CLK_MISO_ON] = {"aud_clk_miso_on", false, NULL}, + [MT8186_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL}, + [MT8186_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL}, + [MT8186_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL}, + [MT8186_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL}, + [MT8186_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL}, + [MT8186_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL}, + [MT8186_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL}, + [MT8186_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL}, + [MT8186_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL}, + [MT8186_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL}, + [MT8186_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL}, + [MT8186_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL}, + [MT8186_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL}, + [MT8186_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL}, + [MT8186_AFE_GPIO_PCM_OFF] = {"aud_gpio_pcm_off", false, NULL}, + [MT8186_AFE_GPIO_PCM_ON] = {"aud_gpio_pcm_on", false, NULL}, +}; + +static DEFINE_MUTEX(gpio_request_mutex); + +int mt8186_afe_gpio_init(struct device *dev) +{ + int i, j, ret; + + aud_pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(aud_pinctrl)) { + ret = PTR_ERR(aud_pinctrl); + dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n", + __func__, ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) { + aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl, + aud_gpios[i].name); + if (IS_ERR(aud_gpios[i].gpioctrl)) { + ret = PTR_ERR(aud_gpios[i].gpioctrl); + dev_info(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n", + __func__, aud_gpios[i].name, ret); + } else { + aud_gpios[i].gpio_prepare = true; + } + } + + /* gpio status init */ + for (i = MT8186_DAI_ADDA; i <= MT8186_DAI_TDM_IN; i++) { + for (j = 0; j <= 1; j++) + mt8186_afe_gpio_request(dev, false, i, j); + } + + return 0; +} +EXPORT_SYMBOL_GPL(mt8186_afe_gpio_init); + +static int mt8186_afe_gpio_select(struct device *dev, + enum mt8186_afe_gpio type) +{ + int ret = 0; + + if (type < 0 || type >= MT8186_AFE_GPIO_GPIO_NUM) { + dev_err(dev, "%s(), error, invalid gpio type %d\n", + __func__, type); + return -EINVAL; + } + + if (!aud_gpios[type].gpio_prepare) { + dev_err(dev, "%s(), error, gpio type %d not prepared\n", + __func__, type); + return -EIO; + } + + ret = pinctrl_select_state(aud_pinctrl, + aud_gpios[type].gpioctrl); + if (ret) { + dev_err(dev, "%s(), error, can not set gpio type %d\n", + __func__, type); + return ret; + } + + return 0; +} + +static int mt8186_afe_gpio_adda_dl(struct device *dev, bool enable) +{ + int ret; + + if (enable) { + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_ON); + if (ret) { + dev_err(dev, "%s(), MOSI CLK ON slect fail!\n", __func__); + return ret; + } + + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_ON); + if (ret) { + dev_err(dev, "%s(), MOSI DAT ON slect fail!\n", __func__); + return ret; + } + } else { + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_OFF); + if (ret) { + dev_err(dev, "%s(), MOSI DAT OFF slect fail!\n", __func__); + return ret; + } + + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_OFF); + if (ret) { + dev_err(dev, "%s(), MOSI CLK ON slect fail!\n", __func__); + return ret; + } + } + + return 0; +} + +static int mt8186_afe_gpio_adda_ul(struct device *dev, bool enable) +{ + int ret; + + if (enable) { + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_ON); + if (ret) { + dev_err(dev, "%s(), MISO CLK ON slect fail!\n", __func__); + return ret; + } + + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_ON); + if (ret) { + dev_err(dev, "%s(), MISO DAT ON slect fail!\n", __func__); + return ret; + } + } else { + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_OFF); + if (ret) { + dev_err(dev, "%s(), MISO DAT OFF slect fail!\n", __func__); + return ret; + } + + ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_OFF); + if (ret) { + dev_err(dev, "%s(), MISO CLK OFF slect fail!\n", __func__); + return ret; + } + } + + return 0; +} + +int mt8186_afe_gpio_request(struct device *dev, bool enable, + int dai, int uplink) +{ + enum mt8186_afe_gpio sel; + int ret = -EINVAL; + + mutex_lock(&gpio_request_mutex); + + switch (dai) { + case MT8186_DAI_ADDA: + if (uplink) + ret = mt8186_afe_gpio_adda_ul(dev, enable); + else + ret = mt8186_afe_gpio_adda_dl(dev, enable); + goto unlock; + case MT8186_DAI_I2S_0: + sel = enable ? MT8186_AFE_GPIO_I2S0_ON : MT8186_AFE_GPIO_I2S0_OFF; + break; + case MT8186_DAI_I2S_1: + sel = enable ? MT8186_AFE_GPIO_I2S1_ON : MT8186_AFE_GPIO_I2S1_OFF; + break; + case MT8186_DAI_I2S_2: + sel = enable ? MT8186_AFE_GPIO_I2S2_ON : MT8186_AFE_GPIO_I2S2_OFF; + break; + case MT8186_DAI_I2S_3: + sel = enable ? MT8186_AFE_GPIO_I2S3_ON : MT8186_AFE_GPIO_I2S3_OFF; + break; + case MT8186_DAI_TDM_IN: + sel = enable ? MT8186_AFE_GPIO_TDM_ON : MT8186_AFE_GPIO_TDM_OFF; + break; + case MT8186_DAI_PCM: + sel = enable ? MT8186_AFE_GPIO_PCM_ON : MT8186_AFE_GPIO_PCM_OFF; + break; + default: + mutex_unlock(&gpio_request_mutex); + dev_err(dev, "%s(), invalid dai %d\n", __func__, dai); + goto unlock; + } + + ret = mt8186_afe_gpio_select(dev, sel); + +unlock: + mutex_unlock(&gpio_request_mutex); + + return ret; +} diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h new file mode 100644 index 0000000000000..1ddc27838eb18 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * mt6833-afe-gpio.h -- Mediatek 6833 afe gpio ctrl definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Jiaxin Yu + */ + +#ifndef _MT8186_AFE_GPIO_H_ +#define _MT8186_AFE_GPIO_H_ + +struct mtk_base_afe; + +int mt8186_afe_gpio_init(struct device *dev); + +int mt8186_afe_gpio_request(struct device *dev, bool enable, + int dai, int uplink); + +#endif -- GitLab From 80d8cad2e9ce21517d50c7084c12a59d38a778f7 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Mon, 23 May 2022 21:28:51 +0800 Subject: [PATCH 246/942] ASoC: mediatek: mt8186: add misc driver and register definitions Add mt8186 platform misc driver and data tables/register definitions files. Signed-off-by: Jiaxin Yu Link: https://lore.kernel.org/r/20220523132858.22166-14-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown --- .../mediatek/mt8186/mt8186-interconnection.h | 69 + .../soc/mediatek/mt8186/mt8186-misc-control.c | 252 ++ sound/soc/mediatek/mt8186/mt8186-reg.h | 2913 +++++++++++++++++ 3 files changed, 3234 insertions(+) create mode 100644 sound/soc/mediatek/mt8186/mt8186-interconnection.h create mode 100644 sound/soc/mediatek/mt8186/mt8186-misc-control.c create mode 100644 sound/soc/mediatek/mt8186/mt8186-reg.h diff --git a/sound/soc/mediatek/mt8186/mt8186-interconnection.h b/sound/soc/mediatek/mt8186/mt8186-interconnection.h new file mode 100644 index 0000000000000..5b188d93ebd3d --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-interconnection.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Mediatek MT8186 audio driver interconnection definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Jiaxin Yu + */ + +#ifndef _MT8186_INTERCONNECTION_H_ +#define _MT8186_INTERCONNECTION_H_ + +/* in port define */ +#define I_I2S0_CH1 0 +#define I_I2S0_CH2 1 +#define I_ADDA_UL_CH1 3 +#define I_ADDA_UL_CH2 4 +#define I_DL1_CH1 5 +#define I_DL1_CH2 6 +#define I_DL2_CH1 7 +#define I_DL2_CH2 8 +#define I_PCM_1_CAP_CH1 9 +#define I_GAIN1_OUT_CH1 10 +#define I_GAIN1_OUT_CH2 11 +#define I_GAIN2_OUT_CH1 12 +#define I_GAIN2_OUT_CH2 13 +#define I_PCM_2_CAP_CH1 14 +#define I_ADDA_UL_CH3 17 +#define I_ADDA_UL_CH4 18 +#define I_DL12_CH1 19 +#define I_DL12_CH2 20 +#define I_DL12_CH3 5 +#define I_DL12_CH4 6 +#define I_PCM_2_CAP_CH2 21 +#define I_PCM_1_CAP_CH2 22 +#define I_DL3_CH1 23 +#define I_DL3_CH2 24 +#define I_I2S2_CH1 25 +#define I_I2S2_CH2 26 +#define I_I2S2_CH3 27 +#define I_I2S2_CH4 28 + +/* in port define >= 32 */ +#define I_32_OFFSET 32 +#define I_CONNSYS_I2S_CH1 (34 - I_32_OFFSET) +#define I_CONNSYS_I2S_CH2 (35 - I_32_OFFSET) +#define I_SRC_1_OUT_CH1 (36 - I_32_OFFSET) +#define I_SRC_1_OUT_CH2 (37 - I_32_OFFSET) +#define I_SRC_2_OUT_CH1 (38 - I_32_OFFSET) +#define I_SRC_2_OUT_CH2 (39 - I_32_OFFSET) +#define I_DL4_CH1 (40 - I_32_OFFSET) +#define I_DL4_CH2 (41 - I_32_OFFSET) +#define I_DL5_CH1 (42 - I_32_OFFSET) +#define I_DL5_CH2 (43 - I_32_OFFSET) +#define I_DL6_CH1 (44 - I_32_OFFSET) +#define I_DL6_CH2 (45 - I_32_OFFSET) +#define I_DL7_CH1 (46 - I_32_OFFSET) +#define I_DL7_CH2 (47 - I_32_OFFSET) +#define I_DL8_CH1 (48 - I_32_OFFSET) +#define I_DL8_CH2 (49 - I_32_OFFSET) +#define I_TDM_IN_CH1 (56 - I_32_OFFSET) +#define I_TDM_IN_CH2 (57 - I_32_OFFSET) +#define I_TDM_IN_CH3 (58 - I_32_OFFSET) +#define I_TDM_IN_CH4 (59 - I_32_OFFSET) +#define I_TDM_IN_CH5 (60 - I_32_OFFSET) +#define I_TDM_IN_CH6 (61 - I_32_OFFSET) +#define I_TDM_IN_CH7 (62 - I_32_OFFSET) +#define I_TDM_IN_CH8 (63 - I_32_OFFSET) + +#endif diff --git a/sound/soc/mediatek/mt8186/mt8186-misc-control.c b/sound/soc/mediatek/mt8186/mt8186-misc-control.c new file mode 100644 index 0000000000000..2317de8c44c09 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// MediaTek ALSA SoC Audio Misc Control +// +// Copyright (c) 2022 MediaTek Inc. +// Author: Jiaxin Yu + +#include +#include +#include +#include +#include + +#include "../common/mtk-afe-fe-dai.h" +#include "../common/mtk-afe-platform-driver.h" +#include "mt8186-afe-common.h" + +static const char * const mt8186_sgen_mode_str[] = { + "I0I1", "I2", "I3I4", "I5I6", + "I7I8", "I9I22", "I10I11", "I12I13", + "I14I21", "I15I16", "I17I18", "I19I20", + "I23I24", "I25I26", "I27I28", "I33", + "I34I35", "I36I37", "I38I39", "I40I41", + "I42I43", "I44I45", "I46I47", "I48I49", + "I56I57", "I58I59", "I60I61", "I62I63", + "O0O1", "O2", "O3O4", "O5O6", + "O7O8", "O9O10", "O11", "O12", + "O13O14", "O15O16", "O17O18", "O19O20", + "O21O22", "O23O24", "O25", "O28O29", + "O34", "O35", "O32O33", "O36O37", + "O38O39", "O30O31", "O40O41", "O42O43", + "O44O45", "O46O47", "O48O49", "O50O51", + "O58O59", "O60O61", "O62O63", "O64O65", + "O66O67", "O68O69", "O26O27", "OFF", +}; + +static const int mt8186_sgen_mode_idx[] = { + 0, 2, 4, 6, + 8, 22, 10, 12, + 14, -1, 18, 20, + 24, 26, 28, 33, + 34, 36, 38, 40, + 42, 44, 46, 48, + 56, 58, 60, 62, + 128, 130, 132, 134, + 135, 138, 139, 140, + 142, 144, 166, 148, + 150, 152, 153, 156, + 162, 163, 160, 164, + 166, -1, 168, 170, + 172, 174, 176, 178, + 186, 188, 190, 192, + 194, 196, -1, -1, +}; + +static const char * const mt8186_sgen_rate_str[] = { + "8K", "11K", "12K", "16K", + "22K", "24K", "32K", "44K", + "48K", "88k", "96k", "176k", + "192k" +}; + +static const int mt8186_sgen_rate_idx[] = { + 0, 1, 2, 4, + 5, 6, 8, 9, + 10, 11, 12, 13, + 14 +}; + +/* this order must match reg bit amp_div_ch1/2 */ +static const char * const mt8186_sgen_amp_str[] = { + "1/128", "1/64", "1/32", "1/16", "1/8", "1/4", "1/2", "1" }; + +static int mt8186_sgen_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->sgen_mode; + + return 0; +} + +static int mt8186_sgen_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int mode; + int mode_idx; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + mode = ucontrol->value.integer.value[0]; + mode_idx = mt8186_sgen_mode_idx[mode]; + + dev_dbg(afe->dev, "%s(), mode %d, mode_idx %d\n", + __func__, mode, mode_idx); + + if (mode == afe_priv->sgen_mode) + return 0; + + if (mode_idx >= 0) { + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2, + INNER_LOOP_BACK_MODE_MASK_SFT, + mode_idx << INNER_LOOP_BACK_MODE_SFT); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + DAC_EN_MASK_SFT, BIT(DAC_EN_SFT)); + } else { + /* disable sgen */ + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + DAC_EN_MASK_SFT, 0); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2, + INNER_LOOP_BACK_MODE_MASK_SFT, + 0x3f << INNER_LOOP_BACK_MODE_SFT); + } + + afe_priv->sgen_mode = mode; + + return 1; +} + +static int mt8186_sgen_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->sgen_rate; + + return 0; +} + +static int mt8186_sgen_rate_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int rate; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + rate = ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), rate %d\n", __func__, rate); + + if (rate == afe_priv->sgen_rate) + return 0; + + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + SINE_MODE_CH1_MASK_SFT, + mt8186_sgen_rate_idx[rate] << SINE_MODE_CH1_SFT); + + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + SINE_MODE_CH2_MASK_SFT, + mt8186_sgen_rate_idx[rate] << SINE_MODE_CH2_SFT); + + afe_priv->sgen_rate = rate; + + return 1; +} + +static int mt8186_sgen_amplitude_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + + ucontrol->value.integer.value[0] = afe_priv->sgen_amplitude; + return 0; +} + +static int mt8186_sgen_amplitude_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8186_afe_private *afe_priv = afe->platform_priv; + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + int amplitude; + + if (ucontrol->value.enumerated.item[0] >= e->items) + return -EINVAL; + + amplitude = ucontrol->value.integer.value[0]; + if (amplitude > AMP_DIV_CH1_MASK) { + dev_err(afe->dev, "%s(), amplitude %d invalid\n", + __func__, amplitude); + return -EINVAL; + } + + dev_dbg(afe->dev, "%s(), amplitude %d\n", __func__, amplitude); + + if (amplitude == afe_priv->sgen_amplitude) + return 0; + + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + AMP_DIV_CH1_MASK_SFT, + amplitude << AMP_DIV_CH1_SFT); + regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0, + AMP_DIV_CH2_MASK_SFT, + amplitude << AMP_DIV_CH2_SFT); + + afe_priv->sgen_amplitude = amplitude; + + return 1; +} + +static const struct soc_enum mt8186_afe_sgen_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mode_str), + mt8186_sgen_mode_str), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_rate_str), + mt8186_sgen_rate_str), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_amp_str), + mt8186_sgen_amp_str), +}; + +static const struct snd_kcontrol_new mt8186_afe_sgen_controls[] = { + SOC_ENUM_EXT("Audio_SineGen_Switch", mt8186_afe_sgen_enum[0], + mt8186_sgen_get, mt8186_sgen_set), + SOC_ENUM_EXT("Audio_SineGen_SampleRate", mt8186_afe_sgen_enum[1], + mt8186_sgen_rate_get, mt8186_sgen_rate_set), + SOC_ENUM_EXT("Audio_SineGen_Amplitude", mt8186_afe_sgen_enum[2], + mt8186_sgen_amplitude_get, mt8186_sgen_amplitude_set), + SOC_SINGLE("Audio_SineGen_Mute_Ch1", AFE_SINEGEN_CON0, + MUTE_SW_CH1_MASK_SFT, MUTE_SW_CH1_MASK, 0), + SOC_SINGLE("Audio_SineGen_Mute_Ch2", AFE_SINEGEN_CON0, + MUTE_SW_CH2_MASK_SFT, MUTE_SW_CH2_MASK, 0), + SOC_SINGLE("Audio_SineGen_Freq_Div_Ch1", AFE_SINEGEN_CON0, + FREQ_DIV_CH1_SFT, FREQ_DIV_CH1_MASK, 0), + SOC_SINGLE("Audio_SineGen_Freq_Div_Ch2", AFE_SINEGEN_CON0, + FREQ_DIV_CH2_SFT, FREQ_DIV_CH2_MASK, 0), +}; + +int mt8186_add_misc_control(struct snd_soc_component *component) +{ + snd_soc_add_component_controls(component, + mt8186_afe_sgen_controls, + ARRAY_SIZE(mt8186_afe_sgen_controls)); + + return 0; +} diff --git a/sound/soc/mediatek/mt8186/mt8186-reg.h b/sound/soc/mediatek/mt8186/mt8186-reg.h new file mode 100644 index 0000000000000..53c3eb7283d89 --- /dev/null +++ b/sound/soc/mediatek/mt8186/mt8186-reg.h @@ -0,0 +1,2913 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * mt8186-reg.h -- Mediatek 8186 audio driver reg definition + * + * Copyright (c) 2022 MediaTek Inc. + * Author: Jiaxin Yu + */ + +#ifndef _MT8186_REG_H_ +#define _MT8186_REG_H_ + +/* reg bit enum */ +enum { + MT8186_MEMIF_PBUF_SIZE_32_BYTES, + MT8186_MEMIF_PBUF_SIZE_64_BYTES, + MT8186_MEMIF_PBUF_SIZE_128_BYTES, + MT8186_MEMIF_PBUF_SIZE_256_BYTES, + MT8186_MEMIF_PBUF_SIZE_NUM, +}; + +/***************************************************************************** + * R E G I S T E R D E F I N I T I O N + *****************************************************************************/ +/* AUDIO_TOP_CON0 */ +#define RESERVED_SFT 31 +#define RESERVED_MASK_SFT BIT(31) +#define AHB_IDLE_EN_INT_SFT 30 +#define AHB_IDLE_EN_INT_MASK_SFT BIT(30) +#define AHB_IDLE_EN_EXT_SFT 29 +#define AHB_IDLE_EN_EXT_MASK_SFT BIT(29) +#define PDN_NLE_SFT 28 +#define PDN_NLE_MASK_SFT BIT(28) +#define PDN_TML_SFT 27 +#define PDN_TML_MASK_SFT BIT(27) +#define PDN_DAC_PREDIS_SFT 26 +#define PDN_DAC_PREDIS_MASK_SFT BIT(26) +#define PDN_DAC_SFT 25 +#define PDN_DAC_MASK_SFT BIT(25) +#define PDN_ADC_SFT 24 +#define PDN_ADC_MASK_SFT BIT(24) +#define PDN_TDM_CK_SFT 20 +#define PDN_TDM_CK_MASK_SFT BIT(20) +#define PDN_APLL_TUNER_SFT 19 +#define PDN_APLL_TUNER_MASK_SFT BIT(19) +#define PDN_APLL2_TUNER_SFT 18 +#define PDN_APLL2_TUNER_MASK_SFT BIT(18) +#define APB3_SEL_SFT 14 +#define APB3_SEL_MASK_SFT BIT(14) +#define APB_R2T_SFT 13 +#define APB_R2T_MASK_SFT BIT(13) +#define APB_W2T_SFT 12 +#define APB_W2T_MASK_SFT BIT(12) +#define PDN_24M_SFT 9 +#define PDN_24M_MASK_SFT BIT(9) +#define PDN_22M_SFT 8 +#define PDN_22M_MASK_SFT BIT(8) +#define PDN_AFE_SFT 2 +#define PDN_AFE_MASK_SFT BIT(2) + +/* AUDIO_TOP_CON1 */ +#define PDN_3RD_DAC_HIRES_SFT 31 +#define PDN_3RD_DAC_HIRES_MASK_SFT BIT(31) +#define PDN_3RD_DAC_TML_SFT 30 +#define PDN_3RD_DAC_TML_MASK_SFT BIT(30) +#define PDN_3RD_DAC_PREDIS_SFT 29 +#define PDN_3RD_DAC_PREDIS_MASK_SFT BIT(29) +#define PDN_3RD_DAC_SFT 28 +#define PDN_3RD_DAC_MASK_SFT BIT(28) +#define I2S_SOFT_RST5_SFT 22 +#define I2S_SOFT_RST5_MASK_SFT BIT(22) +#define PDN_ADDA6_ADC_HIRES_SFT 21 +#define PDN_ADDA6_ADC_HIRES_MASK_SFT BIT(21) +#define PDN_ADDA6_ADC_SFT 20 +#define PDN_ADDA6_ADC_MASK_SFT BIT(20) +#define PDN_ADC_HIRES_TML_SFT 17 +#define PDN_ADC_HIRES_TML_MASK_SFT BIT(17) +#define PDN_ADC_HIRES_SFT 16 +#define PDN_ADC_HIRES_MASK_SFT BIT(16) +#define PDN_DAC_HIRES_SFT 15 +#define PDN_DAC_HIRES_MASK_SFT BIT(15) +#define PDN_GENERAL2_ASRC_SFT 14 +#define PDN_GENERAL2_ASRC_MASK_SFT BIT(14) +#define PDN_GENERAL1_ASRC_SFT 13 +#define PDN_GENERAL1_ASRC_MASK_SFT BIT(13) +#define PDN_CONNSYS_I2S_ASRC_SFT 12 +#define PDN_CONNSYS_I2S_ASRC_MASK_SFT BIT(12) +#define I2S4_BCLK_SW_CG_SFT 7 +#define I2S4_BCLK_SW_CG_MASK_SFT BIT(7) +#define I2S3_BCLK_SW_CG_SFT 6 +#define I2S3_BCLK_SW_CG_MASK_SFT BIT(6) +#define I2S2_BCLK_SW_CG_SFT 5 +#define I2S2_BCLK_SW_CG_MASK_SFT BIT(5) +#define I2S1_BCLK_SW_CG_SFT 4 +#define I2S1_BCLK_SW_CG_MASK_SFT BIT(4) +#define I2S_SOFT_RST2_SFT 2 +#define I2S_SOFT_RST2_MASK_SFT BIT(2) +#define I2S_SOFT_RST_SFT 1 +#define I2S_SOFT_RST_MASK_SFT BIT(1) + +/* AUDIO_TOP_CON3 */ +#define BUSY_SFT 31 +#define BUSY_MASK_SFT BIT(31) +#define OS_DISABLE_SFT 30 +#define OS_DISABLE_MASK_SFT BIT(30) +#define CG_DISABLE_SFT 29 +#define CG_DISABLE_MASK_SFT BIT(29) +#define CLEAR_FLAG_SFT 0 +#define CLEAR_FLAG_MASK_SFT BIT(0) + +/* AFE_DAC_CON0 */ +#define VUL12_ON_SFT 31 +#define VUL12_ON_MASK_SFT BIT(31) +#define MOD_DAI_ON_SFT 30 +#define MOD_DAI_ON_MASK_SFT BIT(30) +#define DAI_ON_SFT 29 +#define DAI_ON_MASK_SFT BIT(29) +#define DAI2_ON_SFT 28 +#define DAI2_ON_MASK_SFT BIT(28) +#define VUL6_ON_SFT 23 +#define VUL6_ON_MASK_SFT BIT(23) +#define VUL5_ON_SFT 22 +#define VUL5_ON_MASK_SFT BIT(22) +#define VUL4_ON_SFT 21 +#define VUL4_ON_MASK_SFT BIT(21) +#define VUL3_ON_SFT 20 +#define VUL3_ON_MASK_SFT BIT(20) +#define VUL2_ON_SFT 19 +#define VUL2_ON_MASK_SFT BIT(19) +#define VUL_ON_SFT 18 +#define VUL_ON_MASK_SFT BIT(18) +#define AWB2_ON_SFT 17 +#define AWB2_ON_MASK_SFT BIT(17) +#define AWB_ON_SFT 16 +#define AWB_ON_MASK_SFT BIT(16) +#define DL12_ON_SFT 15 +#define DL12_ON_MASK_SFT BIT(15) +#define DL8_ON_SFT 11 +#define DL8_ON_MASK_SFT BIT(11) +#define DL7_ON_SFT 10 +#define DL7_ON_MASK_SFT BIT(10) +#define DL6_ON_SFT 9 +#define DL6_ON_MASK_SFT BIT(9) +#define DL5_ON_SFT 8 +#define DL5_ON_MASK_SFT BIT(8) +#define DL4_ON_SFT 7 +#define DL4_ON_MASK_SFT BIT(7) +#define DL3_ON_SFT 6 +#define DL3_ON_MASK_SFT BIT(6) +#define DL2_ON_SFT 5 +#define DL2_ON_MASK_SFT BIT(5) +#define DL1_ON_SFT 4 +#define DL1_ON_MASK_SFT BIT(4) +#define AUDIO_AFE_ON_SFT 0 +#define AUDIO_AFE_ON_MASK_SFT BIT(0) + +/* AFE_DAC_MON */ +#define AFE_ON_RETM_SFT 0 +#define AFE_ON_RETM_MASK_SFT BIT(0) + +/* AFE_I2S_CON */ +#define BCK_NEG_EG_LATCH_SFT 30 +#define BCK_NEG_EG_LATCH_MASK_SFT BIT(30) +#define BCK_INV_SFT 29 +#define BCK_INV_MASK_SFT BIT(29) +#define I2SIN_PAD_SEL_SFT 28 +#define I2SIN_PAD_SEL_MASK_SFT BIT(28) +#define I2S_LOOPBACK_SFT 20 +#define I2S_LOOPBACK_MASK_SFT BIT(20) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define I2S1_HD_EN_SFT 12 +#define I2S1_HD_EN_MASK_SFT BIT(12) +#define I2S_OUT_MODE_SFT 8 +#define I2S_OUT_MODE_MASK_SFT GENMASK(11, 8) +#define INV_PAD_CTRL_SFT 7 +#define INV_PAD_CTRL_MASK_SFT BIT(7) +#define I2S_BYPSRC_SFT 6 +#define I2S_BYPSRC_MASK_SFT BIT(6) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK_SFT BIT(5) +#define I2S_FMT_SFT 3 +#define I2S_FMT_MASK_SFT BIT(3) +#define I2S_SRC_SFT 2 +#define I2S_SRC_MASK_SFT BIT(2) +#define I2S_WLEN_SFT 1 +#define I2S_WLEN_MASK_SFT BIT(1) +#define I2S_EN_SFT 0 +#define I2S_EN_MASK_SFT BIT(0) + +/* AFE_I2S_CON1 */ +#define I2S2_LR_SWAP_SFT 31 +#define I2S2_LR_SWAP_MASK_SFT BIT(31) +#define I2S2_SEL_O19_O20_SFT 18 +#define I2S2_SEL_O19_O20_MASK_SFT BIT(18) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define I2S2_SEL_O03_O04_SFT 16 +#define I2S2_SEL_O03_O04_MASK_SFT BIT(16) +#define I2S2_HD_EN_SFT 12 +#define I2S2_HD_EN_MASK_SFT BIT(12) +#define I2S2_OUT_MODE_SFT 8 +#define I2S2_OUT_MODE_MASK_SFT GENMASK(11, 8) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK_SFT BIT(5) +#define I2S2_FMT_SFT 3 +#define I2S2_FMT_MASK_SFT BIT(3) +#define I2S2_WLEN_SFT 1 +#define I2S2_WLEN_MASK_SFT BIT(1) +#define I2S2_EN_SFT 0 +#define I2S2_EN_MASK_SFT BIT(0) + +/* AFE_I2S_CON2 */ +#define I2S3_LR_SWAP_SFT 31 +#define I2S3_LR_SWAP_MASK_SFT BIT(31) +#define I2S3_UPDATE_WORD_SFT 24 +#define I2S3_UPDATE_WORD_MASK_SFT GENMASK(28, 24) +#define I2S3_BCK_INV_SFT 23 +#define I2S3_BCK_INV_MASK_SFT BIT(23) +#define I2S3_FPGA_BIT_TEST_SFT 22 +#define I2S3_FPGA_BIT_TEST_MASK_SFT BIT(22) +#define I2S3_FPGA_BIT_SFT 21 +#define I2S3_FPGA_BIT_MASK_SFT BIT(21) +#define I2S3_LOOPBACK_SFT 20 +#define I2S3_LOOPBACK_MASK_SFT BIT(20) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define I2S3_HD_EN_SFT 12 +#define I2S3_HD_EN_MASK_SFT BIT(12) +#define I2S3_OUT_MODE_SFT 8 +#define I2S3_OUT_MODE_MASK_SFT GENMASK(11, 8) +#define I2S3_FMT_SFT 3 +#define I2S3_FMT_MASK_SFT BIT(3) +#define I2S3_WLEN_SFT 1 +#define I2S3_WLEN_MASK_SFT BIT(1) +#define I2S3_EN_SFT 0 +#define I2S3_EN_MASK_SFT BIT(0) + +/* AFE_I2S_CON3 */ +#define I2S4_LR_SWAP_SFT 31 +#define I2S4_LR_SWAP_MASK_SFT BIT(31) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define I2S4_HD_EN_SFT 12 +#define I2S4_HD_EN_MASK_SFT BIT(12) +#define I2S4_OUT_MODE_SFT 8 +#define I2S4_OUT_MODE_MASK_SFT GENMASK(11, 8) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK_SFT BIT(5) +#define I2S4_FMT_SFT 3 +#define I2S4_FMT_MASK_SFT BIT(3) +#define I2S4_WLEN_SFT 1 +#define I2S4_WLEN_MASK_SFT BIT(1) +#define I2S4_EN_SFT 0 +#define I2S4_EN_MASK_SFT BIT(0) + +/* AFE_I2S_CON4 */ +#define I2S_LOOPBACK_SFT 20 +#define I2S_LOOPBACK_MASK 0x1 +#define I2S_LOOPBACK_MASK_SFT BIT(20) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK 0x1 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK 0x1 +#define INV_LRCK_MASK_SFT BIT(5) + +/* AFE_CONNSYS_I2S_CON */ +#define BCK_NEG_EG_LATCH_SFT 30 +#define BCK_NEG_EG_LATCH_MASK_SFT BIT(30) +#define BCK_INV_SFT 29 +#define BCK_INV_MASK_SFT BIT(29) +#define I2SIN_PAD_SEL_SFT 28 +#define I2SIN_PAD_SEL_MASK_SFT BIT(28) +#define I2S_LOOPBACK_SFT 20 +#define I2S_LOOPBACK_MASK_SFT BIT(20) +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_SFT 17 +#define I2S_ONOFF_NOT_RESET_CK_ENABLE_MASK_SFT BIT(17) +#define I2S_MODE_SFT 8 +#define I2S_MODE_MASK_SFT GENMASK(11, 8) +#define INV_PAD_CTRL_SFT 7 +#define INV_PAD_CTRL_MASK_SFT BIT(7) +#define I2S_BYPSRC_SFT 6 +#define I2S_BYPSRC_MASK_SFT BIT(6) +#define INV_LRCK_SFT 5 +#define INV_LRCK_MASK_SFT BIT(5) +#define I2S_FMT_SFT 3 +#define I2S_FMT_MASK_SFT BIT(3) +#define I2S_SRC_SFT 2 +#define I2S_SRC_MASK_SFT BIT(2) +#define I2S_WLEN_SFT 1 +#define I2S_WLEN_MASK_SFT BIT(1) +#define I2S_EN_SFT 0 +#define I2S_EN_MASK_SFT BIT(0) + +/* AFE_ASRC_2CH_CON2 */ +#define CHSET_O16BIT_SFT 19 +#define CHSET_O16BIT_MASK_SFT BIT(19) +#define CHSET_CLR_IIR_HISTORY_SFT 17 +#define CHSET_CLR_IIR_HISTORY_MASK_SFT BIT(17) +#define CHSET_IS_MONO_SFT 16 +#define CHSET_IS_MONO_MASK_SFT BIT(16) +#define CHSET_IIR_EN_SFT 11 +#define CHSET_IIR_EN_MASK_SFT BIT(11) +#define CHSET_IIR_STAGE_SFT 8 +#define CHSET_IIR_STAGE_MASK_SFT GENMASK(10, 8) +#define CHSET_STR_CLR_SFT 5 +#define CHSET_STR_CLR_MASK_SFT BIT(5) +#define CHSET_ON_SFT 2 +#define CHSET_ON_MASK_SFT BIT(2) +#define COEFF_SRAM_CTRL_SFT 1 +#define COEFF_SRAM_CTRL_MASK_SFT BIT(1) +#define ASM_ON_SFT 0 +#define ASM_ON_MASK_SFT BIT(0) + +/* AFE_GAIN1_CON0 */ +#define GAIN1_SAMPLE_PER_STEP_SFT 8 +#define GAIN1_SAMPLE_PER_STEP_MASK_SFT GENMASK(15, 8) +#define GAIN1_MODE_SFT 4 +#define GAIN1_MODE_MASK_SFT GENMASK(7, 4) +#define GAIN1_ON_SFT 0 +#define GAIN1_ON_MASK_SFT BIT(0) + +/* AFE_GAIN1_CON1 */ +#define GAIN1_TARGET_SFT 0 +#define GAIN1_TARGET_MASK 0xfffffff +#define GAIN1_TARGET_MASK_SFT GENMASK(27, 0) + +/* AFE_GAIN2_CON0 */ +#define GAIN2_SAMPLE_PER_STEP_SFT 8 +#define GAIN2_SAMPLE_PER_STEP_MASK_SFT GENMASK(15, 8) +#define GAIN2_MODE_SFT 4 +#define GAIN2_MODE_MASK_SFT GENMASK(7, 4) +#define GAIN2_ON_SFT 0 +#define GAIN2_ON_MASK_SFT BIT(0) + +/* AFE_GAIN2_CON1 */ +#define GAIN2_TARGET_SFT 0 +#define GAIN2_TARGET_MASK 0xfffffff +#define GAIN2_TARGET_MASK_SFT GENMASK(27, 0) + +/* AFE_GAIN1_CUR */ +#define AFE_GAIN1_CUR_SFT 0 +#define AFE_GAIN1_CUR_MASK_SFT GENMASK(27, 0) + +/* AFE_GAIN2_CUR */ +#define AFE_GAIN2_CUR_SFT 0 +#define AFE_GAIN2_CUR_MASK_SFT GENMASK(27, 0) + +/* PCM_INTF_CON1 */ +#define PCM_FIX_VALUE_SEL_SFT 31 +#define PCM_FIX_VALUE_SEL_MASK_SFT BIT(31) +#define PCM_BUFFER_LOOPBACK_SFT 30 +#define PCM_BUFFER_LOOPBACK_MASK_SFT BIT(30) +#define PCM_PARALLEL_LOOPBACK_SFT 29 +#define PCM_PARALLEL_LOOPBACK_MASK_SFT BIT(29) +#define PCM_SERIAL_LOOPBACK_SFT 28 +#define PCM_SERIAL_LOOPBACK_MASK_SFT BIT(28) +#define PCM_DAI_PCM_LOOPBACK_SFT 27 +#define PCM_DAI_PCM_LOOPBACK_MASK_SFT BIT(27) +#define PCM_I2S_PCM_LOOPBACK_SFT 26 +#define PCM_I2S_PCM_LOOPBACK_MASK_SFT BIT(26) +#define PCM_SYNC_DELSEL_SFT 25 +#define PCM_SYNC_DELSEL_MASK_SFT BIT(25) +#define PCM_TX_LR_SWAP_SFT 24 +#define PCM_TX_LR_SWAP_MASK_SFT BIT(24) +#define PCM_SYNC_OUT_INV_SFT 23 +#define PCM_SYNC_OUT_INV_MASK_SFT BIT(23) +#define PCM_BCLK_OUT_INV_SFT 22 +#define PCM_BCLK_OUT_INV_MASK_SFT BIT(22) +#define PCM_SYNC_IN_INV_SFT 21 +#define PCM_SYNC_IN_INV_MASK_SFT BIT(21) +#define PCM_BCLK_IN_INV_SFT 20 +#define PCM_BCLK_IN_INV_MASK_SFT BIT(20) +#define PCM_TX_LCH_RPT_SFT 19 +#define PCM_TX_LCH_RPT_MASK_SFT BIT(19) +#define PCM_VBT_16K_MODE_SFT 18 +#define PCM_VBT_16K_MODE_MASK_SFT BIT(18) +#define PCM_EXT_MODEM_SFT 17 +#define PCM_EXT_MODEM_MASK_SFT BIT(17) +#define PCM_24BIT_SFT 16 +#define PCM_24BIT_MASK_SFT BIT(16) +#define PCM_WLEN_SFT 14 +#define PCM_WLEN_MASK_SFT GENMASK(15, 14) +#define PCM_SYNC_LENGTH_SFT 9 +#define PCM_SYNC_LENGTH_MASK_SFT GENMASK(13, 9) +#define PCM_SYNC_TYPE_SFT 8 +#define PCM_SYNC_TYPE_MASK_SFT BIT(8) +#define PCM_BT_MODE_SFT 7 +#define PCM_BT_MODE_MASK_SFT BIT(7) +#define PCM_BYP_ASRC_SFT 6 +#define PCM_BYP_ASRC_MASK_SFT BIT(6) +#define PCM_SLAVE_SFT 5 +#define PCM_SLAVE_MASK_SFT BIT(5) +#define PCM_MODE_SFT 3 +#define PCM_MODE_MASK_SFT GENMASK(4, 3) +#define PCM_FMT_SFT 1 +#define PCM_FMT_MASK_SFT GENMASK(2, 1) +#define PCM_EN_SFT 0 +#define PCM_EN_MASK_SFT BIT(0) + +/* PCM_INTF_CON2 */ +#define PCM1_TX_FIFO_OV_SFT 31 +#define PCM1_TX_FIFO_OV_MASK_SFT BIT(31) +#define PCM1_RX_FIFO_OV_SFT 30 +#define PCM1_RX_FIFO_OV_MASK_SFT BIT(30) +#define PCM2_TX_FIFO_OV_SFT 29 +#define PCM2_TX_FIFO_OV_MASK_SFT BIT(29) +#define PCM2_RX_FIFO_OV_SFT 28 +#define PCM2_RX_FIFO_OV_MASK_SFT BIT(28) +#define PCM1_SYNC_GLITCH_SFT 27 +#define PCM1_SYNC_GLITCH_MASK_SFT BIT(27) +#define PCM2_SYNC_GLITCH_SFT 26 +#define PCM2_SYNC_GLITCH_MASK_SFT BIT(26) +#define TX3_RCH_DBG_MODE_SFT 17 +#define TX3_RCH_DBG_MODE_MASK_SFT BIT(17) +#define PCM1_PCM2_LOOPBACK_SFT 16 +#define PCM1_PCM2_LOOPBACK_MASK_SFT BIT(16) +#define DAI_PCM_LOOPBACK_CH_SFT 14 +#define DAI_PCM_LOOPBACK_CH_MASK_SFT GENMASK(15, 14) +#define I2S_PCM_LOOPBACK_CH_SFT 12 +#define I2S_PCM_LOOPBACK_CH_MASK_SFT GENMASK(13, 12) +#define TX_FIX_VALUE_SFT 0 +#define TX_FIX_VALUE_MASK_SFT GENMASK(7, 0) + +/* PCM2_INTF_CON */ +#define PCM2_TX_FIX_VALUE_SFT 24 +#define PCM2_TX_FIX_VALUE_MASK_SFT GENMASK(31, 24) +#define PCM2_FIX_VALUE_SEL_SFT 23 +#define PCM2_FIX_VALUE_SEL_MASK_SFT BIT(23) +#define PCM2_BUFFER_LOOPBACK_SFT 22 +#define PCM2_BUFFER_LOOPBACK_MASK_SFT BIT(22) +#define PCM2_PARALLEL_LOOPBACK_SFT 21 +#define PCM2_PARALLEL_LOOPBACK_MASK_SFT BIT(21) +#define PCM2_SERIAL_LOOPBACK_SFT 20 +#define PCM2_SERIAL_LOOPBACK_MASK_SFT BIT(20) +#define PCM2_DAI_PCM_LOOPBACK_SFT 19 +#define PCM2_DAI_PCM_LOOPBACK_MASK_SFT BIT(19) +#define PCM2_I2S_PCM_LOOPBACK_SFT 18 +#define PCM2_I2S_PCM_LOOPBACK_MASK_SFT BIT(18) +#define PCM2_SYNC_DELSEL_SFT 17 +#define PCM2_SYNC_DELSEL_MASK_SFT BIT(17) +#define PCM2_TX_LR_SWAP_SFT 16 +#define PCM2_TX_LR_SWAP_MASK_SFT BIT(16) +#define PCM2_SYNC_IN_INV_SFT 15 +#define PCM2_SYNC_IN_INV_MASK_SFT BIT(15) +#define PCM2_BCLK_IN_INV_SFT 14 +#define PCM2_BCLK_IN_INV_MASK_SFT BIT(14) +#define PCM2_TX_LCH_RPT_SFT 13 +#define PCM2_TX_LCH_RPT_MASK_SFT BIT(13) +#define PCM2_VBT_16K_MODE_SFT 12 +#define PCM2_VBT_16K_MODE_MASK_SFT BIT(12) +#define PCM2_LOOPBACK_CH_SEL_SFT 10 +#define PCM2_LOOPBACK_CH_SEL_MASK_SFT GENMASK(11, 10) +#define PCM2_TX2_BT_MODE_SFT 8 +#define PCM2_TX2_BT_MODE_MASK_SFT BIT(8) +#define PCM2_BT_MODE_SFT 7 +#define PCM2_BT_MODE_MASK_SFT BIT(7) +#define PCM2_AFIFO_SFT 6 +#define PCM2_AFIFO_MASK_SFT BIT(6) +#define PCM2_WLEN_SFT 5 +#define PCM2_WLEN_MASK_SFT BIT(5) +#define PCM2_MODE_SFT 3 +#define PCM2_MODE_MASK_SFT GENMASK(4, 3) +#define PCM2_FMT_SFT 1 +#define PCM2_FMT_MASK_SFT GENMASK(2, 1) +#define PCM2_EN_SFT 0 +#define PCM2_EN_MASK_SFT BIT(0) + +// AFE_CM1_CON +#define CHANNEL_MERGE0_DEBUG_MODE_SFT (31) +#define CHANNEL_MERGE0_DEBUG_MODE_MASK_SFT BIT(31) +#define VUL3_BYPASS_CM_SFT (30) +#define VUL3_BYPASS_CM_MASK (0x1) +#define VUL3_BYPASS_CM_MASK_SFT BIT(30) +#define CM1_DEBUG_MODE_SEL_SFT (29) +#define CM1_DEBUG_MODE_SEL_MASK_SFT BIT(29) +#define CHANNEL_MERGE0_UPDATE_CNT_SFT (16) +#define CHANNEL_MERGE0_UPDATE_CNT_MASK_SFT GENMASK(28, 16) +#define CM1_FS_SELECT_SFT (8) +#define CM1_FS_SELECT_MASK_SFT GENMASK(12, 8) +#define CHANNEL_MERGE0_CHNUM_SFT (3) +#define CHANNEL_MERGE0_CHNUM_MASK_SFT GENMASK(7, 3) +#define CHANNEL_MERGE0_BYTE_SWAP_SFT (1) +#define CHANNEL_MERGE0_BYTE_SWAP_MASK_SFT BIT(1) +#define CHANNEL_MERGE0_EN_SFT (0) +#define CHANNEL_MERGE0_EN_MASK_SFT BIT(0) + +/* AFE_ADDA_MTKAIF_CFG0 */ +#define MTKAIF_RXIF_CLKINV_ADC_SFT 31 +#define MTKAIF_RXIF_CLKINV_ADC_MASK_SFT BIT(31) +#define MTKAIF_RXIF_BYPASS_SRC_SFT 17 +#define MTKAIF_RXIF_BYPASS_SRC_MASK_SFT BIT(17) +#define MTKAIF_RXIF_PROTOCOL2_SFT 16 +#define MTKAIF_RXIF_PROTOCOL2_MASK_SFT BIT(16) +#define MTKAIF_TXIF_BYPASS_SRC_SFT 5 +#define MTKAIF_TXIF_BYPASS_SRC_MASK_SFT BIT(5) +#define MTKAIF_TXIF_PROTOCOL2_SFT 4 +#define MTKAIF_TXIF_PROTOCOL2_MASK_SFT BIT(4) +#define MTKAIF_TXIF_8TO5_SFT 2 +#define MTKAIF_TXIF_8TO5_MASK_SFT BIT(2) +#define MTKAIF_RXIF_8TO5_SFT 1 +#define MTKAIF_RXIF_8TO5_MASK_SFT BIT(1) +#define MTKAIF_IF_LOOPBACK1_SFT 0 +#define MTKAIF_IF_LOOPBACK1_MASK_SFT BIT(0) + +/* AFE_ADDA_MTKAIF_RX_CFG2 */ +#define MTKAIF_RXIF_DETECT_ON_PROTOCOL2_SFT 16 +#define MTKAIF_RXIF_DETECT_ON_PROTOCOL2_MASK_SFT BIT(16) +#define MTKAIF_RXIF_DELAY_CYCLE_SFT 12 +#define MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT GENMASK(15, 12) +#define MTKAIF_RXIF_DELAY_DATA_SFT 8 +#define MTKAIF_RXIF_DELAY_DATA_MASK 0x1 +#define MTKAIF_RXIF_DELAY_DATA_MASK_SFT BIT(8) +#define MTKAIF_RXIF_FIFO_RSP_PROTOCOL2_SFT 4 +#define MTKAIF_RXIF_FIFO_RSP_PROTOCOL2_MASK_SFT GENMASK(6, 4) + +/* AFE_ADDA_DL_SRC2_CON0 */ +#define DL_2_INPUT_MODE_CTL_SFT 28 +#define DL_2_INPUT_MODE_CTL_MASK_SFT GENMASK(31, 28) +#define DL_2_CH1_SATURATION_EN_CTL_SFT 27 +#define DL_2_CH1_SATURATION_EN_CTL_MASK_SFT BIT(27) +#define DL_2_CH2_SATURATION_EN_CTL_SFT 26 +#define DL_2_CH2_SATURATION_EN_CTL_MASK_SFT BIT(26) +#define DL_2_OUTPUT_SEL_CTL_SFT 24 +#define DL_2_OUTPUT_SEL_CTL_MASK_SFT GENMASK(25, 24) +#define DL_2_FADEIN_0START_EN_SFT 16 +#define DL_2_FADEIN_0START_EN_MASK_SFT GENMASK(17, 16) +#define DL_DISABLE_HW_CG_CTL_SFT 15 +#define DL_DISABLE_HW_CG_CTL_MASK_SFT BIT(15) +#define C_DATA_EN_SEL_CTL_PRE_SFT 14 +#define C_DATA_EN_SEL_CTL_PRE_MASK_SFT BIT(14) +#define DL_2_SIDE_TONE_ON_CTL_PRE_SFT 13 +#define DL_2_SIDE_TONE_ON_CTL_PRE_MASK_SFT BIT(13) +#define DL_2_MUTE_CH1_OFF_CTL_PRE_SFT 12 +#define DL_2_MUTE_CH1_OFF_CTL_PRE_MASK_SFT BIT(12) +#define DL_2_MUTE_CH2_OFF_CTL_PRE_SFT 11 +#define DL_2_MUTE_CH2_OFF_CTL_PRE_MASK_SFT BIT(11) +#define DL2_ARAMPSP_CTL_PRE_SFT 9 +#define DL2_ARAMPSP_CTL_PRE_MASK_SFT GENMASK(10, 9) +#define DL_2_IIRMODE_CTL_PRE_SFT 6 +#define DL_2_IIRMODE_CTL_PRE_MASK_SFT GENMASK(8, 6) +#define DL_2_VOICE_MODE_CTL_PRE_SFT 5 +#define DL_2_VOICE_MODE_CTL_PRE_MASK_SFT BIT(5) +#define D2_2_MUTE_CH1_ON_CTL_PRE_SFT 4 +#define D2_2_MUTE_CH1_ON_CTL_PRE_MASK_SFT BIT(4) +#define D2_2_MUTE_CH2_ON_CTL_PRE_SFT 3 +#define D2_2_MUTE_CH2_ON_CTL_PRE_MASK_SFT BIT(3) +#define DL_2_IIR_ON_CTL_PRE_SFT 2 +#define DL_2_IIR_ON_CTL_PRE_MASK_SFT BIT(2) +#define DL_2_GAIN_ON_CTL_PRE_SFT 1 +#define DL_2_GAIN_ON_CTL_PRE_MASK_SFT BIT(1) +#define DL_2_SRC_ON_CTL_PRE_SFT 0 +#define DL_2_SRC_ON_CTL_PRE_MASK_SFT BIT(0) + +/* AFE_ADDA_DL_SRC2_CON1 */ +#define DL_2_GAIN_CTL_PRE_SFT 16 +#define DL_2_GAIN_CTL_PRE_MASK 0xffff +#define DL_2_GAIN_CTL_PRE_MASK_SFT GENMASK(31, 16) +#define DL_2_GAIN_MODE_CTL_SFT 0 +#define DL_2_GAIN_MODE_CTL_MASK_SFT BIT(0) + +/* AFE_ADDA_UL_SRC_CON0 */ +#define ULCF_CFG_EN_CTL_SFT 31 +#define ULCF_CFG_EN_CTL_MASK_SFT BIT(31) +#define UL_DMIC_PHASE_SEL_CH1_SFT 27 +#define UL_DMIC_PHASE_SEL_CH1_MASK_SFT GENMASK(29, 27) +#define UL_DMIC_PHASE_SEL_CH2_SFT 24 +#define UL_DMIC_PHASE_SEL_CH2_MASK_SFT GENMASK(26, 24) +#define UL_MODE_3P25M_CH2_CTL_SFT 22 +#define UL_MODE_3P25M_CH2_CTL_MASK_SFT BIT(22) +#define UL_MODE_3P25M_CH1_CTL_SFT 21 +#define UL_MODE_3P25M_CH1_CTL_MASK_SFT BIT(21) +#define UL_VOICE_MODE_CH1_CH2_CTL_SFT 17 +#define UL_VOICE_MODE_CH1_CH2_CTL_MASK_SFT GENMASK(19, 17) +#define UL_AP_DMIC_ON_SFT 16 +#define UL_AP_DMIC_ON_MASK_SFT BIT(16) +#define DMIC_LOW_POWER_CTL_SFT 14 +#define DMIC_LOW_POWER_CTL_MASK_SFT GENMASK(15, 14) +#define UL_DISABLE_HW_CG_CTL_SFT 12 +#define UL_DISABLE_HW_CG_CTL_MASK_SFT BIT(12) +#define UL_IIR_ON_TMP_CTL_SFT 10 +#define UL_IIR_ON_TMP_CTL_MASK_SFT BIT(10) +#define UL_IIRMODE_CTL_SFT 7 +#define UL_IIRMODE_CTL_MASK_SFT GENMASK(9, 7) +#define DIGMIC_4P33M_SEL_SFT 6 +#define DIGMIC_4P33M_SEL_MASK_SFT BIT(6) +#define DIGMIC_3P25M_1P625M_SEL_SFT 5 +#define DIGMIC_3P25M_1P625M_SEL_MASK_SFT BIT(5) +#define UL_LOOP_BACK_MODE_SFT 2 +#define UL_LOOP_BACK_MODE_MASK_SFT BIT(2) +#define UL_SDM_3_LEVEL_SFT 1 +#define UL_SDM_3_LEVEL_MASK_SFT BIT(1) +#define UL_SRC_ON_CTL_SFT 0 +#define UL_SRC_ON_CTL_MASK_SFT BIT(0) + +/* AFE_ADDA_UL_SRC_CON1 */ +#define C_DAC_EN_CTL_SFT 27 +#define C_DAC_EN_CTL_MASK_SFT BIT(27) +#define C_MUTE_SW_CTL_SFT 26 +#define C_MUTE_SW_CTL_MASK_SFT BIT(26) +#define ASDM_SRC_SEL_CTL_SFT 25 +#define ASDM_SRC_SEL_CTL_MASK_SFT BIT(25) +#define C_AMP_DIV_CH2_CTL_SFT 21 +#define C_AMP_DIV_CH2_CTL_MASK_SFT GENMASK(23, 21) +#define C_FREQ_DIV_CH2_CTL_SFT 16 +#define C_FREQ_DIV_CH2_CTL_MASK_SFT GENMASK(20, 16) +#define C_SINE_MODE_CH2_CTL_SFT 12 +#define C_SINE_MODE_CH2_CTL_MASK_SFT GENMASK(15, 12) +#define C_AMP_DIV_CH1_CTL_SFT 9 +#define C_AMP_DIV_CH1_CTL_MASK_SFT GENMASK(11, 9) +#define C_FREQ_DIV_CH1_CTL_SFT 4 +#define C_FREQ_DIV_CH1_CTL_MASK_SFT GENMASK(8, 4) +#define C_SINE_MODE_CH1_CTL_SFT 0 +#define C_SINE_MODE_CH1_CTL_MASK_SFT GENMASK(3, 0) + +/* AFE_ADDA_TOP_CON0 */ +#define C_LOOP_BACK_MODE_CTL_SFT 12 +#define C_LOOP_BACK_MODE_CTL_MASK_SFT GENMASK(15, 12) +#define ADDA_UL_GAIN_MODE_SFT 8 +#define ADDA_UL_GAIN_MODE_MASK_SFT GENMASK(9, 8) +#define C_EXT_ADC_CTL_SFT 0 +#define C_EXT_ADC_CTL_MASK_SFT BIT(0) + +/* AFE_ADDA_UL_DL_CON0 */ +#define AFE_ADDA_UL_LR_SWAP_SFT 31 +#define AFE_ADDA_UL_LR_SWAP_MASK_SFT BIT(31) +#define AFE_ADDA_CKDIV_RST_SFT 30 +#define AFE_ADDA_CKDIV_RST_MASK_SFT BIT(30) +#define AFE_ADDA_FIFO_AUTO_RST_SFT 29 +#define AFE_ADDA_FIFO_AUTO_RST_MASK_SFT BIT(29) +#define AFE_ADDA_UL_FIFO_DIGMIC_TESTIN_SFT 21 +#define AFE_ADDA_UL_FIFO_DIGMIC_TESTIN_MASK_SFT GENMASK(22, 21) +#define AFE_ADDA_UL_FIFO_DIGMIC_WDATA_TESTEN_SFT 20 +#define AFE_ADDA_UL_FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT BIT(20) +#define AFE_ADDA6_UL_LR_SWAP_SFT 15 +#define AFE_ADDA6_UL_LR_SWAP_MASK_SFT BIT(15) +#define AFE_ADDA6_CKDIV_RST_SFT 14 +#define AFE_ADDA6_CKDIV_RST_MASK_SFT BIT(14) +#define AFE_ADDA6_FIFO_AUTO_RST_SFT 13 +#define AFE_ADDA6_FIFO_AUTO_RST_MASK_SFT BIT(13) +#define AFE_ADDA6_UL_FIFO_DIGMIC_TESTIN_SFT 5 +#define AFE_ADDA6_UL_FIFO_DIGMIC_TESTIN_MASK_SFT GENMASK(6, 5) +#define AFE_ADDA6_UL_FIFO_DIGMIC_WDATA_TESTEN_SFT 4 +#define AFE_ADDA6_UL_FIFO_DIGMIC_WDATA_TESTEN_MASK_SFT BIT(4) +#define ADDA_AFE_ON_SFT 0 +#define ADDA_AFE_ON_MASK_SFT BIT(0) + +/* AFE_SIDETONE_CON0 */ +#define R_RDY_SFT 30 +#define R_RDY_MASK_SFT BIT(30) +#define W_RDY_SFT 29 +#define W_RDY_MASK_SFT BIT(29) +#define R_W_EN_SFT 25 +#define R_W_EN_MASK_SFT BIT(25) +#define R_W_SEL_SFT 24 +#define R_W_SEL_MASK_SFT BIT(24) +#define SEL_CH2_SFT 23 +#define SEL_CH2_MASK_SFT BIT(23) +#define SIDE_TONE_COEFFICIENT_ADDR_SFT 16 +#define SIDE_TONE_COEFFICIENT_ADDR_MASK_SFT GENMASK(20, 16) +#define SIDE_TONE_COEFFICIENT_SFT 0 +#define SIDE_TONE_COEFFICIENT_MASK_SFT GENMASK(15, 0) + +/* AFE_SIDETONE_COEFF */ +#define SIDE_TONE_COEFF_SFT 0 +#define SIDE_TONE_COEFF_MASK_SFT GENMASK(15, 0) + +/* AFE_SIDETONE_CON1 */ +#define STF_BYPASS_MODE_SFT 31 +#define STF_BYPASS_MODE_MASK_SFT BIT(31) +#define STF_BYPASS_MODE_O28_O29_SFT 30 +#define STF_BYPASS_MODE_O28_O29_MASK_SFT BIT(30) +#define STF_BYPASS_MODE_I2S4_SFT 29 +#define STF_BYPASS_MODE_I2S4_MASK_SFT BIT(29) +#define STF_BYPASS_MODE_DL3_SFT 27 +#define STF_BYPASS_MODE_DL3_MASK_SFT BIT(27) +#define STF_BYPASS_MODE_I2S7_SFT 26 +#define STF_BYPASS_MODE_I2S7_MASK_SFT BIT(26) +#define STF_BYPASS_MODE_I2S9_SFT 25 +#define STF_BYPASS_MODE_I2S9_MASK_SFT BIT(25) +#define STF_O19O20_OUT_EN_SEL_SFT 13 +#define STF_O19O20_OUT_EN_SEL_MASK_SFT BIT(13) +#define STF_SOURCE_FROM_O19O20_SFT 12 +#define STF_SOURCE_FROM_O19O20_MASK_SFT BIT(12) +#define SIDE_TONE_ON_SFT 8 +#define SIDE_TONE_ON_MASK_SFT BIT(8) +#define SIDE_TONE_HALF_TAP_NUM_SFT 0 +#define SIDE_TONE_HALF_TAP_NUM_MASK_SFT GENMASK(5, 0) + +/* AFE_SIDETONE_GAIN */ +#define POSITIVE_GAIN_SFT 16 +#define POSITIVE_GAIN_MASK_SFT GENMASK(18, 16) +#define SIDE_TONE_GAIN_SFT 0 +#define SIDE_TONE_GAIN_MASK_SFT GENMASK(15, 0) + +/* AFE_ADDA_DL_SDM_DCCOMP_CON */ +#define USE_3RD_SDM_SFT 28 +#define USE_3RD_SDM_MASK_SFT BIT(28) +#define DL_FIFO_START_POINT_SFT 24 +#define DL_FIFO_START_POINT_MASK_SFT GENMASK(26, 24) +#define DL_FIFO_SWAP_SFT 20 +#define DL_FIFO_SWAP_MASK_SFT BIT(20) +#define C_AUDSDM1ORDSELECT_CTL_SFT 19 +#define C_AUDSDM1ORDSELECT_CTL_MASK_SFT BIT(19) +#define C_SDM7BITSEL_CTL_SFT 18 +#define C_SDM7BITSEL_CTL_MASK_SFT BIT(18) +#define GAIN_AT_SDM_RST_PRE_CTL_SFT 15 +#define GAIN_AT_SDM_RST_PRE_CTL_MASK_SFT BIT(15) +#define DL_DCM_AUTO_IDLE_EN_SFT 14 +#define DL_DCM_AUTO_IDLE_EN_MASK_SFT BIT(14) +#define AFE_DL_SRC_DCM_EN_SFT 13 +#define AFE_DL_SRC_DCM_EN_MASK_SFT BIT(13) +#define AFE_DL_POST_SRC_DCM_EN_SFT 12 +#define AFE_DL_POST_SRC_DCM_EN_MASK_SFT BIT(12) +#define AUD_SDM_MONO_SFT 9 +#define AUD_SDM_MONO_MASK_SFT BIT(9) +#define AUD_DC_COMP_EN_SFT 8 +#define AUD_DC_COMP_EN_MASK_SFT BIT(8) +#define ATTGAIN_CTL_SFT 0 +#define ATTGAIN_CTL_MASK_SFT GENMASK(5, 0) + +/* AFE_SINEGEN_CON0 */ +#define DAC_EN_SFT 26 +#define DAC_EN_MASK 0x1 +#define DAC_EN_MASK_SFT BIT(26) +#define MUTE_SW_CH2_SFT 25 +#define MUTE_SW_CH2_MASK 0x1 +#define MUTE_SW_CH2_MASK_SFT BIT(25) +#define MUTE_SW_CH1_SFT 24 +#define MUTE_SW_CH1_MASK 0x1 +#define MUTE_SW_CH1_MASK_SFT BIT(24) +#define SINE_MODE_CH2_SFT 20 +#define SINE_MODE_CH2_MASK 0xf +#define SINE_MODE_CH2_MASK_SFT GENMASK(23, 20) +#define AMP_DIV_CH2_SFT 17 +#define AMP_DIV_CH2_MASK 0x7 +#define AMP_DIV_CH2_MASK_SFT GENMASK(19, 17) +#define FREQ_DIV_CH2_SFT 12 +#define FREQ_DIV_CH2_MASK 0x1f +#define FREQ_DIV_CH2_MASK_SFT GENMASK(16, 12) +#define SINE_MODE_CH1_SFT 8 +#define SINE_MODE_CH1_MASK 0xf +#define SINE_MODE_CH1_MASK_SFT GENMASK(11, 8) +#define AMP_DIV_CH1_SFT 5 +#define AMP_DIV_CH1_MASK 0x7 +#define AMP_DIV_CH1_MASK_SFT GENMASK(7, 5) +#define FREQ_DIV_CH1_SFT 0 +#define FREQ_DIV_CH1_MASK 0x1f +#define FREQ_DIV_CH1_MASK_SFT GENMASK(4, 0) + +/* AFE_SINEGEN_CON2 */ +#define INNER_LOOP_BACK_MODE_SFT 0 +#define INNER_LOOP_BACK_MODE_MASK_SFT GENMASK(7, 0) + +/* AFE_HD_ENGEN_ENABLE */ +#define AFE_24M_ON_SFT 1 +#define AFE_24M_ON_MASK_SFT BIT(1) +#define AFE_22M_ON_SFT 0 +#define AFE_22M_ON_MASK_SFT BIT(0) + +/* AFE_ADDA_DL_NLE_FIFO_MON */ +#define DL_NLE_FIFO_WBIN_SFT 8 +#define DL_NLE_FIFO_WBIN_MASK_SFT GENMASK(11, 8) +#define DL_NLE_FIFO_RBIN_SFT 4 +#define DL_NLE_FIFO_RBIN_MASK_SFT GENMASK(7, 4) +#define DL_NLE_FIFO_RDACTIVE_SFT 3 +#define DL_NLE_FIFO_RDACTIVE_MASK_SFT BIT(3) +#define DL_NLE_FIFO_STARTRD_SFT 2 +#define DL_NLE_FIFO_STARTRD_MASK_SFT BIT(2) +#define DL_NLE_FIFO_RD_EMPTY_SFT 1 +#define DL_NLE_FIFO_RD_EMPTY_MASK_SFT BIT(1) +#define DL_NLE_FIFO_WR_FULL_SFT 0 +#define DL_NLE_FIFO_WR_FULL_MASK_SFT BIT(0) + +/* AFE_DL1_CON0 */ +#define DL1_MODE_SFT 24 +#define DL1_MODE_MASK 0xf +#define DL1_MODE_MASK_SFT GENMASK(27, 24) +#define DL1_MINLEN_SFT 20 +#define DL1_MINLEN_MASK 0xf +#define DL1_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL1_MAXLEN_SFT 16 +#define DL1_MAXLEN_MASK 0xf +#define DL1_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL1_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL1_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL1_PBUF_SIZE_SFT 12 +#define DL1_PBUF_SIZE_MASK 0x3 +#define DL1_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL1_MONO_SFT 8 +#define DL1_MONO_MASK 0x1 +#define DL1_MONO_MASK_SFT BIT(8) +#define DL1_NORMAL_MODE_SFT 5 +#define DL1_NORMAL_MODE_MASK 0x1 +#define DL1_NORMAL_MODE_MASK_SFT BIT(5) +#define DL1_HALIGN_SFT 4 +#define DL1_HALIGN_MASK 0x1 +#define DL1_HALIGN_MASK_SFT BIT(4) +#define DL1_HD_MODE_SFT 0 +#define DL1_HD_MODE_MASK 0x3 +#define DL1_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL2_CON0 */ +#define DL2_MODE_SFT 24 +#define DL2_MODE_MASK 0xf +#define DL2_MODE_MASK_SFT GENMASK(27, 24) +#define DL2_MINLEN_SFT 20 +#define DL2_MINLEN_MASK 0xf +#define DL2_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL2_MAXLEN_SFT 16 +#define DL2_MAXLEN_MASK 0xf +#define DL2_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL2_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL2_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL2_PBUF_SIZE_SFT 12 +#define DL2_PBUF_SIZE_MASK 0x3 +#define DL2_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL2_MONO_SFT 8 +#define DL2_MONO_MASK 0x1 +#define DL2_MONO_MASK_SFT BIT(8) +#define DL2_NORMAL_MODE_SFT 5 +#define DL2_NORMAL_MODE_MASK 0x1 +#define DL2_NORMAL_MODE_MASK_SFT BIT(5) +#define DL2_HALIGN_SFT 4 +#define DL2_HALIGN_MASK 0x1 +#define DL2_HALIGN_MASK_SFT BIT(4) +#define DL2_HD_MODE_SFT 0 +#define DL2_HD_MODE_MASK 0x3 +#define DL2_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL3_CON0 */ +#define DL3_MODE_SFT 24 +#define DL3_MODE_MASK 0xf +#define DL3_MODE_MASK_SFT GENMASK(27, 24) +#define DL3_MINLEN_SFT 20 +#define DL3_MINLEN_MASK 0xf +#define DL3_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL3_MAXLEN_SFT 16 +#define DL3_MAXLEN_MASK 0xf +#define DL3_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL3_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL3_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL3_PBUF_SIZE_SFT 12 +#define DL3_PBUF_SIZE_MASK 0x3 +#define DL3_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL3_MONO_SFT 8 +#define DL3_MONO_MASK 0x1 +#define DL3_MONO_MASK_SFT BIT(8) +#define DL3_NORMAL_MODE_SFT 5 +#define DL3_NORMAL_MODE_MASK 0x1 +#define DL3_NORMAL_MODE_MASK_SFT BIT(5) +#define DL3_HALIGN_SFT 4 +#define DL3_HALIGN_MASK 0x1 +#define DL3_HALIGN_MASK_SFT BIT(4) +#define DL3_HD_MODE_SFT 0 +#define DL3_HD_MODE_MASK 0x3 +#define DL3_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL4_CON0 */ +#define DL4_MODE_SFT 24 +#define DL4_MODE_MASK 0xf +#define DL4_MODE_MASK_SFT GENMASK(27, 24) +#define DL4_MINLEN_SFT 20 +#define DL4_MINLEN_MASK 0xf +#define DL4_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL4_MAXLEN_SFT 16 +#define DL4_MAXLEN_MASK 0xf +#define DL4_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL4_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL4_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL4_PBUF_SIZE_SFT 12 +#define DL4_PBUF_SIZE_MASK 0x3 +#define DL4_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL4_MONO_SFT 8 +#define DL4_MONO_MASK 0x1 +#define DL4_MONO_MASK_SFT BIT(8) +#define DL4_NORMAL_MODE_SFT 5 +#define DL4_NORMAL_MODE_MASK 0x1 +#define DL4_NORMAL_MODE_MASK_SFT BIT(5) +#define DL4_HALIGN_SFT 4 +#define DL4_HALIGN_MASK 0x1 +#define DL4_HALIGN_MASK_SFT BIT(4) +#define DL4_HD_MODE_SFT 0 +#define DL4_HD_MODE_MASK 0x3 +#define DL4_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL5_CON0 */ +#define DL5_MODE_SFT 24 +#define DL5_MODE_MASK 0xf +#define DL5_MODE_MASK_SFT GENMASK(27, 24) +#define DL5_MINLEN_SFT 20 +#define DL5_MINLEN_MASK 0xf +#define DL5_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL5_MAXLEN_SFT 16 +#define DL5_MAXLEN_MASK 0xf +#define DL5_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL5_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL5_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL5_PBUF_SIZE_SFT 12 +#define DL5_PBUF_SIZE_MASK 0x3 +#define DL5_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL5_MONO_SFT 8 +#define DL5_MONO_MASK 0x1 +#define DL5_MONO_MASK_SFT BIT(8) +#define DL5_NORMAL_MODE_SFT 5 +#define DL5_NORMAL_MODE_MASK 0x1 +#define DL5_NORMAL_MODE_MASK_SFT BIT(5) +#define DL5_HALIGN_SFT 4 +#define DL5_HALIGN_MASK 0x1 +#define DL5_HALIGN_MASK_SFT BIT(4) +#define DL5_HD_MODE_SFT 0 +#define DL5_HD_MODE_MASK 0x3 +#define DL5_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL6_CON0 */ +#define DL6_MODE_SFT 24 +#define DL6_MODE_MASK 0xf +#define DL6_MODE_MASK_SFT GENMASK(27, 24) +#define DL6_MINLEN_SFT 20 +#define DL6_MINLEN_MASK 0xf +#define DL6_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL6_MAXLEN_SFT 16 +#define DL6_MAXLEN_MASK 0xf +#define DL6_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL6_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL6_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL6_PBUF_SIZE_SFT 12 +#define DL6_PBUF_SIZE_MASK 0x3 +#define DL6_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL6_MONO_SFT 8 +#define DL6_MONO_MASK 0x1 +#define DL6_MONO_MASK_SFT BIT(8) +#define DL6_NORMAL_MODE_SFT 5 +#define DL6_NORMAL_MODE_MASK 0x1 +#define DL6_NORMAL_MODE_MASK_SFT BIT(5) +#define DL6_HALIGN_SFT 4 +#define DL6_HALIGN_MASK 0x1 +#define DL6_HALIGN_MASK_SFT BIT(4) +#define DL6_HD_MODE_SFT 0 +#define DL6_HD_MODE_MASK 0x3 +#define DL6_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL7_CON0 */ +#define DL7_MODE_SFT 24 +#define DL7_MODE_MASK 0xf +#define DL7_MODE_MASK_SFT GENMASK(27, 24) +#define DL7_MINLEN_SFT 20 +#define DL7_MINLEN_MASK 0xf +#define DL7_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL7_MAXLEN_SFT 16 +#define DL7_MAXLEN_MASK 0xf +#define DL7_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL7_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL7_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL7_PBUF_SIZE_SFT 12 +#define DL7_PBUF_SIZE_MASK 0x3 +#define DL7_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL7_MONO_SFT 8 +#define DL7_MONO_MASK 0x1 +#define DL7_MONO_MASK_SFT BIT(8) +#define DL7_NORMAL_MODE_SFT 5 +#define DL7_NORMAL_MODE_MASK 0x1 +#define DL7_NORMAL_MODE_MASK_SFT BIT(5) +#define DL7_HALIGN_SFT 4 +#define DL7_HALIGN_MASK 0x1 +#define DL7_HALIGN_MASK_SFT BIT(4) +#define DL7_HD_MODE_SFT 0 +#define DL7_HD_MODE_MASK 0x3 +#define DL7_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL8_CON0 */ +#define DL8_MODE_SFT 24 +#define DL8_MODE_MASK 0xf +#define DL8_MODE_MASK_SFT GENMASK(27, 24) +#define DL8_MINLEN_SFT 20 +#define DL8_MINLEN_MASK 0xf +#define DL8_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL8_MAXLEN_SFT 16 +#define DL8_MAXLEN_MASK 0xf +#define DL8_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL8_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL8_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL8_PBUF_SIZE_SFT 12 +#define DL8_PBUF_SIZE_MASK 0x3 +#define DL8_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL8_MONO_SFT 8 +#define DL8_MONO_MASK 0x1 +#define DL8_MONO_MASK_SFT BIT(8) +#define DL8_NORMAL_MODE_SFT 5 +#define DL8_NORMAL_MODE_MASK 0x1 +#define DL8_NORMAL_MODE_MASK_SFT BIT(5) +#define DL8_HALIGN_SFT 4 +#define DL8_HALIGN_MASK 0x1 +#define DL8_HALIGN_MASK_SFT BIT(4) +#define DL8_HD_MODE_SFT 0 +#define DL8_HD_MODE_MASK 0x3 +#define DL8_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DL12_CON0 */ +#define DL12_MODE_SFT 24 +#define DL12_MODE_MASK 0xf +#define DL12_MODE_MASK_SFT GENMASK(27, 24) +#define DL12_MINLEN_SFT 20 +#define DL12_MINLEN_MASK 0xf +#define DL12_MINLEN_MASK_SFT GENMASK(23, 20) +#define DL12_MAXLEN_SFT 16 +#define DL12_MAXLEN_MASK 0xf +#define DL12_MAXLEN_MASK_SFT GENMASK(19, 16) +#define DL12_SW_CLEAR_BUF_EMPTY_SFT 15 +#define DL12_SW_CLEAR_BUF_EMPTY_MASK 0x1 +#define DL12_SW_CLEAR_BUF_EMPTY_MASK_SFT BIT(15) +#define DL12_PBUF_SIZE_SFT 12 +#define DL12_PBUF_SIZE_MASK 0x3 +#define DL12_PBUF_SIZE_MASK_SFT GENMASK(13, 12) +#define DL12_4CH_EN_SFT 11 +#define DL12_4CH_EN_MASK 0x1 +#define DL12_4CH_EN_MASK_SFT BIT(11) +#define DL12_MONO_SFT 8 +#define DL12_MONO_MASK 0x1 +#define DL12_MONO_MASK_SFT BIT(8) +#define DL12_NORMAL_MODE_SFT 5 +#define DL12_NORMAL_MODE_MASK 0x1 +#define DL12_NORMAL_MODE_MASK_SFT BIT(5) +#define DL12_HALIGN_SFT 4 +#define DL12_HALIGN_MASK 0x1 +#define DL12_HALIGN_MASK_SFT BIT(4) +#define DL12_HD_MODE_SFT 0 +#define DL12_HD_MODE_MASK 0x3 +#define DL12_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_AWB_CON0 */ +#define AWB_MODE_SFT 24 +#define AWB_MODE_MASK 0xf +#define AWB_MODE_MASK_SFT GENMASK(27, 24) +#define AWB_SW_CLEAR_BUF_FULL_SFT 15 +#define AWB_SW_CLEAR_BUF_FULL_MASK 0x1 +#define AWB_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define AWB_R_MONO_SFT 9 +#define AWB_R_MONO_MASK 0x1 +#define AWB_R_MONO_MASK_SFT BIT(9) +#define AWB_MONO_SFT 8 +#define AWB_MONO_MASK 0x1 +#define AWB_MONO_MASK_SFT BIT(8) +#define AWB_WR_SIGN_SFT 6 +#define AWB_WR_SIGN_MASK 0x1 +#define AWB_WR_SIGN_MASK_SFT BIT(6) +#define AWB_NORMAL_MODE_SFT 5 +#define AWB_NORMAL_MODE_MASK 0x1 +#define AWB_NORMAL_MODE_MASK_SFT BIT(5) +#define AWB_HALIGN_SFT 4 +#define AWB_HALIGN_MASK 0x1 +#define AWB_HALIGN_MASK_SFT BIT(4) +#define AWB_HD_MODE_SFT 0 +#define AWB_HD_MODE_MASK 0x3 +#define AWB_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_AWB2_CON0 */ +#define AWB2_MODE_SFT 24 +#define AWB2_MODE_MASK 0xf +#define AWB2_MODE_MASK_SFT GENMASK(27, 24) +#define AWB2_SW_CLEAR_BUF_FULL_SFT 15 +#define AWB2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define AWB2_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define AWB2_R_MONO_SFT 9 +#define AWB2_R_MONO_MASK 0x1 +#define AWB2_R_MONO_MASK_SFT BIT(9) +#define AWB2_MONO_SFT 8 +#define AWB2_MONO_MASK 0x1 +#define AWB2_MONO_MASK_SFT BIT(8) +#define AWB2_WR_SIGN_SFT 6 +#define AWB2_WR_SIGN_MASK 0x1 +#define AWB2_WR_SIGN_MASK_SFT BIT(6) +#define AWB2_NORMAL_MODE_SFT 5 +#define AWB2_NORMAL_MODE_MASK 0x1 +#define AWB2_NORMAL_MODE_MASK_SFT BIT(5) +#define AWB2_HALIGN_SFT 4 +#define AWB2_HALIGN_MASK 0x1 +#define AWB2_HALIGN_MASK_SFT BIT(4) +#define AWB2_HD_MODE_SFT 0 +#define AWB2_HD_MODE_MASK 0x3 +#define AWB2_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL_CON0 */ +#define VUL_MODE_SFT 24 +#define VUL_MODE_MASK 0xf +#define VUL_MODE_MASK_SFT GENMASK(27, 24) +#define VUL_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL_R_MONO_SFT 9 +#define VUL_R_MONO_MASK 0x1 +#define VUL_R_MONO_MASK_SFT BIT(9) +#define VUL_MONO_SFT 8 +#define VUL_MONO_MASK 0x1 +#define VUL_MONO_MASK_SFT BIT(8) +#define VUL_WR_SIGN_SFT 6 +#define VUL_WR_SIGN_MASK 0x1 +#define VUL_WR_SIGN_MASK_SFT BIT(6) +#define VUL_NORMAL_MODE_SFT 5 +#define VUL_NORMAL_MODE_MASK 0x1 +#define VUL_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL_HALIGN_SFT 4 +#define VUL_HALIGN_MASK 0x1 +#define VUL_HALIGN_MASK_SFT BIT(4) +#define VUL_HD_MODE_SFT 0 +#define VUL_HD_MODE_MASK 0x3 +#define VUL_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL12_CON0 */ +#define VUL12_MODE_SFT 24 +#define VUL12_MODE_MASK 0xf +#define VUL12_MODE_MASK_SFT GENMASK(27, 24) +#define VUL12_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL12_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL12_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL12_4CH_EN_SFT 11 +#define VUL12_4CH_EN_MASK 0x1 +#define VUL12_4CH_EN_MASK_SFT BIT(11) +#define VUL12_R_MONO_SFT 9 +#define VUL12_R_MONO_MASK 0x1 +#define VUL12_R_MONO_MASK_SFT BIT(9) +#define VUL12_MONO_SFT 8 +#define VUL12_MONO_MASK 0x1 +#define VUL12_MONO_MASK_SFT BIT(8) +#define VUL12_WR_SIGN_SFT 6 +#define VUL12_WR_SIGN_MASK 0x1 +#define VUL12_WR_SIGN_MASK_SFT BIT(6) +#define VUL12_NORMAL_MODE_SFT 5 +#define VUL12_NORMAL_MODE_MASK 0x1 +#define VUL12_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL12_HALIGN_SFT 4 +#define VUL12_HALIGN_MASK 0x1 +#define VUL12_HALIGN_MASK_SFT BIT(4) +#define VUL12_HD_MODE_SFT 0 +#define VUL12_HD_MODE_MASK 0x3 +#define VUL12_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL2_CON0 */ +#define VUL2_MODE_SFT 24 +#define VUL2_MODE_MASK 0xf +#define VUL2_MODE_MASK_SFT GENMASK(27, 24) +#define VUL2_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL2_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL2_R_MONO_SFT 9 +#define VUL2_R_MONO_MASK 0x1 +#define VUL2_R_MONO_MASK_SFT BIT(9) +#define VUL2_MONO_SFT 8 +#define VUL2_MONO_MASK 0x1 +#define VUL2_MONO_MASK_SFT BIT(8) +#define VUL2_WR_SIGN_SFT 6 +#define VUL2_WR_SIGN_MASK 0x1 +#define VUL2_WR_SIGN_MASK_SFT BIT(6) +#define VUL2_NORMAL_MODE_SFT 5 +#define VUL2_NORMAL_MODE_MASK 0x1 +#define VUL2_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL2_HALIGN_SFT 4 +#define VUL2_HALIGN_MASK 0x1 +#define VUL2_HALIGN_MASK_SFT BIT(4) +#define VUL2_HD_MODE_SFT 0 +#define VUL2_HD_MODE_MASK 0x3 +#define VUL2_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL3_CON0 */ +#define VUL3_MODE_SFT 24 +#define VUL3_MODE_MASK 0xf +#define VUL3_MODE_MASK_SFT GENMASK(27, 24) +#define VUL3_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL3_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL3_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL3_R_MONO_SFT 9 +#define VUL3_R_MONO_MASK 0x1 +#define VUL3_R_MONO_MASK_SFT BIT(9) +#define VUL3_MONO_SFT 8 +#define VUL3_MONO_MASK 0x1 +#define VUL3_MONO_MASK_SFT BIT(8) +#define VUL3_WR_SIGN_SFT 6 +#define VUL3_WR_SIGN_MASK 0x1 +#define VUL3_WR_SIGN_MASK_SFT BIT(6) +#define VUL3_NORMAL_MODE_SFT 5 +#define VUL3_NORMAL_MODE_MASK 0x1 +#define VUL3_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL3_HALIGN_SFT 4 +#define VUL3_HALIGN_MASK 0x1 +#define VUL3_HALIGN_MASK_SFT BIT(4) +#define VUL3_HD_MODE_SFT 0 +#define VUL3_HD_MODE_MASK 0x3 +#define VUL3_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL4_CON0 */ +#define VUL4_MODE_SFT 24 +#define VUL4_MODE_MASK 0xf +#define VUL4_MODE_MASK_SFT GENMASK(27, 24) +#define VUL4_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL4_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL4_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL4_R_MONO_SFT 9 +#define VUL4_R_MONO_MASK 0x1 +#define VUL4_R_MONO_MASK_SFT BIT(9) +#define VUL4_MONO_SFT 8 +#define VUL4_MONO_MASK 0x1 +#define VUL4_MONO_MASK_SFT BIT(8) +#define VUL4_WR_SIGN_SFT 6 +#define VUL4_WR_SIGN_MASK 0x1 +#define VUL4_WR_SIGN_MASK_SFT BIT(6) +#define VUL4_NORMAL_MODE_SFT 5 +#define VUL4_NORMAL_MODE_MASK 0x1 +#define VUL4_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL4_HALIGN_SFT 4 +#define VUL4_HALIGN_MASK 0x1 +#define VUL4_HALIGN_MASK_SFT BIT(4) +#define VUL4_HD_MODE_SFT 0 +#define VUL4_HD_MODE_MASK 0x3 +#define VUL4_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL5_CON0 */ +#define VUL5_MODE_SFT 24 +#define VUL5_MODE_MASK 0xf +#define VUL5_MODE_MASK_SFT GENMASK(27, 24) +#define VUL5_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL5_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL5_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL5_R_MONO_SFT 9 +#define VUL5_R_MONO_MASK 0x1 +#define VUL5_R_MONO_MASK_SFT BIT(9) +#define VUL5_MONO_SFT 8 +#define VUL5_MONO_MASK 0x1 +#define VUL5_MONO_MASK_SFT BIT(8) +#define VUL5_WR_SIGN_SFT 6 +#define VUL5_WR_SIGN_MASK 0x1 +#define VUL5_WR_SIGN_MASK_SFT BIT(6) +#define VUL5_NORMAL_MODE_SFT 5 +#define VUL5_NORMAL_MODE_MASK 0x1 +#define VUL5_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL5_HALIGN_SFT 4 +#define VUL5_HALIGN_MASK 0x1 +#define VUL5_HALIGN_MASK_SFT BIT(4) +#define VUL5_HD_MODE_SFT 0 +#define VUL5_HD_MODE_MASK 0x3 +#define VUL5_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_VUL6_CON0 */ +#define VUL6_MODE_SFT 24 +#define VUL6_MODE_MASK 0xf +#define VUL6_MODE_MASK_SFT GENMASK(27, 24) +#define VUL6_SW_CLEAR_BUF_FULL_SFT 15 +#define VUL6_SW_CLEAR_BUF_FULL_MASK 0x1 +#define VUL6_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define VUL6_R_MONO_SFT 9 +#define VUL6_R_MONO_MASK 0x1 +#define VUL6_R_MONO_MASK_SFT BIT(9) +#define VUL6_MONO_SFT 8 +#define VUL6_MONO_MASK 0x1 +#define VUL6_MONO_MASK_SFT BIT(8) +#define VUL6_WR_SIGN_SFT 6 +#define VUL6_WR_SIGN_MASK 0x1 +#define VUL6_WR_SIGN_MASK_SFT BIT(6) +#define VUL6_NORMAL_MODE_SFT 5 +#define VUL6_NORMAL_MODE_MASK 0x1 +#define VUL6_NORMAL_MODE_MASK_SFT BIT(5) +#define VUL6_HALIGN_SFT 4 +#define VUL6_HALIGN_MASK 0x1 +#define VUL6_HALIGN_MASK_SFT BIT(4) +#define VUL6_HD_MODE_SFT 0 +#define VUL6_HD_MODE_MASK 0x3 +#define VUL6_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DAI_CON0 */ +#define DAI_MODE_SFT 24 +#define DAI_MODE_MASK 0x3 +#define DAI_MODE_MASK_SFT GENMASK(25, 24) +#define DAI_SW_CLEAR_BUF_FULL_SFT 15 +#define DAI_SW_CLEAR_BUF_FULL_MASK 0x1 +#define DAI_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define DAI_DUPLICATE_WR_SFT 10 +#define DAI_DUPLICATE_WR_MASK 0x1 +#define DAI_DUPLICATE_WR_MASK_SFT BIT(10) +#define DAI_MONO_SFT 8 +#define DAI_MONO_MASK 0x1 +#define DAI_MONO_MASK_SFT BIT(8) +#define DAI_WR_SIGN_SFT 6 +#define DAI_WR_SIGN_MASK 0x1 +#define DAI_WR_SIGN_MASK_SFT BIT(6) +#define DAI_NORMAL_MODE_SFT 5 +#define DAI_NORMAL_MODE_MASK 0x1 +#define DAI_NORMAL_MODE_MASK_SFT BIT(5) +#define DAI_HALIGN_SFT 4 +#define DAI_HALIGN_MASK 0x1 +#define DAI_HALIGN_MASK_SFT BIT(4) +#define DAI_HD_MODE_SFT 0 +#define DAI_HD_MODE_MASK 0x3 +#define DAI_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_MOD_DAI_CON0 */ +#define MOD_DAI_MODE_SFT 24 +#define MOD_DAI_MODE_MASK 0x3 +#define MOD_DAI_MODE_MASK_SFT GENMASK(25, 24) +#define MOD_DAI_SW_CLEAR_BUF_FULL_SFT 15 +#define MOD_DAI_SW_CLEAR_BUF_FULL_MASK 0x1 +#define MOD_DAI_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define MOD_DAI_DUPLICATE_WR_SFT 10 +#define MOD_DAI_DUPLICATE_WR_MASK 0x1 +#define MOD_DAI_DUPLICATE_WR_MASK_SFT BIT(10) +#define MOD_DAI_MONO_SFT 8 +#define MOD_DAI_MONO_MASK 0x1 +#define MOD_DAI_MONO_MASK_SFT BIT(8) +#define MOD_DAI_WR_SIGN_SFT 6 +#define MOD_DAI_WR_SIGN_MASK 0x1 +#define MOD_DAI_WR_SIGN_MASK_SFT BIT(6) +#define MOD_DAI_NORMAL_MODE_SFT 5 +#define MOD_DAI_NORMAL_MODE_MASK 0x1 +#define MOD_DAI_NORMAL_MODE_MASK_SFT BIT(5) +#define MOD_DAI_HALIGN_SFT 4 +#define MOD_DAI_HALIGN_MASK 0x1 +#define MOD_DAI_HALIGN_MASK_SFT BIT(4) +#define MOD_DAI_HD_MODE_SFT 0 +#define MOD_DAI_HD_MODE_MASK 0x3 +#define MOD_DAI_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_DAI2_CON0 */ +#define DAI2_MODE_SFT 24 +#define DAI2_MODE_MASK 0xf +#define DAI2_MODE_MASK_SFT GENMASK(27, 24) +#define DAI2_SW_CLEAR_BUF_FULL_SFT 15 +#define DAI2_SW_CLEAR_BUF_FULL_MASK 0x1 +#define DAI2_SW_CLEAR_BUF_FULL_MASK_SFT BIT(15) +#define DAI2_DUPLICATE_WR_SFT 10 +#define DAI2_DUPLICATE_WR_MASK 0x1 +#define DAI2_DUPLICATE_WR_MASK_SFT BIT(10) +#define DAI2_MONO_SFT 8 +#define DAI2_MONO_MASK 0x1 +#define DAI2_MONO_MASK_SFT BIT(8) +#define DAI2_WR_SIGN_SFT 6 +#define DAI2_WR_SIGN_MASK 0x1 +#define DAI2_WR_SIGN_MASK_SFT BIT(6) +#define DAI2_NORMAL_MODE_SFT 5 +#define DAI2_NORMAL_MODE_MASK 0x1 +#define DAI2_NORMAL_MODE_MASK_SFT BIT(5) +#define DAI2_HALIGN_SFT 4 +#define DAI2_HALIGN_MASK 0x1 +#define DAI2_HALIGN_MASK_SFT BIT(4) +#define DAI2_HD_MODE_SFT 0 +#define DAI2_HD_MODE_MASK 0x3 +#define DAI2_HD_MODE_MASK_SFT GENMASK(1, 0) + +/* AFE_MEMIF_CON0 */ +#define CPU_COMPACT_MODE_SFT 2 +#define CPU_COMPACT_MODE_MASK_SFT BIT(2) +#define CPU_HD_ALIGN_SFT 1 +#define CPU_HD_ALIGN_MASK_SFT BIT(1) +#define SYSRAM_SIGN_SFT 0 +#define SYSRAM_SIGN_MASK_SFT BIT(0) + +/* AFE_IRQ_MCU_CON0 */ +#define IRQ31_MCU_ON_SFT 31 +#define IRQ31_MCU_ON_MASK 0x1 +#define IRQ31_MCU_ON_MASK_SFT BIT(31) +#define IRQ26_MCU_ON_SFT 26 +#define IRQ26_MCU_ON_MASK 0x1 +#define IRQ26_MCU_ON_MASK_SFT BIT(26) +#define IRQ25_MCU_ON_SFT 25 +#define IRQ25_MCU_ON_MASK 0x1 +#define IRQ25_MCU_ON_MASK_SFT BIT(25) +#define IRQ24_MCU_ON_SFT 24 +#define IRQ24_MCU_ON_MASK 0x1 +#define IRQ24_MCU_ON_MASK_SFT BIT(24) +#define IRQ23_MCU_ON_SFT 23 +#define IRQ23_MCU_ON_MASK 0x1 +#define IRQ23_MCU_ON_MASK_SFT BIT(23) +#define IRQ22_MCU_ON_SFT 22 +#define IRQ22_MCU_ON_MASK 0x1 +#define IRQ22_MCU_ON_MASK_SFT BIT(22) +#define IRQ21_MCU_ON_SFT 21 +#define IRQ21_MCU_ON_MASK 0x1 +#define IRQ21_MCU_ON_MASK_SFT BIT(21) +#define IRQ20_MCU_ON_SFT 20 +#define IRQ20_MCU_ON_MASK 0x1 +#define IRQ20_MCU_ON_MASK_SFT BIT(20) +#define IRQ19_MCU_ON_SFT 19 +#define IRQ19_MCU_ON_MASK 0x1 +#define IRQ19_MCU_ON_MASK_SFT BIT(19) +#define IRQ18_MCU_ON_SFT 18 +#define IRQ18_MCU_ON_MASK 0x1 +#define IRQ18_MCU_ON_MASK_SFT BIT(18) +#define IRQ17_MCU_ON_SFT 17 +#define IRQ17_MCU_ON_MASK 0x1 +#define IRQ17_MCU_ON_MASK_SFT BIT(17) +#define IRQ16_MCU_ON_SFT 16 +#define IRQ16_MCU_ON_MASK 0x1 +#define IRQ16_MCU_ON_MASK_SFT BIT(16) +#define IRQ15_MCU_ON_SFT 15 +#define IRQ15_MCU_ON_MASK 0x1 +#define IRQ15_MCU_ON_MASK_SFT BIT(15) +#define IRQ14_MCU_ON_SFT 14 +#define IRQ14_MCU_ON_MASK 0x1 +#define IRQ14_MCU_ON_MASK_SFT BIT(14) +#define IRQ13_MCU_ON_SFT 13 +#define IRQ13_MCU_ON_MASK 0x1 +#define IRQ13_MCU_ON_MASK_SFT BIT(13) +#define IRQ12_MCU_ON_SFT 12 +#define IRQ12_MCU_ON_MASK 0x1 +#define IRQ12_MCU_ON_MASK_SFT BIT(12) +#define IRQ11_MCU_ON_SFT 11 +#define IRQ11_MCU_ON_MASK 0x1 +#define IRQ11_MCU_ON_MASK_SFT BIT(11) +#define IRQ10_MCU_ON_SFT 10 +#define IRQ10_MCU_ON_MASK 0x1 +#define IRQ10_MCU_ON_MASK_SFT BIT(10) +#define IRQ9_MCU_ON_SFT 9 +#define IRQ9_MCU_ON_MASK 0x1 +#define IRQ9_MCU_ON_MASK_SFT BIT(9) +#define IRQ8_MCU_ON_SFT 8 +#define IRQ8_MCU_ON_MASK 0x1 +#define IRQ8_MCU_ON_MASK_SFT BIT(8) +#define IRQ7_MCU_ON_SFT 7 +#define IRQ7_MCU_ON_MASK 0x1 +#define IRQ7_MCU_ON_MASK_SFT BIT(7) +#define IRQ6_MCU_ON_SFT 6 +#define IRQ6_MCU_ON_MASK 0x1 +#define IRQ6_MCU_ON_MASK_SFT BIT(6) +#define IRQ5_MCU_ON_SFT 5 +#define IRQ5_MCU_ON_MASK 0x1 +#define IRQ5_MCU_ON_MASK_SFT BIT(5) +#define IRQ4_MCU_ON_SFT 4 +#define IRQ4_MCU_ON_MASK 0x1 +#define IRQ4_MCU_ON_MASK_SFT BIT(4) +#define IRQ3_MCU_ON_SFT 3 +#define IRQ3_MCU_ON_MASK 0x1 +#define IRQ3_MCU_ON_MASK_SFT BIT(3) +#define IRQ2_MCU_ON_SFT 2 +#define IRQ2_MCU_ON_MASK 0x1 +#define IRQ2_MCU_ON_MASK_SFT BIT(2) +#define IRQ1_MCU_ON_SFT 1 +#define IRQ1_MCU_ON_MASK 0x1 +#define IRQ1_MCU_ON_MASK_SFT BIT(1) +#define IRQ0_MCU_ON_SFT 0 +#define IRQ0_MCU_ON_MASK 0x1 +#define IRQ0_MCU_ON_MASK_SFT BIT(0) + +/* AFE_IRQ_MCU_CON1 */ +#define IRQ7_MCU_MODE_SFT 28 +#define IRQ7_MCU_MODE_MASK 0xf +#define IRQ7_MCU_MODE_MASK_SFT GENMASK(31, 28) +#define IRQ6_MCU_MODE_SFT 24 +#define IRQ6_MCU_MODE_MASK 0xf +#define IRQ6_MCU_MODE_MASK_SFT GENMASK(27, 24) +#define IRQ5_MCU_MODE_SFT 20 +#define IRQ5_MCU_MODE_MASK 0xf +#define IRQ5_MCU_MODE_MASK_SFT GENMASK(23, 20) +#define IRQ4_MCU_MODE_SFT 16 +#define IRQ4_MCU_MODE_MASK 0xf +#define IRQ4_MCU_MODE_MASK_SFT GENMASK(19, 16) +#define IRQ3_MCU_MODE_SFT 12 +#define IRQ3_MCU_MODE_MASK 0xf +#define IRQ3_MCU_MODE_MASK_SFT GENMASK(15, 12) +#define IRQ2_MCU_MODE_SFT 8 +#define IRQ2_MCU_MODE_MASK 0xf +#define IRQ2_MCU_MODE_MASK_SFT GENMASK(11, 8) +#define IRQ1_MCU_MODE_SFT 4 +#define IRQ1_MCU_MODE_MASK 0xf +#define IRQ1_MCU_MODE_MASK_SFT GENMASK(7, 4) +#define IRQ0_MCU_MODE_SFT 0 +#define IRQ0_MCU_MODE_MASK 0xf +#define IRQ0_MCU_MODE_MASK_SFT GENMASK(3, 0) + +/* AFE_IRQ_MCU_CON2 */ +#define IRQ15_MCU_MODE_SFT 28 +#define IRQ15_MCU_MODE_MASK 0xf +#define IRQ15_MCU_MODE_MASK_SFT GENMASK(31, 28) +#define IRQ14_MCU_MODE_SFT 24 +#define IRQ14_MCU_MODE_MASK 0xf +#define IRQ14_MCU_MODE_MASK_SFT GENMASK(27, 24) +#define IRQ13_MCU_MODE_SFT 20 +#define IRQ13_MCU_MODE_MASK 0xf +#define IRQ13_MCU_MODE_MASK_SFT GENMASK(23, 20) +#define IRQ12_MCU_MODE_SFT 16 +#define IRQ12_MCU_MODE_MASK 0xf +#define IRQ12_MCU_MODE_MASK_SFT GENMASK(19, 16) +#define IRQ11_MCU_MODE_SFT 12 +#define IRQ11_MCU_MODE_MASK 0xf +#define IRQ11_MCU_MODE_MASK_SFT GENMASK(15, 12) +#define IRQ10_MCU_MODE_SFT 8 +#define IRQ10_MCU_MODE_MASK 0xf +#define IRQ10_MCU_MODE_MASK_SFT GENMASK(11, 8) +#define IRQ9_MCU_MODE_SFT 4 +#define IRQ9_MCU_MODE_MASK 0xf +#define IRQ9_MCU_MODE_MASK_SFT GENMASK(7, 4) +#define IRQ8_MCU_MODE_SFT 0 +#define IRQ8_MCU_MODE_MASK 0xf +#define IRQ8_MCU_MODE_MASK_SFT GENMASK(3, 0) + +/* AFE_IRQ_MCU_CON3 */ +#define IRQ23_MCU_MODE_SFT 28 +#define IRQ23_MCU_MODE_MASK 0xf +#define IRQ23_MCU_MODE_MASK_SFT GENMASK(31, 28) +#define IRQ22_MCU_MODE_SFT 24 +#define IRQ22_MCU_MODE_MASK 0xf +#define IRQ22_MCU_MODE_MASK_SFT GENMASK(27, 24) +#define IRQ21_MCU_MODE_SFT 20 +#define IRQ21_MCU_MODE_MASK 0xf +#define IRQ21_MCU_MODE_MASK_SFT GENMASK(23, 20) +#define IRQ20_MCU_MODE_SFT 16 +#define IRQ20_MCU_MODE_MASK 0xf +#define IRQ20_MCU_MODE_MASK_SFT GENMASK(19, 16) +#define IRQ19_MCU_MODE_SFT 12 +#define IRQ19_MCU_MODE_MASK 0xf +#define IRQ19_MCU_MODE_MASK_SFT GENMASK(15, 12) +#define IRQ18_MCU_MODE_SFT 8 +#define IRQ18_MCU_MODE_MASK 0xf +#define IRQ18_MCU_MODE_MASK_SFT GENMASK(11, 8) +#define IRQ17_MCU_MODE_SFT 4 +#define IRQ17_MCU_MODE_MASK 0xf +#define IRQ17_MCU_MODE_MASK_SFT GENMASK(7, 4) +#define IRQ16_MCU_MODE_SFT 0 +#define IRQ16_MCU_MODE_MASK 0xf +#define IRQ16_MCU_MODE_MASK_SFT GENMASK(3, 0) + +/* AFE_IRQ_MCU_CON4 */ +#define IRQ26_MCU_MODE_SFT 8 +#define IRQ26_MCU_MODE_MASK 0xf +#define IRQ26_MCU_MODE_MASK_SFT GENMASK(11, 8) +#define IRQ25_MCU_MODE_SFT 4 +#define IRQ25_MCU_MODE_MASK 0xf +#define IRQ25_MCU_MODE_MASK_SFT GENMASK(7, 4) +#define IRQ24_MCU_MODE_SFT 0 +#define IRQ24_MCU_MODE_MASK 0xf +#define IRQ24_MCU_MODE_MASK_SFT GENMASK(3, 0) + +/* AFE_IRQ_MCU_CLR */ +#define IRQ31_MCU_CLR_SFT 31 +#define IRQ31_MCU_CLR_MASK_SFT BIT(31) +#define IRQ26_MCU_CLR_SFT 26 +#define IRQ26_MCU_CLR_MASK_SFT BIT(26) +#define IRQ25_MCU_CLR_SFT 25 +#define IRQ25_MCU_CLR_MASK_SFT BIT(25) +#define IRQ24_MCU_CLR_SFT 24 +#define IRQ24_MCU_CLR_MASK_SFT BIT(24) +#define IRQ23_MCU_CLR_SFT 23 +#define IRQ23_MCU_CLR_MASK_SFT BIT(23) +#define IRQ22_MCU_CLR_SFT 22 +#define IRQ22_MCU_CLR_MASK_SFT BIT(22) +#define IRQ21_MCU_CLR_SFT 21 +#define IRQ21_MCU_CLR_MASK_SFT BIT(21) +#define IRQ20_MCU_CLR_SFT 20 +#define IRQ20_MCU_CLR_MASK_SFT BIT(20) +#define IRQ19_MCU_CLR_SFT 19 +#define IRQ19_MCU_CLR_MASK_SFT BIT(19) +#define IRQ18_MCU_CLR_SFT 18 +#define IRQ18_MCU_CLR_MASK_SFT BIT(18) +#define IRQ17_MCU_CLR_SFT 17 +#define IRQ17_MCU_CLR_MASK_SFT BIT(17) +#define IRQ16_MCU_CLR_SFT 16 +#define IRQ16_MCU_CLR_MASK_SFT BIT(16) +#define IRQ15_MCU_CLR_SFT 15 +#define IRQ15_MCU_CLR_MASK_SFT BIT(15) +#define IRQ14_MCU_CLR_SFT 14 +#define IRQ14_MCU_CLR_MASK_SFT BIT(14) +#define IRQ13_MCU_CLR_SFT 13 +#define IRQ13_MCU_CLR_MASK_SFT BIT(13) +#define IRQ12_MCU_CLR_SFT 12 +#define IRQ12_MCU_CLR_MASK_SFT BIT(12) +#define IRQ11_MCU_CLR_SFT 11 +#define IRQ11_MCU_CLR_MASK_SFT BIT(11) +#define IRQ10_MCU_CLR_SFT 10 +#define IRQ10_MCU_CLR_MASK_SFT BIT(10) +#define IRQ9_MCU_CLR_SFT 9 +#define IRQ9_MCU_CLR_MASK_SFT BIT(9) +#define IRQ8_MCU_CLR_SFT 8 +#define IRQ8_MCU_CLR_MASK_SFT BIT(8) +#define IRQ7_MCU_CLR_SFT 7 +#define IRQ7_MCU_CLR_MASK_SFT BIT(7) +#define IRQ6_MCU_CLR_SFT 6 +#define IRQ6_MCU_CLR_MASK_SFT BIT(6) +#define IRQ5_MCU_CLR_SFT 5 +#define IRQ5_MCU_CLR_MASK_SFT BIT(5) +#define IRQ4_MCU_CLR_SFT 4 +#define IRQ4_MCU_CLR_MASK_SFT BIT(4) +#define IRQ3_MCU_CLR_SFT 3 +#define IRQ3_MCU_CLR_MASK_SFT BIT(3) +#define IRQ2_MCU_CLR_SFT 2 +#define IRQ2_MCU_CLR_MASK_SFT BIT(2) +#define IRQ1_MCU_CLR_SFT 1 +#define IRQ1_MCU_CLR_MASK_SFT BIT(1) +#define IRQ0_MCU_CLR_SFT 0 +#define IRQ0_MCU_CLR_MASK_SFT BIT(0) + +/* AFE_IRQ_MCU_EN */ +#define IRQ31_MCU_EN_SFT 31 +#define IRQ30_MCU_EN_SFT 30 +#define IRQ29_MCU_EN_SFT 29 +#define IRQ28_MCU_EN_SFT 28 +#define IRQ27_MCU_EN_SFT 27 +#define IRQ26_MCU_EN_SFT 26 +#define IRQ25_MCU_EN_SFT 25 +#define IRQ24_MCU_EN_SFT 24 +#define IRQ23_MCU_EN_SFT 23 +#define IRQ22_MCU_EN_SFT 22 +#define IRQ21_MCU_EN_SFT 21 +#define IRQ20_MCU_EN_SFT 20 +#define IRQ19_MCU_EN_SFT 19 +#define IRQ18_MCU_EN_SFT 18 +#define IRQ17_MCU_EN_SFT 17 +#define IRQ16_MCU_EN_SFT 16 +#define IRQ15_MCU_EN_SFT 15 +#define IRQ14_MCU_EN_SFT 14 +#define IRQ13_MCU_EN_SFT 13 +#define IRQ12_MCU_EN_SFT 12 +#define IRQ11_MCU_EN_SFT 11 +#define IRQ10_MCU_EN_SFT 10 +#define IRQ9_MCU_EN_SFT 9 +#define IRQ8_MCU_EN_SFT 8 +#define IRQ7_MCU_EN_SFT 7 +#define IRQ6_MCU_EN_SFT 6 +#define IRQ5_MCU_EN_SFT 5 +#define IRQ4_MCU_EN_SFT 4 +#define IRQ3_MCU_EN_SFT 3 +#define IRQ2_MCU_EN_SFT 2 +#define IRQ1_MCU_EN_SFT 1 +#define IRQ0_MCU_EN_SFT 0 + +/* AFE_IRQ_MCU_SCP_EN */ +#define IRQ31_MCU_SCP_EN_SFT 31 +#define IRQ30_MCU_SCP_EN_SFT 30 +#define IRQ29_MCU_SCP_EN_SFT 29 +#define IRQ28_MCU_SCP_EN_SFT 28 +#define IRQ27_MCU_SCP_EN_SFT 27 +#define IRQ26_MCU_SCP_EN_SFT 26 +#define IRQ25_MCU_SCP_EN_SFT 25 +#define IRQ24_MCU_SCP_EN_SFT 24 +#define IRQ23_MCU_SCP_EN_SFT 23 +#define IRQ22_MCU_SCP_EN_SFT 22 +#define IRQ21_MCU_SCP_EN_SFT 21 +#define IRQ20_MCU_SCP_EN_SFT 20 +#define IRQ19_MCU_SCP_EN_SFT 19 +#define IRQ18_MCU_SCP_EN_SFT 18 +#define IRQ17_MCU_SCP_EN_SFT 17 +#define IRQ16_MCU_SCP_EN_SFT 16 +#define IRQ15_MCU_SCP_EN_SFT 15 +#define IRQ14_MCU_SCP_EN_SFT 14 +#define IRQ13_MCU_SCP_EN_SFT 13 +#define IRQ12_MCU_SCP_EN_SFT 12 +#define IRQ11_MCU_SCP_EN_SFT 11 +#define IRQ10_MCU_SCP_EN_SFT 10 +#define IRQ9_MCU_SCP_EN_SFT 9 +#define IRQ8_MCU_SCP_EN_SFT 8 +#define IRQ7_MCU_SCP_EN_SFT 7 +#define IRQ6_MCU_SCP_EN_SFT 6 +#define IRQ5_MCU_SCP_EN_SFT 5 +#define IRQ4_MCU_SCP_EN_SFT 4 +#define IRQ3_MCU_SCP_EN_SFT 3 +#define IRQ2_MCU_SCP_EN_SFT 2 +#define IRQ1_MCU_SCP_EN_SFT 1 +#define IRQ0_MCU_SCP_EN_SFT 0 + +/* AFE_IRQ_MCU_DSP_EN */ +#define IRQ31_MCU_DSP_EN_SFT 31 +#define IRQ30_MCU_DSP_EN_SFT 30 +#define IRQ29_MCU_DSP_EN_SFT 29 +#define IRQ28_MCU_DSP_EN_SFT 28 +#define IRQ27_MCU_DSP_EN_SFT 27 +#define IRQ26_MCU_DSP_EN_SFT 26 +#define IRQ25_MCU_DSP_EN_SFT 25 +#define IRQ24_MCU_DSP_EN_SFT 24 +#define IRQ23_MCU_DSP_EN_SFT 23 +#define IRQ22_MCU_DSP_EN_SFT 22 +#define IRQ21_MCU_DSP_EN_SFT 21 +#define IRQ20_MCU_DSP_EN_SFT 20 +#define IRQ19_MCU_DSP_EN_SFT 19 +#define IRQ18_MCU_DSP_EN_SFT 18 +#define IRQ17_MCU_DSP_EN_SFT 17 +#define IRQ16_MCU_DSP_EN_SFT 16 +#define IRQ15_MCU_DSP_EN_SFT 15 +#define IRQ14_MCU_DSP_EN_SFT 14 +#define IRQ13_MCU_DSP_EN_SFT 13 +#define IRQ12_MCU_DSP_EN_SFT 12 +#define IRQ11_MCU_DSP_EN_SFT 11 +#define IRQ10_MCU_DSP_EN_SFT 10 +#define IRQ9_MCU_DSP_EN_SFT 9 +#define IRQ8_MCU_DSP_EN_SFT 8 +#define IRQ7_MCU_DSP_EN_SFT 7 +#define IRQ6_MCU_DSP_EN_SFT 6 +#define IRQ5_MCU_DSP_EN_SFT 5 +#define IRQ4_MCU_DSP_EN_SFT 4 +#define IRQ3_MCU_DSP_EN_SFT 3 +#define IRQ2_MCU_DSP_EN_SFT 2 +#define IRQ1_MCU_DSP_EN_SFT 1 +#define IRQ0_MCU_DSP_EN_SFT 0 + +/* AFE_AUD_PAD_TOP */ +#define AUD_PAD_TOP_MON_SFT 15 +#define AUD_PAD_TOP_MON_MASK_SFT GENMASK(31, 15) +#define AUD_PAD_TOP_FIFO_RSP_SFT 4 +#define AUD_PAD_TOP_FIFO_RSP_MASK_SFT GENMASK(7, 4) +#define RG_RX_PROTOCOL2_SFT 3 +#define RG_RX_PROTOCOL2_MASK_SFT BIT(3) +#define RESERVDED_01_SFT 1 +#define RESERVDED_01_MASK_SFT GENMASK(2, 1) +#define RG_RX_FIFO_ON_SFT 0 +#define RG_RX_FIFO_ON_MASK_SFT BIT(0) + +/* AFE_ADDA_MTKAIF_SYNCWORD_CFG */ +#define RG_ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE_SFT 23 +#define RG_ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE_MASK_SFT BIT(23) + +/* AFE_ADDA_MTKAIF_RX_CFG0 */ +#define MTKAIF_RXIF_VOICE_MODE_SFT 20 +#define MTKAIF_RXIF_VOICE_MODE_MASK_SFT GENMASK(23, 20) +#define MTKAIF_RXIF_DETECT_ON_SFT 16 +#define MTKAIF_RXIF_DETECT_ON_MASK_SFT BIT(16) +#define MTKAIF_RXIF_DATA_BIT_SFT 8 +#define MTKAIF_RXIF_DATA_BIT_MASK_SFT GENMASK(10, 8) +#define MTKAIF_RXIF_FIFO_RSP_SFT 4 +#define MTKAIF_RXIF_FIFO_RSP_MASK_SFT GENMASK(6, 4) +#define MTKAIF_RXIF_DATA_MODE_SFT 0 +#define MTKAIF_RXIF_DATA_MODE_MASK_SFT BIT(0) + +/* GENERAL_ASRC_MODE */ +#define GENERAL2_ASRCOUT_MODE_SFT 12 +#define GENERAL2_ASRCOUT_MODE_MASK 0xf +#define GENERAL2_ASRCOUT_MODE_MASK_SFT GENMASK(15, 12) +#define GENERAL2_ASRCIN_MODE_SFT 8 +#define GENERAL2_ASRCIN_MODE_MASK 0xf +#define GENERAL2_ASRCIN_MODE_MASK_SFT GENMASK(11, 8) +#define GENERAL1_ASRCOUT_MODE_SFT 4 +#define GENERAL1_ASRCOUT_MODE_MASK 0xf +#define GENERAL1_ASRCOUT_MODE_MASK_SFT GENMASK(7, 4) +#define GENERAL1_ASRCIN_MODE_SFT 0 +#define GENERAL1_ASRCIN_MODE_MASK 0xf +#define GENERAL1_ASRCIN_MODE_MASK_SFT GENMASK(3, 0) + +/* GENERAL_ASRC_EN_ON */ +#define GENERAL2_ASRC_EN_ON_SFT 1 +#define GENERAL2_ASRC_EN_ON_MASK_SFT BIT(1) +#define GENERAL1_ASRC_EN_ON_SFT 0 +#define GENERAL1_ASRC_EN_ON_MASK_SFT BIT(0) + +/* AFE_GENERAL1_ASRC_2CH_CON0 */ +#define G_SRC_CHSET_STR_CLR_SFT 4 +#define G_SRC_CHSET_STR_CLR_MASK_SFT BIT(4) +#define G_SRC_CHSET_ON_SFT 2 +#define G_SRC_CHSET_ON_MASK_SFT BIT(2) +#define G_SRC_COEFF_SRAM_CTRL_SFT 1 +#define G_SRC_COEFF_SRAM_CTRL_MASK_SFT BIT(1) +#define G_SRC_ASM_ON_SFT 0 +#define G_SRC_ASM_ON_MASK_SFT BIT(0) + +/* AFE_GENERAL1_ASRC_2CH_CON3 */ +#define G_SRC_ASM_FREQ_4_SFT 0 +#define G_SRC_ASM_FREQ_4_MASK_SFT GENMASK(23, 0) + +/* AFE_GENERAL1_ASRC_2CH_CON4 */ +#define G_SRC_ASM_FREQ_5_SFT 0 +#define G_SRC_ASM_FREQ_5_MASK_SFT GENMASK(23, 0) + +/* AFE_GENERAL1_ASRC_2CH_CON13 */ +#define G_SRC_COEFF_SRAM_ADR_SFT 0 +#define G_SRC_COEFF_SRAM_ADR_MASK_SFT GENMASK(5, 0) + +/* AFE_GENERAL1_ASRC_2CH_CON2 */ +#define G_SRC_CHSET_O16BIT_SFT 19 +#define G_SRC_CHSET_O16BIT_MASK_SFT BIT(19) +#define G_SRC_CHSET_CLR_IIR_HISTORY_SFT 17 +#define G_SRC_CHSET_CLR_IIR_HISTORY_MASK_SFT BIT(17) +#define G_SRC_CHSET_IS_MONO_SFT 16 +#define G_SRC_CHSET_IS_MONO_MASK_SFT BIT(16) +#define G_SRC_CHSET_IIR_EN_SFT 11 +#define G_SRC_CHSET_IIR_EN_MASK_SFT BIT(11) +#define G_SRC_CHSET_IIR_STAGE_SFT 8 +#define G_SRC_CHSET_IIR_STAGE_MASK_SFT GENMASK(10, 8) +#define G_SRC_CHSET_STR_CLR_RU_SFT 5 +#define G_SRC_CHSET_STR_CLR_RU_MASK_SFT BIT(5) +#define G_SRC_CHSET_ON_SFT 2 +#define G_SRC_CHSET_ON_MASK_SFT BIT(2) +#define G_SRC_COEFF_SRAM_CTRL_SFT 1 +#define G_SRC_COEFF_SRAM_CTRL_MASK_SFT BIT(1) +#define G_SRC_ASM_ON_SFT 0 +#define G_SRC_ASM_ON_MASK_SFT BIT(0) + +/* AFE_ADDA_DL_SDM_DITHER_CON */ +#define AFE_DL_SDM_DITHER_64TAP_EN_SFT 20 +#define AFE_DL_SDM_DITHER_64TAP_EN_MASK_SFT BIT(20) +#define AFE_DL_SDM_DITHER_EN_SFT 16 +#define AFE_DL_SDM_DITHER_EN_MASK_SFT BIT(16) +#define AFE_DL_SDM_DITHER_GAIN_SFT 0 +#define AFE_DL_SDM_DITHER_GAIN_MASK_SFT GENMASK(7, 0) + +/* AFE_ADDA_DL_SDM_AUTO_RESET_CON */ +#define SDM_AUTO_RESET_TEST_ON_SFT 31 +#define SDM_AUTO_RESET_TEST_ON_MASK_SFT BIT(31) +#define AFE_DL_USE_NEW_2ND_SDM_SFT 28 +#define AFE_DL_USE_NEW_2ND_SDM_MASK_SFT BIT(28) +#define SDM_AUTO_RESET_COUNT_TH_SFT 0 +#define SDM_AUTO_RESET_COUNT_TH_MASK_SFT GENMASK(23, 0) + +/* AFE_ASRC_2CH_CON0 */ +#define CON0_CHSET_STR_CLR_SFT 4 +#define CON0_CHSET_STR_CLR_MASK_SFT BIT(4) +#define CON0_ASM_ON_SFT 0 +#define CON0_ASM_ON_MASK_SFT BIT(0) + +/* AFE_ASRC_2CH_CON5 */ +#define CALI_EN_SFT 0 +#define CALI_EN_MASK_SFT BIT(0) + +/* FPGA_CFG4 */ +#define IRQ_COUNTER_SFT 3 +#define IRQ_COUNTER_MASK_SFT GENMASK(31, 3) +#define IRQ_CLK_COUNTER_CLEAN_SFT 2 +#define IRQ_CLK_COUNTER_CLEAN_MASK_SFT BIT(2) +#define IRQ_CLK_COUNTER_PAUSE_SFT 1 +#define IRQ_CLK_COUNTER_PAUSE_MASK_SFT BIT(1) +#define IRQ_CLK_COUNTER_ON_SFT 0 +#define IRQ_CLK_COUNTER_ON_MASK_SFT BIT(0) + +/* FPGA_CFG5 */ +#define WR_MSTR_ON_SFT 16 +#define WR_MSTR_ON_MASK_SFT GENMASK(28, 16) +#define WR_AG_SEL_SFT 0 +#define WR_AG_SEL_MASK_SFT GENMASK(12, 0) + +/* FPGA_CFG6 */ +#define WR_MSTR_REQ_REAL_SFT 16 +#define WR_MSTR_REQ_REAL_MASK_SFT GENMASK(28, 16) +#define WR_MSTR_REQ_IN_SFT 0 +#define WR_MSTR_REQ_IN_MASK_SFT GENMASK(12, 0) + +/* FPGA_CFG7 */ +#define MEM1_WDATA_MON0_SFT 0 +#define MEM1_WDATA_MON0_MASK_SFT GENMASK(31, 0) + +/* FPGA_CFG8 */ +#define MEM1_WDATA_MON1_SFT 0 +#define MEM1_WDATA_MON1_MASK_SFT GENMASK(31, 0) + +/* FPGA_CFG9 */ +#define MEM_WE_SFT 31 +#define MEM_WE_MASK_SFT BIT(31) +#define AFE_HREADY_SFT 30 +#define AFE_HREADY_MASK_SFT BIT(30) +#define MEM_WR_REQ_SFT 29 +#define MEM_WR_REQ_MASK_SFT BIT(29) +#define WR_AG_REG_MON_SFT 16 +#define WR_AG_REG_MON_MASK_SFT GENMASK(28, 16) +#define HCLK_CK_SFT 15 +#define HCLK_CK_MASK_SFT BIT(15) +#define MEM_RD_REQ_SFT 14 +#define MEM_RD_REQ_MASK_SFT BIT(14) +#define RD_AG_REQ_MON_SFT 0 +#define RD_AG_REQ_MON_MASK_SFT GENMASK(13, 0) + +/* FPGA_CFG10 */ +#define MEM_BYTE_0_SFT 0 +#define MEM_BYTE_0_MASK_SFT GENMASK(31, 0) + +/* FPGA_CFG11 */ +#define MEM_BYTE_1_SFT 0 +#define MEM_BYTE_1_MASK_SFT GENMASK(31, 0) + +/* FPGA_CFG12 */ +#define RDATA_CNT_SFT 30 +#define RDATA_CNT_MASK_SFT GENMASK(31, 30) +#define MS2_HREADY_SFT 29 +#define MS2_HREADY_MASK_SFT BIT(29) +#define MS1_HREADY_SFT 28 +#define MS1_HREADY_MASK_SFT BIT(28) +#define AG_SEL_SFT 0 +#define AG_SEL_MASK_SFT GENMASK(25, 0) + +/* FPGA_CFG13 */ +#define AFE_ST_SFT 27 +#define AFE_ST_MASK_SFT GENMASK(31, 27) +#define AG_IN_SERVICE_SFT 0 +#define AG_IN_SERVICE_MASK_SFT GENMASK(25, 0) + +/* ETDM_IN1_CON0 */ +#define ETDM_IN1_CON0_REG_ETDM_IN_EN_SFT 0 +#define ETDM_IN1_CON0_REG_ETDM_IN_EN_MASK_SFT BIT(0) +#define ETDM_IN1_CON0_REG_SYNC_MODE_SFT 1 +#define ETDM_IN1_CON0_REG_SYNC_MODE_MASK_SFT BIT(1) +#define ETDM_IN1_CON0_REG_LSB_FIRST_SFT 3 +#define ETDM_IN1_CON0_REG_LSB_FIRST_MASK_SFT BIT(3) +#define ETDM_IN1_CON0_REG_SOFT_RST_SFT 4 +#define ETDM_IN1_CON0_REG_SOFT_RST_MASK_SFT BIT(4) +#define ETDM_IN1_CON0_REG_SLAVE_MODE_SFT 5 +#define ETDM_IN1_CON0_REG_SLAVE_MODE_MASK_SFT BIT(5) +#define ETDM_IN1_CON0_REG_FMT_SFT 6 +#define ETDM_IN1_CON0_REG_FMT_MASK_SFT GENMASK(8, 6) +#define ETDM_IN1_CON0_REG_LRCK_EDGE_SEL_SFT 10 +#define ETDM_IN1_CON0_REG_LRCK_EDGE_SEL_MASK_SFT BIT(10) +#define ETDM_IN1_CON0_REG_BIT_LENGTH_SFT 11 +#define ETDM_IN1_CON0_REG_BIT_LENGTH_MASK_SFT GENMASK(15, 11) +#define ETDM_IN1_CON0_REG_WORD_LENGTH_SFT 16 +#define ETDM_IN1_CON0_REG_WORD_LENGTH_MASK_SFT GENMASK(20, 16) +#define ETDM_IN1_CON0_REG_CH_NUM_SFT 23 +#define ETDM_IN1_CON0_REG_CH_NUM_MASK_SFT GENMASK(27, 23) +#define ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT 28 +#define ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_MASK_SFT GENMASK(31, 28) +#define ETDM_IN1_CON0_REG_VALID_TOGETHER_SFT 31 +#define ETDM_IN1_CON0_REG_VALID_TOGETHER_MASK_SFT BIT(31) +#define ETDM_IN_CON0_CTRL_MASK 0x1f9ff9e2 + +/* ETDM_IN1_CON1 */ +#define ETDM_IN1_CON1_REG_INITIAL_COUNT_SFT 0 +#define ETDM_IN1_CON1_REG_INITIAL_COUNT_MASK_SFT GENMASK(4, 0) +#define ETDM_IN1_CON1_REG_INITIAL_POINT_SFT 5 +#define ETDM_IN1_CON1_REG_INITIAL_POINT_MASK_SFT GENMASK(9, 5) +#define ETDM_IN1_CON1_REG_LRCK_AUTO_OFF_SFT 10 +#define ETDM_IN1_CON1_REG_LRCK_AUTO_OFF_MASK_SFT BIT(10) +#define ETDM_IN1_CON1_REG_BCK_AUTO_OFF_SFT 11 +#define ETDM_IN1_CON1_REG_BCK_AUTO_OFF_MASK_SFT BIT(11) +#define ETDM_IN1_CON1_REG_INITIAL_LRCK_SFT 13 +#define ETDM_IN1_CON1_REG_INITIAL_LRCK_MASK_SFT BIT(13) +#define ETDM_IN1_CON1_REG_LRCK_RESET_SFT 15 +#define ETDM_IN1_CON1_REG_LRCK_RESET_MASK_SFT BIT(15) +#define ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT 16 +#define ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_MASK_SFT BIT(16) +#define ETDM_IN1_CON1_REG_OUTPUT_CR_EN_SFT 18 +#define ETDM_IN1_CON1_REG_OUTPUT_CR_EN_MASK_SFT BIT(18) +#define ETDM_IN1_CON1_REG_LR_ALIGN_SFT 19 +#define ETDM_IN1_CON1_REG_LR_ALIGN_MASK_SFT BIT(19) +#define ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT 20 +#define ETDM_IN1_CON1_REG_LRCK_WIDTH_MASK_SFT GENMASK(29, 20) +#define ETDM_IN1_CON1_REG_DIRECT_INPUT_MASTER_BCK_SFT 30 +#define ETDM_IN1_CON1_REG_DIRECT_INPUT_MASTER_BCK_MASK_SFT BIT(30) +#define ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT 31 +#define ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_MASK_SFT BIT(31) +#define ETDM_IN_CON1_CTRL_MASK 0xbff10000 + +/* ETDM_IN1_CON2 */ +#define ETDM_IN1_CON2_REG_UPDATE_POINT_SFT 0 +#define ETDM_IN1_CON2_REG_UPDATE_POINT_MASK_SFT GENMASK(4, 0) +#define ETDM_IN1_CON2_REG_UPDATE_GAP_SFT 5 +#define ETDM_IN1_CON2_REG_UPDATE_GAP_MASK_SFT GENMASK(9, 5) +#define ETDM_IN1_CON2_REG_CLOCK_SOURCE_SEL_SFT 10 +#define ETDM_IN1_CON2_REG_CLOCK_SOURCE_SEL_MASK_SFT GENMASK(12, 10) +#define ETDM_IN1_CON2_REG_AGENT_USE_ETDM_BCK_SFT 13 +#define ETDM_IN1_CON2_REG_AGENT_USE_ETDM_BCK_MASK_SFT BIT(13) +#define ETDM_IN1_CON2_REG_CK_EN_SEL_AUTO_SFT 14 +#define ETDM_IN1_CON2_REG_CK_EN_SEL_AUTO_MASK_SFT BIT(14) +#define ETDM_IN1_CON2_REG_MULTI_IP_ONE_DATA_CH_NUM_SFT 15 +#define ETDM_IN1_CON2_REG_MULTI_IP_ONE_DATA_CH_NUM_MASK_SFT GENMASK(19, 15) +#define ETDM_IN1_CON2_REG_MASK_AUTO_SFT 20 +#define ETDM_IN1_CON2_REG_MASK_AUTO_MASK_SFT BIT(20) +#define ETDM_IN1_CON2_REG_MASK_NUM_SFT 21 +#define ETDM_IN1_CON2_REG_MASK_NUM_MASK_SFT GENMASK(25, 21) +#define ETDM_IN1_CON2_REG_UPDATE_POINT_AUTO_SFT 26 +#define ETDM_IN1_CON2_REG_UPDATE_POINT_AUTO_MASK_SFT BIT(26) +#define ETDM_IN1_CON2_REG_SDATA_DELAY_0P5T_EN_SFT 27 +#define ETDM_IN1_CON2_REG_SDATA_DELAY_0P5T_EN_MASK_SFT BIT(27) +#define ETDM_IN1_CON2_REG_SDATA_DELAY_BCK_INV_SFT 28 +#define ETDM_IN1_CON2_REG_SDATA_DELAY_BCK_INV_MASK_SFT BIT(28) +#define ETDM_IN1_CON2_REG_LRCK_DELAY_0P5T_EN_SFT 29 +#define ETDM_IN1_CON2_REG_LRCK_DELAY_0P5T_EN_MASK_SFT BIT(29) +#define ETDM_IN1_CON2_REG_LRCK_DELAY_BCK_INV_SFT 30 +#define ETDM_IN1_CON2_REG_LRCK_DELAY_BCK_INV_MASK_SFT BIT(30) +#define ETDM_IN1_CON2_REG_MULTI_IP_MODE_SFT 31 +#define ETDM_IN1_CON2_REG_MULTI_IP_MODE_MASK_SFT BIT(31) +#define ETDM_IN_CON2_CTRL_MASK 0x800f8000 +#define ETDM_IN_CON2_MULTI_IP_CH(x) (((x) - 1) << 15) +#define ETDM_IN_CON2_MULTI_IP_2CH_MODE BIT(31) + +/* ETDM_IN1_CON3 */ +#define ETDM_IN1_CON3_REG_DISABLE_OUT_0_SFT 0 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_0_MASK_SFT BIT(0) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_1_SFT 1 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_1_MASK_SFT BIT(1) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_2_SFT 2 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_2_MASK_SFT BIT(2) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_3_SFT 3 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_3_MASK_SFT BIT(3) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_4_SFT 4 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_4_MASK_SFT BIT(4) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_5_SFT 5 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_5_MASK_SFT BIT(5) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_6_SFT 6 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_6_MASK_SFT BIT(6) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_7_SFT 7 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_7_MASK_SFT BIT(7) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_8_SFT 8 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_8_MASK_SFT BIT(8) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_9_SFT 9 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_9_MASK_SFT BIT(9) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_10_SFT 10 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_10_MASK_SFT BIT(10) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_11_SFT 11 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_11_MASK_SFT BIT(11) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_12_SFT 12 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_12_MASK_SFT BIT(12) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_13_SFT 13 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_13_MASK_SFT BIT(13) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_14_SFT 14 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_14_MASK_SFT BIT(14) +#define ETDM_IN1_CON3_REG_DISABLE_OUT_15_SFT 15 +#define ETDM_IN1_CON3_REG_DISABLE_OUT_15_MASK_SFT BIT(15) +#define ETDM_IN1_CON3_REG_RJ_DATA_RIGHT_ALIGN_SFT 16 +#define ETDM_IN1_CON3_REG_RJ_DATA_RIGHT_ALIGN_MASK_SFT BIT(16) +#define ETDM_IN1_CON3_REG_MONITOR_SEL_SFT 17 +#define ETDM_IN1_CON3_REG_MONITOR_SEL_MASK_SFT GENMASK(18, 17) +#define ETDM_IN1_CON3_REG_CNT_UPPER_LIMIT_SFT 19 +#define ETDM_IN1_CON3_REG_CNT_UPPER_LIMIT_MASK_SFT GENMASK(24, 19) +#define ETDM_IN1_CON3_REG_COMPACT_SAMPLE_END_DIS_SFT 25 +#define ETDM_IN1_CON3_REG_COMPACT_SAMPLE_END_DIS_MASK_SFT BIT(25) +#define ETDM_IN1_CON3_REG_FS_TIMING_SEL_SFT 26 +#define ETDM_IN1_CON3_REG_FS_TIMING_SEL_MASK_SFT GENMASK(30, 26) +#define ETDM_IN1_CON3_REG_SAMPLE_END_MODE_SFT 31 +#define ETDM_IN1_CON3_REG_SAMPLE_END_MODE_MASK_SFT BIT(31) +#define ETDM_IN_CON3_CTRL_MASK (0x7c000000) +#define ETDM_IN_CON3_FS(x) (((x) & 0x1f) << 26) + +/* ETDM_IN1_CON4 */ +#define ETDM_IN1_CON4_REG_DSD_MODE_SFT 0 +#define ETDM_IN1_CON4_REG_DSD_MODE_MASK_SFT GENMASK(5, 0) +#define ETDM_IN1_CON4_REG_DSD_REPACK_AUTO_MODE_SFT 8 +#define ETDM_IN1_CON4_REG_DSD_REPACK_AUTO_MODE_MASK_SFT BIT(8) +#define ETDM_IN1_CON4_REG_REPACK_WORD_LENGTH_SFT 9 +#define ETDM_IN1_CON4_REG_REPACK_WORD_LENGTH_MASK_SFT GENMASK(10, 9) +#define ETDM_IN1_CON4_REG_ASYNC_RESET_SFT 11 +#define ETDM_IN1_CON4_REG_ASYNC_RESET_MASK_SFT BIT(11) +#define ETDM_IN1_CON4_REG_DSD_CHNUM_SFT 12 +#define ETDM_IN1_CON4_REG_DSD_CHNUM_MASK_SFT GENMASK(15, 12) +#define ETDM_IN1_CON4_REG_SLAVE_BCK_INV_SFT 16 +#define ETDM_IN1_CON4_REG_SLAVE_BCK_INV_MASK_SFT BIT(16) +#define ETDM_IN1_CON4_REG_SLAVE_LRCK_INV_SFT 17 +#define ETDM_IN1_CON4_REG_SLAVE_LRCK_INV_MASK_SFT BIT(17) +#define ETDM_IN1_CON4_REG_MASTER_BCK_INV_SFT 18 +#define ETDM_IN1_CON4_REG_MASTER_BCK_INV_MASK_SFT BIT(18) +#define ETDM_IN1_CON4_REG_MASTER_LRCK_INV_SFT 19 +#define ETDM_IN1_CON4_REG_MASTER_LRCK_INV_MASK_SFT BIT(19) +#define ETDM_IN1_CON4_REG_RELATCH_1X_EN_SEL_SFT 20 +#define ETDM_IN1_CON4_REG_RELATCH_1X_EN_SEL_MASK_SFT GENMASK(24, 20) +#define ETDM_IN1_CON4_REG_SAMPLE_END_POINT_SFT 25 +#define ETDM_IN1_CON4_REG_SAMPLE_END_POINT_MASK_SFT GENMASK(29, 25) +#define ETDM_IN1_CON4_REG_WAIT_LAST_SAMPLE_SFT 30 +#define ETDM_IN1_CON4_REG_WAIT_LAST_SAMPLE_MASK_SFT BIT(30) +#define ETDM_IN1_CON4_REG_MASTER_BCK_FORCE_ON_SFT 31 +#define ETDM_IN1_CON4_REG_MASTER_BCK_FORCE_ON_MASK_SFT BIT(31) +#define ETDM_IN_CON4_CTRL_MASK 0x1ff0000 +#define ETDM_IN_CON4_FS(x) (((x) & 0x1f) << 20) +#define ETDM_IN_CON4_CON0_MASTER_LRCK_INV BIT(19) +#define ETDM_IN_CON4_CON0_MASTER_BCK_INV BIT(18) +#define ETDM_IN_CON4_CON0_SLAVE_LRCK_INV BIT(17) +#define ETDM_IN_CON4_CON0_SLAVE_BCK_INV BIT(16) + +/* ETDM_IN1_CON5 */ +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_0_SFT 0 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_0_MASK_SFT BIT(0) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_1_SFT 1 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_1_MASK_SFT BIT(1) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_2_SFT 2 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_2_MASK_SFT BIT(2) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_3_SFT 3 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_3_MASK_SFT BIT(3) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_4_SFT 4 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_4_MASK_SFT BIT(4) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_5_SFT 5 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_5_MASK_SFT BIT(5) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_6_SFT 6 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_6_MASK_SFT BIT(6) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_7_SFT 7 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_7_MASK_SFT BIT(7) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_8_SFT 8 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_8_MASK_SFT BIT(8) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_9_SFT 9 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_9_MASK_SFT BIT(9) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_10_SFT 10 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_10_MASK_SFT BIT(10) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_11_SFT 11 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_11_MASK_SFT BIT(11) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_12_SFT 12 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_12_MASK_SFT BIT(12) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_13_SFT 13 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_13_MASK_SFT BIT(13) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_14_SFT 14 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_14_MASK_SFT BIT(14) +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_15_SFT 15 +#define ETDM_IN1_CON5_REG_ODD_FLAG_EN_15_MASK_SFT BIT(15) +#define ETDM_IN1_CON5_REG_LR_SWAP_0_SFT 16 +#define ETDM_IN1_CON5_REG_LR_SWAP_0_MASK_SFT BIT(16) +#define ETDM_IN1_CON5_REG_LR_SWAP_1_SFT 17 +#define ETDM_IN1_CON5_REG_LR_SWAP_1_MASK_SFT BIT(17) +#define ETDM_IN1_CON5_REG_LR_SWAP_2_SFT 18 +#define ETDM_IN1_CON5_REG_LR_SWAP_2_MASK_SFT BIT(18) +#define ETDM_IN1_CON5_REG_LR_SWAP_3_SFT 19 +#define ETDM_IN1_CON5_REG_LR_SWAP_3_MASK_SFT BIT(19) +#define ETDM_IN1_CON5_REG_LR_SWAP_4_SFT 20 +#define ETDM_IN1_CON5_REG_LR_SWAP_4_MASK_SFT BIT(20) +#define ETDM_IN1_CON5_REG_LR_SWAP_5_SFT 21 +#define ETDM_IN1_CON5_REG_LR_SWAP_5_MASK_SFT BIT(21) +#define ETDM_IN1_CON5_REG_LR_SWAP_6_SFT 22 +#define ETDM_IN1_CON5_REG_LR_SWAP_6_MASK_SFT BIT(22) +#define ETDM_IN1_CON5_REG_LR_SWAP_7_SFT 23 +#define ETDM_IN1_CON5_REG_LR_SWAP_7_MASK_SFT BIT(23) +#define ETDM_IN1_CON5_REG_LR_SWAP_8_SFT 24 +#define ETDM_IN1_CON5_REG_LR_SWAP_8_MASK_SFT BIT(24) +#define ETDM_IN1_CON5_REG_LR_SWAP_9_SFT 25 +#define ETDM_IN1_CON5_REG_LR_SWAP_9_MASK_SFT BIT(25) +#define ETDM_IN1_CON5_REG_LR_SWAP_10_SFT 26 +#define ETDM_IN1_CON5_REG_LR_SWAP_10_MASK_SFT BIT(26) +#define ETDM_IN1_CON5_REG_LR_SWAP_11_SFT 27 +#define ETDM_IN1_CON5_REG_LR_SWAP_11_MASK_SFT BIT(27) +#define ETDM_IN1_CON5_REG_LR_SWAP_12_SFT 28 +#define ETDM_IN1_CON5_REG_LR_SWAP_12_MASK_SFT BIT(28) +#define ETDM_IN1_CON5_REG_LR_SWAP_13_SFT 29 +#define ETDM_IN1_CON5_REG_LR_SWAP_13_MASK_SFT BIT(29) +#define ETDM_IN1_CON5_REG_LR_SWAP_14_SFT 30 +#define ETDM_IN1_CON5_REG_LR_SWAP_14_MASK_SFT BIT(30) +#define ETDM_IN1_CON5_REG_LR_SWAP_15_SFT 31 +#define ETDM_IN1_CON5_REG_LR_SWAP_15_MASK_SFT BIT(31) + +/* ETDM_IN1_CON6 */ +#define ETDM_IN1_CON6_LCH_DATA_REG_SFT 0 +#define ETDM_IN1_CON6_LCH_DATA_REG_MASK_SFT GENMASK(31, 0) + +/* ETDM_IN1_CON7 */ +#define ETDM_IN1_CON7_RCH_DATA_REG_SFT 0 +#define ETDM_IN1_CON7_RCH_DATA_REG_MASK_SFT GENMASK(31, 0) + +/* ETDM_IN1_CON8 */ +#define ETDM_IN1_CON8_REG_AFIFO_THRESHOLD_SFT 29 +#define ETDM_IN1_CON8_REG_AFIFO_THRESHOLD_MASK_SFT GENMASK(30, 29) +#define ETDM_IN1_CON8_REG_CK_EN_SEL_MANUAL_SFT 16 +#define ETDM_IN1_CON8_REG_CK_EN_SEL_MANUAL_MASK_SFT GENMASK(25, 16) +#define ETDM_IN1_CON8_REG_AFIFO_SW_RESET_SFT 15 +#define ETDM_IN1_CON8_REG_AFIFO_SW_RESET_MASK_SFT BIT(15) +#define ETDM_IN1_CON8_REG_AFIFO_RESET_SEL_SFT 14 +#define ETDM_IN1_CON8_REG_AFIFO_RESET_SEL_MASK_SFT BIT(14) +#define ETDM_IN1_CON8_REG_AFIFO_AUTO_RESET_DIS_SFT 9 +#define ETDM_IN1_CON8_REG_AFIFO_AUTO_RESET_DIS_MASK_SFT BIT(9) +#define ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT 8 +#define ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_MASK_SFT BIT(8) +#define ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT 5 +#define ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_MASK_SFT GENMASK(7, 5) +#define ETDM_IN1_CON8_REG_AFIFO_MODE_SFT 0 +#define ETDM_IN1_CON8_REG_AFIFO_MODE_MASK_SFT GENMASK(4, 0) +#define ETDM_IN_CON8_FS(x) (((x) & 0x1f) << 0) +#define ETDM_IN_CON8_CTRL_MASK 0x13f + +#define AUDIO_TOP_CON0 0x0000 +#define AUDIO_TOP_CON1 0x0004 +#define AUDIO_TOP_CON2 0x0008 +#define AUDIO_TOP_CON3 0x000c +#define AFE_DAC_CON0 0x0010 +#define AFE_I2S_CON 0x0018 +#define AFE_CONN0 0x0020 +#define AFE_CONN1 0x0024 +#define AFE_CONN2 0x0028 +#define AFE_CONN3 0x002c +#define AFE_CONN4 0x0030 +#define AFE_I2S_CON1 0x0034 +#define AFE_I2S_CON2 0x0038 +#define AFE_I2S_CON3 0x0040 +#define AFE_CONN5 0x0044 +#define AFE_CONN_24BIT 0x0048 +#define AFE_DL1_CON0 0x004c +#define AFE_DL1_BASE_MSB 0x0050 +#define AFE_DL1_BASE 0x0054 +#define AFE_DL1_CUR_MSB 0x0058 +#define AFE_DL1_CUR 0x005c +#define AFE_DL1_END_MSB 0x0060 +#define AFE_DL1_END 0x0064 +#define AFE_DL2_CON0 0x0068 +#define AFE_DL2_BASE_MSB 0x006c +#define AFE_DL2_BASE 0x0070 +#define AFE_DL2_CUR_MSB 0x0074 +#define AFE_DL2_CUR 0x0078 +#define AFE_DL2_END_MSB 0x007c +#define AFE_DL2_END 0x0080 +#define AFE_DL3_CON0 0x0084 +#define AFE_DL3_BASE_MSB 0x0088 +#define AFE_DL3_BASE 0x008c +#define AFE_DL3_CUR_MSB 0x0090 +#define AFE_DL3_CUR 0x0094 +#define AFE_DL3_END_MSB 0x0098 +#define AFE_DL3_END 0x009c +#define AFE_CONN6 0x00bc +#define AFE_DL4_CON0 0x00cc +#define AFE_DL4_BASE_MSB 0x00d0 +#define AFE_DL4_BASE 0x00d4 +#define AFE_DL4_CUR_MSB 0x00d8 +#define AFE_DL4_CUR 0x00dc +#define AFE_DL4_END_MSB 0x00e0 +#define AFE_DL4_END 0x00e4 +#define AFE_DL12_CON0 0x00e8 +#define AFE_DL12_BASE_MSB 0x00ec +#define AFE_DL12_BASE 0x00f0 +#define AFE_DL12_CUR_MSB 0x00f4 +#define AFE_DL12_CUR 0x00f8 +#define AFE_DL12_END_MSB 0x00fc +#define AFE_DL12_END 0x0100 +#define AFE_ADDA_DL_SRC2_CON0 0x0108 +#define AFE_ADDA_DL_SRC2_CON1 0x010c +#define AFE_ADDA_UL_SRC_CON0 0x0114 +#define AFE_ADDA_UL_SRC_CON1 0x0118 +#define AFE_ADDA_TOP_CON0 0x0120 +#define AFE_ADDA_UL_DL_CON0 0x0124 +#define AFE_ADDA_SRC_DEBUG 0x012c +#define AFE_ADDA_SRC_DEBUG_MON0 0x0130 +#define AFE_ADDA_SRC_DEBUG_MON1 0x0134 +#define AFE_ADDA_UL_SRC_MON0 0x0148 +#define AFE_ADDA_UL_SRC_MON1 0x014c +#define AFE_SECURE_CON0 0x0150 +#define AFE_SRAM_BOUND 0x0154 +#define AFE_SECURE_CON1 0x0158 +#define AFE_SECURE_CONN0 0x015c +#define AFE_VUL_CON0 0x0170 +#define AFE_VUL_BASE_MSB 0x0174 +#define AFE_VUL_BASE 0x0178 +#define AFE_VUL_CUR_MSB 0x017c +#define AFE_VUL_CUR 0x0180 +#define AFE_VUL_END_MSB 0x0184 +#define AFE_VUL_END 0x0188 +#define AFE_SIDETONE_DEBUG 0x01d0 +#define AFE_SIDETONE_MON 0x01d4 +#define AFE_SINEGEN_CON2 0x01dc +#define AFE_SIDETONE_CON0 0x01e0 +#define AFE_SIDETONE_COEFF 0x01e4 +#define AFE_SIDETONE_CON1 0x01e8 +#define AFE_SIDETONE_GAIN 0x01ec +#define AFE_SINEGEN_CON0 0x01f0 +#define AFE_TOP_CON0 0x0200 +#define AFE_VUL2_CON0 0x020c +#define AFE_VUL2_BASE_MSB 0x0210 +#define AFE_VUL2_BASE 0x0214 +#define AFE_VUL2_CUR_MSB 0x0218 +#define AFE_VUL2_CUR 0x021c +#define AFE_VUL2_END_MSB 0x0220 +#define AFE_VUL2_END 0x0224 +#define AFE_VUL3_CON0 0x0228 +#define AFE_VUL3_BASE_MSB 0x022c +#define AFE_VUL3_BASE 0x0230 +#define AFE_VUL3_CUR_MSB 0x0234 +#define AFE_VUL3_CUR 0x0238 +#define AFE_VUL3_END_MSB 0x023c +#define AFE_VUL3_END 0x0240 +#define AFE_BUSY 0x0244 +#define AFE_BUS_CFG 0x0250 +#define AFE_ADDA_PREDIS_CON0 0x0260 +#define AFE_ADDA_PREDIS_CON1 0x0264 +#define AFE_I2S_MON 0x027c +#define AFE_ADDA_IIR_COEF_02_01 0x0290 +#define AFE_ADDA_IIR_COEF_04_03 0x0294 +#define AFE_ADDA_IIR_COEF_06_05 0x0298 +#define AFE_ADDA_IIR_COEF_08_07 0x029c +#define AFE_ADDA_IIR_COEF_10_09 0x02a0 +#define AFE_IRQ_MCU_CON1 0x02e4 +#define AFE_IRQ_MCU_CON2 0x02e8 +#define AFE_DAC_MON 0x02ec +#define AFE_IRQ_MCU_CON3 0x02f0 +#define AFE_IRQ_MCU_CON4 0x02f4 +#define AFE_IRQ_MCU_CNT0 0x0300 +#define AFE_IRQ_MCU_CNT6 0x0304 +#define AFE_IRQ_MCU_CNT8 0x0308 +#define AFE_IRQ_MCU_DSP2_EN 0x030c +#define AFE_IRQ0_MCU_CNT_MON 0x0310 +#define AFE_IRQ6_MCU_CNT_MON 0x0314 +#define AFE_VUL4_CON0 0x0358 +#define AFE_VUL4_BASE_MSB 0x035c +#define AFE_VUL4_BASE 0x0360 +#define AFE_VUL4_CUR_MSB 0x0364 +#define AFE_VUL4_CUR 0x0368 +#define AFE_VUL4_END_MSB 0x036c +#define AFE_VUL4_END 0x0370 +#define AFE_VUL12_CON0 0x0374 +#define AFE_VUL12_BASE_MSB 0x0378 +#define AFE_VUL12_BASE 0x037c +#define AFE_VUL12_CUR_MSB 0x0380 +#define AFE_VUL12_CUR 0x0384 +#define AFE_VUL12_END_MSB 0x0388 +#define AFE_VUL12_END 0x038c +#define AFE_IRQ3_MCU_CNT_MON 0x0398 +#define AFE_IRQ4_MCU_CNT_MON 0x039c +#define AFE_IRQ_MCU_CON0 0x03a0 +#define AFE_IRQ_MCU_STATUS 0x03a4 +#define AFE_IRQ_MCU_CLR 0x03a8 +#define AFE_IRQ_MCU_CNT1 0x03ac +#define AFE_IRQ_MCU_CNT2 0x03b0 +#define AFE_IRQ_MCU_EN 0x03b4 +#define AFE_IRQ_MCU_MON2 0x03b8 +#define AFE_IRQ_MCU_CNT5 0x03bc +#define AFE_IRQ1_MCU_CNT_MON 0x03c0 +#define AFE_IRQ2_MCU_CNT_MON 0x03c4 +#define AFE_IRQ5_MCU_CNT_MON 0x03cc +#define AFE_IRQ_MCU_DSP_EN 0x03d0 +#define AFE_IRQ_MCU_SCP_EN 0x03d4 +#define AFE_IRQ_MCU_CNT7 0x03dc +#define AFE_IRQ7_MCU_CNT_MON 0x03e0 +#define AFE_IRQ_MCU_CNT3 0x03e4 +#define AFE_IRQ_MCU_CNT4 0x03e8 +#define AFE_IRQ_MCU_CNT11 0x03ec +#define AFE_APLL1_TUNER_CFG 0x03f0 +#define AFE_APLL2_TUNER_CFG 0x03f4 +#define AFE_IRQ_MCU_MISS_CLR 0x03f8 +#define AFE_CONN33 0x0408 +#define AFE_IRQ_MCU_CNT12 0x040c +#define AFE_GAIN1_CON0 0x0410 +#define AFE_GAIN1_CON1 0x0414 +#define AFE_GAIN1_CON2 0x0418 +#define AFE_GAIN1_CON3 0x041c +#define AFE_CONN7 0x0420 +#define AFE_GAIN1_CUR 0x0424 +#define AFE_GAIN2_CON0 0x0428 +#define AFE_GAIN2_CON1 0x042c +#define AFE_GAIN2_CON2 0x0430 +#define AFE_GAIN2_CON3 0x0434 +#define AFE_CONN8 0x0438 +#define AFE_GAIN2_CUR 0x043c +#define AFE_CONN9 0x0440 +#define AFE_CONN10 0x0444 +#define AFE_CONN11 0x0448 +#define AFE_CONN12 0x044c +#define AFE_CONN13 0x0450 +#define AFE_CONN14 0x0454 +#define AFE_CONN15 0x0458 +#define AFE_CONN16 0x045c +#define AFE_CONN17 0x0460 +#define AFE_CONN18 0x0464 +#define AFE_CONN19 0x0468 +#define AFE_CONN20 0x046c +#define AFE_CONN21 0x0470 +#define AFE_CONN22 0x0474 +#define AFE_CONN23 0x0478 +#define AFE_CONN24 0x047c +#define AFE_CONN_RS 0x0494 +#define AFE_CONN_DI 0x0498 +#define AFE_CONN25 0x04b0 +#define AFE_CONN26 0x04b4 +#define AFE_CONN27 0x04b8 +#define AFE_CONN28 0x04bc +#define AFE_CONN29 0x04c0 +#define AFE_CONN30 0x04c4 +#define AFE_CONN31 0x04c8 +#define AFE_CONN32 0x04cc +#define AFE_SRAM_DELSEL_CON1 0x04f4 +#define AFE_CONN56 0x0500 +#define AFE_CONN57 0x0504 +#define AFE_CONN58 0x0508 +#define AFE_CONN59 0x050c +#define AFE_CONN56_1 0x0510 +#define AFE_CONN57_1 0x0514 +#define AFE_CONN58_1 0x0518 +#define AFE_CONN59_1 0x051c +#define PCM_INTF_CON1 0x0530 +#define PCM_INTF_CON2 0x0538 +#define PCM2_INTF_CON 0x053c +#define AFE_CM1_CON 0x0550 +#define AFE_CONN34 0x0580 +#define FPGA_CFG0 0x05b0 +#define FPGA_CFG1 0x05b4 +#define FPGA_CFG2 0x05c0 +#define FPGA_CFG3 0x05c4 +#define AUDIO_TOP_DBG_CON 0x05c8 +#define AUDIO_TOP_DBG_MON0 0x05cc +#define AUDIO_TOP_DBG_MON1 0x05d0 +#define AFE_IRQ8_MCU_CNT_MON 0x05e4 +#define AFE_IRQ11_MCU_CNT_MON 0x05e8 +#define AFE_IRQ12_MCU_CNT_MON 0x05ec +#define AFE_IRQ_MCU_CNT9 0x0600 +#define AFE_IRQ_MCU_CNT10 0x0604 +#define AFE_IRQ_MCU_CNT13 0x0608 +#define AFE_IRQ_MCU_CNT14 0x060c +#define AFE_IRQ_MCU_CNT15 0x0610 +#define AFE_IRQ_MCU_CNT16 0x0614 +#define AFE_IRQ_MCU_CNT17 0x0618 +#define AFE_IRQ_MCU_CNT18 0x061c +#define AFE_IRQ_MCU_CNT19 0x0620 +#define AFE_IRQ_MCU_CNT20 0x0624 +#define AFE_IRQ_MCU_CNT21 0x0628 +#define AFE_IRQ_MCU_CNT22 0x062c +#define AFE_IRQ_MCU_CNT23 0x0630 +#define AFE_IRQ_MCU_CNT24 0x0634 +#define AFE_IRQ_MCU_CNT25 0x0638 +#define AFE_IRQ_MCU_CNT26 0x063c +#define AFE_IRQ9_MCU_CNT_MON 0x0660 +#define AFE_IRQ10_MCU_CNT_MON 0x0664 +#define AFE_IRQ13_MCU_CNT_MON 0x0668 +#define AFE_IRQ14_MCU_CNT_MON 0x066c +#define AFE_IRQ15_MCU_CNT_MON 0x0670 +#define AFE_IRQ16_MCU_CNT_MON 0x0674 +#define AFE_IRQ17_MCU_CNT_MON 0x0678 +#define AFE_IRQ18_MCU_CNT_MON 0x067c +#define AFE_IRQ19_MCU_CNT_MON 0x0680 +#define AFE_IRQ20_MCU_CNT_MON 0x0684 +#define AFE_IRQ21_MCU_CNT_MON 0x0688 +#define AFE_IRQ22_MCU_CNT_MON 0x068c +#define AFE_IRQ23_MCU_CNT_MON 0x0690 +#define AFE_IRQ24_MCU_CNT_MON 0x0694 +#define AFE_IRQ25_MCU_CNT_MON 0x0698 +#define AFE_IRQ26_MCU_CNT_MON 0x069c +#define AFE_IRQ31_MCU_CNT_MON 0x06a0 +#define AFE_GENERAL_REG0 0x0800 +#define AFE_GENERAL_REG1 0x0804 +#define AFE_GENERAL_REG2 0x0808 +#define AFE_GENERAL_REG3 0x080c +#define AFE_GENERAL_REG4 0x0810 +#define AFE_GENERAL_REG5 0x0814 +#define AFE_GENERAL_REG6 0x0818 +#define AFE_GENERAL_REG7 0x081c +#define AFE_GENERAL_REG8 0x0820 +#define AFE_GENERAL_REG9 0x0824 +#define AFE_GENERAL_REG10 0x0828 +#define AFE_GENERAL_REG11 0x082c +#define AFE_GENERAL_REG12 0x0830 +#define AFE_GENERAL_REG13 0x0834 +#define AFE_GENERAL_REG14 0x0838 +#define AFE_GENERAL_REG15 0x083c +#define AFE_CBIP_CFG0 0x0840 +#define AFE_CBIP_MON0 0x0844 +#define AFE_CBIP_SLV_MUX_MON0 0x0848 +#define AFE_CBIP_SLV_DECODER_MON0 0x084c +#define AFE_ADDA6_MTKAIF_MON0 0x0854 +#define AFE_ADDA6_MTKAIF_MON1 0x0858 +#define AFE_AWB_CON0 0x085c +#define AFE_AWB_BASE_MSB 0x0860 +#define AFE_AWB_BASE 0x0864 +#define AFE_AWB_CUR_MSB 0x0868 +#define AFE_AWB_CUR 0x086c +#define AFE_AWB_END_MSB 0x0870 +#define AFE_AWB_END 0x0874 +#define AFE_AWB2_CON0 0x0878 +#define AFE_AWB2_BASE_MSB 0x087c +#define AFE_AWB2_BASE 0x0880 +#define AFE_AWB2_CUR_MSB 0x0884 +#define AFE_AWB2_CUR 0x0888 +#define AFE_AWB2_END_MSB 0x088c +#define AFE_AWB2_END 0x0890 +#define AFE_DAI_CON0 0x0894 +#define AFE_DAI_BASE_MSB 0x0898 +#define AFE_DAI_BASE 0x089c +#define AFE_DAI_CUR_MSB 0x08a0 +#define AFE_DAI_CUR 0x08a4 +#define AFE_DAI_END_MSB 0x08a8 +#define AFE_DAI_END 0x08ac +#define AFE_DAI2_CON0 0x08b0 +#define AFE_DAI2_BASE_MSB 0x08b4 +#define AFE_DAI2_BASE 0x08b8 +#define AFE_DAI2_CUR_MSB 0x08bc +#define AFE_DAI2_CUR 0x08c0 +#define AFE_DAI2_END_MSB 0x08c4 +#define AFE_DAI2_END 0x08c8 +#define AFE_MEMIF_CON0 0x08cc +#define AFE_CONN0_1 0x0900 +#define AFE_CONN1_1 0x0904 +#define AFE_CONN2_1 0x0908 +#define AFE_CONN3_1 0x090c +#define AFE_CONN4_1 0x0910 +#define AFE_CONN5_1 0x0914 +#define AFE_CONN6_1 0x0918 +#define AFE_CONN7_1 0x091c +#define AFE_CONN8_1 0x0920 +#define AFE_CONN9_1 0x0924 +#define AFE_CONN10_1 0x0928 +#define AFE_CONN11_1 0x092c +#define AFE_CONN12_1 0x0930 +#define AFE_CONN13_1 0x0934 +#define AFE_CONN14_1 0x0938 +#define AFE_CONN15_1 0x093c +#define AFE_CONN16_1 0x0940 +#define AFE_CONN17_1 0x0944 +#define AFE_CONN18_1 0x0948 +#define AFE_CONN19_1 0x094c +#define AFE_CONN20_1 0x0950 +#define AFE_CONN21_1 0x0954 +#define AFE_CONN22_1 0x0958 +#define AFE_CONN23_1 0x095c +#define AFE_CONN24_1 0x0960 +#define AFE_CONN25_1 0x0964 +#define AFE_CONN26_1 0x0968 +#define AFE_CONN27_1 0x096c +#define AFE_CONN28_1 0x0970 +#define AFE_CONN29_1 0x0974 +#define AFE_CONN30_1 0x0978 +#define AFE_CONN31_1 0x097c +#define AFE_CONN32_1 0x0980 +#define AFE_CONN33_1 0x0984 +#define AFE_CONN34_1 0x0988 +#define AFE_CONN_RS_1 0x098c +#define AFE_CONN_DI_1 0x0990 +#define AFE_CONN_24BIT_1 0x0994 +#define AFE_CONN_REG 0x0998 +#define AFE_CONN35 0x09a0 +#define AFE_CONN36 0x09a4 +#define AFE_CONN37 0x09a8 +#define AFE_CONN38 0x09ac +#define AFE_CONN35_1 0x09b0 +#define AFE_CONN36_1 0x09b4 +#define AFE_CONN37_1 0x09b8 +#define AFE_CONN38_1 0x09bc +#define AFE_CONN39 0x09c0 +#define AFE_CONN40 0x09c4 +#define AFE_CONN41 0x09c8 +#define AFE_CONN42 0x09cc +#define AFE_CONN39_1 0x09e0 +#define AFE_CONN40_1 0x09e4 +#define AFE_CONN41_1 0x09e8 +#define AFE_CONN42_1 0x09ec +#define AFE_I2S_CON4 0x09f8 +#define AFE_CONN60 0x0a64 +#define AFE_CONN61 0x0a68 +#define AFE_CONN62 0x0a6c +#define AFE_CONN63 0x0a70 +#define AFE_CONN64 0x0a74 +#define AFE_CONN65 0x0a78 +#define AFE_CONN66 0x0a7c +#define AFE_ADDA6_TOP_CON0 0x0a80 +#define AFE_ADDA6_UL_SRC_CON0 0x0a84 +#define AFE_ADDA6_UL_SRC_CON1 0x0a88 +#define AFE_ADDA6_SRC_DEBUG 0x0a8c +#define AFE_ADDA6_SRC_DEBUG_MON0 0x0a90 +#define AFE_ADDA6_ULCF_CFG_02_01 0x0aa0 +#define AFE_ADDA6_ULCF_CFG_04_03 0x0aa4 +#define AFE_ADDA6_ULCF_CFG_06_05 0x0aa8 +#define AFE_ADDA6_ULCF_CFG_08_07 0x0aac +#define AFE_ADDA6_ULCF_CFG_10_09 0x0ab0 +#define AFE_ADDA6_ULCF_CFG_12_11 0x0ab4 +#define AFE_ADDA6_ULCF_CFG_14_13 0x0ab8 +#define AFE_ADDA6_ULCF_CFG_16_15 0x0abc +#define AFE_ADDA6_ULCF_CFG_18_17 0x0ac0 +#define AFE_ADDA6_ULCF_CFG_20_19 0x0ac4 +#define AFE_ADDA6_ULCF_CFG_22_21 0x0ac8 +#define AFE_ADDA6_ULCF_CFG_24_23 0x0acc +#define AFE_ADDA6_ULCF_CFG_26_25 0x0ad0 +#define AFE_ADDA6_ULCF_CFG_28_27 0x0ad4 +#define AFE_ADDA6_ULCF_CFG_30_29 0x0ad8 +#define AFE_ADD6A_UL_SRC_MON0 0x0ae4 +#define AFE_ADDA6_UL_SRC_MON1 0x0ae8 +#define AFE_CONN43 0x0af8 +#define AFE_CONN43_1 0x0afc +#define AFE_MOD_DAI_CON0 0x0b00 +#define AFE_MOD_DAI_BASE_MSB 0x0b04 +#define AFE_MOD_DAI_BASE 0x0b08 +#define AFE_MOD_DAI_CUR_MSB 0x0b0c +#define AFE_MOD_DAI_CUR 0x0b10 +#define AFE_MOD_DAI_END_MSB 0x0b14 +#define AFE_MOD_DAI_END 0x0b18 +#define AFE_AWB_RCH_MON 0x0b70 +#define AFE_AWB_LCH_MON 0x0b74 +#define AFE_VUL_RCH_MON 0x0b78 +#define AFE_VUL_LCH_MON 0x0b7c +#define AFE_VUL12_RCH_MON 0x0b80 +#define AFE_VUL12_LCH_MON 0x0b84 +#define AFE_VUL2_RCH_MON 0x0b88 +#define AFE_VUL2_LCH_MON 0x0b8c +#define AFE_DAI_DATA_MON 0x0b90 +#define AFE_MOD_DAI_DATA_MON 0x0b94 +#define AFE_DAI2_DATA_MON 0x0b98 +#define AFE_AWB2_RCH_MON 0x0b9c +#define AFE_AWB2_LCH_MON 0x0ba0 +#define AFE_VUL3_RCH_MON 0x0ba4 +#define AFE_VUL3_LCH_MON 0x0ba8 +#define AFE_VUL4_RCH_MON 0x0bac +#define AFE_VUL4_LCH_MON 0x0bb0 +#define AFE_VUL5_RCH_MON 0x0bb4 +#define AFE_VUL5_LCH_MON 0x0bb8 +#define AFE_VUL6_RCH_MON 0x0bbc +#define AFE_VUL6_LCH_MON 0x0bc0 +#define AFE_DL1_RCH_MON 0x0bc4 +#define AFE_DL1_LCH_MON 0x0bc8 +#define AFE_DL2_RCH_MON 0x0bcc +#define AFE_DL2_LCH_MON 0x0bd0 +#define AFE_DL12_RCH1_MON 0x0bd4 +#define AFE_DL12_LCH1_MON 0x0bd8 +#define AFE_DL12_RCH2_MON 0x0bdc +#define AFE_DL12_LCH2_MON 0x0be0 +#define AFE_DL3_RCH_MON 0x0be4 +#define AFE_DL3_LCH_MON 0x0be8 +#define AFE_DL4_RCH_MON 0x0bec +#define AFE_DL4_LCH_MON 0x0bf0 +#define AFE_DL5_RCH_MON 0x0bf4 +#define AFE_DL5_LCH_MON 0x0bf8 +#define AFE_DL6_RCH_MON 0x0bfc +#define AFE_DL6_LCH_MON 0x0c00 +#define AFE_DL7_RCH_MON 0x0c04 +#define AFE_DL7_LCH_MON 0x0c08 +#define AFE_DL8_RCH_MON 0x0c0c +#define AFE_DL8_LCH_MON 0x0c10 +#define AFE_VUL5_CON0 0x0c14 +#define AFE_VUL5_BASE_MSB 0x0c18 +#define AFE_VUL5_BASE 0x0c1c +#define AFE_VUL5_CUR_MSB 0x0c20 +#define AFE_VUL5_CUR 0x0c24 +#define AFE_VUL5_END_MSB 0x0c28 +#define AFE_VUL5_END 0x0c2c +#define AFE_VUL6_CON0 0x0c30 +#define AFE_VUL6_BASE_MSB 0x0c34 +#define AFE_VUL6_BASE 0x0c38 +#define AFE_VUL6_CUR_MSB 0x0c3c +#define AFE_VUL6_CUR 0x0c40 +#define AFE_VUL6_END_MSB 0x0c44 +#define AFE_VUL6_END 0x0c48 +#define AFE_ADDA_DL_SDM_DCCOMP_CON 0x0c50 +#define AFE_ADDA_DL_SDM_TEST 0x0c54 +#define AFE_ADDA_DL_DC_COMP_CFG0 0x0c58 +#define AFE_ADDA_DL_DC_COMP_CFG1 0x0c5c +#define AFE_ADDA_DL_SDM_FIFO_MON 0x0c60 +#define AFE_ADDA_DL_SRC_LCH_MON 0x0c64 +#define AFE_ADDA_DL_SRC_RCH_MON 0x0c68 +#define AFE_ADDA_DL_SDM_OUT_MON 0x0c6c +#define AFE_ADDA_DL_SDM_DITHER_CON 0x0c70 +#define AFE_ADDA_DL_SDM_AUTO_RESET_CON 0x0c74 +#define AFE_CONNSYS_I2S_CON 0x0c78 +#define AFE_CONNSYS_I2S_MON 0x0c7c +#define AFE_ASRC_2CH_CON0 0x0c80 +#define AFE_ASRC_2CH_CON1 0x0c84 +#define AFE_ASRC_2CH_CON2 0x0c88 +#define AFE_ASRC_2CH_CON3 0x0c8c +#define AFE_ASRC_2CH_CON4 0x0c90 +#define AFE_ASRC_2CH_CON5 0x0c94 +#define AFE_ASRC_2CH_CON6 0x0c98 +#define AFE_ASRC_2CH_CON7 0x0c9c +#define AFE_ASRC_2CH_CON8 0x0ca0 +#define AFE_ASRC_2CH_CON9 0x0ca4 +#define AFE_ASRC_2CH_CON10 0x0ca8 +#define AFE_ASRC_2CH_CON12 0x0cb0 +#define AFE_ASRC_2CH_CON13 0x0cb4 +#define AFE_ADDA6_IIR_COEF_02_01 0x0ce0 +#define AFE_ADDA6_IIR_COEF_04_03 0x0ce4 +#define AFE_ADDA6_IIR_COEF_06_05 0x0ce8 +#define AFE_ADDA6_IIR_COEF_08_07 0x0cec +#define AFE_ADDA6_IIR_COEF_10_09 0x0cf0 +#define AFE_CONN67 0x0cf4 +#define AFE_CONN68 0x0cf8 +#define AFE_CONN69 0x0cfc +#define AFE_SE_PROT_SIDEBAND 0x0d38 +#define AFE_SE_DOMAIN_SIDEBAND0 0x0d3c +#define AFE_ADDA_PREDIS_CON2 0x0d40 +#define AFE_ADDA_PREDIS_CON3 0x0d44 +#define AFE_SE_DOMAIN_SIDEBAND1 0x0d54 +#define AFE_SE_DOMAIN_SIDEBAND2 0x0d58 +#define AFE_SE_DOMAIN_SIDEBAND3 0x0d5c +#define AFE_CONN44 0x0d70 +#define AFE_CONN45 0x0d74 +#define AFE_CONN46 0x0d78 +#define AFE_CONN47 0x0d7c +#define AFE_CONN44_1 0x0d80 +#define AFE_CONN45_1 0x0d84 +#define AFE_CONN46_1 0x0d88 +#define AFE_CONN47_1 0x0d8c +#define AFE_HD_ENGEN_ENABLE 0x0dd0 +#define AFE_ADDA_DL_NLE_FIFO_MON 0x0dfc +#define AFE_ADDA_MTKAIF_CFG0 0x0e00 +#define AFE_CONN67_1 0x0e04 +#define AFE_CONN68_1 0x0e08 +#define AFE_CONN69_1 0x0e0c +#define AFE_ADDA_MTKAIF_SYNCWORD_CFG 0x0e14 +#define AFE_ADDA_MTKAIF_RX_CFG0 0x0e20 +#define AFE_ADDA_MTKAIF_RX_CFG1 0x0e24 +#define AFE_ADDA_MTKAIF_RX_CFG2 0x0e28 +#define AFE_ADDA_MTKAIF_MON0 0x0e34 +#define AFE_ADDA_MTKAIF_MON1 0x0e38 +#define AFE_AUD_PAD_TOP 0x0e40 +#define AFE_DL_NLE_R_CFG0 0x0e44 +#define AFE_DL_NLE_R_CFG1 0x0e48 +#define AFE_DL_NLE_L_CFG0 0x0e4c +#define AFE_DL_NLE_L_CFG1 0x0e50 +#define AFE_DL_NLE_R_MON0 0x0e54 +#define AFE_DL_NLE_R_MON1 0x0e58 +#define AFE_DL_NLE_R_MON2 0x0e5c +#define AFE_DL_NLE_L_MON0 0x0e60 +#define AFE_DL_NLE_L_MON1 0x0e64 +#define AFE_DL_NLE_L_MON2 0x0e68 +#define AFE_DL_NLE_GAIN_CFG0 0x0e6c +#define AFE_ADDA6_MTKAIF_CFG0 0x0e70 +#define AFE_ADDA6_MTKAIF_RX_CFG0 0x0e74 +#define AFE_ADDA6_MTKAIF_RX_CFG1 0x0e78 +#define AFE_ADDA6_MTKAIF_RX_CFG2 0x0e7c +#define AFE_GENERAL1_ASRC_2CH_CON0 0x0e80 +#define AFE_GENERAL1_ASRC_2CH_CON1 0x0e84 +#define AFE_GENERAL1_ASRC_2CH_CON2 0x0e88 +#define AFE_GENERAL1_ASRC_2CH_CON3 0x0e8c +#define AFE_GENERAL1_ASRC_2CH_CON4 0x0e90 +#define AFE_GENERAL1_ASRC_2CH_CON5 0x0e94 +#define AFE_GENERAL1_ASRC_2CH_CON6 0x0e98 +#define AFE_GENERAL1_ASRC_2CH_CON7 0x0e9c +#define AFE_GENERAL1_ASRC_2CH_CON8 0x0ea0 +#define AFE_GENERAL1_ASRC_2CH_CON9 0x0ea4 +#define AFE_GENERAL1_ASRC_2CH_CON10 0x0ea8 +#define AFE_GENERAL1_ASRC_2CH_CON12 0x0eb0 +#define AFE_GENERAL1_ASRC_2CH_CON13 0x0eb4 +#define GENERAL_ASRC_MODE 0x0eb8 +#define GENERAL_ASRC_EN_ON 0x0ebc +#define AFE_CONN48 0x0ec0 +#define AFE_CONN49 0x0ec4 +#define AFE_CONN50 0x0ec8 +#define AFE_CONN51 0x0ecc +#define AFE_CONN52 0x0ed0 +#define AFE_CONN53 0x0ed4 +#define AFE_CONN54 0x0ed8 +#define AFE_CONN55 0x0edc +#define AFE_CONN48_1 0x0ee0 +#define AFE_CONN49_1 0x0ee4 +#define AFE_CONN50_1 0x0ee8 +#define AFE_CONN51_1 0x0eec +#define AFE_CONN52_1 0x0ef0 +#define AFE_CONN53_1 0x0ef4 +#define AFE_CONN54_1 0x0ef8 +#define AFE_CONN55_1 0x0efc +#define AFE_GENERAL2_ASRC_2CH_CON0 0x0f00 +#define AFE_GENERAL2_ASRC_2CH_CON1 0x0f04 +#define AFE_GENERAL2_ASRC_2CH_CON2 0x0f08 +#define AFE_GENERAL2_ASRC_2CH_CON3 0x0f0c +#define AFE_GENERAL2_ASRC_2CH_CON4 0x0f10 +#define AFE_GENERAL2_ASRC_2CH_CON5 0x0f14 +#define AFE_GENERAL2_ASRC_2CH_CON6 0x0f18 +#define AFE_GENERAL2_ASRC_2CH_CON7 0x0f1c +#define AFE_GENERAL2_ASRC_2CH_CON8 0x0f20 +#define AFE_GENERAL2_ASRC_2CH_CON9 0x0f24 +#define AFE_GENERAL2_ASRC_2CH_CON10 0x0f28 +#define AFE_GENERAL2_ASRC_2CH_CON12 0x0f30 +#define AFE_GENERAL2_ASRC_2CH_CON13 0x0f34 +#define AFE_DL5_CON0 0x0f4c +#define AFE_DL5_BASE_MSB 0x0f50 +#define AFE_DL5_BASE 0x0f54 +#define AFE_DL5_CUR_MSB 0x0f58 +#define AFE_DL5_CUR 0x0f5c +#define AFE_DL5_END_MSB 0x0f60 +#define AFE_DL5_END 0x0f64 +#define AFE_DL6_CON0 0x0f68 +#define AFE_DL6_BASE_MSB 0x0f6c +#define AFE_DL6_BASE 0x0f70 +#define AFE_DL6_CUR_MSB 0x0f74 +#define AFE_DL6_CUR 0x0f78 +#define AFE_DL6_END_MSB 0x0f7c +#define AFE_DL6_END 0x0f80 +#define AFE_DL7_CON0 0x0f84 +#define AFE_DL7_BASE_MSB 0x0f88 +#define AFE_DL7_BASE 0x0f8c +#define AFE_DL7_CUR_MSB 0x0f90 +#define AFE_DL7_CUR 0x0f94 +#define AFE_DL7_END_MSB 0x0f98 +#define AFE_DL7_END 0x0f9c +#define AFE_DL8_CON0 0x0fa0 +#define AFE_DL8_BASE_MSB 0x0fa4 +#define AFE_DL8_BASE 0x0fa8 +#define AFE_DL8_CUR_MSB 0x0fac +#define AFE_DL8_CUR 0x0fb0 +#define AFE_DL8_END_MSB 0x0fb4 +#define AFE_DL8_END 0x0fb8 +#define AFE_SE_SECURE_CON 0x1004 +#define AFE_PROT_SIDEBAND_MON 0x1008 +#define AFE_DOMAIN_SIDEBAND0_MON 0x100c +#define AFE_DOMAIN_SIDEBAND1_MON 0x1010 +#define AFE_DOMAIN_SIDEBAND2_MON 0x1014 +#define AFE_DOMAIN_SIDEBAND3_MON 0x1018 +#define AFE_SECURE_MASK_CONN0 0x1020 +#define AFE_SECURE_MASK_CONN1 0x1024 +#define AFE_SECURE_MASK_CONN2 0x1028 +#define AFE_SECURE_MASK_CONN3 0x102c +#define AFE_SECURE_MASK_CONN4 0x1030 +#define AFE_SECURE_MASK_CONN5 0x1034 +#define AFE_SECURE_MASK_CONN6 0x1038 +#define AFE_SECURE_MASK_CONN7 0x103c +#define AFE_SECURE_MASK_CONN8 0x1040 +#define AFE_SECURE_MASK_CONN9 0x1044 +#define AFE_SECURE_MASK_CONN10 0x1048 +#define AFE_SECURE_MASK_CONN11 0x104c +#define AFE_SECURE_MASK_CONN12 0x1050 +#define AFE_SECURE_MASK_CONN13 0x1054 +#define AFE_SECURE_MASK_CONN14 0x1058 +#define AFE_SECURE_MASK_CONN15 0x105c +#define AFE_SECURE_MASK_CONN16 0x1060 +#define AFE_SECURE_MASK_CONN17 0x1064 +#define AFE_SECURE_MASK_CONN18 0x1068 +#define AFE_SECURE_MASK_CONN19 0x106c +#define AFE_SECURE_MASK_CONN20 0x1070 +#define AFE_SECURE_MASK_CONN21 0x1074 +#define AFE_SECURE_MASK_CONN22 0x1078 +#define AFE_SECURE_MASK_CONN23 0x107c +#define AFE_SECURE_MASK_CONN24 0x1080 +#define AFE_SECURE_MASK_CONN25 0x1084 +#define AFE_SECURE_MASK_CONN26 0x1088 +#define AFE_SECURE_MASK_CONN27 0x108c +#define AFE_SECURE_MASK_CONN28 0x1090 +#define AFE_SECURE_MASK_CONN29 0x1094 +#define AFE_SECURE_MASK_CONN30 0x1098 +#define AFE_SECURE_MASK_CONN31 0x109c +#define AFE_SECURE_MASK_CONN32 0x10a0 +#define AFE_SECURE_MASK_CONN33 0x10a4 +#define AFE_SECURE_MASK_CONN34 0x10a8 +#define AFE_SECURE_MASK_CONN35 0x10ac +#define AFE_SECURE_MASK_CONN36 0x10b0 +#define AFE_SECURE_MASK_CONN37 0x10b4 +#define AFE_SECURE_MASK_CONN38 0x10b8 +#define AFE_SECURE_MASK_CONN39 0x10bc +#define AFE_SECURE_MASK_CONN40 0x10c0 +#define AFE_SECURE_MASK_CONN41 0x10c4 +#define AFE_SECURE_MASK_CONN42 0x10c8 +#define AFE_SECURE_MASK_CONN43 0x10cc +#define AFE_SECURE_MASK_CONN44 0x10d0 +#define AFE_SECURE_MASK_CONN45 0x10d4 +#define AFE_SECURE_MASK_CONN46 0x10d8 +#define AFE_SECURE_MASK_CONN47 0x10dc +#define AFE_SECURE_MASK_CONN48 0x10e0 +#define AFE_SECURE_MASK_CONN49 0x10e4 +#define AFE_SECURE_MASK_CONN50 0x10e8 +#define AFE_SECURE_MASK_CONN51 0x10ec +#define AFE_SECURE_MASK_CONN52 0x10f0 +#define AFE_SECURE_MASK_CONN53 0x10f4 +#define AFE_SECURE_MASK_CONN54 0x10f8 +#define AFE_SECURE_MASK_CONN55 0x10fc +#define AFE_SECURE_MASK_CONN56 0x1100 +#define AFE_SECURE_MASK_CONN57 0x1104 +#define AFE_SECURE_MASK_CONN0_1 0x1108 +#define AFE_SECURE_MASK_CONN1_1 0x110c +#define AFE_SECURE_MASK_CONN2_1 0x1110 +#define AFE_SECURE_MASK_CONN3_1 0x1114 +#define AFE_SECURE_MASK_CONN4_1 0x1118 +#define AFE_SECURE_MASK_CONN5_1 0x111c +#define AFE_SECURE_MASK_CONN6_1 0x1120 +#define AFE_SECURE_MASK_CONN7_1 0x1124 +#define AFE_SECURE_MASK_CONN8_1 0x1128 +#define AFE_SECURE_MASK_CONN9_1 0x112c +#define AFE_SECURE_MASK_CONN10_1 0x1130 +#define AFE_SECURE_MASK_CONN11_1 0x1134 +#define AFE_SECURE_MASK_CONN12_1 0x1138 +#define AFE_SECURE_MASK_CONN13_1 0x113c +#define AFE_SECURE_MASK_CONN14_1 0x1140 +#define AFE_SECURE_MASK_CONN15_1 0x1144 +#define AFE_SECURE_MASK_CONN16_1 0x1148 +#define AFE_SECURE_MASK_CONN17_1 0x114c +#define AFE_SECURE_MASK_CONN18_1 0x1150 +#define AFE_SECURE_MASK_CONN19_1 0x1154 +#define AFE_SECURE_MASK_CONN20_1 0x1158 +#define AFE_SECURE_MASK_CONN21_1 0x115c +#define AFE_SECURE_MASK_CONN22_1 0x1160 +#define AFE_SECURE_MASK_CONN23_1 0x1164 +#define AFE_SECURE_MASK_CONN24_1 0x1168 +#define AFE_SECURE_MASK_CONN25_1 0x116c +#define AFE_SECURE_MASK_CONN26_1 0x1170 +#define AFE_SECURE_MASK_CONN27_1 0x1174 +#define AFE_SECURE_MASK_CONN28_1 0x1178 +#define AFE_SECURE_MASK_CONN29_1 0x117c +#define AFE_SECURE_MASK_CONN30_1 0x1180 +#define AFE_SECURE_MASK_CONN31_1 0x1184 +#define AFE_SECURE_MASK_CONN32_1 0x1188 +#define AFE_SECURE_MASK_CONN33_1 0x118c +#define AFE_SECURE_MASK_CONN34_1 0x1190 +#define AFE_SECURE_MASK_CONN35_1 0x1194 +#define AFE_SECURE_MASK_CONN36_1 0x1198 +#define AFE_SECURE_MASK_CONN37_1 0x119c +#define AFE_SECURE_MASK_CONN38_1 0x11a0 +#define AFE_SECURE_MASK_CONN39_1 0x11a4 +#define AFE_SECURE_MASK_CONN40_1 0x11a8 +#define AFE_SECURE_MASK_CONN41_1 0x11ac +#define AFE_SECURE_MASK_CONN42_1 0x11b0 +#define AFE_SECURE_MASK_CONN43_1 0x11b4 +#define AFE_SECURE_MASK_CONN44_1 0x11b8 +#define AFE_SECURE_MASK_CONN45_1 0x11bc +#define AFE_SECURE_MASK_CONN46_1 0x11c0 +#define AFE_SECURE_MASK_CONN47_1 0x11c4 +#define AFE_SECURE_MASK_CONN48_1 0x11c8 +#define AFE_SECURE_MASK_CONN49_1 0x11cc +#define AFE_SECURE_MASK_CONN50_1 0x11d0 +#define AFE_SECURE_MASK_CONN51_1 0x11d4 +#define AFE_SECURE_MASK_CONN52_1 0x11d8 +#define AFE_SECURE_MASK_CONN53_1 0x11dc +#define AFE_SECURE_MASK_CONN54_1 0x11e0 +#define AFE_SECURE_MASK_CONN55_1 0x11e4 +#define AFE_SECURE_MASK_CONN56_1 0x11e8 +#define AFE_CONN60_1 0x11f0 +#define AFE_CONN61_1 0x11f4 +#define AFE_CONN62_1 0x11f8 +#define AFE_CONN63_1 0x11fc +#define AFE_CONN64_1 0x1220 +#define AFE_CONN65_1 0x1224 +#define AFE_CONN66_1 0x1228 +#define FPGA_CFG4 0x1230 +#define FPGA_CFG5 0x1234 +#define FPGA_CFG6 0x1238 +#define FPGA_CFG7 0x123c +#define FPGA_CFG8 0x1240 +#define FPGA_CFG9 0x1244 +#define FPGA_CFG10 0x1248 +#define FPGA_CFG11 0x124c +#define FPGA_CFG12 0x1250 +#define FPGA_CFG13 0x1254 +#define ETDM_IN1_CON0 0x1430 +#define ETDM_IN1_CON1 0x1434 +#define ETDM_IN1_CON2 0x1438 +#define ETDM_IN1_CON3 0x143c +#define ETDM_IN1_CON4 0x1440 +#define ETDM_IN1_CON5 0x1444 +#define ETDM_IN1_CON6 0x1448 +#define ETDM_IN1_CON7 0x144c +#define ETDM_IN1_CON8 0x1450 +#define ETDM_OUT1_CON0 0x1454 +#define ETDM_OUT1_CON1 0x1458 +#define ETDM_OUT1_CON2 0x145c +#define ETDM_OUT1_CON3 0x1460 +#define ETDM_OUT1_CON4 0x1464 +#define ETDM_OUT1_CON5 0x1468 +#define ETDM_OUT1_CON6 0x146c +#define ETDM_OUT1_CON7 0x1470 +#define ETDM_OUT1_CON8 0x1474 +#define ETDM_IN1_MON 0x1478 +#define ETDM_OUT1_MON 0x147c +#define ETDM_0_3_COWORK_CON0 0x18b0 +#define ETDM_0_3_COWORK_CON1 0x18b4 +#define ETDM_0_3_COWORK_CON3 0x18bc + +#define AFE_MAX_REGISTER ETDM_0_3_COWORK_CON3 + +#define AFE_IRQ_STATUS_BITS 0x87FFFFFF +#define AFE_IRQ_CNT_SHIFT 0 +#define AFE_IRQ_CNT_MASK 0x3ffff +#endif -- GitLab From c271cc9febaaa1bcbc0842d1ee30466aa6148ea8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 5 Jun 2022 13:40:06 +0200 Subject: [PATCH 247/942] netfilter: nf_tables: release new hooks on unsupported flowtable flags Release the list of new hooks that are pending to be registered in case that unsupported flowtable flags are provided. Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 2faa77cd2fe25..252796a99f5e4 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -7433,11 +7433,15 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh, if (nla[NFTA_FLOWTABLE_FLAGS]) { flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS])); - if (flags & ~NFT_FLOWTABLE_MASK) - return -EOPNOTSUPP; + if (flags & ~NFT_FLOWTABLE_MASK) { + err = -EOPNOTSUPP; + goto err_flowtable_update_hook; + } if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^ - (flags & NFT_FLOWTABLE_HW_OFFLOAD)) - return -EOPNOTSUPP; + (flags & NFT_FLOWTABLE_HW_OFFLOAD)) { + err = -EOPNOTSUPP; + goto err_flowtable_update_hook; + } } else { flags = flowtable->data.flags; } -- GitLab From 9dd732e0bdf538b1b76dc7c157e2b5e560ff30d3 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 6 Jun 2022 17:15:57 +0200 Subject: [PATCH 248/942] netfilter: nf_tables: memleak flow rule from commit path Abort path release flow rule object, however, commit path does not. Update code to destroy these objects before releasing the transaction. Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 252796a99f5e4..1a6a21bfb18d6 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -8329,6 +8329,9 @@ static void nft_commit_release(struct nft_trans *trans) nf_tables_chain_destroy(&trans->ctx); break; case NFT_MSG_DELRULE: + if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) + nft_flow_rule_destroy(nft_trans_flow_rule(trans)); + nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans)); break; case NFT_MSG_DELSET: @@ -8817,6 +8820,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) nf_tables_rule_notify(&trans->ctx, nft_trans_rule(trans), NFT_MSG_NEWRULE); + if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD) + nft_flow_rule_destroy(nft_trans_flow_rule(trans)); + nft_trans_destroy(trans); break; case NFT_MSG_DELRULE: -- GitLab From c76acfb7e19dcc3a0964e0563770b1d11b8d4540 Mon Sep 17 00:00:00 2001 From: Tan Tee Min Date: Thu, 26 May 2022 17:03:47 +0800 Subject: [PATCH 249/942] net: phy: dp83867: retrigger SGMII AN when link change There is a limitation in TI DP83867 PHY device where SGMII AN is only triggered once after the device is booted up. Even after the PHY TPI is down and up again, SGMII AN is not triggered and hence no new in-band message from PHY to MAC side SGMII. This could cause an issue during power up, when PHY is up prior to MAC. At this condition, once MAC side SGMII is up, MAC side SGMII wouldn`t receive new in-band message from TI PHY with correct link status, speed and duplex info. As suggested by TI, implemented a SW solution here to retrigger SGMII Auto-Neg whenever there is a link change. v2: Add Fixes tag in commit message. Fixes: 2a10154abcb7 ("net: phy: dp83867: Add TI dp83867 phy") Cc: # 5.4.x Signed-off-by: Sit, Michael Wei Hong Reviewed-by: Voon Weifeng Signed-off-by: Tan Tee Min Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220526090347.128742-1-tee.min.tan@linux.intel.com Signed-off-by: Jakub Kicinski --- drivers/net/phy/dp83867.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 8561f2d4443bf..13dafe7a29bde 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -137,6 +137,7 @@ #define DP83867_DOWNSHIFT_2_COUNT 2 #define DP83867_DOWNSHIFT_4_COUNT 4 #define DP83867_DOWNSHIFT_8_COUNT 8 +#define DP83867_SGMII_AUTONEG_EN BIT(7) /* CFG3 bits */ #define DP83867_CFG3_INT_OE BIT(7) @@ -855,6 +856,32 @@ static int dp83867_phy_reset(struct phy_device *phydev) DP83867_PHYCR_FORCE_LINK_GOOD, 0); } +static void dp83867_link_change_notify(struct phy_device *phydev) +{ + /* There is a limitation in DP83867 PHY device where SGMII AN is + * only triggered once after the device is booted up. Even after the + * PHY TPI is down and up again, SGMII AN is not triggered and + * hence no new in-band message from PHY to MAC side SGMII. + * This could cause an issue during power up, when PHY is up prior + * to MAC. At this condition, once MAC side SGMII is up, MAC side + * SGMII wouldn`t receive new in-band message from TI PHY with + * correct link status, speed and duplex info. + * Thus, implemented a SW solution here to retrigger SGMII Auto-Neg + * whenever there is a link change. + */ + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + int val = 0; + + val = phy_clear_bits(phydev, DP83867_CFG2, + DP83867_SGMII_AUTONEG_EN); + if (val < 0) + return; + + phy_set_bits(phydev, DP83867_CFG2, + DP83867_SGMII_AUTONEG_EN); + } +} + static struct phy_driver dp83867_driver[] = { { .phy_id = DP83867_PHY_ID, @@ -879,6 +906,8 @@ static struct phy_driver dp83867_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, + + .link_change_notify = dp83867_link_change_notify, }, }; module_phy_driver(dp83867_driver); -- GitLab From e0b5c5984d4810733b7c24a3d16c904fffc086d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:23 +0100 Subject: [PATCH 250/942] dt-bindings: mfd: bd9571mwv: update rohm,bd9571mwv.yaml reference Changeset 983b62975e90 ("dt-bindings: mfd: bd9571mwv: Convert to json-schema") renamed: Documentation/devicetree/bindings/mfd/bd9571mwv.txt to: Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml. Update its cross-reference accordingly. Fixes: 983b62975e90 ("dt-bindings: mfd: bd9571mwv: Convert to json-schema") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/1906a4d935eab57c10ce09358eae02175ce4abb7.1654529011.git.mchehab@kernel.org --- Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator b/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator index 42214b4ff14a1..90596d8bb51c0 100644 --- a/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator +++ b/Documentation/ABI/testing/sysfs-driver-bd9571mwv-regulator @@ -26,6 +26,6 @@ Description: Read/write the current state of DDR Backup Mode, which controls DDR Backup Mode must be explicitly enabled by the user, to invoke step 1. - See also Documentation/devicetree/bindings/mfd/bd9571mwv.txt. + See also Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml. Users: User space applications for embedded boards equipped with a BD9571MWV PMIC. -- GitLab From 7e40381d8a33e41e347cea5bdd000091653000c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:24 +0100 Subject: [PATCH 251/942] dt-bindings: interrupt-controller: update brcm,l2-intc.yaml reference Changeset 539d25b21fe8 ("dt-bindings: interrupt-controller: Convert Broadcom STB L2 to YAML") renamed: Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt to: Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.yaml. Update its cross-reference accordingly. Fixes: 539d25b21fe8 ("dt-bindings: interrupt-controller: Convert Broadcom STB L2 to YAML") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/a40c02a7aaea91ea7b6ce24b6bc574ae5bcf4cf6.1654529011.git.mchehab@kernel.org --- .../devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt b/Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt index 73470ecd1f12f..ce91a91976976 100644 --- a/Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt +++ b/Documentation/devicetree/bindings/cpufreq/brcm,stb-avs-cpu-freq.txt @@ -16,7 +16,7 @@ has been processed. See [2] for more information on the brcm,l2-intc node. firmware. On some SoCs, this firmware supports DFS and DVFS in addition to Adaptive Voltage Scaling. -[2] Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.txt +[2] Documentation/devicetree/bindings/interrupt-controller/brcm,l2-intc.yaml Node brcm,avs-cpu-data-mem -- GitLab From 71a834b7f744fab6ae83dc1bfc22030b5baa5dd5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:25 +0100 Subject: [PATCH 252/942] dt-bindings: arm: update vexpress-config.yaml references Changeset 7e8339b5162f ("dt-bindings: arm: convert vexpress-config to DT schema") renamed: Documentation/devicetree/bindings/arm/vexpress-sysreg.txt to: Documentation/devicetree/bindings/arm/vexpress-config.yaml. Update the cross-references accordingly. Fixes: 7e8339b5162f ("dt-bindings: arm: convert vexpress-config to DT schema") Signed-off-by: Mauro Carvalho Chehab Acked-by: Guenter Roeck Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/7020edd9e183652249fc95bf61a1055cc342a4dc.1654529011.git.mchehab@kernel.org --- Documentation/devicetree/bindings/hwmon/vexpress.txt | 2 +- Documentation/devicetree/bindings/regulator/vexpress.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/hwmon/vexpress.txt b/Documentation/devicetree/bindings/hwmon/vexpress.txt index 9c27ed694bbbf..4a4df4ffc460b 100644 --- a/Documentation/devicetree/bindings/hwmon/vexpress.txt +++ b/Documentation/devicetree/bindings/hwmon/vexpress.txt @@ -9,7 +9,7 @@ Requires node properties: "arm,vexpress-power" "arm,vexpress-energy" - "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg - (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt + (see Documentation/devicetree/bindings/arm/vexpress-config.yaml for more details) Optional node properties: diff --git a/Documentation/devicetree/bindings/regulator/vexpress.txt b/Documentation/devicetree/bindings/regulator/vexpress.txt index d775f72487aa3..1c2e92c7831ea 100644 --- a/Documentation/devicetree/bindings/regulator/vexpress.txt +++ b/Documentation/devicetree/bindings/regulator/vexpress.txt @@ -4,7 +4,7 @@ Versatile Express voltage regulators Requires node properties: - "compatible" value: "arm,vexpress-volt" - "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg - (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt + (see Documentation/devicetree/bindings/arm/vexpress-config.yaml for more details) Required regulator properties: -- GitLab From 47a22a251543f4710b954f4b36f3e6063017a82b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:26 +0100 Subject: [PATCH 253/942] dt-bindings: reset: update st,stih407-powerdown.yaml references Changeset 2ca065dc9468 ("dt-bindings: reset: st,sti-powerdown: Convert to yaml") renamed: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt to: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml. Update the cross-references accordingly. Fixes: 2ca065dc9468 ("dt-bindings: reset: st,sti-powerdown: Convert to yaml") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/debdd5a9a1bfa0cf1c7e9c45da32edbc2ac2d10a.1654529011.git.mchehab@kernel.org --- Documentation/devicetree/bindings/phy/phy-stih407-usb.txt | 2 +- Documentation/devicetree/bindings/usb/dwc3-st.txt | 2 +- Documentation/devicetree/bindings/usb/ehci-st.txt | 2 +- Documentation/devicetree/bindings/usb/ohci-st.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt index de6a706abcdbe..35f03df001304 100644 --- a/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt +++ b/Documentation/devicetree/bindings/phy/phy-stih407-usb.txt @@ -9,7 +9,7 @@ Required properties: - resets : list of phandle and reset specifier pairs. There should be two entries, one for the whole phy and one for the port - reset-names : list of reset signal names. Should be "global" and "port" -See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt +See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml See: Documentation/devicetree/bindings/reset/reset.txt Example: diff --git a/Documentation/devicetree/bindings/usb/dwc3-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index bf73de0d5b4af..4aa368447b1e8 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt @@ -13,7 +13,7 @@ Required properties: - resets : list of phandle and reset specifier pairs. There should be two entries, one for the powerdown and softreset lines of the usb3 IP - reset-names : list of reset signal names. Names should be "powerdown" and "softreset" -See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt +See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml See: Documentation/devicetree/bindings/reset/reset.txt - #address-cells, #size-cells : should be '1' if the device has sub-nodes diff --git a/Documentation/devicetree/bindings/usb/ehci-st.txt b/Documentation/devicetree/bindings/usb/ehci-st.txt index 065c91d955ad1..d6f2bdee20fc2 100644 --- a/Documentation/devicetree/bindings/usb/ehci-st.txt +++ b/Documentation/devicetree/bindings/usb/ehci-st.txt @@ -17,7 +17,7 @@ See: Documentation/devicetree/bindings/clock/clock-bindings.txt - resets : phandle + reset specifier pairs to the powerdown and softreset lines of the USB IP - reset-names : should be "power" and "softreset" -See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt +See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml See: Documentation/devicetree/bindings/reset/reset.txt Example: diff --git a/Documentation/devicetree/bindings/usb/ohci-st.txt b/Documentation/devicetree/bindings/usb/ohci-st.txt index 44c998c16f85b..1c735573abc03 100644 --- a/Documentation/devicetree/bindings/usb/ohci-st.txt +++ b/Documentation/devicetree/bindings/usb/ohci-st.txt @@ -15,7 +15,7 @@ See: Documentation/devicetree/bindings/clock/clock-bindings.txt - resets : phandle to the powerdown and reset controller for the USB IP - reset-names : should be "power" and "softreset". -See: Documentation/devicetree/bindings/reset/st,sti-powerdown.txt +See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml See: Documentation/devicetree/bindings/reset/reset.txt Example: -- GitLab From 69c2533eb9dfc650baa5f0f624ee4e7cc57afd7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:27 +0100 Subject: [PATCH 254/942] dt-bindings: mfd: rk808: update rockchip,rk808.yaml reference Changeset 6c38ca03406e ("dt-bindings: mfd: rk808: Convert bindings to yaml") renamed: Documentation/devicetree/bindings/mfd/rk808.txt to: Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml. Update its cross-reference accordingly. Fixes: 6c38ca03406e ("dt-bindings: mfd: rk808: Convert bindings to yaml") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/417281c270e098eefed763859480014bec75c883.1654529011.git.mchehab@kernel.org --- Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt index cbcbd31e3ce85..939cb5b6ffeac 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt @@ -27,7 +27,7 @@ Required properties: - pins: List of pins. Valid values of pins properties are: gpio0, gpio1. First 2 properties must be added in the RK805 PMIC node, documented in -Documentation/devicetree/bindings/mfd/rk808.txt +Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml Optional properties: ------------------- -- GitLab From 7470ce60be24de8117b71614a3d610b8619f2108 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:39 +0100 Subject: [PATCH 255/942] MAINTAINERS: update cortina,gemini-ethernet.yaml reference Changeset 208b65f7b5cc ("dt-bindings: net: convert net/cortina,gemini-ethernet to yaml") renamed: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt to: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml. Update its cross-reference accordingly. Fixes: 208b65f7b5cc ("dt-bindings: net: convert net/cortina,gemini-ethernet to yaml") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/d27b5d508fb757147b720bf573ce5a2e3fc5920e.1654529011.git.mchehab@kernel.org --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d0..d6bf4f0d1f04e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2009,7 +2009,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://github.com/ulli-kroll/linux.git F: Documentation/devicetree/bindings/arm/gemini.yaml -F: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt +F: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml F: arch/arm/boot/dts/gemini* -- GitLab From e5f580e72498ef634ae293c8d4ba7184f5191c74 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:40 +0100 Subject: [PATCH 256/942] MAINTAINERS: update dongwoon,dw9807-vcm.yaml reference Changeset a1f4626b282d ("media: dt-bindings: Convert Dongwoon dw9807-vcm bindings to json-schema") renamed: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt to: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.yaml. Update its cross-reference accordingly. Fixes: a1f4626b282d ("media: dt-bindings: Convert Dongwoon dw9807-vcm bindings to json-schema") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/89f11772dd4afe9700d6cbbb3da8749eb98b396a.1654529011.git.mchehab@kernel.org --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index d6bf4f0d1f04e..3c9723f9d61c7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6078,7 +6078,7 @@ M: Sakari Ailus L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git -F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.txt +F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9807-vcm.yaml F: drivers/media/i2c/dw9807-vcm.c DOUBLETALK DRIVER -- GitLab From 09fed02c20a659e15c9b47a52e8cf2dffa41cda9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:42 +0100 Subject: [PATCH 257/942] MAINTAINERS: update snps,axs10x-reset.yaml reference Changeset 820f722c05dd ("dt-bindings: reset: snps,axs10x-reset: Convert to yaml") renamed: Documentation/devicetree/bindings/reset/snps,axs10x-reset.txt to: Documentation/devicetree/bindings/reset/snps,axs10x-reset.yaml. Update its cross-reference accordingly. Fixes: 820f722c05dd ("dt-bindings: reset: snps,axs10x-reset: Convert to yaml") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/56560a2bcc06af94d36a28ed2cfdb25de481eee5.1654529011.git.mchehab@kernel.org --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3c9723f9d61c7..5400bdc2104e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19220,7 +19220,7 @@ F: arch/arc/plat-axs10x SYNOPSYS AXS10x RESET CONTROLLER DRIVER M: Eugeniy Paltsev S: Supported -F: Documentation/devicetree/bindings/reset/snps,axs10x-reset.txt +F: Documentation/devicetree/bindings/reset/snps,axs10x-reset.yaml F: drivers/reset/reset-axs10x.c SYNOPSYS CREG GPIO DRIVER -- GitLab From a2d2bfc9d56513684260b6aab26a2e0b56b09d92 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 1 Jun 2022 06:17:46 +0200 Subject: [PATCH 258/942] MAINTAINERS: rectify entries for ARM DRM DRIVERS after dt conversion The three commits: 36fd2a65bcaf ("dt-bindings: display: convert Arm HDLCD to DT schema") 0f6983509ea1 ("dt-bindings: display: convert Arm Komeda to DT schema") 2c8b082a3ab1 ("dt-bindings: display: convert Arm Mali-DP to DT schema") convert the arm display dt-bindings, arm,*.txt to arm,*.yaml, but miss to adjust its reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about broken references. Repair these file references in ARM HDLCD DRM DRIVER, ARM KOMEDA DRM-KMS DRIVER and ARM MALI-DP DRM DRIVER. Signed-off-by: Lukas Bulwahn Acked-by: Andre Przywara Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220601041746.22986-1-lukas.bulwahn@gmail.com --- MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5400bdc2104e0..7e970b1d56509 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1507,7 +1507,7 @@ F: drivers/clocksource/arm_arch_timer.c ARM HDLCD DRM DRIVER M: Liviu Dudau S: Supported -F: Documentation/devicetree/bindings/display/arm,hdlcd.txt +F: Documentation/devicetree/bindings/display/arm,hdlcd.yaml F: drivers/gpu/drm/arm/hdlcd_* ARM INTEGRATOR, VERSATILE AND REALVIEW SUPPORT @@ -1542,7 +1542,7 @@ M: Mihail Atanassov L: Mali DP Maintainers S: Supported T: git git://anongit.freedesktop.org/drm/drm-misc -F: Documentation/devicetree/bindings/display/arm,komeda.txt +F: Documentation/devicetree/bindings/display/arm,komeda.yaml F: Documentation/gpu/komeda-kms.rst F: drivers/gpu/drm/arm/display/include/ F: drivers/gpu/drm/arm/display/komeda/ @@ -1564,7 +1564,7 @@ M: Brian Starkey L: Mali DP Maintainers S: Supported T: git git://anongit.freedesktop.org/drm/drm-misc -F: Documentation/devicetree/bindings/display/arm,malidp.txt +F: Documentation/devicetree/bindings/display/arm,malidp.yaml F: Documentation/gpu/afbc.rst F: drivers/gpu/drm/arm/ -- GitLab From 3a41c64d9c1185a2f3a184015e2a9b78bfc99c71 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 6 Jun 2022 17:31:29 +0200 Subject: [PATCH 259/942] netfilter: nf_tables: bail out early if hardware offload is not supported If user requests for NFT_CHAIN_HW_OFFLOAD, then check if either device provides the .ndo_setup_tc interface or there is an indirect flow block that has been registered. Otherwise, bail out early from the preparation phase. Moreover, validate that family == NFPROTO_NETDEV and hook is NF_NETDEV_INGRESS. Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support") Signed-off-by: Pablo Neira Ayuso --- include/net/flow_offload.h | 1 + include/net/netfilter/nf_tables_offload.h | 2 +- net/core/flow_offload.c | 6 ++++++ net/netfilter/nf_tables_api.c | 2 +- net/netfilter/nf_tables_offload.c | 23 ++++++++++++++++++++++- 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index 021778a7e1afa..6484095a8c011 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -612,5 +612,6 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, enum tc_setup_type type, void *data, struct flow_block_offload *bo, void (*cleanup)(struct flow_block_cb *block_cb)); +bool flow_indr_dev_exists(void); #endif /* _NET_FLOW_OFFLOAD_H */ diff --git a/include/net/netfilter/nf_tables_offload.h b/include/net/netfilter/nf_tables_offload.h index 7971478439580..3568b6a2f5f0f 100644 --- a/include/net/netfilter/nf_tables_offload.h +++ b/include/net/netfilter/nf_tables_offload.h @@ -92,7 +92,7 @@ int nft_flow_rule_offload_commit(struct net *net); NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \ memset(&(__reg)->mask, 0xff, (__reg)->len); -int nft_chain_offload_priority(struct nft_base_chain *basechain); +bool nft_chain_offload_support(const struct nft_base_chain *basechain); int nft_offload_init(void); void nft_offload_exit(void); diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index 73f68d4625f32..929f6379a2798 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -595,3 +595,9 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch, return (bo && list_empty(&bo->cb_list)) ? -EOPNOTSUPP : count; } EXPORT_SYMBOL(flow_indr_dev_setup_offload); + +bool flow_indr_dev_exists(void) +{ + return !list_empty(&flow_block_indr_dev_list); +} +EXPORT_SYMBOL(flow_indr_dev_exists); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 1a6a21bfb18d6..51144fc66889b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -2166,7 +2166,7 @@ static int nft_basechain_init(struct nft_base_chain *basechain, u8 family, chain->flags |= NFT_CHAIN_BASE | flags; basechain->policy = NF_ACCEPT; if (chain->flags & NFT_CHAIN_HW_OFFLOAD && - nft_chain_offload_priority(basechain) < 0) + !nft_chain_offload_support(basechain)) return -EOPNOTSUPP; flow_block_init(&basechain->flow_block); diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index 2d36952b13920..910ef881c3b85 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -208,7 +208,7 @@ static int nft_setup_cb_call(enum tc_setup_type type, void *type_data, return 0; } -int nft_chain_offload_priority(struct nft_base_chain *basechain) +static int nft_chain_offload_priority(const struct nft_base_chain *basechain) { if (basechain->ops.priority <= 0 || basechain->ops.priority > USHRT_MAX) @@ -217,6 +217,27 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain) return 0; } +bool nft_chain_offload_support(const struct nft_base_chain *basechain) +{ + struct net_device *dev; + struct nft_hook *hook; + + if (nft_chain_offload_priority(basechain) < 0) + return false; + + list_for_each_entry(hook, &basechain->hook_list, list) { + if (hook->ops.pf != NFPROTO_NETDEV || + hook->ops.hooknum != NF_NETDEV_INGRESS) + return false; + + dev = hook->ops.dev; + if (!dev->netdev_ops->ndo_setup_tc && !flow_indr_dev_exists()) + return false; + } + + return true; +} + static void nft_flow_cls_offload_setup(struct flow_cls_offload *cls_flow, const struct nft_base_chain *basechain, const struct nft_rule *rule, -- GitLab From ca871659ec1606d33b1e76de8d4cf924cf627e34 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 28 Feb 2022 12:25:31 -0800 Subject: [PATCH 260/942] drm/bridge: analogix_dp: Support PSR-exit to disable transition Most eDP panel functions only work correctly when the panel is not in self-refresh. In particular, analogix_dp_bridge_disable() tends to hit AUX channel errors if the panel is in self-refresh. Given the above, it appears that so far, this driver assumes that we are never in self-refresh when it comes time to fully disable the bridge. Prior to commit 846c7dfc1193 ("drm/atomic: Try to preserve the crtc enabled state in drm_atomic_remove_fb, v2."), this tended to be true, because we would automatically disable the pipe when framebuffers were removed, and so we'd typically disable the bridge shortly after the last display activity. However, that is not guaranteed: an idle (self-refresh) display pipe may be disabled, e.g., when switching CRTCs. We need to exit PSR first. Stable notes: this is definitely a bugfix, and the bug has likely existed in some form for quite a while. It may predate the "PSR helpers" refactor, but the code looked very different before that, and it's probably not worth rewriting the fix. Cc: Fixes: 6c836d965bad ("drm/rockchip: Use the helpers for PSR") Signed-off-by: Brian Norris Reviewed-by: Sean Paul Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.1.I161904be17ba14526f78536ccd78b85818449b51@changeid --- .../drm/bridge/analogix/analogix_dp_core.c | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index eb590fb8e8d0d..0300f670a4fde 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1268,6 +1268,25 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, return 0; } +static +struct drm_crtc *analogix_dp_get_old_crtc(struct analogix_dp_device *dp, + struct drm_atomic_state *state) +{ + struct drm_encoder *encoder = dp->encoder; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + + connector = drm_atomic_get_old_connector_for_encoder(state, encoder); + if (!connector) + return NULL; + + conn_state = drm_atomic_get_old_connector_state(state, connector); + if (!conn_state) + return NULL; + + return conn_state->crtc; +} + static struct drm_crtc *analogix_dp_get_new_crtc(struct analogix_dp_device *dp, struct drm_atomic_state *state) @@ -1448,14 +1467,16 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, { struct drm_atomic_state *old_state = old_bridge_state->base.state; struct analogix_dp_device *dp = bridge->driver_private; - struct drm_crtc *crtc; + struct drm_crtc *old_crtc, *new_crtc; + struct drm_crtc_state *old_crtc_state = NULL; struct drm_crtc_state *new_crtc_state = NULL; + int ret; - crtc = analogix_dp_get_new_crtc(dp, old_state); - if (!crtc) + new_crtc = analogix_dp_get_new_crtc(dp, old_state); + if (!new_crtc) goto out; - new_crtc_state = drm_atomic_get_new_crtc_state(old_state, crtc); + new_crtc_state = drm_atomic_get_new_crtc_state(old_state, new_crtc); if (!new_crtc_state) goto out; @@ -1464,6 +1485,19 @@ analogix_dp_bridge_atomic_disable(struct drm_bridge *bridge, return; out: + old_crtc = analogix_dp_get_old_crtc(dp, old_state); + if (old_crtc) { + old_crtc_state = drm_atomic_get_old_crtc_state(old_state, + old_crtc); + + /* When moving from PSR to fully disabled, exit PSR first. */ + if (old_crtc_state && old_crtc_state->self_refresh_active) { + ret = analogix_dp_disable_psr(dp); + if (ret) + DRM_ERROR("Failed to disable psr (%d)\n", ret); + } + } + analogix_dp_bridge_disable(bridge); } -- GitLab From e54a4424925a27ed94dff046db3ce5caf4b1e748 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 28 Feb 2022 12:25:32 -0800 Subject: [PATCH 261/942] drm/atomic: Force bridge self-refresh-exit on CRTC switch It's possible to change which CRTC is in use for a given connector/encoder/bridge while we're in self-refresh without fully disabling the connector/encoder/bridge along the way. This can confuse the bridge encoder/bridge, because (a) it needs to track the SR state (trying to perform "active" operations while the panel is still in SR can be Bad(TM)); and (b) it tracks the SR state via the CRTC state (and after the switch, the previous SR state is lost). Thus, we need to either somehow carry the self-refresh state over to the new CRTC, or else force an encoder/bridge self-refresh transition during such a switch. I choose the latter, so we disable the encoder (and exit PSR) before attaching it to the new CRTC (where we can continue to assume a clean (non-self-refresh) state). This fixes PSR issues seen on Rockchip RK3399 systems with drivers/gpu/drm/bridge/analogix/analogix_dp_core.c. Change in v2: - Drop "->enable" condition; this could possibly be "->active" to reflect the intended hardware state, but it also is a little over-specific. We want to make a transition through "disabled" any time we're exiting PSR at the same time as a CRTC switch. (Thanks Liu Ying) Cc: Liu Ying Cc: Fixes: 1452c25b0e60 ("drm: Add helpers to kick off self refresh mode in drivers") Signed-off-by: Brian Norris Reviewed-by: Sean Paul Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20220228122522.v2.2.Ic15a2ef69c540aee8732703103e2cff51fb9c399@changeid --- drivers/gpu/drm/drm_atomic_helper.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 9603193d2fa13..987e4b212e9fb 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1011,9 +1011,19 @@ crtc_needs_disable(struct drm_crtc_state *old_state, return drm_atomic_crtc_effectively_active(old_state); /* - * We need to run through the crtc_funcs->disable() function if the CRTC - * is currently on, if it's transitioning to self refresh mode, or if - * it's in self refresh mode and needs to be fully disabled. + * We need to disable bridge(s) and CRTC if we're transitioning out of + * self-refresh and changing CRTCs at the same time, because the + * bridge tracks self-refresh status via CRTC state. + */ + if (old_state->self_refresh_active && + old_state->crtc != new_state->crtc) + return true; + + /* + * We also need to run through the crtc_funcs->disable() function if + * the CRTC is currently on, if it's transitioning to self refresh + * mode, or if it's in self refresh mode and needs to be fully + * disabled. */ return old_state->active || (old_state->self_refresh_active && !new_state->active) || -- GitLab From 11fe58c4450a8108b498d2f849976ba2686820fc Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 6 Jun 2022 15:46:20 -0500 Subject: [PATCH 262/942] ASoC: SOF: Intel: add MeteorLake machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for MeteorLake (MTL) machines support, starting with mockup devices. Reviewed-by: Péter Ujfalusi Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606204622.144424-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- include/sound/soc-acpi-intel-match.h | 2 + sound/soc/intel/common/Makefile | 1 + .../intel/common/soc-acpi-intel-mtl-match.c | 41 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 sound/soc/intel/common/soc-acpi-intel-mtl-match.c diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h index 59551b1f22f3c..bc7fd46ec2bc8 100644 --- a/include/sound/soc-acpi-intel-match.h +++ b/include/sound/soc-acpi-intel-match.h @@ -30,6 +30,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[]; @@ -37,6 +38,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[]; extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[]; +extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[]; /* * generic table used for HDA codec-based platforms, possibly with diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index fef0b2d1de68b..8ca8f872ec80c 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -9,6 +9,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \ soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \ soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \ + soc-acpi-intel-mtl-match.o \ soc-acpi-intel-hda-match.o \ soc-acpi-intel-sdw-mockup-match.o diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c new file mode 100644 index 0000000000000..cc594b27e03be --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-acpi-intel-mtl-match.c - tables and support for MTL ACPI enumeration. + * + * Copyright (c) 2022, Intel Corporation. + * + */ + +#include +#include +#include "soc-acpi-intel-sdw-mockup-match.h" + +struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines); + +/* this table is used when there is no I2S codec present */ +struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { + /* mockup tests need to be first */ + { + .link_mask = GENMASK(3, 0), + .links = sdw_mockup_headset_2amps_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt711-rt1308-rt715.tplg", + }, + { + .link_mask = BIT(0) | BIT(1) | BIT(3), + .links = sdw_mockup_headset_1amp_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt711-rt1308-mono-rt715.tplg", + }, + { + .link_mask = GENMASK(2, 0), + .links = sdw_mockup_mic_headset_1amp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg", + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); -- GitLab From 93693dcf2a4d7ab6a355f80c14653cd9c27a1422 Mon Sep 17 00:00:00 2001 From: Yong Zhi Date: Mon, 6 Jun 2022 15:46:21 -0500 Subject: [PATCH 263/942] ASoC: Intel: boards: rename RTL1019 compatible driver to rt1019p Use rt1019p for rt1015p.c compatible codec and reserve the name rt1019 for 10EC1019 matched driver in sof_realtek_common. Reviewed-by: Bard Liao Signed-off-by: Yong Zhi Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606204622.144424-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_realtek_common.c | 24 ++++++++++----------- sound/soc/intel/boards/sof_realtek_common.h | 6 +++--- sound/soc/intel/boards/sof_rt5682.c | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index 2ab568c1d40ba..b9643ca2e2f22 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -463,26 +463,26 @@ EXPORT_SYMBOL_NS(sof_rt1308_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); * 2-amp Configuration for RT1019 */ -static const struct snd_soc_dapm_route rt1019_dapm_routes[] = { +static const struct snd_soc_dapm_route rt1019p_dapm_routes[] = { /* speaker */ { "Left Spk", NULL, "Speaker" }, { "Right Spk", NULL, "Speaker" }, }; -static struct snd_soc_dai_link_component rt1019_components[] = { +static struct snd_soc_dai_link_component rt1019p_components[] = { { - .name = RT1019_DEV0_NAME, - .dai_name = RT1019_CODEC_DAI, + .name = RT1019P_DEV0_NAME, + .dai_name = RT1019P_CODEC_DAI, }, }; -static int rt1019_init(struct snd_soc_pcm_runtime *rtd) +static int rt1019p_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; int ret; - ret = snd_soc_dapm_add_routes(&card->dapm, rt1019_dapm_routes, - ARRAY_SIZE(rt1019_dapm_routes)); + ret = snd_soc_dapm_add_routes(&card->dapm, rt1019p_dapm_routes, + ARRAY_SIZE(rt1019p_dapm_routes)); if (ret) { dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); return ret; @@ -490,13 +490,13 @@ static int rt1019_init(struct snd_soc_pcm_runtime *rtd) return ret; } -void sof_rt1019_dai_link(struct snd_soc_dai_link *link) +void sof_rt1019p_dai_link(struct snd_soc_dai_link *link) { - link->codecs = rt1019_components; - link->num_codecs = ARRAY_SIZE(rt1019_components); - link->init = rt1019_init; + link->codecs = rt1019p_components; + link->num_codecs = ARRAY_SIZE(rt1019p_components); + link->init = rt1019p_init; } -EXPORT_SYMBOL_NS(sof_rt1019_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); +EXPORT_SYMBOL_NS(sof_rt1019p_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON); MODULE_DESCRIPTION("ASoC Intel SOF Realtek helpers"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_realtek_common.h b/sound/soc/intel/boards/sof_realtek_common.h index ec3eea633e048..7784434210900 100644 --- a/sound/soc/intel/boards/sof_realtek_common.h +++ b/sound/soc/intel/boards/sof_realtek_common.h @@ -39,9 +39,9 @@ void sof_rt1015_codec_conf(struct snd_soc_card *card); #define RT1308_DEV0_NAME "i2c-10EC1308:00" void sof_rt1308_dai_link(struct snd_soc_dai_link *link); -#define RT1019_CODEC_DAI "HiFi" -#define RT1019_DEV0_NAME "RTL1019:00" +#define RT1019P_CODEC_DAI "HiFi" +#define RT1019P_DEV0_NAME "RTL1019:00" -void sof_rt1019_dai_link(struct snd_soc_dai_link *link); +void sof_rt1019p_dai_link(struct snd_soc_dai_link *link); #endif /* __SOF_REALTEK_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 5d67a2c87a1d4..f28dae64587e1 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -735,7 +735,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { sof_rt1015p_dai_link(&links[id]); } else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) { - sof_rt1019_dai_link(&links[id]); + sof_rt1019p_dai_link(&links[id]); } else if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { links[id].codecs = max_98373_components; -- GitLab From 8208dd75eb468d1bb90aef52f385e5b3486bb737 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:46:22 -0500 Subject: [PATCH 264/942] ASoC: Intel: sof_sdw: allow HDaudio/HDMI disable For tests, it's rather common to disable the HDaudio links and codecs in the build. Since we already get a codec_mask parameter indicating that there are no codecs detected, it's straightforward to skip the HDMI dailink creation and create a card. Note that when disabling HDMI, a modified topology without HDMI pipelines needs to be provided as well. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606204622.144424-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 1 - sound/soc/intel/boards/sof_sdw.c | 24 +++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index f3873b5bea87e..4b4c1e1e48087 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -660,7 +660,6 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST depends on SOUNDWIRE - depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_MAX98373_I2C select SND_SOC_MAX98373_SDW select SND_SOC_RT700_SDW diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 1f00679b42409..f871daa5cb33d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1127,10 +1127,14 @@ static int sof_card_dai_links_create(struct device *dev, for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) codec_info_list[i].amp_num = 0; - if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) - hdmi_num = SOF_TGL_HDMI_COUNT; - else - hdmi_num = SOF_PRE_TGL_HDMI_COUNT; + if (mach_params->codec_mask & IDISP_CODEC_MASK) { + ctx->idisp_codec = true; + + if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) + hdmi_num = SOF_TGL_HDMI_COUNT; + else + hdmi_num = SOF_PRE_TGL_HDMI_COUNT; + } ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk); /* @@ -1150,9 +1154,6 @@ static int sof_card_dai_links_create(struct device *dev, return ret; } - if (mach_params->codec_mask & IDISP_CODEC_MASK) - ctx->idisp_codec = true; - /* enable dmic01 & dmic16k */ dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) ? 2 : 0; comp_num += dmic_num; @@ -1375,7 +1376,9 @@ static int sof_card_dai_links_create(struct device *dev, static int sof_sdw_card_late_probe(struct snd_soc_card *card) { - int i, ret; + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + int ret = 0; + int i; for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { if (!codec_info_list[i].late_probe) @@ -1386,7 +1389,10 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card) return ret; } - return sof_sdw_hdmi_card_late_probe(card); + if (ctx->idisp_codec) + ret = sof_sdw_hdmi_card_late_probe(card); + + return ret; } /* SoC card */ -- GitLab From b585692fc937dc8f9d494078b5ffe2aafe31ec18 Mon Sep 17 00:00:00 2001 From: Ajit Kumar Pandey Date: Mon, 6 Jun 2022 16:02:08 -0500 Subject: [PATCH 265/942] ASoC: SOF: amd: Add SOF pm ops callback for Renoir Add SOF PM ops callback in renoir dsp ops to power off and on ACP IP block during system suspend and resume on Renoir platform. Signed-off-by: Ajit Kumar Pandey Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606210212.146626-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/amd/acp-dsp-offset.h | 2 ++ sound/soc/sof/amd/acp.c | 36 ++++++++++++++++++++++++++++++ sound/soc/sof/amd/acp.h | 4 ++++ sound/soc/sof/amd/pci-rn.c | 4 ++++ sound/soc/sof/amd/renoir.c | 4 ++++ 5 files changed, 50 insertions(+) diff --git a/sound/soc/sof/amd/acp-dsp-offset.h b/sound/soc/sof/amd/acp-dsp-offset.h index 40fbf11facba5..56cefd4a84fcd 100644 --- a/sound/soc/sof/amd/acp-dsp-offset.h +++ b/sound/soc/sof/amd/acp-dsp-offset.h @@ -46,12 +46,14 @@ #define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0xC3C #define ACPAXI2AXI_ATU_CTRL 0xC40 #define ACP_SOFT_RESET 0x1000 +#define ACP_CONTROL 0x1004 #define ACP_I2S_PIN_CONFIG 0x1400 /* Registers from ACP_PGFSM block */ #define ACP_PGFSM_CONTROL 0x141C #define ACP_PGFSM_STATUS 0x1420 +#define ACP_CLKMUX_SEL 0x1424 /* Registers from ACP_INTR block */ #define ACP_EXTERNAL_INTR_ENB 0x1800 diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index 0c272573df979..c40d2900dd36d 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -413,10 +413,46 @@ static int acp_init(struct snd_sof_dev *sdev) dev_err(sdev->dev, "ACP power on failed\n"); return ret; } + + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x01); /* Reset */ return acp_reset(sdev); } +int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state) +{ + int ret; + + ret = acp_reset(sdev); + if (ret) { + dev_err(sdev->dev, "ACP Reset failed\n"); + return ret; + } + + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x00); + + return 0; +} +EXPORT_SYMBOL_NS(amd_sof_acp_suspend, SND_SOC_SOF_AMD_COMMON); + +int amd_sof_acp_resume(struct snd_sof_dev *sdev) +{ + int ret; + + ret = acp_init(sdev); + if (ret) { + dev_err(sdev->dev, "ACP Init failed\n"); + return ret; + } + + snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CLKMUX_SEL, 0x03); + + ret = acp_memory_init(sdev); + + return ret; +} +EXPORT_SYMBOL_NS(amd_sof_acp_resume, SND_SOC_SOF_AMD_COMMON); + int amd_sof_acp_probe(struct snd_sof_dev *sdev) { struct pci_dev *pci = to_pci_dev(sdev->dev); diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h index 291b44c54bcc2..4c42b8fd6abf1 100644 --- a/sound/soc/sof/amd/acp.h +++ b/sound/soc/sof/amd/acp.h @@ -216,6 +216,10 @@ int acp_sof_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct sof_ipc_dma_trace_params_ext *dtrace_params); int acp_sof_trace_release(struct snd_sof_dev *sdev); +/* PM Callbacks */ +int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state); +int amd_sof_acp_resume(struct snd_sof_dev *sdev); + struct sof_amd_acp_desc { unsigned int host_bridge_id; }; diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index d5d9bcc2c997d..3a7fed25a2267 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -49,6 +49,7 @@ static const struct sof_amd_acp_desc renoir_chip_info = { static const struct sof_dev_desc renoir_desc = { .machines = snd_soc_acpi_amd_sof_machines, + .use_acpi_target_states = true, .resindex_lpe_base = 0, .resindex_pcicfg_base = -1, .resindex_imr_base = -1, @@ -166,6 +167,9 @@ static struct pci_driver snd_sof_pci_amd_rn_driver = { .id_table = rn_pci_ids, .probe = acp_pci_rn_probe, .remove = acp_pci_rn_remove, + .driver = { + .pm = &sof_pci_pm, + }, }; module_pci_driver(snd_sof_pci_amd_rn_driver); diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c index 70190365328ce..9261c8bc2236d 100644 --- a/sound/soc/sof/amd/renoir.c +++ b/sound/soc/sof/amd/renoir.c @@ -173,6 +173,10 @@ struct snd_sof_dsp_ops sof_renoir_ops = { /* Trace Logger */ .trace_init = acp_sof_trace_init, .trace_release = acp_sof_trace_release, + + /* PM */ + .suspend = amd_sof_acp_suspend, + .resume = amd_sof_acp_resume, }; EXPORT_SYMBOL(sof_renoir_ops); -- GitLab From e53b20598f394e37951d6355f1c88ae01165b53f Mon Sep 17 00:00:00 2001 From: YC Hung Date: Mon, 6 Jun 2022 16:02:09 -0500 Subject: [PATCH 266/942] ASoC: SOF: mediatek: revise mt8195 clock sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clock enable : enable and set audio_h selection as 26M. Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: YC Hung Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606210212.146626-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8195/mt8195-clk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-clk.c b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c index 6bcb4b9b00fb9..9ef08e43aa38b 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195-clk.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c @@ -132,6 +132,13 @@ static int adsp_default_clk_init(struct snd_sof_dev *sdev, bool enable) return ret; } + ret = clk_set_parent(priv->clk[CLK_TOP_AUDIO_H], + priv->clk[CLK_TOP_CLK26M]); + if (ret) { + dev_err(dev, "set audio_h_sel failed %d\n", ret); + return ret; + } + ret = adsp_enable_all_clock(sdev); if (ret) { dev_err(dev, "failed to adsp_enable_clock: %d\n", ret); -- GitLab From fd43dcbb859c85831a05e37287e1c5395f54aba8 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Mon, 6 Jun 2022 16:02:10 -0500 Subject: [PATCH 267/942] ASoC: SOF: mediatek: Add shared_size for mediatek common chip information Add shared_size for mediatek common chip information which is used for audio and trace dma. Reviewed-by: Curtis Malainey Reviewed-by: Ranjani Sridharan Signed-off-by: YC Hung Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606210212.146626-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/adsp_helper.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h index 4ab998756bbc0..d41e904e6614e 100644 --- a/sound/soc/sof/mediatek/adsp_helper.h +++ b/sound/soc/sof/mediatek/adsp_helper.h @@ -20,6 +20,7 @@ struct mtk_adsp_chip_info { u32 sramsize; u32 dramsize; u32 cfgregsize; + u32 shared_size; void __iomem *va_sram; /* corresponding to pa_sram */ void __iomem *va_dram; /* corresponding to pa_dram */ void __iomem *va_cfgreg; -- GitLab From 0bf4276cc7883d65e594926c1159d4c0712d02e7 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Mon, 6 Jun 2022 16:02:11 -0500 Subject: [PATCH 268/942] ASoC: SOF: mediatek: mt8195 modify dram type as non-cache Modify dram as non-cache memory type to avoid wrong access between host and dsp side and get the size of shared dma from device tree. Reviewed-by: Curtis Malainey Reviewed-by: Ranjani Sridharan Signed-off-by: YC Hung Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606210212.146626-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8195/mt8195.c | 37 +++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 30111ab23bf5e..64d1b5a4e31b1 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -145,6 +145,14 @@ static int platform_parse_resource(struct platform_device *pdev, void *data) dev_dbg(dev, "DMA %pR\n", &res); + adsp->pa_shared_dram = (phys_addr_t)res.start; + adsp->shared_size = resource_size(&res); + if (adsp->pa_shared_dram & DRAM_REMAP_MASK) { + dev_err(dev, "adsp shared dma memory(%#x) is not 4K-aligned\n", + (u32)adsp->pa_shared_dram); + return -EINVAL; + } + ret = of_reserved_mem_device_init(dev); if (ret) { dev_err(dev, "of_reserved_mem_device_init failed\n"); @@ -273,23 +281,18 @@ static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data) { struct device *dev = &pdev->dev; struct mtk_adsp_chip_info *adsp = data; - u32 shared_size; /* remap shared-dram base to be non-cachable */ - shared_size = TOTAL_SIZE_SHARED_DRAM_FROM_TAIL; - adsp->pa_shared_dram = adsp->pa_dram + adsp->dramsize - shared_size; - if (adsp->va_dram) { - adsp->shared_dram = adsp->va_dram + DSP_DRAM_SIZE - shared_size; - } else { - adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram, - shared_size); - if (!adsp->shared_dram) { - dev_err(dev, "ioremap failed for shared DRAM\n"); - return -ENOMEM; - } + adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram, + adsp->shared_size); + if (!adsp->shared_dram) { + dev_err(dev, "failed to ioremap base %pa size %#x\n", + adsp->shared_dram, adsp->shared_size); + return -ENOMEM; } + dev_dbg(dev, "shared-dram vbase=%p, phy addr :%pa, size=%#x\n", - adsp->shared_dram, &adsp->pa_shared_dram, shared_size); + adsp->shared_dram, &adsp->pa_shared_dram, adsp->shared_size); return 0; } @@ -361,9 +364,11 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev) goto err_adsp_sram_power_off; } - sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, - priv->adsp->pa_dram, - priv->adsp->dramsize); + priv->adsp->va_sram = sdev->bar[SOF_FW_BLK_TYPE_IRAM]; + + sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap(sdev->dev, + priv->adsp->pa_dram, + priv->adsp->dramsize); if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n", &priv->adsp->pa_dram, priv->adsp->dramsize); -- GitLab From 078f28fee5aa417169d8e8906815c684beddbe74 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Mon, 6 Jun 2022 16:02:12 -0500 Subject: [PATCH 269/942] ASoC: SOF: mediatek: mt8195 suspend check dsp idle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During suspend flow, sof_suspend will be called and the pm_ops->ctx_save callback notifies DSP of the upcoming power down. Upon receipt of the ctx_save IPC, the DSP will start the D3 transition. Before the DSP enter idle, an interrupt is generated to notify the host of the power state change. Since the host and DSP are two different processors, there could be a race condition, which can be avoided by polling with 1s timeout and 500us intervals Reviewed-by: Péter Ujfalusi Signed-off-by: YC Hung Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220606210212.146626-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8195/mt8195.c | 13 +++++++++++++ sound/soc/sof/mediatek/mt8195/mt8195.h | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 64d1b5a4e31b1..9c146015cd1b7 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -443,6 +443,19 @@ static int mt8195_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) { struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); int ret; + u32 reset_sw, dbg_pc; + + /* wait dsp enter idle, timeout is 1 second */ + ret = snd_sof_dsp_read_poll_timeout(sdev, DSP_REG_BAR, + DSP_RESET_SW, reset_sw, + ((reset_sw & ADSP_PWAIT) == ADSP_PWAIT), + SUSPEND_DSP_IDLE_POLL_INTERVAL_US, + SUSPEND_DSP_IDLE_TIMEOUT_US); + if (ret < 0) { + dbg_pc = snd_sof_dsp_read(sdev, DSP_REG_BAR, DSP_PDEBUGPC); + dev_warn(sdev->dev, "dsp not idle, powering off anyway : swrest %#x, pc %#x, ret %d\n", + reset_sw, dbg_pc, ret); + } /* stall and reset dsp */ sof_hifixdsp_shutdown(sdev); diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.h b/sound/soc/sof/mediatek/mt8195/mt8195.h index 9294241823572..7ffd523f936c8 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.h +++ b/sound/soc/sof/mediatek/mt8195/mt8195.h @@ -34,6 +34,7 @@ struct snd_sof_dev; #define ADSP_DRESET_SW BIT(1) #define ADSP_RUNSTALL BIT(3) #define STATVECTOR_SEL BIT(4) +#define ADSP_PWAIT BIT(16) #define DSP_PFAULTBUS 0x0028 #define DSP_PFAULTINFO 0x002c #define DSP_GPR00 0x0030 @@ -153,6 +154,10 @@ struct snd_sof_dev; #define DRAM_REMAP_SHIFT 12 #define DRAM_REMAP_MASK (BIT(DRAM_REMAP_SHIFT) - 1) +/* suspend dsp idle check interval and timeout */ +#define SUSPEND_DSP_IDLE_TIMEOUT_US 1000000 /* timeout to wait dsp idle, 1 sec */ +#define SUSPEND_DSP_IDLE_POLL_INTERVAL_US 500 /* 0.5 msec */ + void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr); void sof_hifixdsp_shutdown(struct snd_sof_dev *sdev); #endif -- GitLab From f55a07074fdd38cab8c097ac5bd397d68eff733c Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Thu, 2 Jun 2022 14:01:06 +0000 Subject: [PATCH 270/942] amt: fix wrong usage of pskb_may_pull() It adds missing pskb_may_pull() in amt_update_handler() and amt_multicast_data_handler(). And it fixes wrong parameter of pskb_may_pull() in amt_advertisement_handler() and amt_membership_query_handler(). Reported-by: Jakub Kicinski Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface") Signed-off-by: Taehee Yoo Signed-off-by: Jakub Kicinski --- drivers/net/amt.c | 55 +++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/net/amt.c b/drivers/net/amt.c index ebee5f07a208e..900948e135ad1 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -2220,8 +2220,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb) struct amt_header_advertisement *amta; int hdr_size; - hdr_size = sizeof(*amta) - sizeof(struct amt_header); - + hdr_size = sizeof(*amta) + sizeof(struct udphdr); if (!pskb_may_pull(skb, hdr_size)) return true; @@ -2251,19 +2250,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb) struct ethhdr *eth; struct iphdr *iph; + hdr_size = sizeof(*amtmd) + sizeof(struct udphdr); + if (!pskb_may_pull(skb, hdr_size)) + return true; + amtmd = (struct amt_header_mcast_data *)(udp_hdr(skb) + 1); if (amtmd->reserved || amtmd->version) return true; - hdr_size = sizeof(*amtmd) + sizeof(struct udphdr); if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_IP), false)) return true; + skb_reset_network_header(skb); skb_push(skb, sizeof(*eth)); skb_reset_mac_header(skb); skb_pull(skb, sizeof(*eth)); eth = eth_hdr(skb); + + if (!pskb_may_pull(skb, sizeof(*iph))) + return true; iph = ip_hdr(skb); + if (iph->version == 4) { if (!ipv4_is_multicast(iph->daddr)) return true; @@ -2274,6 +2281,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb) } else if (iph->version == 6) { struct ipv6hdr *ip6h; + if (!pskb_may_pull(skb, sizeof(*ip6h))) + return true; + ip6h = ipv6_hdr(skb); if (!ipv6_addr_is_multicast(&ip6h->daddr)) return true; @@ -2306,8 +2316,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt, struct iphdr *iph; int hdr_size, len; - hdr_size = sizeof(*amtmq) - sizeof(struct amt_header); - + hdr_size = sizeof(*amtmq) + sizeof(struct udphdr); if (!pskb_may_pull(skb, hdr_size)) return true; @@ -2315,22 +2324,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt, if (amtmq->reserved || amtmq->version) return true; - hdr_size = sizeof(*amtmq) + sizeof(struct udphdr) - sizeof(*eth); + hdr_size -= sizeof(*eth); if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false)) return true; + oeth = eth_hdr(skb); skb_reset_mac_header(skb); skb_pull(skb, sizeof(*eth)); skb_reset_network_header(skb); eth = eth_hdr(skb); + if (!pskb_may_pull(skb, sizeof(*iph))) + return true; + iph = ip_hdr(skb); if (iph->version == 4) { - if (!ipv4_is_multicast(iph->daddr)) - return true; if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS + sizeof(*ihv3))) return true; + if (!ipv4_is_multicast(iph->daddr)) + return true; + ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS); skb_reset_transport_header(skb); skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS); @@ -2345,15 +2359,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt, ip_eth_mc_map(iph->daddr, eth->h_dest); #if IS_ENABLED(CONFIG_IPV6) } else if (iph->version == 6) { - struct ipv6hdr *ip6h = ipv6_hdr(skb); struct mld2_query *mld2q; + struct ipv6hdr *ip6h; - if (!ipv6_addr_is_multicast(&ip6h->daddr)) - return true; if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS + sizeof(*mld2q))) return true; + ip6h = ipv6_hdr(skb); + if (!ipv6_addr_is_multicast(&ip6h->daddr)) + return true; + mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS); skb_reset_transport_header(skb); skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS); @@ -2389,23 +2405,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) { struct amt_header_membership_update *amtmu; struct amt_tunnel_list *tunnel; - struct udphdr *udph; struct ethhdr *eth; struct iphdr *iph; - int len; + int len, hdr_size; iph = ip_hdr(skb); - udph = udp_hdr(skb); - if (__iptunnel_pull_header(skb, sizeof(*udph), skb->protocol, - false, false)) + hdr_size = sizeof(*amtmu) + sizeof(struct udphdr); + if (!pskb_may_pull(skb, hdr_size)) return true; - amtmu = (struct amt_header_membership_update *)skb->data; + amtmu = (struct amt_header_membership_update *)(udp_hdr(skb) + 1); if (amtmu->reserved || amtmu->version) return true; - skb_pull(skb, sizeof(*amtmu)); + if (iptunnel_pull_header(skb, hdr_size, skb->protocol, false)) + return true; + skb_reset_network_header(skb); list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) { @@ -2426,6 +2442,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) return true; report: + if (!pskb_may_pull(skb, sizeof(*iph))) + return true; + iph = ip_hdr(skb); if (iph->version == 4) { if (ip_mc_check_igmp(skb)) { -- GitLab From d16207f92a4a823c48b4ea953ad51f4483456768 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Thu, 2 Jun 2022 14:01:07 +0000 Subject: [PATCH 271/942] amt: fix possible null-ptr-deref in amt_rcv() When amt interface receives amt message, it tries to obtain amt private data from sock. If there is no amt private data, it frees an skb immediately. After kfree_skb(), it increases the rx_dropped stats. But in order to use rx_dropped, amt private data is needed. So, it makes amt_rcv() to do not increase rx_dropped stats when it can not obtain amt private data. Reported-by: kernel test robot Reported-by: Dan Carpenter Fixes: 1a1a0e80e005 ("amt: fix possible memory leak in amt_rcv()") Signed-off-by: Taehee Yoo Signed-off-by: Jakub Kicinski --- drivers/net/amt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 900948e135ad1..ef483bf510330 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -2698,7 +2698,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb) amt = rcu_dereference_sk_user_data(sk); if (!amt) { err = true; - goto drop; + kfree_skb(skb); + goto out; } skb->dev = amt->dev; -- GitLab From d7970039d87c926bb648982e920cb9851c19f3e1 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Thu, 2 Jun 2022 14:01:08 +0000 Subject: [PATCH 272/942] amt: fix wrong type string definition amt message type definition starts from 1, not 0. But type_str[] starts from 0. So, it prints wrong type information. Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface") Signed-off-by: Taehee Yoo Signed-off-by: Jakub Kicinski --- drivers/net/amt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/amt.c b/drivers/net/amt.c index ef483bf510330..be2719a3ba702 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -51,6 +51,7 @@ static char *status_str[] = { }; static char *type_str[] = { + "", /* Type 0 is not defined */ "AMT_MSG_DISCOVERY", "AMT_MSG_ADVERTISEMENT", "AMT_MSG_REQUEST", -- GitLab From b8d91399775c55162073bb2aca061ec42e3d4bc1 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 3 Jun 2022 17:32:38 +0400 Subject: [PATCH 273/942] net: ethernet: bgmac: Fix refcount leak in bcma_mdio_mii_register of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: 55954f3bfdac ("net: ethernet: bgmac: move BCMA MDIO Phy code into a separate file") Signed-off-by: Miaoqian Lin Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/20220603133238.44114-1-linmq006@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c index 086739e4f40a9..9b83d53616994 100644 --- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c +++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c @@ -234,6 +234,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac) np = of_get_child_by_name(core->dev.of_node, "mdio"); err = of_mdiobus_register(mii_bus, np); + of_node_put(np); if (err) { dev_err(&core->dev, "Registration of mii bus failed\n"); goto err_free_bus; -- GitLab From 8ea21823aa584b55ba4b861307093b78054b0c1b Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Tue, 31 May 2022 12:31:05 +0000 Subject: [PATCH 274/942] cifs: return errors during session setup during reconnects During reconnects, we check the return value from cifs_negotiate_protocol, and have handlers for both success and failures. But if that passes, and cifs_setup_session returns any errors other than -EACCES, we do not handle that. This fix adds a handler for that, so that we don't go ahead and try a tree_connect on a failed session. Signed-off-by: Shyam Prasad N Reviewed-by: Enzo Matsumiya Cc: stable@vger.kernel.org Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 0e8c852495791..eaf975f1ad893 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -288,6 +288,9 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, mutex_unlock(&ses->session_mutex); rc = -EHOSTDOWN; goto failed; + } else if (rc) { + mutex_unlock(&ses->session_mutex); + goto out; } } else { mutex_unlock(&ses->session_mutex); -- GitLab From dbac14a5a05ff8e1ce7c0da0e1f520ce39ec62ea Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 6 Jun 2022 13:59:20 +0900 Subject: [PATCH 275/942] xen: unexport __init-annotated xen_xlate_map_ballooned_pages() EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic. modpost used to detect it, but it has been broken for a decade. Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds. There are two ways to fix it: - Remove __init - Remove EXPORT_SYMBOL I chose the latter for this case because none of the in-tree call-sites (arch/arm/xen/enlighten.c, arch/x86/xen/grant-table.c) is compiled as modular. Fixes: 243848fc018c ("xen/grant-table: Move xlated_setup_gnttab_pages to common place") Reported-by: Stephen Rothwell Signed-off-by: Masahiro Yamada Reviewed-by: Oleksandr Tyshchenko Acked-by: Stefano Stabellini Link: https://lore.kernel.org/r/20220606045920.4161881-1-masahiroy@kernel.org Signed-off-by: Juergen Gross --- drivers/xen/xlate_mmu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c index 34742c6e189e3..f17c4c03db30c 100644 --- a/drivers/xen/xlate_mmu.c +++ b/drivers/xen/xlate_mmu.c @@ -261,7 +261,6 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt, return 0; } -EXPORT_SYMBOL_GPL(xen_xlate_map_ballooned_pages); struct remap_pfn { struct mm_struct *mm; -- GitLab From 77991645952c21962a095910c51fe0f73d35bf91 Mon Sep 17 00:00:00 2001 From: Roger Knecht Date: Sat, 21 May 2022 14:47:45 +0200 Subject: [PATCH 276/942] crc-itu-t: fix typo in CRC ITU-T polynomial comment The code comment says that the polynomial is x^16 + x^12 + x^15 + 1, but the correct polynomial is x^16 + x^12 + x^5 + 1. Quoting from page 2 in the ITU-T V.41 specification [1]: 2 Encoding and checking process The service bits and information bits, taken in conjunction, correspond to the coefficients of a message polynomial having terms from x^(n-1) (n = total number of bits in a block or sequence) down to x^16. This polynomial is divided, modulo 2, by the generating polynomial x^16 + x^12 + x^5 + 1. The hex (truncated) polynomial 0x1021 and CRC code implementation are correct, however. [1] https://www.itu.int/rec/T-REC-V.41-198811-I/en Signed-off-by: Roger Knecht Acked-by: Randy Dunlap Signed-off-by: Jason A. Donenfeld --- include/linux/crc-itu-t.h | 2 +- lib/crc-itu-t.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/crc-itu-t.h b/include/linux/crc-itu-t.h index a4367051e192c..2f991a427aded 100644 --- a/include/linux/crc-itu-t.h +++ b/include/linux/crc-itu-t.h @@ -4,7 +4,7 @@ * * Implements the standard CRC ITU-T V.41: * Width 16 - * Poly 0x1021 (x^16 + x^12 + x^15 + 1) + * Poly 0x1021 (x^16 + x^12 + x^5 + 1) * Init 0 */ diff --git a/lib/crc-itu-t.c b/lib/crc-itu-t.c index 1974b355c1486..1d26a1647da53 100644 --- a/lib/crc-itu-t.c +++ b/lib/crc-itu-t.c @@ -7,7 +7,7 @@ #include #include -/** CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^15 + 1) */ +/* CRC table for the CRC ITU-T V.41 0x1021 (x^16 + x^12 + x^5 + 1) */ const u16 crc_itu_t_table[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, -- GitLab From 5e74a4b3ec1816e3bbfd715d46ae29d2508079cb Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 5 Jun 2022 22:50:48 +0200 Subject: [PATCH 277/942] stmmac: intel: Fix an error handling path in intel_eth_pci_probe() When the managed API is used, there is no need to explicitly call pci_free_irq_vectors(). This looks to be a left-over from the commit in the Fixes tag. Only the .remove() function had been updated. So remove this unused function call and update goto label accordingly. Fixes: 8accc467758e ("stmmac: intel: use managed PCI function on probe and resume") Signed-off-by: Christophe JAILLET Reviewed-by: Wong Vee Khee Link: https://lore.kernel.org/r/1ac9b6787b0db83b0095711882c55c77c8ea8da0.1654462241.git.christophe.jaillet@wanadoo.fr Signed-off-by: Paolo Abeni --- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index f9f80933e0c9c..38fe77d1035e3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -1072,13 +1072,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, ret = stmmac_dvr_probe(&pdev->dev, plat, &res); if (ret) { - goto err_dvr_probe; + goto err_alloc_irq; } return 0; -err_dvr_probe: - pci_free_irq_vectors(pdev); err_alloc_irq: clk_disable_unprepare(plat->stmmac_clk); clk_unregister_fixed_rate(plat->stmmac_clk); -- GitLab From 662a80946ce13633ae90a55379f1346c10f0c432 Mon Sep 17 00:00:00 2001 From: Kuniyuki Iwashima Date: Sun, 5 Jun 2022 16:23:25 -0700 Subject: [PATCH 278/942] af_unix: Fix a data-race in unix_dgram_peer_wake_me(). unix_dgram_poll() calls unix_dgram_peer_wake_me() without `other`'s lock held and check if its receive queue is full. Here we need to use unix_recvq_full_lockless() instead of unix_recvq_full(), otherwise KCSAN will report a data-race. Fixes: 7d267278a9ec ("unix: avoid use-after-free in ep_remove_wait_queue") Signed-off-by: Kuniyuki Iwashima Link: https://lore.kernel.org/r/20220605232325.11804-1-kuniyu@amazon.com Signed-off-by: Paolo Abeni --- net/unix/af_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 654dcef7cfb38..2206e6f8902d7 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -490,7 +490,7 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) * -ECONNREFUSED. Otherwise, if we haven't queued any skbs * to other and its full, we will hang waiting for POLLOUT. */ - if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD)) + if (unix_recvq_full_lockless(other) && !sock_flag(other, SOCK_DEAD)) return 1; if (connected) -- GitLab From aa0d5f095093610e7274591d41a28381f60467a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 5 Jun 2022 17:39:04 +0200 Subject: [PATCH 279/942] ASoC: Intel: broadwell: Make broadwell_disable_jack() return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit broadwell_disable_jack() returns zero unconditionally. Letting it return void instead makes it easier to see in the callers that there is no error to handle. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220605153904.26921-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/intel/boards/broadwell.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index c30a9dca68011..b29d77dfb2813 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -227,7 +227,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { }, }; -static int broadwell_disable_jack(struct snd_soc_card *card) +static void broadwell_disable_jack(struct snd_soc_card *card) { struct snd_soc_component *component; @@ -239,13 +239,13 @@ static int broadwell_disable_jack(struct snd_soc_card *card) break; } } - - return 0; } static int broadwell_suspend(struct snd_soc_card *card) { - return broadwell_disable_jack(card); + broadwell_disable_jack(card); + + return 0; } static int broadwell_resume(struct snd_soc_card *card){ @@ -315,7 +315,9 @@ static int broadwell_audio_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - return broadwell_disable_jack(card); + broadwell_disable_jack(card); + + return 0; } static struct platform_driver broadwell_audio = { -- GitLab From 69c8027c5ff43d68449fda4510a8cce70e8578b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 6 Jun 2022 16:25:44 +0100 Subject: [PATCH 280/942] ASoC: wm8731: update wlf,wm8731.yaml reference Changeset 0e336eeaf467 ("ASoC: wm8731: Convert DT bindings to YAML format") renamed: Documentation/devicetree/bindings/sound/wm8731.txt to: Documentation/devicetree/bindings/sound/wlf,wm8731.yaml. Update its cross-reference accordingly. Fixes: 0e336eeaf467 ("ASoC: wm8731: Convert DT bindings to YAML format") Signed-off-by: Mauro Carvalho Chehab Acked-by: Rob Herring Link: https://lore.kernel.org/r/e56e54fe0ebb1b6e8dd2e245c398190016eb0a34.1654529011.git.mchehab@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt index 0720857089a7d..8facbce53db86 100644 --- a/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt +++ b/Documentation/devicetree/bindings/sound/atmel-sam9x5-wm8731-audio.txt @@ -16,7 +16,7 @@ Board connectors: * Line In Jack wm8731 pins: -cf Documentation/devicetree/bindings/sound/wm8731.txt +cf Documentation/devicetree/bindings/sound/wlf,wm8731.yaml Example: sound { -- GitLab From e6f08af6340eaf88e9eeff71bd4533eee9a04119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Sun, 5 Jun 2022 17:35:37 +0200 Subject: [PATCH 281/942] ASoC: simple-card-utils: Make asoc_simple_clean_reference() return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit asoc_simple_clean_reference() returns zero unconditionally. Letting it return void instead makes it easier to see in the caller that there is no error to handle. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220605153537.26591-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- include/sound/simple_card_utils.h | 2 +- sound/soc/generic/simple-card-utils.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 8faa649f712b8..fe2337fde1f46 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -173,7 +173,7 @@ void asoc_simple_canonicalize_platform(struct snd_soc_dai_link_component *platfo void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link_component *cpus, int is_single_links); -int asoc_simple_clean_reference(struct snd_soc_card *card); +void asoc_simple_clean_reference(struct snd_soc_card *card); void asoc_simple_convert_fixup(struct asoc_simple_data *data, struct snd_pcm_hw_params *params); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index fa080f166345c..0beda9739ebed 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -609,7 +609,7 @@ void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link_component *cpus, } EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_cpu); -int asoc_simple_clean_reference(struct snd_soc_card *card) +void asoc_simple_clean_reference(struct snd_soc_card *card) { struct snd_soc_dai_link *dai_link; struct snd_soc_dai_link_component *cpu; @@ -622,7 +622,6 @@ int asoc_simple_clean_reference(struct snd_soc_card *card) for_each_link_codecs(dai_link, j, codec) of_node_put(codec->of_node); } - return 0; } EXPORT_SYMBOL_GPL(asoc_simple_clean_reference); @@ -877,7 +876,9 @@ int asoc_simple_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - return asoc_simple_clean_reference(card); + asoc_simple_clean_reference(card); + + return 0; } EXPORT_SYMBOL_GPL(asoc_simple_remove); -- GitLab From efe2178d1a32492f99e7f1f2568eea5c88a85729 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Fri, 3 Jun 2022 16:42:41 +0400 Subject: [PATCH 282/942] ASoC: mediatek: mt8173-rt5650: Fix refcount leak in mt8173_rt5650_dev_probe of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore. Fix refcount leak in some error paths. Fixes: 0f83f9296d5c ("ASoC: mediatek: Add machine driver for ALC5650 codec") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220603124243.31358-1-linmq006@gmail.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8173/mt8173-rt5650.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index d1c94acb45169..e05f2b0231fe8 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -280,7 +280,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node; @@ -293,7 +294,7 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s codec_capture_dai name fail %d\n", __func__, ret); - return ret; + goto put_platform_node; } mt8173_rt5650_dais[DAI_LINK_CODEC_I2S].codecs[1].dai_name = codec_capture_dai; @@ -315,12 +316,14 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) if (!mt8173_rt5650_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto put_platform_node; } card->dev = &pdev->dev; ret = devm_snd_soc_register_card(&pdev->dev, card); +put_platform_node: of_node_put(platform_node); return ret; } -- GitLab From cf67838c4422eab826679b076dad99f96152b4de Mon Sep 17 00:00:00 2001 From: Lina Wang Date: Mon, 6 Jun 2022 14:45:17 +0800 Subject: [PATCH 283/942] selftests net: fix bpf build error bpf_helpers.h has been moved to tools/lib/bpf since 5.10, so add more including path. Fixes: edae34a3ed92 ("selftests net: add UDP GRO fraglist + bpf self-tests") Reported-by: kernel test robot Signed-off-by: Lina Wang Acked-by: Song Liu Acked-by: Paolo Abeni Link: https://lore.kernel.org/r/20220606064517.8175-1-lina.wang@mediatek.com Signed-off-by: Paolo Abeni --- tools/testing/selftests/net/bpf/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/bpf/Makefile b/tools/testing/selftests/net/bpf/Makefile index f91bf14bbee7b..8a69c91fcca07 100644 --- a/tools/testing/selftests/net/bpf/Makefile +++ b/tools/testing/selftests/net/bpf/Makefile @@ -2,6 +2,7 @@ CLANG ?= clang CCINCLUDE += -I../../bpf +CCINCLUDE += -I../../../lib CCINCLUDE += -I../../../../../usr/include/ TEST_CUSTOM_PROGS = $(OUTPUT)/bpf/nat6to4.o @@ -10,5 +11,4 @@ all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/%.o: %.c $(CLANG) -O2 -target bpf -c $< $(CCINCLUDE) -o $@ -clean: - rm -f $(TEST_CUSTOM_PROGS) +EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) -- GitLab From e8bc2427018826e02add7b0ed0fc625a60390ae5 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 1 Jun 2022 03:43:28 +0200 Subject: [PATCH 284/942] KVM: Don't null dereference ops->destroy A KVM device cleanup happens in either of two callbacks: 1) destroy() which is called when the VM is being destroyed; 2) release() which is called when a device fd is closed. Most KVM devices use 1) but Book3s's interrupt controller KVM devices (XICS, XIVE, XIVE-native) use 2) as they need to close and reopen during the machine execution. The error handling in kvm_ioctl_create_device() assumes destroy() is always defined which leads to NULL dereference as discovered by Syzkaller. This adds a checks for destroy!=NULL and adds a missing release(). This is not changing kvm_destroy_devices() as devices with defined release() should have been removed from the KVM devices list by then. Suggested-by: Paolo Bonzini Signed-off-by: Alexey Kardashevskiy Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 342043b301254..f2922ba3b7a81 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4300,8 +4300,11 @@ static int kvm_ioctl_create_device(struct kvm *kvm, kvm_put_kvm_no_destroy(kvm); mutex_lock(&kvm->lock); list_del(&dev->vm_node); + if (ops->release) + ops->release(dev); mutex_unlock(&kvm->lock); - ops->destroy(dev); + if (ops->destroy) + ops->destroy(dev); return ret; } -- GitLab From 3e684903a8574ffc9475fdf13c4780a7adb506ad Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Wed, 4 May 2022 13:08:40 -0500 Subject: [PATCH 285/942] entry/kvm: Exit to user mode when TIF_NOTIFY_SIGNAL is set A livepatch transition may stall indefinitely when a kvm vCPU is heavily loaded. To the host, the vCPU task is a user thread which is spending a very long time in the ioctl(KVM_RUN) syscall. During livepatch transition, set_notify_signal() will be called on such tasks to interrupt the syscall so that the task can be transitioned. This interrupts guest execution, but when xfer_to_guest_mode_work() sees that TIF_NOTIFY_SIGNAL is set but not TIF_SIGPENDING it concludes that an exit to user mode is unnecessary, and guest execution is resumed without transitioning the task for the livepatch. This handling of TIF_NOTIFY_SIGNAL is incorrect, as set_notify_signal() is expected to break tasks out of interruptible kernel loops and cause them to return to userspace. Change xfer_to_guest_mode_work() to handle TIF_NOTIFY_SIGNAL the same as TIF_SIGPENDING, signaling to the vCPU run loop that an exit to userpsace is needed. Any pending task_work will be run when get_signal() is called from exit_to_user_mode_loop(), so there is no longer any need to run task work from xfer_to_guest_mode_work(). Suggested-by: "Eric W. Biederman" Cc: Petr Mladek Signed-off-by: Seth Forshee Message-Id: <20220504180840.2907296-1-sforshee@digitalocean.com> Signed-off-by: Paolo Bonzini --- kernel/entry/kvm.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c index 9d09f489b60e0..2e0f75bcb7fd1 100644 --- a/kernel/entry/kvm.c +++ b/kernel/entry/kvm.c @@ -9,12 +9,6 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work) int ret; if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) { - clear_notify_signal(); - if (task_work_pending(current)) - task_work_run(); - } - - if (ti_work & _TIF_SIGPENDING) { kvm_handle_signal_exit(vcpu); return -EINTR; } -- GitLab From cf4a8693d97a51dccf5a1557248d12d6d8be4b9e Mon Sep 17 00:00:00 2001 From: Shaoqin Huang Date: Mon, 6 Jun 2022 18:59:05 -0600 Subject: [PATCH 286/942] KVM: x86/mmu: Check every prev_roots in __kvm_mmu_free_obsolete_roots() When freeing obsolete previous roots, check prev_roots as intended, not the current root. Signed-off-by: Shaoqin Huang Fixes: 527d5cd7eece ("KVM: x86/mmu: Zap only obsolete roots if a root shadow page is zapped") Message-Id: <20220607005905.2933378-1-shaoqin.huang@intel.com> Cc: stable@vger.kernel.org Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index efe5a3dca1e09..e46771e951911 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5179,7 +5179,7 @@ static void __kvm_mmu_free_obsolete_roots(struct kvm *kvm, struct kvm_mmu *mmu) roots_to_free |= KVM_MMU_ROOT_CURRENT; for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) { - if (is_obsolete_root(kvm, mmu->root.hpa)) + if (is_obsolete_root(kvm, mmu->prev_roots[i].hpa)) roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i); } -- GitLab From 1df931d95f4dc1c11db1123e85d4e08156e46ef9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Jun 2022 17:00:53 +0200 Subject: [PATCH 287/942] x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm() As noted (and fixed) a couple of times in the past, "=@cc" outputs and clobbering of "cc" don't work well together. The compiler appears to mean to reject such, but doesn't - in its upstream form - quite manage to yet for "cc". Furthermore two similar macros don't clobber "cc", and clobbering "cc" is pointless in asm()-s for x86 anyway - the compiler always assumes status flags to be clobbered there. Fixes: 989b5db215a2 ("x86/uaccess: Implement macros for CMPXCHG on user addresses") Signed-off-by: Jan Beulich Message-Id: <485c0c0b-a3a7-0b7c-5264-7d00c01de032@suse.com> Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 35f222aa66bfc..913e593a3b45f 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -439,7 +439,7 @@ do { \ [ptr] "+m" (*_ptr), \ [old] "+a" (__old) \ : [new] ltype (__new) \ - : "memory", "cc"); \ + : "memory"); \ if (unlikely(__err)) \ goto label; \ if (unlikely(!success)) \ -- GitLab From 5ba7c4c6d1c7af47a916f728bb5940669684a087 Mon Sep 17 00:00:00 2001 From: Ben Gardon Date: Wed, 25 May 2022 23:09:04 +0000 Subject: [PATCH 288/942] KVM: x86/MMU: Zap non-leaf SPTEs when disabling dirty logging Currently disabling dirty logging with the TDP MMU is extremely slow. On a 96 vCPU / 96G VM backed with gigabyte pages, it takes ~200 seconds to disable dirty logging with the TDP MMU, as opposed to ~4 seconds with the shadow MMU. When disabling dirty logging, zap non-leaf parent entries to allow replacement with huge pages instead of recursing and zapping all of the child, leaf entries. This reduces the number of TLB flushes required. and reduces the disable dirty log time with the TDP MMU to ~3 seconds. Opportunistically add a WARN() to catch GFNs that are mapped at a higher level than their max level. Signed-off-by: Ben Gardon Message-Id: <20220525230904.1584480-1-bgardon@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/tdp_iter.c | 9 +++++++++ arch/x86/kvm/mmu/tdp_iter.h | 1 + arch/x86/kvm/mmu/tdp_mmu.c | 38 +++++++++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu/tdp_iter.c b/arch/x86/kvm/mmu/tdp_iter.c index 6d3b3e5a5533b..ee4802d7b36cd 100644 --- a/arch/x86/kvm/mmu/tdp_iter.c +++ b/arch/x86/kvm/mmu/tdp_iter.c @@ -145,6 +145,15 @@ static bool try_step_up(struct tdp_iter *iter) return true; } +/* + * Step the iterator back up a level in the paging structure. Should only be + * used when the iterator is below the root level. + */ +void tdp_iter_step_up(struct tdp_iter *iter) +{ + WARN_ON(!try_step_up(iter)); +} + /* * Step to the next SPTE in a pre-order traversal of the paging structure. * To get to the next SPTE, the iterator either steps down towards the goal diff --git a/arch/x86/kvm/mmu/tdp_iter.h b/arch/x86/kvm/mmu/tdp_iter.h index f0af385c56e03..adfca0cf94d3a 100644 --- a/arch/x86/kvm/mmu/tdp_iter.h +++ b/arch/x86/kvm/mmu/tdp_iter.h @@ -114,5 +114,6 @@ void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root, int min_level, gfn_t next_last_level_gfn); void tdp_iter_next(struct tdp_iter *iter); void tdp_iter_restart(struct tdp_iter *iter); +void tdp_iter_step_up(struct tdp_iter *iter); #endif /* __KVM_X86_MMU_TDP_ITER_H */ diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 841feaa48be5e..7b9265d671310 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1742,12 +1742,12 @@ static void zap_collapsible_spte_range(struct kvm *kvm, gfn_t start = slot->base_gfn; gfn_t end = start + slot->npages; struct tdp_iter iter; + int max_mapping_level; kvm_pfn_t pfn; rcu_read_lock(); tdp_root_for_each_pte(iter, root, start, end) { -retry: if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true)) continue; @@ -1755,15 +1755,41 @@ static void zap_collapsible_spte_range(struct kvm *kvm, !is_last_spte(iter.old_spte, iter.level)) continue; + /* + * This is a leaf SPTE. Check if the PFN it maps can + * be mapped at a higher level. + */ pfn = spte_to_pfn(iter.old_spte); - if (kvm_is_reserved_pfn(pfn) || - iter.level >= kvm_mmu_max_mapping_level(kvm, slot, iter.gfn, - pfn, PG_LEVEL_NUM)) + + if (kvm_is_reserved_pfn(pfn)) continue; + max_mapping_level = kvm_mmu_max_mapping_level(kvm, slot, + iter.gfn, pfn, PG_LEVEL_NUM); + + WARN_ON(max_mapping_level < iter.level); + + /* + * If this page is already mapped at the highest + * viable level, there's nothing more to do. + */ + if (max_mapping_level == iter.level) + continue; + + /* + * The page can be remapped at a higher level, so step + * up to zap the parent SPTE. + */ + while (max_mapping_level > iter.level) + tdp_iter_step_up(&iter); + /* Note, a successful atomic zap also does a remote TLB flush. */ - if (tdp_mmu_zap_spte_atomic(kvm, &iter)) - goto retry; + tdp_mmu_zap_spte_atomic(kvm, &iter); + + /* + * If the atomic zap fails, the iter will recurse back into + * the same subtree to retry. + */ } rcu_read_unlock(); -- GitLab From eae260be3a0111a28fe95923e117a55dddec0384 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Wed, 1 Jun 2022 16:43:22 +0200 Subject: [PATCH 289/942] KVM: selftests: Make hyperv_clock selftest more stable hyperv_clock doesn't always give a stable test result, especially with AMD CPUs. The test compares Hyper-V MSR clocksource (acquired either with rdmsr() from within the guest or KVM_GET_MSRS from the host) against rdtsc(). To increase the accuracy, increase the measured delay (done with nop loop) by two orders of magnitude and take the mean rdtsc() value before and after rdmsr()/KVM_GET_MSRS. Reported-by: Maxim Levitsky Signed-off-by: Vitaly Kuznetsov Reviewed-by: Maxim Levitsky Tested-by: Maxim Levitsky Message-Id: <20220601144322.1968742-1-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/hyperv_clock.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/hyperv_clock.c b/tools/testing/selftests/kvm/x86_64/hyperv_clock.c index e0b2bb1339b16..3330fb183c680 100644 --- a/tools/testing/selftests/kvm/x86_64/hyperv_clock.c +++ b/tools/testing/selftests/kvm/x86_64/hyperv_clock.c @@ -44,7 +44,7 @@ static inline void nop_loop(void) { int i; - for (i = 0; i < 1000000; i++) + for (i = 0; i < 100000000; i++) asm volatile("nop"); } @@ -56,12 +56,14 @@ static inline void check_tsc_msr_rdtsc(void) tsc_freq = rdmsr(HV_X64_MSR_TSC_FREQUENCY); GUEST_ASSERT(tsc_freq > 0); - /* First, check MSR-based clocksource */ + /* For increased accuracy, take mean rdtsc() before and afrer rdmsr() */ r1 = rdtsc(); t1 = rdmsr(HV_X64_MSR_TIME_REF_COUNT); + r1 = (r1 + rdtsc()) / 2; nop_loop(); r2 = rdtsc(); t2 = rdmsr(HV_X64_MSR_TIME_REF_COUNT); + r2 = (r2 + rdtsc()) / 2; GUEST_ASSERT(r2 > r1 && t2 > t1); @@ -181,12 +183,14 @@ static void host_check_tsc_msr_rdtsc(struct kvm_vm *vm) tsc_freq = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TSC_FREQUENCY); TEST_ASSERT(tsc_freq > 0, "TSC frequency must be nonzero"); - /* First, check MSR-based clocksource */ + /* For increased accuracy, take mean rdtsc() before and afrer ioctl */ r1 = rdtsc(); t1 = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TIME_REF_COUNT); + r1 = (r1 + rdtsc()) / 2; nop_loop(); r2 = rdtsc(); t2 = vcpu_get_msr(vm, VCPU_ID, HV_X64_MSR_TIME_REF_COUNT); + r2 = (r2 + rdtsc()) / 2; TEST_ASSERT(t2 > t1, "Time reference MSR is not monotonic (%ld <= %ld)", t1, t2); -- GitLab From 11d39e8cc43e1c6737af19ca9372e590061b5ad2 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 6 Jun 2022 21:11:49 +0300 Subject: [PATCH 290/942] KVM: SVM: fix tsc scaling cache logic SVM uses a per-cpu variable to cache the current value of the tsc scaling multiplier msr on each cpu. Commit 1ab9287add5e2 ("KVM: X86: Add vendor callbacks for writing the TSC multiplier") broke this caching logic. Refactor the code so that all TSC scaling multiplier writes go through a single function which checks and updates the cache. This fixes the following scenario: 1. A CPU runs a guest with some tsc scaling ratio. 2. New guest with different tsc scaling ratio starts on this CPU and terminates almost immediately. This ensures that the short running guest had set the tsc scaling ratio just once when it was set via KVM_SET_TSC_KHZ. Due to the bug, the per-cpu cache is not updated. 3. The original guest continues to run, it doesn't restore the msr value back to its own value, because the cache matches, and thus continues to run with a wrong tsc scaling ratio. Fixes: 1ab9287add5e2 ("KVM: X86: Add vendor callbacks for writing the TSC multiplier") Signed-off-by: Maxim Levitsky Message-Id: <20220606181149.103072-1-mlevitsk@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/nested.c | 4 ++-- arch/x86/kvm/svm/svm.c | 32 ++++++++++++++++++++------------ arch/x86/kvm/svm/svm.h | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index bed5e1692cef0..3361258640a27 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -982,7 +982,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm) if (svm->tsc_ratio_msr != kvm_default_tsc_scaling_ratio) { WARN_ON(!svm->tsc_scaling_enabled); vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio; - svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio); + __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); } svm->nested.ctl.nested_cr3 = 0; @@ -1387,7 +1387,7 @@ void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu) vcpu->arch.tsc_scaling_ratio = kvm_calc_nested_tsc_multiplier(vcpu->arch.l1_tsc_scaling_ratio, svm->tsc_ratio_msr); - svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio); + __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); } /* Inverse operation of nested_copy_vmcb_control_to_cache(). asid is copied too. */ diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 63880b33ce370..478e6ee81d883 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -465,11 +465,24 @@ static int has_svm(void) return 1; } +void __svm_write_tsc_multiplier(u64 multiplier) +{ + preempt_disable(); + + if (multiplier == __this_cpu_read(current_tsc_ratio)) + goto out; + + wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); + __this_cpu_write(current_tsc_ratio, multiplier); +out: + preempt_enable(); +} + static void svm_hardware_disable(void) { /* Make sure we clean up behind us */ if (tsc_scaling) - wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT); + __svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT); cpu_svm_disable(); @@ -515,8 +528,7 @@ static int svm_hardware_enable(void) * Set the default value, even if we don't use TSC scaling * to avoid having stale value in the msr */ - wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT); - __this_cpu_write(current_tsc_ratio, SVM_TSC_RATIO_DEFAULT); + __svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT); } @@ -999,11 +1011,12 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset) vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS); } -void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier) +static void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier) { - wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); + __svm_write_tsc_multiplier(multiplier); } + /* Evaluate instruction intercepts that depend on guest CPUID features. */ static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu, struct vcpu_svm *svm) @@ -1363,13 +1376,8 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) sev_es_prepare_switch_to_guest(hostsa); } - if (tsc_scaling) { - u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio; - if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) { - __this_cpu_write(current_tsc_ratio, tsc_ratio); - wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio); - } - } + if (tsc_scaling) + __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); if (likely(tsc_aux_uret_slot >= 0)) kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 45a87b2a8b3c4..29d6fd205a494 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -590,7 +590,7 @@ int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, bool has_error_code, u32 error_code); int nested_svm_exit_special(struct vcpu_svm *svm); void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu); -void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier); +void __svm_write_tsc_multiplier(u64 multiplier); void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm, struct vmcb_control_area *control); void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm, -- GitLab From c3c09e393a5e25fb2fd30b62f3c689e92b4343c4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 6 Jun 2022 16:22:30 -0500 Subject: [PATCH 291/942] dt-bindings: nvme: apple,nvme-ans: Drop 'maxItems' from 'apple,sart' A 'phandle' type is always a single cell, so 'maxItems: 1' is redundant. Fixes: 82b96552f15a ("dt-bindings: nvme: Add Apple ANS NVMe") Signed-off-by: Rob Herring Reviewed-by: Sven Peter Link: https://lore.kernel.org/r/20220606212230.1360617-1-robh@kernel.org --- Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml b/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml index ddff9233b1595..34dd1cc671246 100644 --- a/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml +++ b/Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml @@ -55,7 +55,6 @@ properties: maxItems: 1 apple,sart: - maxItems: 1 $ref: /schemas/types.yaml#/definitions/phandle description: | Reference to the SART address filter. -- GitLab From 927c63e07810fe41cc0428d767ea4b59db193b80 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 6 Jun 2022 17:51:36 -0500 Subject: [PATCH 292/942] dt-bindings: Drop more redundant 'maxItems/minItems' in if/then schemas Another round from new cases in 5.19-rc of removing redundant minItems/maxItems when 'items' list is specified. This time it is in if/then schemas as the meta-schema was failing to check this case. If a property has an 'items' list, then a 'minItems' or 'maxItems' with the same size as the list is redundant and can be dropped. Note that is DT schema specific behavior and not standard json-schema behavior. The tooling will fixup the final schema adding any unspecified minItems/maxItems. Signed-off-by: Rob Herring Acked-by: Guenter Roeck Reviewed-by: Krzysztof Kozlowski Acked-by: Ulf Hansson Link: https://lore.kernel.org/r/20220606225137.1536010-1-robh@kernel.org --- .../bindings/memory-controllers/nvidia,tegra186-mc.yaml | 3 --- Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml | 1 - .../devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml | 1 - 3 files changed, 5 deletions(-) diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml index c7cfa6c2cd81c..935d63d181d9e 100644 --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml @@ -150,7 +150,6 @@ allOf: description: 5 memory controller channels and 1 for stream-id registers reg-names: - maxItems: 6 items: - const: sid - const: broadcast @@ -170,7 +169,6 @@ allOf: description: 17 memory controller channels and 1 for stream-id registers reg-names: - minItems: 18 items: - const: sid - const: broadcast @@ -202,7 +200,6 @@ allOf: description: 17 memory controller channels and 1 for stream-id registers reg-names: - minItems: 18 items: - const: sid - const: broadcast diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml index c79639e9027ed..7a2b22dd6d058 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml @@ -145,7 +145,6 @@ allOf: items: - description: Xenon IP registers - description: Armada 3700 SoC PHY PAD Voltage Control register - minItems: 2 marvell,pad-type: $ref: /schemas/types.yaml#/definitions/string diff --git a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml index cbcf19f514114..ed6c1ca80dcc4 100644 --- a/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/allwinner,sun4i-a10-wdt.yaml @@ -64,7 +64,6 @@ if: then: properties: clocks: - minItems: 2 items: - description: High-frequency oscillator input, divided internally - description: Low-frequency oscillator input -- GitLab From 7bf179de5b2dfae54a6839eaf7caba44a888ee2e Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Mon, 6 Jun 2022 20:42:54 -0600 Subject: [PATCH 293/942] kbuild: avoid regex RS for POSIX awk In 22f26f21774f8 awk was added to deduplicate *.mod files. The awk invocation passes -v RS='( |\n)' to match a space or newline character as the record separator. Unfortunately, POSIX states[1] > If RS contains more than one character, the results are unspecified. Some implementations (such as the One True Awk[2] used by the BSDs) do not treat RS as a regular expression. When awk does not support regex RS, build failures such as the following are produced (first error using allmodconfig): CC [M] arch/x86/events/intel/uncore.o CC [M] arch/x86/events/intel/uncore_nhmex.o CC [M] arch/x86/events/intel/uncore_snb.o CC [M] arch/x86/events/intel/uncore_snbep.o CC [M] arch/x86/events/intel/uncore_discovery.o LD [M] arch/x86/events/intel/intel-uncore.o ld: cannot find uncore_nhmex.o: No such file or directory ld: cannot find uncore_snb.o: No such file or directory ld: cannot find uncore_snbep.o: No such file or directory ld: cannot find uncore_discovery.o: No such file or directory make[3]: *** [scripts/Makefile.build:422: arch/x86/events/intel/intel-uncore.o] Error 1 make[2]: *** [scripts/Makefile.build:487: arch/x86/events/intel] Error 2 make[1]: *** [scripts/Makefile.build:487: arch/x86/events] Error 2 make: *** [Makefile:1839: arch/x86] Error 2 To avoid this, use printf(1) to produce a newline between each object path, instead of the space produced by echo(1), so that the default RS can be used by awk. [1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html [2]: https://github.com/onetrueawk/awk Fixes: 22f26f21774f ("kbuild: get rid of duplication in *.mod files") Signed-off-by: Kevin Locke Signed-off-by: Masahiro Yamada --- scripts/Makefile.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1f01ac65c0cd4..cac070aee7915 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -251,8 +251,8 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE # To make this rule robust against "Argument list too long" error, # ensure to add $(obj)/ prefix by a shell command. -cmd_mod = echo $(call real-search, $*.o, .o, -objs -y -m) | \ - $(AWK) -v RS='( |\n)' '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ +cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \ + $(AWK) '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ $(obj)/%.mod: FORCE $(call if_changed,mod) -- GitLab From c4f135d643823a869becfa87539f7820ef9d5bfa Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Wed, 1 Jun 2022 16:32:47 +0900 Subject: [PATCH 294/942] workqueue: Wrap flush_workqueue() using a macro Since flush operation synchronously waits for completion, flushing system-wide WQs (e.g. system_wq) might introduce possibility of deadlock due to unexpected locking dependency. Tejun Heo commented at [1] that it makes no sense at all to call flush_workqueue() on the shared WQs as the caller has no idea what it's gonna end up waiting for. Although there is flush_scheduled_work() which flushes system_wq WQ with "Think twice before calling this function! It's very easy to get into trouble if you don't take great care." warning message, syzbot found a circular locking dependency caused by flushing system_wq WQ [2]. Therefore, let's change the direction to that developers had better use their local WQs if flush_scheduled_work()/flush_workqueue(system_*_wq) is inevitable. Steps for converting system-wide WQs into local WQs are explained at [3], and a conversion to stop flushing system-wide WQs is in progress. Now we want some mechanism for preventing developers who are not aware of this conversion from again start flushing system-wide WQs. Since I found that WARN_ON() is complete but awkward approach for teaching developers about this problem, let's use __compiletime_warning() for incomplete but handy approach. For completeness, we will also insert WARN_ON() into __flush_workqueue() after all in-tree users stopped calling flush_scheduled_work(). Link: https://lore.kernel.org/all/YgnQGZWT%2Fn3VAITX@slm.duckdns.org/ [1] Link: https://syzkaller.appspot.com/bug?extid=bde0f89deacca7c765b8 [2] Link: https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@I-love.SAKURA.ne.jp [3] Signed-off-by: Tetsuo Handa Signed-off-by: Tejun Heo --- include/linux/workqueue.h | 64 ++++++++++++++++++++++++++++++++++----- kernel/workqueue.c | 16 +++++++--- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 7fee9b6cfedef..e1f1c8b1121bd 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -445,7 +445,7 @@ extern bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay); extern bool queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork); -extern void flush_workqueue(struct workqueue_struct *wq); +extern void __flush_workqueue(struct workqueue_struct *wq); extern void drain_workqueue(struct workqueue_struct *wq); extern int schedule_on_each_cpu(work_func_t func); @@ -563,15 +563,23 @@ static inline bool schedule_work(struct work_struct *work) return queue_work(system_wq, work); } +/* + * Detect attempt to flush system-wide workqueues at compile time when possible. + * + * See https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@I-love.SAKURA.ne.jp + * for reasons and steps for converting system-wide workqueues into local workqueues. + */ +extern void __warn_flushing_systemwide_wq(void) + __compiletime_warning("Please avoid flushing system-wide workqueues."); + /** * flush_scheduled_work - ensure that any scheduled work has run to completion. * * Forces execution of the kernel-global workqueue and blocks until its * completion. * - * Think twice before calling this function! It's very easy to get into - * trouble if you don't take great care. Either of the following situations - * will lead to deadlock: + * It's very easy to get into trouble if you don't take great care. + * Either of the following situations will lead to deadlock: * * One of the work items currently on the workqueue needs to acquire * a lock held by your code or its caller. @@ -586,11 +594,51 @@ static inline bool schedule_work(struct work_struct *work) * need to know that a particular work item isn't queued and isn't running. * In such cases you should use cancel_delayed_work_sync() or * cancel_work_sync() instead. + * + * Please stop calling this function! A conversion to stop flushing system-wide + * workqueues is in progress. This function will be removed after all in-tree + * users stopped calling this function. */ -static inline void flush_scheduled_work(void) -{ - flush_workqueue(system_wq); -} +/* + * The background of commit 771c035372a036f8 ("deprecate the + * '__deprecated' attribute warnings entirely and for good") is that, + * since Linus builds all modules between every single pull he does, + * the standard kernel build needs to be _clean_ in order to be able to + * notice when new problems happen. Therefore, don't emit warning while + * there are in-tree users. + */ +#define flush_scheduled_work() \ +({ \ + if (0) \ + __warn_flushing_systemwide_wq(); \ + __flush_workqueue(system_wq); \ +}) + +/* + * Although there is no longer in-tree caller, for now just emit warning + * in order to give out-of-tree callers time to update. + */ +#define flush_workqueue(wq) \ +({ \ + struct workqueue_struct *_wq = (wq); \ + \ + if ((__builtin_constant_p(_wq == system_wq) && \ + _wq == system_wq) || \ + (__builtin_constant_p(_wq == system_highpri_wq) && \ + _wq == system_highpri_wq) || \ + (__builtin_constant_p(_wq == system_long_wq) && \ + _wq == system_long_wq) || \ + (__builtin_constant_p(_wq == system_unbound_wq) && \ + _wq == system_unbound_wq) || \ + (__builtin_constant_p(_wq == system_freezable_wq) && \ + _wq == system_freezable_wq) || \ + (__builtin_constant_p(_wq == system_power_efficient_wq) && \ + _wq == system_power_efficient_wq) || \ + (__builtin_constant_p(_wq == system_freezable_power_efficient_wq) && \ + _wq == system_freezable_power_efficient_wq)) \ + __warn_flushing_systemwide_wq(); \ + __flush_workqueue(_wq); \ +}) /** * schedule_delayed_work_on - queue work in global workqueue on CPU after delay diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 4056f2a3f9d59..1ea50f6be8436 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -2788,13 +2788,13 @@ static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq, } /** - * flush_workqueue - ensure that any scheduled work has run to completion. + * __flush_workqueue - ensure that any scheduled work has run to completion. * @wq: workqueue to flush * * This function sleeps until all work items which were queued on entry * have finished execution, but it is not livelocked by new incoming ones. */ -void flush_workqueue(struct workqueue_struct *wq) +void __flush_workqueue(struct workqueue_struct *wq) { struct wq_flusher this_flusher = { .list = LIST_HEAD_INIT(this_flusher.list), @@ -2943,7 +2943,7 @@ void flush_workqueue(struct workqueue_struct *wq) out_unlock: mutex_unlock(&wq->mutex); } -EXPORT_SYMBOL(flush_workqueue); +EXPORT_SYMBOL(__flush_workqueue); /** * drain_workqueue - drain a workqueue @@ -2971,7 +2971,7 @@ void drain_workqueue(struct workqueue_struct *wq) wq->flags |= __WQ_DRAINING; mutex_unlock(&wq->mutex); reflush: - flush_workqueue(wq); + __flush_workqueue(wq); mutex_lock(&wq->mutex); @@ -6111,3 +6111,11 @@ void __init workqueue_init(void) wq_online = true; wq_watchdog_init(); } + +/* + * Despite the naming, this is a no-op function which is here only for avoiding + * link error. Since compile-time warning may fail to catch, we will need to + * emit run-time warning from __flush_workqueue(). + */ +void __warn_flushing_systemwide_wq(void) { } +EXPORT_SYMBOL(__warn_flushing_systemwide_wq); -- GitLab From 873a400938b31a1e443c4d94b560b78300787540 Mon Sep 17 00:00:00 2001 From: Wonhyuk Yang Date: Wed, 4 May 2022 11:32:03 +0900 Subject: [PATCH 295/942] workqueue: Fix type of cpu in trace event The trace event "workqueue_queue_work" use unsigned int type for req_cpu, cpu. This casue confusing cpu number like below log. $ cat /sys/kernel/debug/tracing/trace cat-317 [001] ...: workqueue_queue_work: ... req_cpu=8192 cpu=4294967295 So, change unsigned type to signed type in the trace event. After applying this patch, cpu number will be printed as -1 instead of 4294967295 as folllows. $ cat /sys/kernel/debug/tracing/trace cat-1338 [002] ...: workqueue_queue_work: ... req_cpu=8192 cpu=-1 Cc: Baik Song An Cc: Hong Yeon Kim Cc: Taeung Song Cc: linuxgeek@linuxgeek.io Signed-off-by: Wonhyuk Yang Signed-off-by: Tejun Heo --- include/trace/events/workqueue.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index 6154a2e72bce6..262d52021c236 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h @@ -22,7 +22,7 @@ struct pool_workqueue; */ TRACE_EVENT(workqueue_queue_work, - TP_PROTO(unsigned int req_cpu, struct pool_workqueue *pwq, + TP_PROTO(int req_cpu, struct pool_workqueue *pwq, struct work_struct *work), TP_ARGS(req_cpu, pwq, work), @@ -31,8 +31,8 @@ TRACE_EVENT(workqueue_queue_work, __field( void *, work ) __field( void *, function) __string( workqueue, pwq->wq->name) - __field( unsigned int, req_cpu ) - __field( unsigned int, cpu ) + __field( int, req_cpu ) + __field( int, cpu ) ), TP_fast_assign( @@ -43,7 +43,7 @@ TRACE_EVENT(workqueue_queue_work, __entry->cpu = pwq->pool->cpu; ), - TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%u cpu=%u", + TP_printk("work struct=%p function=%ps workqueue=%s req_cpu=%d cpu=%d", __entry->work, __entry->function, __get_str(workqueue), __entry->req_cpu, __entry->cpu) ); -- GitLab From 10f3b29c65bb2fe0d47c2945cd0b4087be1c5218 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 31 May 2022 14:51:13 -0700 Subject: [PATCH 296/942] bpf, arm64: Clear prog->jited_len along prog->jited syzbot reported an illegal copy_to_user() attempt from bpf_prog_get_info_by_fd() [1] There was no repro yet on this bug, but I think that commit 0aef499f3172 ("mm/usercopy: Detect vmalloc overruns") is exposing a prior bug in bpf arm64. bpf_prog_get_info_by_fd() looks at prog->jited_len to determine if the JIT image can be copied out to user space. My theory is that syzbot managed to get a prog where prog->jited_len has been set to 43, while prog->bpf_func has ben cleared. It is not clear why copy_to_user(uinsns, NULL, ulen) is triggering this particular warning. I thought find_vma_area(NULL) would not find a vm_struct. As we do not hold vmap_area_lock spinlock, it might be possible that the found vm_struct was garbage. [1] usercopy: Kernel memory exposure attempt detected from vmalloc (offset 792633534417210172, size 43)! kernel BUG at mm/usercopy.c:101! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 25002 Comm: syz-executor.1 Not tainted 5.18.0-syzkaller-10139-g8291eaafed36 #0 Hardware name: linux,dummy-virt (DT) pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : usercopy_abort+0x90/0x94 mm/usercopy.c:101 lr : usercopy_abort+0x90/0x94 mm/usercopy.c:89 sp : ffff80000b773a20 x29: ffff80000b773a30 x28: faff80000b745000 x27: ffff80000b773b48 x26: 0000000000000000 x25: 000000000000002b x24: 0000000000000000 x23: 00000000000000e0 x22: ffff80000b75db67 x21: 0000000000000001 x20: 000000000000002b x19: ffff80000b75db3c x18: 00000000fffffffd x17: 2820636f6c6c616d x16: 76206d6f72662064 x15: 6574636574656420 x14: 74706d6574746120 x13: 2129333420657a69 x12: 73202c3237313031 x11: 3237313434333533 x10: 3336323937207465 x9 : 657275736f707865 x8 : ffff80000a30c550 x7 : ffff80000b773830 x6 : ffff80000b773830 x5 : 0000000000000000 x4 : ffff00007fbbaa10 x3 : 0000000000000000 x2 : 0000000000000000 x1 : f7ff000028fc0000 x0 : 0000000000000064 Call trace: usercopy_abort+0x90/0x94 mm/usercopy.c:89 check_heap_object mm/usercopy.c:186 [inline] __check_object_size mm/usercopy.c:252 [inline] __check_object_size+0x198/0x36c mm/usercopy.c:214 check_object_size include/linux/thread_info.h:199 [inline] check_copy_size include/linux/thread_info.h:235 [inline] copy_to_user include/linux/uaccess.h:159 [inline] bpf_prog_get_info_by_fd.isra.0+0xf14/0xfdc kernel/bpf/syscall.c:3993 bpf_obj_get_info_by_fd+0x12c/0x510 kernel/bpf/syscall.c:4253 __sys_bpf+0x900/0x2150 kernel/bpf/syscall.c:4956 __do_sys_bpf kernel/bpf/syscall.c:5021 [inline] __se_sys_bpf kernel/bpf/syscall.c:5019 [inline] __arm64_sys_bpf+0x28/0x40 kernel/bpf/syscall.c:5019 __invoke_syscall arch/arm64/kernel/syscall.c:38 [inline] invoke_syscall+0x48/0x114 arch/arm64/kernel/syscall.c:52 el0_svc_common.constprop.0+0x44/0xec arch/arm64/kernel/syscall.c:142 do_el0_svc+0xa0/0xc0 arch/arm64/kernel/syscall.c:206 el0_svc+0x44/0xb0 arch/arm64/kernel/entry-common.c:624 el0t_64_sync_handler+0x1ac/0x1b0 arch/arm64/kernel/entry-common.c:642 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:581 Code: aa0003e3 d00038c0 91248000 97fff65f (d4210000) Fixes: db496944fdaa ("bpf: arm64: add JIT support for multi-function programs") Reported-by: syzbot Signed-off-by: Eric Dumazet Signed-off-by: Daniel Borkmann Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20220531215113.1100754-1-eric.dumazet@gmail.com Signed-off-by: Alexei Starovoitov --- arch/arm64/net/bpf_jit_comp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 8ab4035dea274..42f2e9a8616c3 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -1478,6 +1478,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) bpf_jit_binary_free(header); prog->bpf_func = NULL; prog->jited = 0; + prog->jited_len = 0; goto out_off; } bpf_jit_binary_lock_ro(header); -- GitLab From fd58f7df2415ef747782e01f94880fefad1247cf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 26 May 2022 13:24:05 +0300 Subject: [PATCH 297/942] bpf: Use safer kvmalloc_array() where possible The kvmalloc_array() function is safer because it has a check for integer overflows. These sizes come from the user and I was not able to see any bounds checking so an integer overflow seems like a realistic concern. Fixes: 0dcac2725406 ("bpf: Add multi kprobe link") Signed-off-by: Dan Carpenter Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/Yo9VRVMeHbALyjUH@kili Signed-off-by: Alexei Starovoitov --- kernel/trace/bpf_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 10b157a6d73e0..7a13e6ac6327c 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32 int err = -ENOMEM; unsigned int i; - syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL); + syms = kvmalloc_array(cnt, sizeof(*syms), GFP_KERNEL); if (!syms) goto error; - buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL); + buf = kvmalloc_array(cnt, KSYM_NAME_LEN, GFP_KERNEL); if (!buf) goto error; @@ -2464,7 +2464,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr return -EINVAL; size = cnt * sizeof(*addrs); - addrs = kvmalloc(size, GFP_KERNEL); + addrs = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL); if (!addrs) return -ENOMEM; @@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr ucookies = u64_to_user_ptr(attr->link_create.kprobe_multi.cookies); if (ucookies) { - cookies = kvmalloc(size, GFP_KERNEL); + cookies = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL); if (!cookies) { err = -ENOMEM; goto error; -- GitLab From f858c2b2ca04fc7ead291821a793638ae120c11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Mon, 6 Jun 2022 09:52:51 +0200 Subject: [PATCH 298/942] bpf: Fix calling global functions from BPF_PROG_TYPE_EXT programs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The verifier allows programs to call global functions as long as their argument types match, using BTF to check the function arguments. One of the allowed argument types to such global functions is PTR_TO_CTX; however the check for this fails on BPF_PROG_TYPE_EXT functions because the verifier uses the wrong type to fetch the vmlinux BTF ID for the program context type. This failure is seen when an XDP program is loaded using libxdp (which loads it as BPF_PROG_TYPE_EXT and attaches it to a global XDP type program). Fix the issue by passing in the target program type instead of the BPF_PROG_TYPE_EXT type to bpf_prog_get_ctx() when checking function argument compatibility. The first Fixes tag refers to the latest commit that touched the code in question, while the second one points to the code that first introduced the global function call verification. v2: - Use resolve_prog_type() Fixes: 3363bd0cfbb8 ("bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support") Fixes: 51c39bb1d5d1 ("bpf: Introduce function-by-function verification") Reported-by: Simon Sundberg Signed-off-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/r/20220606075253.28422-1-toke@redhat.com Signed-off-by: Alexei Starovoitov --- kernel/bpf/btf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 7bccaa4646e51..63d0ac7dfe2fb 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -6054,6 +6054,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, struct bpf_reg_state *regs, bool ptr_to_mem_ok) { + enum bpf_prog_type prog_type = resolve_prog_type(env->prog); struct bpf_verifier_log *log = &env->log; u32 i, nargs, ref_id, ref_obj_id = 0; bool is_kfunc = btf_is_kernel(btf); @@ -6171,7 +6172,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, return -EINVAL; } /* rest of the arguments can be anything, like normal kfunc */ - } else if (btf_get_prog_ctx_type(log, btf, t, env->prog->type, i)) { + } else if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) { /* If function expects ctx type in BTF check that caller * is passing PTR_TO_CTX. */ -- GitLab From 2cf7b7ffdae519b284f1406012b52e2282fa36bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Mon, 6 Jun 2022 09:52:52 +0200 Subject: [PATCH 299/942] selftests/bpf: Add selftest for calling global functions from freplace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a selftest that calls a global function with a context object parameter from an freplace function to check that the program context type is correctly converted to the freplace target when fetching the context type from the kernel BTF. v2: - Trim includes - Get rid of global function - Use __noinline Signed-off-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/r/20220606075253.28422-2-toke@redhat.com Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/prog_tests/fexit_bpf2bpf.c | 14 ++++++++++++++ .../selftests/bpf/progs/freplace_global_func.c | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/freplace_global_func.c diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c index d9aad15e0d242..02bb8cbf91949 100644 --- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c +++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c @@ -395,6 +395,18 @@ static void test_func_map_prog_compatibility(void) "./test_attach_probe.o"); } +static void test_func_replace_global_func(void) +{ + const char *prog_name[] = { + "freplace/test_pkt_access", + }; + + test_fexit_bpf2bpf_common("./freplace_global_func.o", + "./test_pkt_access.o", + ARRAY_SIZE(prog_name), + prog_name, false, NULL); +} + /* NOTE: affect other tests, must run in serial mode */ void serial_test_fexit_bpf2bpf(void) { @@ -416,4 +428,6 @@ void serial_test_fexit_bpf2bpf(void) test_func_replace_multi(); if (test__start_subtest("fmod_ret_freplace")) test_fmod_ret_freplace(); + if (test__start_subtest("func_replace_global_func")) + test_func_replace_global_func(); } diff --git a/tools/testing/selftests/bpf/progs/freplace_global_func.c b/tools/testing/selftests/bpf/progs/freplace_global_func.c new file mode 100644 index 0000000000000..96cb61a6ce87a --- /dev/null +++ b/tools/testing/selftests/bpf/progs/freplace_global_func.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +__noinline +int test_ctx_global_func(struct __sk_buff *skb) +{ + volatile int retval = 1; + return retval; +} + +SEC("freplace/test_pkt_access") +int new_test_pkt_access(struct __sk_buff *skb) +{ + return test_ctx_global_func(skb); +} + +char _license[] SEC("license") = "GPL"; -- GitLab From 2b8c612c6102f751e6e3e1bd425f64e9d3d3f638 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 6 Jun 2022 19:56:40 +0300 Subject: [PATCH 300/942] kernel/reboot: Fix powering off using a non-syscall code paths There are other methods of powering off machine than the reboot syscall. Previously we missed to cover those methods and it created power-off regression for some machines, like the PowerPC e500. Fix this problem by moving the legacy sys-off handler registration to the latest phase of power-off process and making the kernel_can_power_off() check the legacy pm_power_off presence. Tested-by: Michael Ellerman # ppce500 Reported-by: Michael Ellerman # ppce500 Fixes: da007f171fc9 ("kernel/reboot: Change registration order of legacy power-off handler") Signed-off-by: Dmitry Osipenko Signed-off-by: Rafael J. Wysocki --- kernel/reboot.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/kernel/reboot.c b/kernel/reboot.c index 3b19b123efecb..b5a71d1ff603c 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -320,6 +320,7 @@ static struct sys_off_handler platform_sys_off_handler; static struct sys_off_handler *alloc_sys_off_handler(int priority) { struct sys_off_handler *handler; + gfp_t flags; /* * Platforms like m68k can't allocate sys_off handler dynamically @@ -330,7 +331,12 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority) if (handler->cb_data) return ERR_PTR(-EBUSY); } else { - handler = kzalloc(sizeof(*handler), GFP_KERNEL); + if (system_state > SYSTEM_RUNNING) + flags = GFP_ATOMIC; + else + flags = GFP_KERNEL; + + handler = kzalloc(sizeof(*handler), flags); if (!handler) return ERR_PTR(-ENOMEM); } @@ -440,7 +446,7 @@ void unregister_sys_off_handler(struct sys_off_handler *handler) { int err; - if (!handler) + if (IS_ERR_OR_NULL(handler)) return; if (handler->blocking) @@ -615,7 +621,23 @@ static void do_kernel_power_off_prepare(void) */ void do_kernel_power_off(void) { + struct sys_off_handler *sys_off = NULL; + + /* + * Register sys-off handlers for legacy PM callback. This allows + * legacy PM callbacks temporary co-exist with the new sys-off API. + * + * TODO: Remove legacy handlers once all legacy PM users will be + * switched to the sys-off based APIs. + */ + if (pm_power_off) + sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_DEFAULT, + legacy_pm_power_off, NULL); + atomic_notifier_call_chain(&power_off_handler_list, 0, NULL); + + unregister_sys_off_handler(sys_off); } /** @@ -626,7 +648,8 @@ void do_kernel_power_off(void) */ bool kernel_can_power_off(void) { - return !atomic_notifier_call_chain_is_empty(&power_off_handler_list); + return !atomic_notifier_call_chain_is_empty(&power_off_handler_list) || + pm_power_off; } EXPORT_SYMBOL_GPL(kernel_can_power_off); @@ -661,7 +684,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg) { struct pid_namespace *pid_ns = task_active_pid_ns(current); - struct sys_off_handler *sys_off = NULL; char buffer[256]; int ret = 0; @@ -686,21 +708,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, if (ret) return ret; - /* - * Register sys-off handlers for legacy PM callback. This allows - * legacy PM callbacks temporary co-exist with the new sys-off API. - * - * TODO: Remove legacy handlers once all legacy PM users will be - * switched to the sys-off based APIs. - */ - if (pm_power_off) { - sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, - SYS_OFF_PRIO_DEFAULT, - legacy_pm_power_off, NULL); - if (IS_ERR(sys_off)) - return PTR_ERR(sys_off); - } - /* Instead of trying to make the power_off code look like * halt when pm_power_off is not set do it the easy way. */ @@ -758,7 +765,6 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, break; } mutex_unlock(&system_transition_mutex); - unregister_sys_off_handler(sys_off); return ret; } -- GitLab From 803e9895ea2b0fe80bc85980ae2d7a7e44037914 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Wed, 6 Apr 2022 11:52:51 +0200 Subject: [PATCH 301/942] ixgbe: fix bcast packets Rx on VF after promisc removal After a VF requested to remove the promiscuous flag on an interface, the broadcast packets are not received anymore. This breaks some protocols like ARP. In ixgbe_update_vf_xcast_mode(), we should keep the IXGBE_VMOLR_BAM bit (Broadcast Accept) on promiscuous removal. This flag is already set by default in ixgbe_set_vmolr() on VF reset. Fixes: 8443c1a4b192 ("ixgbe, ixgbevf: Add new mbox API xcast mode") Cc: stable@vger.kernel.org Cc: Nicolas Dichtel Signed-off-by: Olivier Matz Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 7f11c0a8e7a91..8d108a78941b0 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1184,9 +1184,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter, switch (xcast_mode) { case IXGBEVF_XCAST_MODE_NONE: - disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | + disable = IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; - enable = 0; + enable = IXGBE_VMOLR_BAM; break; case IXGBEVF_XCAST_MODE_MULTI: disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; -- GitLab From 7bb0fb7c63df95d6027dc50d6af3bc3bbbc25483 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Wed, 6 Apr 2022 11:52:52 +0200 Subject: [PATCH 302/942] ixgbe: fix unexpected VLAN Rx in promisc mode on VF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the promiscuous mode is enabled on a VF, the IXGBE_VMOLR_VPE bit (VLAN Promiscuous Enable) is set. This means that the VF will receive packets whose VLAN is not the same than the VLAN of the VF. For instance, in this situation: ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ VF0├────┤VF1 VF2├────┤VF3 │ │ │ │ │ │ │ └────────┘ └────────┘ └────────┘ VM1 VM2 VM3 vf 0: vlan 1000 vf 1: vlan 1000 vf 2: vlan 1001 vf 3: vlan 1001 If we tcpdump on VF3, we see all the packets, even those transmitted on vlan 1000. This behavior prevents to bridge VF1 and VF2 in VM2, because it will create a loop: packets transmitted on VF1 will be received by VF2 and vice-versa, and bridged again through the software bridge. This patch remove the activation of VLAN Promiscuous when a VF enables the promiscuous mode. However, the IXGBE_VMOLR_UPE bit (Unicast Promiscuous) is kept, so that a VF receives all packets that has the same VLAN, whatever the destination MAC address. Fixes: 8443c1a4b192 ("ixgbe, ixgbevf: Add new mbox API xcast mode") Cc: stable@vger.kernel.org Cc: Nicolas Dichtel Signed-off-by: Olivier Matz Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index 8d108a78941b0..d4e63f0644c36 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1208,9 +1208,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter, return -EPERM; } - disable = 0; + disable = IXGBE_VMOLR_VPE; enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | - IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE; break; default: return -EOPNOTSUPP; -- GitLab From f9e9bdd5bb180325256e3bdfeb9c4c6526133478 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:46 -0500 Subject: [PATCH 303/942] ASoC: Realtek/Maxim SoundWire codecs: disable pm_runtime on remove When binding/unbinding codec drivers, the following warnings are thrown: [ 107.266879] rt715-sdca sdw:3:025d:0714:01: Unbalanced pm_runtime_enable! [ 306.879700] rt711-sdca sdw:0:025d:0711:01: Unbalanced pm_runtime_enable! Add a remove callback for all Realtek/Maxim SoundWire codecs and remove this warning. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373-sdw.c | 12 +++++++++++- sound/soc/codecs/rt1308-sdw.c | 11 +++++++++++ sound/soc/codecs/rt1316-sdw.c | 11 +++++++++++ sound/soc/codecs/rt5682-sdw.c | 5 ++++- sound/soc/codecs/rt700-sdw.c | 6 +++++- sound/soc/codecs/rt711-sdca-sdw.c | 6 +++++- sound/soc/codecs/rt711-sdw.c | 6 +++++- sound/soc/codecs/rt715-sdca-sdw.c | 12 ++++++++++++ sound/soc/codecs/rt715-sdw.c | 12 ++++++++++++ 9 files changed, 76 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index f47e956d4f55a..97b64477dde67 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -862,6 +862,16 @@ static int max98373_sdw_probe(struct sdw_slave *slave, return max98373_init(slave, regmap); } +static int max98373_sdw_remove(struct sdw_slave *slave) +{ + struct max98373_priv *max98373 = dev_get_drvdata(&slave->dev); + + if (max98373->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + #if defined(CONFIG_OF) static const struct of_device_id max98373_of_match[] = { { .compatible = "maxim,max98373", }, @@ -893,7 +903,7 @@ static struct sdw_driver max98373_sdw_driver = { .pm = &max98373_pm, }, .probe = max98373_sdw_probe, - .remove = NULL, + .remove = max98373_sdw_remove, .ops = &max98373_slave_ops, .id_table = max98373_id, }; diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 1c11b42dd76e0..72f673f278eec 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -691,6 +691,16 @@ static int rt1308_sdw_probe(struct sdw_slave *slave, return 0; } +static int rt1308_sdw_remove(struct sdw_slave *slave) +{ + struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev); + + if (rt1308->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt1308_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x1308, 0x2, 0, 0), {}, @@ -750,6 +760,7 @@ static struct sdw_driver rt1308_sdw_driver = { .pm = &rt1308_pm, }, .probe = rt1308_sdw_probe, + .remove = rt1308_sdw_remove, .ops = &rt1308_slave_ops, .id_table = rt1308_id, }; diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 60baa9ff19070..2d6b5f9d4d770 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -676,6 +676,16 @@ static int rt1316_sdw_probe(struct sdw_slave *slave, return rt1316_sdw_init(&slave->dev, regmap, slave); } +static int rt1316_sdw_remove(struct sdw_slave *slave) +{ + struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(&slave->dev); + + if (rt1316->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt1316_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x1316, 0x3, 0x1, 0), {}, @@ -735,6 +745,7 @@ static struct sdw_driver rt1316_sdw_driver = { .pm = &rt1316_pm, }, .probe = rt1316_sdw_probe, + .remove = rt1316_sdw_remove, .ops = &rt1316_slave_ops, .id_table = rt1316_id, }; diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 248257a2e4e0f..f04e18c32489d 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -719,9 +719,12 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) { struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); - if (rt5682 && rt5682->hw_init) + if (rt5682->hw_init) cancel_delayed_work_sync(&rt5682->jack_detect_work); + if (rt5682->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index bda5948996642..f7439e40ca8b5 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt700.h" @@ -463,11 +464,14 @@ static int rt700_sdw_remove(struct sdw_slave *slave) { struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); - if (rt700 && rt700->hw_init) { + if (rt700->hw_init) { cancel_delayed_work_sync(&rt700->jack_detect_work); cancel_delayed_work_sync(&rt700->jack_btn_check_work); } + if (rt700->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index aaf5af153d3fe..c722a2b0041f7 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "rt711-sdca.h" #include "rt711-sdca-sdw.h" @@ -364,11 +365,14 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave) { struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev); - if (rt711 && rt711->hw_init) { + if (rt711->hw_init) { cancel_delayed_work_sync(&rt711->jack_detect_work); cancel_delayed_work_sync(&rt711->jack_btn_check_work); } + if (rt711->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index bda2cc9439c98..f49c94baa37c6 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt711.h" @@ -464,12 +465,15 @@ static int rt711_sdw_remove(struct sdw_slave *slave) { struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); - if (rt711 && rt711->hw_init) { + if (rt711->hw_init) { cancel_delayed_work_sync(&rt711->jack_detect_work); cancel_delayed_work_sync(&rt711->jack_btn_check_work); cancel_work_sync(&rt711->calibration_work); } + if (rt711->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index 0ecd2948f7aa7..13e731d166753 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt715-sdca.h" @@ -193,6 +194,16 @@ static int rt715_sdca_sdw_probe(struct sdw_slave *slave, return rt715_sdca_init(&slave->dev, mbq_regmap, regmap, slave); } +static int rt715_sdca_sdw_remove(struct sdw_slave *slave) +{ + struct rt715_sdca_priv *rt715 = dev_get_drvdata(&slave->dev); + + if (rt715->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt715_sdca_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x3, 0x1, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x3, 0x1, 0), @@ -267,6 +278,7 @@ static struct sdw_driver rt715_sdw_driver = { .pm = &rt715_pm, }, .probe = rt715_sdca_sdw_probe, + .remove = rt715_sdca_sdw_remove, .ops = &rt715_sdca_slave_ops, .id_table = rt715_sdca_id, }; diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index a7b21b03c08bb..b047bf87a100c 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -514,6 +515,16 @@ static int rt715_sdw_probe(struct sdw_slave *slave, return 0; } +static int rt715_sdw_remove(struct sdw_slave *slave) +{ + struct rt715_priv *rt715 = dev_get_drvdata(&slave->dev); + + if (rt715->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt715_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x2, 0, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x2, 0, 0), @@ -575,6 +586,7 @@ static struct sdw_driver rt715_sdw_driver = { .pm = &rt715_pm, }, .probe = rt715_sdw_probe, + .remove = rt715_sdw_remove, .ops = &rt715_slave_ops, .id_table = rt715_id, }; -- GitLab From 716c2e7e1608a89423ec84398b99ff2fa855d161 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:47 -0500 Subject: [PATCH 304/942] ASoC: rt711-sdca-sdw: fix calibrate mutex initialization In codec driver bind/unbind test, the following warning is thrown: DEBUG_LOCKS_WARN_ON(lock->magic != lock) ... [ 699.182495] rt711_sdca_jack_init+0x1b/0x1d0 [snd_soc_rt711_sdca] [ 699.182498] rt711_sdca_set_jack_detect+0x3b/0x90 [snd_soc_rt711_sdca] [ 699.182500] snd_soc_component_set_jack+0x24/0x50 [snd_soc_core] A quick check in the code shows that the 'calibrate_mutex' used by this driver are not initialized at probe time. Moving the initialization to the probe removes the issue. BugLink: https://github.com/thesofproject/linux/issues/3644 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdca-sdw.c | 3 +++ sound/soc/codecs/rt711-sdca.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index c722a2b0041f7..a085b2f530aa1 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -373,6 +373,9 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave) if (rt711->first_hw_init) pm_runtime_disable(&slave->dev); + mutex_destroy(&rt711->calibrate_mutex); + mutex_destroy(&rt711->disable_irq_lock); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 57629c18db384..af73bcb4560a3 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1412,6 +1412,7 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap, rt711->regmap = regmap; rt711->mbq_regmap = mbq_regmap; + mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); /* @@ -1550,7 +1551,6 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave) rt711_sdca_jack_detect_handler); INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_sdca_btn_check_handler); - mutex_init(&rt711->calibrate_mutex); } /* calibration */ -- GitLab From 768ad6d80db2dbbb1bfbb5e616d701a0b560f12a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:48 -0500 Subject: [PATCH 305/942] ASoC: Intel: sof_sdw: handle errors on card registration If the card registration fails, typically because of deferred probes, the device properties added for headset codecs are not removed, which leads to kernel oopses in driver bind/unbind tests. We already clean-up the device properties when the card is removed, this code can be moved as a helper and called upon card registration errors. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 51 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 1f00679b42409..ad826ad82d51a 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1398,6 +1398,33 @@ static struct snd_soc_card card_sof_sdw = { .late_probe = sof_sdw_card_late_probe, }; +static void mc_dailink_exit_loop(struct snd_soc_card *card) +{ + struct snd_soc_dai_link *link; + int ret; + int i, j; + + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { + if (!codec_info_list[i].exit) + continue; + /* + * We don't need to call .exit function if there is no matched + * dai link found. + */ + for_each_card_prelinks(card, j, link) { + if (!strcmp(link->codecs[0].dai_name, + codec_info_list[i].dai_name)) { + ret = codec_info_list[i].exit(card, link); + if (ret) + dev_warn(card->dev, + "codec exit failed %d\n", + ret); + break; + } + } + } +} + static int mc_probe(struct platform_device *pdev) { struct snd_soc_card *card = &card_sof_sdw; @@ -1462,6 +1489,7 @@ static int mc_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) { dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); + mc_dailink_exit_loop(card); return ret; } @@ -1473,29 +1501,8 @@ static int mc_probe(struct platform_device *pdev) static int mc_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct snd_soc_dai_link *link; - int ret; - int i, j; - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - if (!codec_info_list[i].exit) - continue; - /* - * We don't need to call .exit function if there is no matched - * dai link found. - */ - for_each_card_prelinks(card, j, link) { - if (!strcmp(link->codecs[0].dai_name, - codec_info_list[i].dai_name)) { - ret = codec_info_list[i].exit(card, link); - if (ret) - dev_warn(&pdev->dev, - "codec exit failed %d\n", - ret); - break; - } - } - } + mc_dailink_exit_loop(card); return 0; } -- GitLab From 74d40901ebad7c466a95b1ae3c6891f1ba09786f Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:49 -0500 Subject: [PATCH 306/942] ASoC: rt711: fix calibrate mutex initialization Follow the same flow as rt711-sdca and initialize all mutexes at probe time. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdw.c | 3 +++ sound/soc/codecs/rt711.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index f49c94baa37c6..4fe68bcf2a7c2 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -474,6 +474,9 @@ static int rt711_sdw_remove(struct sdw_slave *slave) if (rt711->first_hw_init) pm_runtime_disable(&slave->dev); + mutex_destroy(&rt711->calibrate_mutex); + mutex_destroy(&rt711->disable_irq_lock); + return 0; } diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 9838fb4d5b9c0..1e35ba433a7e7 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -1204,6 +1204,7 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap, rt711->sdw_regmap = sdw_regmap; rt711->regmap = regmap; + mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); /* @@ -1318,7 +1319,6 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave) rt711_jack_detect_handler); INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_btn_check_handler); - mutex_init(&rt711->calibrate_mutex); INIT_WORK(&rt711->calibration_work, rt711_calibration_work); schedule_work(&rt711->calibration_work); } -- GitLab From 05ba4c00fa9cb077a0dd91f5e6056951a787f63c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:50 -0500 Subject: [PATCH 307/942] ASoC: rt7*-sdw: harden jack_detect_handler Realtek headset codec drivers typically check if the card is instantiated before proceeding with the jack detection. The rt700, rt711 and rt711-sdca are however missing a check on the card pointer, which can lead to NULL dereferences encountered in driver bind/unbind tests. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 2 +- sound/soc/codecs/rt711-sdca.c | 2 +- sound/soc/codecs/rt711.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index af32295fa9b93..4a99d5f4706fd 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -162,7 +162,7 @@ static void rt700_jack_detect_handler(struct work_struct *work) if (!rt700->hs_jack) return; - if (!rt700->component->card->instantiated) + if (!rt700->component->card || !rt700->component->card->instantiated) return; reg = RT700_VERB_GET_PIN_SENSE | RT700_HP_OUT; diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index af73bcb4560a3..93b36f05cb567 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -294,7 +294,7 @@ static void rt711_sdca_jack_detect_handler(struct work_struct *work) if (!rt711->hs_jack) return; - if (!rt711->component->card->instantiated) + if (!rt711->component->card || !rt711->component->card->instantiated) return; /* SDW_SCP_SDCA_INT_SDCA_0 is used for jack detection */ diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 1e35ba433a7e7..2f445b27305a4 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -242,7 +242,7 @@ static void rt711_jack_detect_handler(struct work_struct *work) if (!rt711->hs_jack) return; - if (!rt711->component->card->instantiated) + if (!rt711->component->card || !rt711->component->card->instantiated) return; if (pm_runtime_status_suspended(rt711->slave->dev.parent)) { -- GitLab From a49267a3bd102e3991514e884aac89cc0d0b5f35 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:51 -0500 Subject: [PATCH 308/942] ASoC: codecs: rt700/rt711/rt711-sdca: initialize workqueues in probe The workqueues are initialized in the io_init functions, which isn't quite right. In some tests, this leads to warnings throw from __queue_delayed_work() WARN_ON_FUNCTION_MISMATCH(timer->function, delayed_work_timer_fn); Move all the initializations to the probe functions. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 12 +++++------- sound/soc/codecs/rt711-sdca.c | 10 +++------- sound/soc/codecs/rt711.c | 12 +++++------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 4a99d5f4706fd..7a6cf3434591a 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -1115,6 +1115,11 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap, mutex_init(&rt700->disable_irq_lock); + INIT_DELAYED_WORK(&rt700->jack_detect_work, + rt700_jack_detect_handler); + INIT_DELAYED_WORK(&rt700->jack_btn_check_work, + rt700_btn_check_handler); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1209,13 +1214,6 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave) /* Finish Initial Settings, set power to D3 */ regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D3); - if (!rt700->first_hw_init) { - INIT_DELAYED_WORK(&rt700->jack_detect_work, - rt700_jack_detect_handler); - INIT_DELAYED_WORK(&rt700->jack_btn_check_work, - rt700_btn_check_handler); - } - /* * if set_jack callback occurred early than io_init, * we set up the jack detection function now diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 93b36f05cb567..2b3b77577d1fd 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1415,6 +1415,9 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap, mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); + INIT_DELAYED_WORK(&rt711->jack_detect_work, rt711_sdca_jack_detect_handler); + INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_sdca_btn_check_handler); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1546,13 +1549,6 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave) rt711_sdca_index_update_bits(rt711, RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x20, 0x00); - if (!rt711->first_hw_init) { - INIT_DELAYED_WORK(&rt711->jack_detect_work, - rt711_sdca_jack_detect_handler); - INIT_DELAYED_WORK(&rt711->jack_btn_check_work, - rt711_sdca_btn_check_handler); - } - /* calibration */ ret = rt711_sdca_calibration(rt711); if (ret < 0) diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 2f445b27305a4..5709a6bbe8fc5 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -1207,6 +1207,10 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap, mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); + INIT_DELAYED_WORK(&rt711->jack_detect_work, rt711_jack_detect_handler); + INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_btn_check_handler); + INIT_WORK(&rt711->calibration_work, rt711_calibration_work); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1314,14 +1318,8 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave) if (rt711->first_hw_init) rt711_calibration(rt711); - else { - INIT_DELAYED_WORK(&rt711->jack_detect_work, - rt711_jack_detect_handler); - INIT_DELAYED_WORK(&rt711->jack_btn_check_work, - rt711_btn_check_handler); - INIT_WORK(&rt711->calibration_work, rt711_calibration_work); + else schedule_work(&rt711->calibration_work); - } /* * if set_jack callback occurred early than io_init, -- GitLab From e02b99e9b79ff272e8c299a3ee53bdb194ca885e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:52 -0500 Subject: [PATCH 309/942] ASoC: codecs: rt700/rt711/rt711-sdca: resume bus/codec in .set_jack_detect The .set_jack_detect() codec component callback is invoked during card registration, which happens when the machine driver is probed. The issue is that this callback can race with the bus suspend/resume, and IO timeouts can happen. This can be reproduced very easily if the machine driver is 'blacklisted' and manually probed after the bus suspends. The bus and codec need to be re-initialized using pm_runtime helpers. Previous contributions tried to make sure accesses to the bus during the .set_jack_detect() component callback only happen when the bus is active. This was done by changing the regcache status on a component remove. This is however a layering violation, the regcache status should only be modified on device probe, suspend and resume. The component probe/remove should not modify how the device regcache is handled. This solution also didn't handle all the possible race conditions, and the RT700 headset codec was not handled. This patch tries to resume the codec device before handling the jack initializations. In case the codec has not yet been initialized, pm_runtime may not be enabled yet, so we don't squelch the -EACCES error code and only stop the jack information. When the codec reports as attached, the jack initialization will proceed as usual. BugLink: https://github.com/thesofproject/linux/issues/3643 Fixes: 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver') Fixes: 899b12542b089 ('ASoC: rt711: add snd_soc_component remove callback') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 16 +++++++++++++--- sound/soc/codecs/rt711-sdca.c | 26 ++++++++++++++------------ sound/soc/codecs/rt711.c | 24 +++++++++++++----------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 7a6cf3434591a..9bceeeb830b15 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->hs_jack = hs_jack; - if (!rt700->hw_init) { - dev_dbg(&rt700->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt700_jack_init(rt700); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 2b3b77577d1fd..dfe3c9299ebde 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -487,16 +487,27 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711->hs_jack = hs_jack; - if (!rt711->hw_init) { - dev_dbg(&rt711->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt711_sdca_jack_init(rt711); + + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } @@ -1190,14 +1201,6 @@ static int rt711_sdca_probe(struct snd_soc_component *component) return 0; } -static void rt711_sdca_remove(struct snd_soc_component *component) -{ - struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(rt711->regmap, true); - regcache_cache_only(rt711->mbq_regmap, true); -} - static const struct snd_soc_component_driver soc_sdca_dev_rt711 = { .probe = rt711_sdca_probe, .controls = rt711_sdca_snd_controls, @@ -1207,7 +1210,6 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = { .dapm_routes = rt711_sdca_audio_map, .num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map), .set_jack = rt711_sdca_set_jack_detect, - .remove = rt711_sdca_remove, .endianness = 1, }; diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 5709a6bbe8fc5..9df800abfc2d8 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -457,17 +457,27 @@ static int rt711_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711->hs_jack = hs_jack; - if (!rt711->hw_init) { - dev_dbg(&rt711->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt711_jack_init(rt711); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } @@ -932,13 +942,6 @@ static int rt711_probe(struct snd_soc_component *component) return 0; } -static void rt711_remove(struct snd_soc_component *component) -{ - struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(rt711->regmap, true); -} - static const struct snd_soc_component_driver soc_codec_dev_rt711 = { .probe = rt711_probe, .set_bias_level = rt711_set_bias_level, @@ -949,7 +952,6 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = { .dapm_routes = rt711_audio_map, .num_dapm_routes = ARRAY_SIZE(rt711_audio_map), .set_jack = rt711_set_jack_detect, - .remove = rt711_remove, .endianness = 1, }; -- GitLab From 41782d7056e2866ca40cb2d3f56c4c97fd5af337 Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Mon, 6 Jun 2022 10:09:48 +0800 Subject: [PATCH 310/942] Revert "drm/amdgpu: Ensure the DMA engine is deactivated during set ups" This reverts commit b992a19085885c096b19625a85c674cb89829ca1. This causes regression in GPU reset related test. Cc: Alexander Deucher Cc: ricetons@gmail.com Signed-off-by: Guchun Chen Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 109 ++++++++++--------------- 1 file changed, 45 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 06b2635b142a5..83c6ccaaa9e4e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -469,6 +469,7 @@ static void sdma_v5_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se } } + /** * sdma_v5_2_gfx_stop - stop the gfx async dma engines * @@ -514,21 +515,17 @@ static void sdma_v5_2_rlc_stop(struct amdgpu_device *adev) } /** - * sdma_v5_2_ctx_switch_enable_for_instance - start the async dma engines - * context switch for an instance + * sdma_v5_2_ctx_switch_enable - stop the async dma engines context switch * * @adev: amdgpu_device pointer - * @instance_idx: the index of the SDMA instance + * @enable: enable/disable the DMA MEs context switch. * - * Unhalt the async dma engines context switch. + * Halt or unhalt the async dma engines context switch. */ -static void sdma_v5_2_ctx_switch_enable_for_instance(struct amdgpu_device *adev, int instance_idx) +static void sdma_v5_2_ctx_switch_enable(struct amdgpu_device *adev, bool enable) { u32 f32_cntl, phase_quantum = 0; - - if (WARN_ON(instance_idx >= adev->sdma.num_instances)) { - return; - } + int i; if (amdgpu_sdma_phase_quantum) { unsigned value = amdgpu_sdma_phase_quantum; @@ -552,68 +549,50 @@ static void sdma_v5_2_ctx_switch_enable_for_instance(struct amdgpu_device *adev, phase_quantum = value << SDMA0_PHASE0_QUANTUM__VALUE__SHIFT | unit << SDMA0_PHASE0_QUANTUM__UNIT__SHIFT; - - WREG32_SOC15_IP(GC, - sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE0_QUANTUM), - phase_quantum); - WREG32_SOC15_IP(GC, - sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE1_QUANTUM), - phase_quantum); - WREG32_SOC15_IP(GC, - sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_PHASE2_QUANTUM), - phase_quantum); } - if (!amdgpu_sriov_vf(adev)) { - f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_CNTL)); - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, - AUTO_CTXSW_ENABLE, 1); - WREG32(sdma_v5_2_get_reg_offset(adev, instance_idx, mmSDMA0_CNTL), f32_cntl); + for (i = 0; i < adev->sdma.num_instances; i++) { + if (enable && amdgpu_sdma_phase_quantum) { + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM), + phase_quantum); + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE1_QUANTUM), + phase_quantum); + WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM), + phase_quantum); + } + + if (!amdgpu_sriov_vf(adev)) { + f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, + AUTO_CTXSW_ENABLE, enable ? 1 : 0); + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl); + } } + } /** - * sdma_v5_2_ctx_switch_disable_all - stop the async dma engines context switch + * sdma_v5_2_enable - stop the async dma engines * * @adev: amdgpu_device pointer + * @enable: enable/disable the DMA MEs. * - * Halt the async dma engines context switch. + * Halt or unhalt the async dma engines. */ -static void sdma_v5_2_ctx_switch_disable_all(struct amdgpu_device *adev) +static void sdma_v5_2_enable(struct amdgpu_device *adev, bool enable) { u32 f32_cntl; int i; - if (amdgpu_sriov_vf(adev)) - return; - - for (i = 0; i < adev->sdma.num_instances; i++) { - f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL)); - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL, - AUTO_CTXSW_ENABLE, 0); - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl); + if (!enable) { + sdma_v5_2_gfx_stop(adev); + sdma_v5_2_rlc_stop(adev); } -} - -/** - * sdma_v5_2_halt - stop the async dma engines - * - * @adev: amdgpu_device pointer - * - * Halt the async dma engines. - */ -static void sdma_v5_2_halt(struct amdgpu_device *adev) -{ - int i; - u32 f32_cntl; - - sdma_v5_2_gfx_stop(adev); - sdma_v5_2_rlc_stop(adev); if (!amdgpu_sriov_vf(adev)) { for (i = 0; i < adev->sdma.num_instances; i++) { f32_cntl = RREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL)); - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 1); + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1); WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl); } } @@ -625,9 +604,6 @@ static void sdma_v5_2_halt(struct amdgpu_device *adev) * @adev: amdgpu_device pointer * * Set up the gfx DMA ring buffers and enable them. - * It assumes that the dma engine is stopped for each instance. - * The function enables the engine and preemptions sequentially for each instance. - * * Returns 0 for success, error for failure. */ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) @@ -769,7 +745,10 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) ring->sched.ready = true; - sdma_v5_2_ctx_switch_enable_for_instance(adev, i); + if (amdgpu_sriov_vf(adev)) { /* bare-metal sequence doesn't need below to lines */ + sdma_v5_2_ctx_switch_enable(adev, true); + sdma_v5_2_enable(adev, true); + } r = amdgpu_ring_test_ring(ring); if (r) { @@ -813,7 +792,7 @@ static int sdma_v5_2_load_microcode(struct amdgpu_device *adev) int i, j; /* halt the MEs */ - sdma_v5_2_halt(adev); + sdma_v5_2_enable(adev, false); for (i = 0; i < adev->sdma.num_instances; i++) { if (!adev->sdma.instance[i].fw) @@ -885,8 +864,8 @@ static int sdma_v5_2_start(struct amdgpu_device *adev) int r = 0; if (amdgpu_sriov_vf(adev)) { - sdma_v5_2_ctx_switch_disable_all(adev); - sdma_v5_2_halt(adev); + sdma_v5_2_ctx_switch_enable(adev, false); + sdma_v5_2_enable(adev, false); /* set RB registers */ r = sdma_v5_2_gfx_resume(adev); @@ -910,10 +889,12 @@ static int sdma_v5_2_start(struct amdgpu_device *adev) amdgpu_gfx_off_ctrl(adev, false); sdma_v5_2_soft_reset(adev); + /* unhalt the MEs */ + sdma_v5_2_enable(adev, true); + /* enable sdma ring preemption */ + sdma_v5_2_ctx_switch_enable(adev, true); - /* Soft reset supposes to disable the dma engine and preemption. - * Now start the gfx rings and rlc compute queues. - */ + /* start the gfx rings and rlc compute queues */ r = sdma_v5_2_gfx_resume(adev); if (adev->in_s0ix) amdgpu_gfx_off_ctrl(adev, true); @@ -1447,8 +1428,8 @@ static int sdma_v5_2_hw_fini(void *handle) if (amdgpu_sriov_vf(adev)) return 0; - sdma_v5_2_ctx_switch_disable_all(adev); - sdma_v5_2_halt(adev); + sdma_v5_2_ctx_switch_enable(adev, false); + sdma_v5_2_enable(adev, false); return 0; } -- GitLab From 8b8ce2b90af1bea3d7b24e250832fcc3c7e687ea Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Tue, 17 May 2022 10:12:27 -0400 Subject: [PATCH 311/942] Revert "drm/amd/display: Pass the new context into disable OTG WA" This reverts commit 8440f57532496d398a461887e56ca6f45089fbcf. Causes a hang when hotplugging DP, shutting down system, or enabling dual eDP. Reviewed-by: Dmytro Laktyushkin Acked-by: Hamza Mahfooz Signed-off-by: Nicholas Kazlauskas Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c | 8 ++++---- .../drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 8 ++++---- .../drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c index 6a81c1aea0be5..bca5f01da7637 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c @@ -99,13 +99,13 @@ static int dcn31_get_active_display_cnt_wa( return display_count; } -static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) +static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -211,11 +211,11 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn31_disable_otg_wa(clk_mgr_base, context, true); + dcn31_disable_otg_wa(clk_mgr_base, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn31_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn31_disable_otg_wa(clk_mgr_base, context, false); + dcn31_disable_otg_wa(clk_mgr_base, false); update_dispclk = true; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c index aa01a18df419f..fb4ae800e9193 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c @@ -79,13 +79,13 @@ static int dcn315_get_active_display_cnt_wa( return display_count; } -static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) +static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -173,11 +173,11 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn315_disable_otg_wa(clk_mgr_base, context, true); + dcn315_disable_otg_wa(clk_mgr_base, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn315_disable_otg_wa(clk_mgr_base, context, false); + dcn315_disable_otg_wa(clk_mgr_base, false); update_dispclk = true; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c index 7192f30858eb4..e4bb9c6193b57 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c @@ -112,13 +112,13 @@ static int dcn316_get_active_display_cnt_wa( return display_count; } -static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) +static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; @@ -221,11 +221,11 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base, } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn316_disable_otg_wa(clk_mgr_base, context, true); + dcn316_disable_otg_wa(clk_mgr_base, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn316_disable_otg_wa(clk_mgr_base, context, false); + dcn316_disable_otg_wa(clk_mgr_base, false); update_dispclk = true; } -- GitLab From b3f9234e106c9ca4dd0fab3cebbdc8ac74504f97 Mon Sep 17 00:00:00 2001 From: Joseph Greathouse Date: Mon, 6 Jun 2022 16:09:25 -0500 Subject: [PATCH 312/942] drm/amdgpu: Add MODE register to wave debug info in gfx11 All other chips, from gfx6-gfx10, now include the MODE register at the end of the wave debug state. This appears to have been missed in gfx11, so this patch adds in MODE to the debug state for gfx11. Signed-off-by: Joseph Greathouse Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 10e180b2d0f52..a4a6751b1e449 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1096,6 +1096,7 @@ static void gfx_v11_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_STS2); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_DBG1); dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_M0); + dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_MODE); } static void gfx_v11_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd, -- GitLab From c42e65664390be7c1ef3838cd84956d3a2739d60 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 7 Jun 2022 12:11:33 -0700 Subject: [PATCH 313/942] Input: bcm5974 - set missing URB_NO_TRANSFER_DMA_MAP urb flag The bcm5974 driver does the allocation and dma mapping of the usb urb data buffer, but driver does not set the URB_NO_TRANSFER_DMA_MAP flag to let usb core know the buffer is already mapped. usb core tries to map the already mapped buffer, causing a warning: "xhci_hcd 0000:00:14.0: rejecting DMA map of vmalloc memory" Fix this by setting the URB_NO_TRANSFER_DMA_MAP, letting usb core know buffer is already mapped by bcm5974 driver Signed-off-by: Mathias Nyman Cc: stable@vger.kernel.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=215890 Link: https://lore.kernel.org/r/20220606113636.588955-1-mathias.nyman@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/bcm5974.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 59a14505b9cd1..ca150618d32f1 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -942,17 +942,22 @@ static int bcm5974_probe(struct usb_interface *iface, if (!dev->tp_data) goto err_free_bt_buffer; - if (dev->bt_urb) + if (dev->bt_urb) { usb_fill_int_urb(dev->bt_urb, udev, usb_rcvintpipe(udev, cfg->bt_ep), dev->bt_data, dev->cfg.bt_datalen, bcm5974_irq_button, dev, 1); + dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + } + usb_fill_int_urb(dev->tp_urb, udev, usb_rcvintpipe(udev, cfg->tp_ep), dev->tp_data, dev->cfg.tp_datalen, bcm5974_irq_trackpad, dev, 1); + dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + /* create bcm5974 device */ usb_make_path(udev, dev->phys, sizeof(dev->phys)); strlcat(dev->phys, "/input0", sizeof(dev->phys)); -- GitLab From 6ab2e51898cd4343bbdf8587af8ce8fbabddbcb5 Mon Sep 17 00:00:00 2001 From: Marius Hoch Date: Tue, 7 Jun 2022 12:10:52 -0700 Subject: [PATCH 314/942] Input: soc_button_array - also add Lenovo Yoga Tablet2 1051F to dmi_use_low_level_irq Commit 223f61b8c5ad ("Input: soc_button_array - add Lenovo Yoga Tablet2 1051L to the dmi_use_low_level_irq list") added the 1051L to this list already, but the same problem applies to the 1051F. As there are no further 1051 variants (just the F/L), we can just DMI match 1051. Tested on a Lenovo Yoga Tablet2 1051F: Without this patch the home-button stops working after a wakeup from suspend. Signed-off-by: Marius Hoch Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20220603120246.3065-1-mail@mariushoch.de Signed-off-by: Dmitry Torokhov --- drivers/input/misc/soc_button_array.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index cb6ec59a045d4..efffcf0ebd3b4 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -85,13 +85,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = { }, { /* - * Lenovo Yoga Tab2 1051L, something messes with the home-button + * Lenovo Yoga Tab2 1051F/1051L, something messes with the home-button * IRQ settings, leading to a non working home-button. */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "60073"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1051L"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1051"), }, }, {} /* Terminating entry */ -- GitLab From f92de9d110429e39929a49240d823251c2fe903e Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Thu, 2 Jun 2022 16:51:13 -0600 Subject: [PATCH 315/942] scsi: sd: Fix interpretation of VPD B9h length Fixing the interpretation of the length of the B9h VPD page (Concurrent Positioning Ranges). Adding 4 is necessary as the first 4 bytes of the page is the header with page number and length information. Adding 3 was likely a misinterpretation of the SBC-5 specification which sets all offsets starting at zero. This fixes the error in dmesg: [ 9.014456] sd 1:0:0:0: [sda] Invalid Concurrent Positioning Ranges VPD page Link: https://lore.kernel.org/r/20220602225113.10218-4-tyler.erickson@seagate.com Fixes: e815d36548f0 ("scsi: sd: add concurrent positioning ranges support") Cc: stable@vger.kernel.org Tested-by: Michael English Reviewed-by: Muhammad Ahmad Reviewed-by: Damien Le Moal Reviewed-by: Hannes Reinecke Signed-off-by: Tyler Erickson Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 895b56c8f25e3..a1a2ac09066fd 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3072,7 +3072,7 @@ static void sd_read_cpr(struct scsi_disk *sdkp) goto out; /* We must have at least a 64B header and one 32B range descriptor */ - vpd_len = get_unaligned_be16(&buffer[2]) + 3; + vpd_len = get_unaligned_be16(&buffer[2]) + 4; if (vpd_len > buf_len || vpd_len < 64 + 32 || (vpd_len & 31)) { sd_printk(KERN_ERR, sdkp, "Invalid Concurrent Positioning Ranges VPD page\n"); -- GitLab From cf71d59c2eceadfcde0fb52e237990a0909880d7 Mon Sep 17 00:00:00 2001 From: Wentao Wang Date: Thu, 2 Jun 2022 08:57:00 +0000 Subject: [PATCH 316/942] scsi: vmw_pvscsi: Expand vcpuHint to 16 bits vcpuHint has been expanded to 16 bit on host to enable routing to more CPUs. Guest side should align with the change. This change has been tested with hosts with 8-bit and 16-bit vcpuHint, on both platforms host side can get correct value. Link: https://lore.kernel.org/r/EF35F4D5-5DCC-42C5-BCC4-29DF1729B24C@vmware.com Signed-off-by: Wentao Wang Signed-off-by: Martin K. Petersen --- drivers/scsi/vmw_pvscsi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h index 51a82f7803d3c..9d16cf9254837 100644 --- a/drivers/scsi/vmw_pvscsi.h +++ b/drivers/scsi/vmw_pvscsi.h @@ -331,8 +331,8 @@ struct PVSCSIRingReqDesc { u8 tag; u8 bus; u8 target; - u8 vcpuHint; - u8 unused[59]; + u16 vcpuHint; + u8 unused[58]; } __packed; /* -- GitLab From 44ba9786b67345dc4e5eabe537c9ef2bfd889888 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:21 -0700 Subject: [PATCH 317/942] scsi: lpfc: Correct BDE type for XMIT_SEQ64_WQE in lpfc_ct_reject_event() A previous commit assumed all XMIT_SEQ64_WQEs are prepped with the correct BDE type in word 0-2. However, lpfc_ct_reject_event() routine was missed and is still filling out the incorrect BDE type. Fix lpfc_ct_reject_event() routine so that type BUFF_TYPE_BDE_64 is set instead of BUFF_TYPE_BLP_64. Link: https://lore.kernel.org/r/20220603174329.63777-2-jsmart2021@gmail.com Fixes: 596fc8adb171 ("scsi: lpfc: Fix dmabuf ptr assignment in lpfc_ct_reject_event()") Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_ct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 9d36b20fb8787..13dfe285493d1 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -197,7 +197,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, memset(bpl, 0, sizeof(struct ulp_bde64)); bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys)); bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys)); - bpl->tus.f.bdeFlags = BUFF_TYPE_BLP_64; + bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64; bpl->tus.f.bdeSize = (LPFC_CT_PREAMBLE - 4); bpl->tus.w = le32_to_cpu(bpl->tus.w); -- GitLab From 24e1f056677eefe834d5dcf61905cce857ca4b19 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:22 -0700 Subject: [PATCH 318/942] scsi: lpfc: Resolve some cleanup issues following abort path refactoring Refactoring and consolidation of abort paths: - lpfc_sli4_abort_fcp_cmpl() and lpfc_sli_abort_fcp_cmpl() are combined into a single generic lpfc_sli_abort_fcp_cmpl() routine. Thus, remove extraneous lpfc_sli4_abort_fcp_cmpl() prototype declaration. - lpfc_nvme_abort_fcreq_cmpl() abort completion routine is called with a mismatched argument type. This may result in misleading log message content. Update to the correct argument type of lpfc_iocbq instead of lpfc_wcqe_complete. The lpfc_wcqe_complete should be derived from the lpfc_iocbq structure. Link: https://lore.kernel.org/r/20220603174329.63777-3-jsmart2021@gmail.com Fixes: 31a59f75702f ("scsi: lpfc: SLI path split: Refactor Abort paths") Cc: # v5.18 Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 4 +--- drivers/scsi/lpfc/lpfc_nvme.c | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index b1be0dd0337a5..f5d74958b6643 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -420,8 +420,6 @@ int lpfc_sli_issue_iocb_wait(struct lpfc_hba *, uint32_t, uint32_t); void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *, struct lpfc_iocbq *, struct lpfc_iocbq *); -void lpfc_sli4_abort_fcp_cmpl(struct lpfc_hba *h, struct lpfc_iocbq *i, - struct lpfc_wcqe_complete *w); void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *); @@ -630,7 +628,7 @@ void lpfc_nvmet_invalidate_host(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp); void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_wcqe_complete *abts_cmpl); + struct lpfc_iocbq *rspiocb); void lpfc_create_multixri_pools(struct lpfc_hba *phba); void lpfc_create_destroy_pools(struct lpfc_hba *phba); void lpfc_move_xri_pvt_to_pbl(struct lpfc_hba *phba, u32 hwqid); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 335e906339331..88fa630ab93af 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1787,7 +1787,7 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, * lpfc_nvme_abort_fcreq_cmpl - Complete an NVME FCP abort request. * @phba: Pointer to HBA context object * @cmdiocb: Pointer to command iocb object. - * @abts_cmpl: Pointer to wcqe complete object. + * @rspiocb: Pointer to response iocb object. * * This is the callback function for any NVME FCP IO that was aborted. * @@ -1796,8 +1796,10 @@ lpfc_nvme_fcp_io_submit(struct nvme_fc_local_port *pnvme_lport, **/ void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_wcqe_complete *abts_cmpl) + struct lpfc_iocbq *rspiocb) { + struct lpfc_wcqe_complete *abts_cmpl = &rspiocb->wcqe_cmpl; + lpfc_printf_log(phba, KERN_INFO, LOG_NVME, "6145 ABORT_XRI_CN completing on rpi x%x " "original iotag x%x, abort cmd iotag x%x " -- GitLab From e27f05147bff21408c1b8410ad8e90cd286e7952 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:23 -0700 Subject: [PATCH 319/942] scsi: lpfc: Resolve some cleanup issues following SLI path refactoring Following refactoring and consolidation in SLI processing, fix up some minor issues related to SLI path: - Correct the setting of LPFC_EXCHANGE_BUSY flag in response IOCB. - Fix some typographical errors. - Fix duplicate log messages. Link: https://lore.kernel.org/r/20220603174329.63777-4-jsmart2021@gmail.com Fixes: 1b64aa9eae28 ("scsi: lpfc: SLI path split: Refactor fast and slow paths to native SLI4") Cc: # v5.18 Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 93b94c64518df..750dd1e9f2cc7 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -12188,7 +12188,7 @@ lpfc_sli_enable_msi(struct lpfc_hba *phba) rc = pci_enable_msi(phba->pcidev); if (!rc) lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "0462 PCI enable MSI mode success.\n"); + "0012 PCI enable MSI mode success.\n"); else { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0471 PCI enable MSI mode failed (%d)\n", rc); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6ed696c4602aa..80ac3a051c192 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1930,7 +1930,7 @@ lpfc_issue_cmf_sync_wqe(struct lpfc_hba *phba, u32 ms, u64 total) sync_buf = __lpfc_sli_get_iocbq(phba); if (!sync_buf) { lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT, - "6213 No available WQEs for CMF_SYNC_WQE\n"); + "6244 No available WQEs for CMF_SYNC_WQE\n"); ret_val = ENOMEM; goto out_unlock; } @@ -3805,7 +3805,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, set_job_ulpword4(cmdiocbp, IOERR_ABORT_REQUESTED); /* - * For SLI4, irsiocb contains + * For SLI4, irspiocb contains * NO_XRI in sli_xritag, it * shall not affect releasing * sgl (xri) process. @@ -3823,7 +3823,7 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } } } - (cmdiocbp->cmd_cmpl) (phba, cmdiocbp, saveq); + cmdiocbp->cmd_cmpl(phba, cmdiocbp, saveq); } else lpfc_sli_release_iocbq(phba, cmdiocbp); } else { @@ -4063,8 +4063,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, cmdiocbq->cmd_flag &= ~LPFC_DRIVER_ABORTED; if (cmdiocbq->cmd_cmpl) { spin_unlock_irqrestore(&phba->hbalock, iflag); - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, - &rspiocbq); + cmdiocbq->cmd_cmpl(phba, cmdiocbq, &rspiocbq); spin_lock_irqsave(&phba->hbalock, iflag); } break; @@ -10288,7 +10287,7 @@ __lpfc_sli_issue_iocb_s3(struct lpfc_hba *phba, uint32_t ring_number, * @flag: Flag indicating if this command can be put into txq. * * __lpfc_sli_issue_fcp_io_s3 is wrapper function to invoke lockless func to - * send an iocb command to an HBA with SLI-4 interface spec. + * send an iocb command to an HBA with SLI-3 interface spec. * * This function takes the hbalock before invoking the lockless version. * The function will return success after it successfully submit the wqe to @@ -12740,7 +12739,7 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, cmdiocbq->cmd_cmpl = cmdiocbq->wait_cmd_cmpl; cmdiocbq->wait_cmd_cmpl = NULL; if (cmdiocbq->cmd_cmpl) - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, NULL); + cmdiocbq->cmd_cmpl(phba, cmdiocbq, NULL); else lpfc_sli_release_iocbq(phba, cmdiocbq); return; @@ -12754,9 +12753,9 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba, /* Set the exchange busy flag for task management commands */ if ((cmdiocbq->cmd_flag & LPFC_IO_FCP) && - !(cmdiocbq->cmd_flag & LPFC_IO_LIBDFC)) { + !(cmdiocbq->cmd_flag & LPFC_IO_LIBDFC)) { lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf, - cur_iocbq); + cur_iocbq); if (rspiocbq && (rspiocbq->cmd_flag & LPFC_EXCHANGE_BUSY)) lpfc_cmd->flags |= LPFC_SBUF_XBUSY; else @@ -13896,7 +13895,7 @@ void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *phba) * @irspiocbq: Pointer to work-queue completion queue entry. * * This routine handles an ELS work-queue completion event and construct - * a pseudo response ELS IODBQ from the SLI4 ELS WCQE for the common + * a pseudo response ELS IOCBQ from the SLI4 ELS WCQE for the common * discovery engine to handle. * * Return: Pointer to the receive IOCBQ, NULL otherwise. @@ -13940,7 +13939,7 @@ lpfc_sli4_els_preprocess_rspiocbq(struct lpfc_hba *phba, if (bf_get(lpfc_wcqe_c_xb, wcqe)) { spin_lock_irqsave(&phba->hbalock, iflags); - cmdiocbq->cmd_flag |= LPFC_EXCHANGE_BUSY; + irspiocbq->cmd_flag |= LPFC_EXCHANGE_BUSY; spin_unlock_irqrestore(&phba->hbalock, iflags); } @@ -14799,7 +14798,7 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, /* Pass the cmd_iocb and the wcqe to the upper layer */ memcpy(&cmdiocbq->wcqe_cmpl, wcqe, sizeof(struct lpfc_wcqe_complete)); - (cmdiocbq->cmd_cmpl)(phba, cmdiocbq, cmdiocbq); + cmdiocbq->cmd_cmpl(phba, cmdiocbq, cmdiocbq); } else { lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, "0375 FCP cmdiocb not callback function " @@ -18956,7 +18955,7 @@ lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport, /* Free iocb created in lpfc_prep_seq */ list_for_each_entry_safe(curr_iocb, next_iocb, - &iocbq->list, list) { + &iocbq->list, list) { list_del_init(&curr_iocb->list); lpfc_sli_release_iocbq(phba, curr_iocb); } -- GitLab From 6f808bd78e8296b4ded813b7182988d57e1f6176 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:24 -0700 Subject: [PATCH 320/942] scsi: lpfc: Address NULL pointer dereference after starget_to_rport() Calls to starget_to_rport() may return NULL. Add check for NULL rport before dereference. Link: https://lore.kernel.org/r/20220603174329.63777-5-jsmart2021@gmail.com Fixes: bb21fc9911ee ("scsi: lpfc: Use fc_block_rport()") Cc: # v5.18 Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index d439682032489..ba5e4016262e2 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6062,6 +6062,9 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) int status; u32 logit = LOG_FCP; + if (!rport) + return FAILED; + rdata = rport->dd_data; if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, @@ -6140,6 +6143,9 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) unsigned long flags; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); + if (!rport) + return FAILED; + rdata = rport->dd_data; if (!rdata || !rdata->pnode) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, -- GitLab From b1b3440f437b75fb2a9b0cfe58df461e40eca474 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:25 -0700 Subject: [PATCH 321/942] scsi: lpfc: Resolve NULL ptr dereference after an ELS LOGO is aborted A use-after-free crash can occur after an ELS LOGO is aborted. Specifically, a nodelist structure is freed and then ndlp->vport->cfg_log_verbose is dereferenced in lpfc_nlp_get() when the discovery state machine is mistakenly called a second time with NLP_EVT_DEVICE_RM argument. Rework lpfc_cmpl_els_logo() to prevent the duplicate calls to release a nodelist structure. Link: https://lore.kernel.org/r/20220603174329.63777-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 07f9a6e61e10b..3fababb7c1818 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2998,10 +2998,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_DID, ulp_status, ulp_word4); - /* Call NLP_EVT_DEVICE_RM if link is down or LOGO is aborted */ if (lpfc_error_lost_link(ulp_status, ulp_word4)) { - lpfc_disc_state_machine(vport, ndlp, cmdiocb, - NLP_EVT_DEVICE_RM); skip_recovery = 1; goto out; } @@ -3021,18 +3018,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, spin_unlock_irq(&ndlp->lock); lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); - lpfc_els_free_iocb(phba, cmdiocb); - lpfc_nlp_put(ndlp); - - /* Presume the node was released. */ - return; + goto out_rsrc_free; } out: - /* Driver is done with the IO. */ - lpfc_els_free_iocb(phba, cmdiocb); - lpfc_nlp_put(ndlp); - /* At this point, the LOGO processing is complete. NOTE: For a * pt2pt topology, we are assuming the NPortID will only change * on link up processing. For a LOGO / PLOGI initiated by the @@ -3059,6 +3048,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_DID, ulp_status, ulp_word4, tmo, vport->num_disc_nodes); + + lpfc_els_free_iocb(phba, cmdiocb); + lpfc_nlp_put(ndlp); + lpfc_disc_start(vport); return; } @@ -3075,6 +3068,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); } +out_rsrc_free: + /* Driver is done with the I/O. */ + lpfc_els_free_iocb(phba, cmdiocb); + lpfc_nlp_put(ndlp); } /** -- GitLab From 336d63615466b4c06b9401c987813fd19bdde39b Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:26 -0700 Subject: [PATCH 322/942] scsi: lpfc: Fix port stuck in bypassed state after LIP in PT2PT topology After issuing a LIP, a specific target vendor does not ACC the FLOGI that lpfc sends. However, it does send its own FLOGI that lpfc ACCs. The target then establishes the port IDs by sending a PLOGI. lpfc PLOGI_ACCs and starts the RPI registration for DID 0x000001. The target then sends a LOGO to the fabric DID. lpfc is currently treating the LOGO from the fabric DID as a link down and cleans up all the ndlps. The ndlp for DID 0x000001 is put back into NPR and discovery stops, leaving the port in stuck in bypassed mode. Change lpfc behavior such that if a LOGO is received for the fabric DID in PT2PT topology skip the lpfc_linkdown_port() routine and just move the fabric DID back to NPR. Link: https://lore.kernel.org/r/20220603174329.63777-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 639f866351271..b86ff9fcdf0c6 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -834,7 +834,8 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_nvmet_invalidate_host(phba, ndlp); if (ndlp->nlp_DID == Fabric_DID) { - if (vport->port_state <= LPFC_FDISC) + if (vport->port_state <= LPFC_FDISC || + vport->fc_flag & FC_PT2PT) goto out; lpfc_linkdown_port(vport); spin_lock_irq(shost->host_lock); -- GitLab From ea7bd1f393311e823716a232e9d8857fb64eb105 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:27 -0700 Subject: [PATCH 323/942] scsi: lpfc: Add more logging of cmd and cqe information for aborted NVMe cmds When an NVMe command is aborted or completes with an ERSP, log the opcode and command ID fields to help provide more detail on the failed command. Link: https://lore.kernel.org/r/20220603174329.63777-8-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvme.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 88fa630ab93af..9cc22cefcb372 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1065,25 +1065,37 @@ lpfc_nvme_io_cmd_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, nCmd->rcv_rsplen = wcqe->parameter; nCmd->status = 0; + /* Get the NVME cmd details for this unique error. */ + cp = (struct nvme_fc_cmd_iu *)nCmd->cmdaddr; + ep = (struct nvme_fc_ersp_iu *)nCmd->rspaddr; + /* Check if this is really an ERSP */ if (nCmd->rcv_rsplen == LPFC_NVME_ERSP_LEN) { lpfc_ncmd->status = IOSTAT_SUCCESS; lpfc_ncmd->result = 0; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, - "6084 NVME Completion ERSP: " - "xri %x placed x%x\n", - lpfc_ncmd->cur_iocbq.sli4_xritag, - wcqe->total_data_placed); + "6084 NVME FCP_ERR ERSP: " + "xri %x placed x%x opcode x%x cmd_id " + "x%x cqe_status x%x\n", + lpfc_ncmd->cur_iocbq.sli4_xritag, + wcqe->total_data_placed, + cp->sqe.common.opcode, + cp->sqe.common.command_id, + ep->cqe.status); break; } lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6081 NVME Completion Protocol Error: " "xri %x status x%x result x%x " - "placed x%x\n", + "placed x%x opcode x%x cmd_id x%x, " + "cqe_status x%x\n", lpfc_ncmd->cur_iocbq.sli4_xritag, lpfc_ncmd->status, lpfc_ncmd->result, - wcqe->total_data_placed); + wcqe->total_data_placed, + cp->sqe.common.opcode, + cp->sqe.common.command_id, + ep->cqe.status); break; case IOSTAT_LOCAL_REJECT: /* Let fall through to set command final state. */ @@ -1842,6 +1854,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, struct lpfc_nvme_fcpreq_priv *freqpriv; unsigned long flags; int ret_val; + struct nvme_fc_cmd_iu *cp; /* Validate pointers. LLDD fault handling with transport does * have timing races. @@ -1965,10 +1978,16 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, return; } + /* + * Get Command Id from cmd to plug into response. This + * code is not needed in the next NVME Transport drop. + */ + cp = (struct nvme_fc_cmd_iu *)lpfc_nbuf->nvmeCmd->cmdaddr; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_ABTS, "6138 Transport Abort NVME Request Issued for " - "ox_id x%x\n", - nvmereq_wqe->sli4_xritag); + "ox_id x%x nvme opcode x%x nvme cmd_id x%x\n", + nvmereq_wqe->sli4_xritag, cp->sqe.common.opcode, + cp->sqe.common.command_id); return; out_unlock: -- GitLab From 2e7e9c0c1ec05f18d320ecc8a31eec59d2af1af9 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:28 -0700 Subject: [PATCH 324/942] scsi: lpfc: Allow reduced polling rate for nvme_admin_async_event cmd completion NVMe Asynchronous Event Request commands have no command timeout value per specifications. Set WQE option to allow a reduced FLUSH polling rate for I/O error detection specifically for nvme_admin_async_event commands. Link: https://lore.kernel.org/r/20220603174329.63777-9-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 3 +++ drivers/scsi/lpfc/lpfc_nvme.c | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 8511369d2cf8e..f024415731ac7 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -4487,6 +4487,9 @@ struct wqe_common { #define wqe_sup_SHIFT 6 #define wqe_sup_MASK 0x00000001 #define wqe_sup_WORD word11 +#define wqe_ffrq_SHIFT 6 +#define wqe_ffrq_MASK 0x00000001 +#define wqe_ffrq_WORD word11 #define wqe_wqec_SHIFT 7 #define wqe_wqec_MASK 0x00000001 #define wqe_wqec_WORD word11 diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 9cc22cefcb372..cd10ee6482fc0 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1207,7 +1207,8 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, { struct lpfc_hba *phba = vport->phba; struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; - struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq); + struct nvme_common_command *sqe; + struct lpfc_iocbq *pwqeq = &lpfc_ncmd->cur_iocbq; union lpfc_wqe128 *wqe = &pwqeq->wqe; uint32_t req_len; @@ -1264,8 +1265,14 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, cstat->control_requests++; } - if (pnode->nlp_nvme_info & NLP_NVME_NSLER) + if (pnode->nlp_nvme_info & NLP_NVME_NSLER) { bf_set(wqe_erp, &wqe->generic.wqe_com, 1); + sqe = &((struct nvme_fc_cmd_iu *) + nCmd->cmdaddr)->sqe.common; + if (sqe->opcode == nvme_admin_async_event) + bf_set(wqe_ffrq, &wqe->generic.wqe_com, 1); + } + /* * Finish initializing those WQE fields that are independent * of the nvme_cmnd request_buffer -- GitLab From 1af48fffd7ffe280e0c225659d826fd5ae802a08 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 3 Jun 2022 10:43:29 -0700 Subject: [PATCH 325/942] scsi: lpfc: Update lpfc version to 14.2.0.4 Update lpfc version to 14.2.0.4 Link: https://lore.kernel.org/r/20220603174329.63777-10-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 4fab79ed58ed0..2ab6f7db64d86 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "14.2.0.3" +#define LPFC_DRIVER_VERSION "14.2.0.4" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- GitLab From 120f1d95efb1cdb6fe023c84e38ba06d8f78cd03 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 31 May 2022 22:09:27 +0200 Subject: [PATCH 326/942] scsi: mpt3sas: Fix out-of-bounds compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm facing this warning when building for the parisc64 architecture: drivers/scsi/mpt3sas/mpt3sas_base.c: In function ‘_base_make_ioc_operational’: drivers/scsi/mpt3sas/mpt3sas_base.c:5396:40: warning: array subscript ‘Mpi2SasIOUnitPage1_t {aka struct _MPI2_CONFIG_PAGE_SASIOUNIT_1}[0]’ is partly outside array bounds of ‘unsigned char[20]’ [-Warray-bounds] 5396 | (le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth)) ? drivers/scsi/mpt3sas/mpt3sas_base.c:5382:26: note: referencing an object of size 20 allocated by ‘kzalloc’ 5382 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ^~~~~~~~~~~~~~~~~~~~~~~ The problem is, that only 20 bytes are allocated with kmalloc(), which is sufficient to hold the bytes which are needed. Nevertheless, gcc complains because the whole Mpi2SasIOUnitPage1_t struct is 32 bytes in size and thus doesn't fit into those 20 bytes. This patch simply allocates all 32 bytes (instead of 20) and thus avoids the warning. There is no functional change introduced by this patch. While touching the code I cleaned up to calculation of max_wideport_qd, max_narrowport_qd and max_sata_qd to make it easier readable. Test successfully tested on a HP C8000 PA-RISC workstation with 64-bit kernel. Link: https://lore.kernel.org/r/YpZ197iZdDZSCzrT@p100 Signed-off-by: Helge Deller Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 37d46ae5c61d3..9a1ae52bb621d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5369,6 +5369,7 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc) Mpi2ConfigReply_t mpi_reply; Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; Mpi26PCIeIOUnitPage1_t pcie_iounit_pg1; + u16 depth; int sz; int rc = 0; @@ -5380,7 +5381,7 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc) goto out; /* sas iounit page 1 */ sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData); - sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); + sas_iounit_pg1 = kzalloc(sizeof(Mpi2SasIOUnitPage1_t), GFP_KERNEL); if (!sas_iounit_pg1) { pr_err("%s: failure at %s:%d/%s()!\n", ioc->name, __FILE__, __LINE__, __func__); @@ -5393,16 +5394,16 @@ static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc) ioc->name, __FILE__, __LINE__, __func__); goto out; } - ioc->max_wideport_qd = - (le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth)) ? - le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth) : - MPT3SAS_SAS_QUEUE_DEPTH; - ioc->max_narrowport_qd = - (le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth)) ? - le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth) : - MPT3SAS_SAS_QUEUE_DEPTH; - ioc->max_sata_qd = (sas_iounit_pg1->SATAMaxQDepth) ? - sas_iounit_pg1->SATAMaxQDepth : MPT3SAS_SATA_QUEUE_DEPTH; + + depth = le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth); + ioc->max_wideport_qd = (depth ? depth : MPT3SAS_SAS_QUEUE_DEPTH); + + depth = le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth); + ioc->max_narrowport_qd = (depth ? depth : MPT3SAS_SAS_QUEUE_DEPTH); + + depth = sas_iounit_pg1->SATAMaxQDepth; + ioc->max_sata_qd = (depth ? depth : MPT3SAS_SATA_QUEUE_DEPTH); + /* pcie iounit page 1 */ rc = mpt3sas_config_get_pcie_iounit_pg1(ioc, &mpi_reply, &pcie_iounit_pg1, sizeof(Mpi26PCIeIOUnitPage1_t)); -- GitLab From d64c491911322af1dcada98e5b9ee0d87e8c8fee Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Sun, 29 May 2022 23:34:53 +0800 Subject: [PATCH 327/942] scsi: ipr: Fix missing/incorrect resource cleanup in error case Fix missing resource cleanup (when '(--i) == 0') for error case in ipr_alloc_mem() and skip incorrect resource cleanup (when '(--i) == 0') for error case in ipr_request_other_msi_irqs() because variable i started from 1. Link: https://lore.kernel.org/r/20220529153456.4183738-4-cgxu519@mykernel.net Reviewed-by: Dan Carpenter Acked-by: Brian King Signed-off-by: Chengguang Xu Signed-off-by: Martin K. Petersen --- drivers/scsi/ipr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 256ec6d08c168..9d01a3e3c26aa 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9795,7 +9795,7 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) GFP_KERNEL); if (!ioa_cfg->hrrq[i].host_rrq) { - while (--i > 0) + while (--i >= 0) dma_free_coherent(&pdev->dev, sizeof(u32) * ioa_cfg->hrrq[i].size, ioa_cfg->hrrq[i].host_rrq, @@ -10068,7 +10068,7 @@ static int ipr_request_other_msi_irqs(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->vectors_info[i].desc, &ioa_cfg->hrrq[i]); if (rc) { - while (--i >= 0) + while (--i > 0) free_irq(pci_irq_vector(pdev, i), &ioa_cfg->hrrq[i]); return rc; -- GitLab From ec1e8adcbdf661c57c395bca342945f4f815add7 Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Sun, 29 May 2022 23:34:55 +0800 Subject: [PATCH 328/942] scsi: pmcraid: Fix missing resource cleanup in error case Fix missing resource cleanup (when '(--i) == 0') for error case in pmcraid_register_interrupt_handler(). Link: https://lore.kernel.org/r/20220529153456.4183738-6-cgxu519@mykernel.net Reviewed-by: Dan Carpenter Signed-off-by: Chengguang Xu Signed-off-by: Martin K. Petersen --- drivers/scsi/pmcraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index bfce60183a6e5..836ddc476764e 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4031,7 +4031,7 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) return 0; out_unwind: - while (--i > 0) + while (--i >= 0) free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]); pci_free_irq_vectors(pdev); return rc; -- GitLab From 255b4658c809e194bc10236ac24a722ec14a83d6 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sun, 5 Jun 2022 16:19:53 +0800 Subject: [PATCH 329/942] LoongArch: Fix the !CONFIG_SMP build 1, We assume arch/loongarch/include/asm/smp.h be included in include/ linux/smp.h is valid and the reverse inclusion isn't. So remove the in arch/loongarch/include/asm/smp.h. 2, arch/loongarch/include/asm/smp.h is only needed when CONFIG_SMP, and setup.c include it only because it need plat_smp_setup(). So, reorganize setup.c & smp.h, and then remove in setup.c. 3, Fix cacheinfo.c and percpu.h build error by adding the missing header files when !CONFIG_SMP. 4, Fix acpi.c build error by adding CONFIG_SMP guards. 5, Move irq_stat definition from smp.c to irq.c and fix its declaration. 6, Select CONFIG_SMP for CONFIG_NUMA, similar as other architectures do. Signed-off-by: Huacai Chen --- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/hardirq.h | 2 +- arch/loongarch/include/asm/percpu.h | 1 + arch/loongarch/include/asm/smp.h | 23 +++++++---------------- arch/loongarch/kernel/acpi.c | 4 ++++ arch/loongarch/kernel/cacheinfo.c | 1 + arch/loongarch/kernel/irq.c | 7 ++++++- arch/loongarch/kernel/setup.c | 5 ++--- arch/loongarch/kernel/smp.c | 2 -- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 80657bf83b056..1920d52653b41 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -343,6 +343,7 @@ config NR_CPUS config NUMA bool "NUMA Support" + select SMP select ACPI_NUMA if ACPI help Say Y to compile the kernel with NUMA (Non-Uniform Memory Access) diff --git a/arch/loongarch/include/asm/hardirq.h b/arch/loongarch/include/asm/hardirq.h index befe8184aa082..0ef3b18f89803 100644 --- a/arch/loongarch/include/asm/hardirq.h +++ b/arch/loongarch/include/asm/hardirq.h @@ -19,7 +19,7 @@ typedef struct { unsigned int __softirq_pending; } ____cacheline_aligned irq_cpustat_t; -DECLARE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat); +DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #define __ARCH_IRQ_STAT diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h index 34f15a6fb1e7b..e6569f18c6ddf 100644 --- a/arch/loongarch/include/asm/percpu.h +++ b/arch/loongarch/include/asm/percpu.h @@ -6,6 +6,7 @@ #define __ASM_PERCPU_H #include +#include /* Use r21 for fast access */ register unsigned long __my_cpu_offset __asm__("$r21"); diff --git a/arch/loongarch/include/asm/smp.h b/arch/loongarch/include/asm/smp.h index 551e1f37c7053..71189b28bfb27 100644 --- a/arch/loongarch/include/asm/smp.h +++ b/arch/loongarch/include/asm/smp.h @@ -9,10 +9,16 @@ #include #include #include -#include #include #include +extern int smp_num_siblings; +extern int num_processors; +extern int disabled_cpus; +extern cpumask_t cpu_sibling_map[]; +extern cpumask_t cpu_core_map[]; +extern cpumask_t cpu_foreign_map[]; + void loongson3_smp_setup(void); void loongson3_prepare_cpus(unsigned int max_cpus); void loongson3_boot_secondary(int cpu, struct task_struct *idle); @@ -25,26 +31,11 @@ int loongson3_cpu_disable(void); void loongson3_cpu_die(unsigned int cpu); #endif -#ifdef CONFIG_SMP - static inline void plat_smp_setup(void) { loongson3_smp_setup(); } -#else /* !CONFIG_SMP */ - -static inline void plat_smp_setup(void) { } - -#endif /* !CONFIG_SMP */ - -extern int smp_num_siblings; -extern int num_processors; -extern int disabled_cpus; -extern cpumask_t cpu_sibling_map[]; -extern cpumask_t cpu_core_map[]; -extern cpumask_t cpu_foreign_map[]; - static inline int raw_smp_processor_id(void) { #if defined(__VDSO__) diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c index b16c3dea5eeb9..bb729ee8a2370 100644 --- a/arch/loongarch/kernel/acpi.c +++ b/arch/loongarch/kernel/acpi.c @@ -138,6 +138,7 @@ void __init acpi_boot_table_init(void) } } +#ifdef CONFIG_SMP static int set_processor_mask(u32 id, u32 flags) { @@ -166,15 +167,18 @@ static int set_processor_mask(u32 id, u32 flags) return cpu; } +#endif static void __init acpi_process_madt(void) { +#ifdef CONFIG_SMP int i; for (i = 0; i < NR_CPUS; i++) { __cpu_number_map[i] = -1; __cpu_logical_map[i] = -1; } +#endif loongson_sysconf.nr_cpus = num_processors; } diff --git a/arch/loongarch/kernel/cacheinfo.c b/arch/loongarch/kernel/cacheinfo.c index 8c9fe29e98f00..b38f5489d0945 100644 --- a/arch/loongarch/kernel/cacheinfo.c +++ b/arch/loongarch/kernel/cacheinfo.c @@ -4,6 +4,7 @@ * * Copyright (C) 2020-2022 Loongson Technology Corporation Limited */ +#include #include /* Populates leaf and increments to next leaf */ diff --git a/arch/loongarch/kernel/irq.c b/arch/loongarch/kernel/irq.c index 4b671d305ede7..b34b8d792aa4d 100644 --- a/arch/loongarch/kernel/irq.c +++ b/arch/loongarch/kernel/irq.c @@ -22,6 +22,8 @@ #include DEFINE_PER_CPU(unsigned long, irq_stack); +DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); +EXPORT_PER_CPU_SYMBOL(irq_stat); struct irq_domain *cpu_domain; struct irq_domain *liointc_domain; @@ -56,8 +58,11 @@ int arch_show_interrupts(struct seq_file *p, int prec) void __init init_IRQ(void) { - int i, r, ipi_irq; + int i; +#ifdef CONFIG_SMP + int r, ipi_irq; static int ipi_dummy_dev; +#endif unsigned int order = get_order(IRQ_STACK_SIZE); struct page *page; diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 185e4035811ad..c74860b53375a 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #define SMBIOS_BIOSSIZE_OFFSET 0x09 @@ -349,8 +348,6 @@ static void __init prefill_possible_map(void) nr_cpu_ids = possible; } -#else -static inline void prefill_possible_map(void) {} #endif void __init setup_arch(char **cmdline_p) @@ -367,8 +364,10 @@ void __init setup_arch(char **cmdline_p) arch_mem_init(cmdline_p); resource_init(); +#ifdef CONFIG_SMP plat_smp_setup(); prefill_possible_map(); +#endif paging_init(); } diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index b8c53b755a25a..73cec62504fbe 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -66,8 +66,6 @@ static cpumask_t cpu_core_setup_map; struct secondary_data cpuboot_data; static DEFINE_PER_CPU(int, cpu_state); -DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); -EXPORT_PER_CPU_SYMBOL(irq_stat); enum ipi_msg_type { IPI_RESCHEDULE, -- GitLab From 0626e1c9f3e5536545431538d12c762d5abf59c8 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Sun, 5 Jun 2022 16:20:03 +0800 Subject: [PATCH 330/942] LoongArch: Fix copy_thread() build errors Commit c5febea0956fd387 ("fork: Pass struct kernel_clone_args into copy_thread") change the prototype of copy_thread(), while commit 5bd2e97c868a8a44 ("fork: Generalize PF_IO_WORKER handling") change the structure of kernel_clone_args. They cause build errors, so fix it. Fixes: 5bd2e97c868a8a44 ("fork: Generalize PF_IO_WORKER handling") Fixes: c5febea0956fd387 ("fork: Pass struct kernel_clone_args into copy_thread") Signed-off-by: Huacai Chen --- arch/loongarch/kernel/process.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c index 6d944d65f6002..bfa0dfe8b7d75 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -120,10 +120,12 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) /* * Copy architecture-specific thread state */ -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long kthread_arg, struct task_struct *p, unsigned long tls) +int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) { unsigned long childksp; + unsigned long tls = args->tls; + unsigned long usp = args->stack; + unsigned long clone_flags = args->flags; struct pt_regs *childregs, *regs = current_pt_regs(); childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; @@ -136,12 +138,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.csr_crmd = csr_read32(LOONGARCH_CSR_CRMD); p->thread.csr_prmd = csr_read32(LOONGARCH_CSR_PRMD); p->thread.csr_ecfg = csr_read32(LOONGARCH_CSR_ECFG); - if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { + if (unlikely(args->fn)) { /* kernel thread */ - p->thread.reg23 = usp; /* fn */ - p->thread.reg24 = kthread_arg; p->thread.reg03 = childksp; - p->thread.reg01 = (unsigned long) ret_from_kernel_thread; + p->thread.reg23 = (unsigned long)args->fn; + p->thread.reg24 = (unsigned long)args->fn_arg; + p->thread.reg01 = (unsigned long)ret_from_kernel_thread; memset(childregs, 0, sizeof(struct pt_regs)); childregs->csr_euen = p->thread.csr_euen; childregs->csr_crmd = p->thread.csr_crmd; -- GitLab From 5c95fe8b02011c3b69173e0d86aff6d4c2798601 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 5 Jun 2022 16:20:08 +0800 Subject: [PATCH 331/942] LoongArch: Remove MIPS comment about cycle counter This comment block was taken originally from the MIPS architecture code, where indeed there are particular assumptions one can make regarding SMP and !SMP and cycle counters. On LoongArch, however, the rdtime family of functions is always available. As Xuerui wrote: The rdtime family of instructions is in fact guaranteed to be available on LoongArch; LoongArch's subsets all contain them, even the 32-bit "Primary" subset intended for university teaching -- they provide the rdtimeh.w and rdtimel.w pair of instructions that access the same 64-bit counter. So this commit simply removes the incorrect comment block. Link: https://lore.kernel.org/lkml/e78940bc-9be2-2fe7-026f-9e64a1416c9f@xen0n.name/ Fixes: b738c106f735 ("LoongArch: Add other common headers") Reviewed-by: WANG Xuerui Signed-off-by: Jason A. Donenfeld Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/timex.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/loongarch/include/asm/timex.h b/arch/loongarch/include/asm/timex.h index d3ed99a4fdbd9..fb41e9e7a222c 100644 --- a/arch/loongarch/include/asm/timex.h +++ b/arch/loongarch/include/asm/timex.h @@ -12,13 +12,6 @@ #include #include -/* - * Standard way to access the cycle counter. - * Currently only used on SMP for scheduling. - * - * We know that all SMP capable CPUs have cycle counters. - */ - typedef unsigned long cycles_t; #define get_cycles get_cycles -- GitLab From c745dfc541e78428ba3986f1d17fe1dfdaca8184 Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Thu, 2 Jun 2022 16:51:11 -0600 Subject: [PATCH 332/942] libata: fix reading concurrent positioning ranges log The concurrent positioning ranges log is not a fixed size and may depend on how many ranges are supported by the device. This patch uses the size reported in the GPL directory to determine the number of pages supported by the device before attempting to read this log page. This resolves this error from the dmesg output: ata6.00: Read log 0x47 page 0x00 failed, Emask 0x1 Cc: stable@vger.kernel.org Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log") Signed-off-by: Tyler Erickson Reviewed-by: Muhammad Ahmad Tested-by: Michael English Signed-off-by: Damien Le Moal --- drivers/ata/libata-core.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c214ff928e452..9601fa92950a0 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2010,16 +2010,16 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log, return err_mask; } -static bool ata_log_supported(struct ata_device *dev, u8 log) +static int ata_log_supported(struct ata_device *dev, u8 log) { struct ata_port *ap = dev->link->ap; if (dev->horkage & ATA_HORKAGE_NO_LOG_DIR) - return false; + return 0; if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) - return false; - return get_unaligned_le16(&ap->sector_buf[log * 2]) ? true : false; + return 0; + return get_unaligned_le16(&ap->sector_buf[log * 2]); } static bool ata_identify_page_supported(struct ata_device *dev, u8 page) @@ -2455,15 +2455,20 @@ static void ata_dev_config_cpr(struct ata_device *dev) struct ata_cpr_log *cpr_log = NULL; u8 *desc, *buf = NULL; - if (ata_id_major_version(dev->id) < 11 || - !ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES)) + if (ata_id_major_version(dev->id) < 11) + goto out; + + buf_len = ata_log_supported(dev, ATA_LOG_CONCURRENT_POSITIONING_RANGES); + if (buf_len == 0) goto out; /* * Read the concurrent positioning ranges log (0x47). We can have at - * most 255 32B range descriptors plus a 64B header. + * most 255 32B range descriptors plus a 64B header. This log varies in + * size, so use the size reported in the GPL directory. Reading beyond + * the supported length will result in an error. */ - buf_len = (64 + 255 * 32 + 511) & ~511; + buf_len <<= 9; buf = kzalloc(buf_len, GFP_KERNEL); if (!buf) goto out; -- GitLab From 6d11acd452fd885ef6ace184c9c70bc863a8c72f Mon Sep 17 00:00:00 2001 From: Tyler Erickson Date: Thu, 2 Jun 2022 16:51:12 -0600 Subject: [PATCH 333/942] libata: fix translation of concurrent positioning ranges Fixing the page length in the SCSI translation for the concurrent positioning ranges VPD page. It was writing starting in offset 3 rather than offset 2 where the MSB is supposed to start for the VPD page length. Cc: stable@vger.kernel.org Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log") Signed-off-by: Tyler Erickson Reviewed-by: Muhammad Ahmad Tested-by: Michael English Reviewed-by: Hannes Reinecke Signed-off-by: Damien Le Moal --- drivers/ata/libata-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 42cecf95a4e58..86dbb1cdfabd8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2125,7 +2125,7 @@ static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf) /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */ rbuf[1] = 0xb9; - put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[3]); + put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]); for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) { desc[0] = cpr_log->cpr[i].num; -- GitLab From 0737e018a05e2aa352828c52bdeed3b02cff2930 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Sun, 5 Jun 2022 11:23:34 +0400 Subject: [PATCH 334/942] net: dsa: lantiq_gswip: Fix refcount leak in gswip_gphy_fw_list Every iteration of for_each_available_child_of_node() decrements the reference count of the previous node. when breaking early from a for_each_available_child_of_node() loop, we need to explicitly call of_node_put() on the gphy_fw_np. Add missing of_node_put() to avoid refcount leak. Fixes: 14fceff4771e ("net: dsa: Add Lantiq / Intel DSA driver for vrx200") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220605072335.11257-1-linmq006@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/lantiq_gswip.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index 8af4def38a988..e531b93f3cb27 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -2070,8 +2070,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv, for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) { err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i], gphy_fw_np, i); - if (err) + if (err) { + of_node_put(gphy_fw_np); goto remove_gphy; + } i++; } -- GitLab From f5826c8c9d57210a17031af5527056eefdc2b7eb Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Mon, 6 Jun 2022 14:57:18 +0300 Subject: [PATCH 335/942] net/mlx4_en: Fix wrong return value on ioctl EEPROM query failure The ioctl EEPROM query wrongly returns success on read failures, fix that by returning the appropriate error code. Fixes: 7202da8b7f71 ("ethtool, net/mlx4_en: Cable info, get_module_info/eeprom ethtool support") Signed-off-by: Gal Pressman Signed-off-by: Tariq Toukan Link: https://lore.kernel.org/r/20220606115718.14233-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index ed5038d98ef6e..6400a827173cf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -2110,7 +2110,7 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev, en_err(priv, "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n", i, offset, ee->len - i, ret); - return 0; + return ret; } i += ret; -- GitLab From a2a513be7139b279f1b5b2cee59c6c4950c34346 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Thu, 2 Jun 2022 23:16:57 +0900 Subject: [PATCH 336/942] zonefs: fix handling of explicit_open option on mount Ignoring the explicit_open mount option on mount for devices that do not have a limit on the number of open zones must be done after the mount options are parsed and set in s_mount_opts. Move the check to ignore the explicit_open option after the call to zonefs_parse_options() in zonefs_fill_super(). Fixes: b5c00e975779 ("zonefs: open/close zone on file open/close") Cc: Signed-off-by: Damien Le Moal Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn --- fs/zonefs/super.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index bcb21aea990ae..ecce84909ca17 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -1760,12 +1760,6 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) atomic_set(&sbi->s_wro_seq_files, 0); sbi->s_max_wro_seq_files = bdev_max_open_zones(sb->s_bdev); - if (!sbi->s_max_wro_seq_files && - sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) { - zonefs_info(sb, "No open zones limit. Ignoring explicit_open mount option\n"); - sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN; - } - atomic_set(&sbi->s_active_seq_files, 0); sbi->s_max_active_seq_files = bdev_max_active_zones(sb->s_bdev); @@ -1790,6 +1784,12 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) zonefs_info(sb, "Mounting %u zones", blkdev_nr_zones(sb->s_bdev->bd_disk)); + if (!sbi->s_max_wro_seq_files && + sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) { + zonefs_info(sb, "No open zones limit. Ignoring explicit_open mount option\n"); + sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN; + } + /* Create root directory inode */ ret = -ENOMEM; inode = new_inode(sb); -- GitLab From 96eca145cb51f4e0132a3ea8066dfc6fdf75f24a Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Thu, 2 Jun 2022 21:33:25 +0900 Subject: [PATCH 337/942] zonefs: Do not ignore explicit_open with active zone limit A zoned device may have no limit on the number of open zones but may have a limit on the number of active zones it can support. In such case, the explicit_open mount option should not be ignored to ensure that the open() system call activates the zone with an explicit zone open command, thus guaranteeing that the zone can be written. Enforce this by ignoring the explicit_open mount option only for devices that have both the open and active zone limits equal to 0. Fixes: 87c9ce3ffec9 ("zonefs: Add active seq file accounting") Signed-off-by: Damien Le Moal Reviewed-by: Christoph Hellwig --- fs/zonefs/super.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index ecce84909ca17..123464d2145aa 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -1085,7 +1085,8 @@ static int zonefs_seq_file_write_open(struct inode *inode) if (sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) { - if (wro > sbi->s_max_wro_seq_files) { + if (sbi->s_max_wro_seq_files + && wro > sbi->s_max_wro_seq_files) { atomic_dec(&sbi->s_wro_seq_files); ret = -EBUSY; goto unlock; @@ -1785,8 +1786,10 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) blkdev_nr_zones(sb->s_bdev->bd_disk)); if (!sbi->s_max_wro_seq_files && + !sbi->s_max_active_seq_files && sbi->s_mount_opts & ZONEFS_MNTOPT_EXPLICIT_OPEN) { - zonefs_info(sb, "No open zones limit. Ignoring explicit_open mount option\n"); + zonefs_info(sb, + "No open and active zone limits. Ignoring explicit_open mount option\n"); sbi->s_mount_opts &= ~ZONEFS_MNTOPT_EXPLICIT_OPEN; } -- GitLab From 54aa83c90198e68eee8b0850c749bc70efb548da Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 7 Jun 2022 10:07:11 -0400 Subject: [PATCH 338/942] KVM: x86: do not set st->preempted when going back to user space Similar to the Xen path, only change the vCPU's reported state if the vCPU was actually preempted. The reason for KVM's behavior is that for example optimistic spinning might not be a good idea if the guest is doing repeated exits to userspace; however, it is confusing and unlikely to make a difference, because well-tuned guests will hardly ever exit KVM_RUN in the first place. Suggested-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 26 ++++++++++++++------------ arch/x86/kvm/xen.h | 6 ++++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b81ef4f497f44..a8bb635cb76b2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4654,19 +4654,21 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { int idx; - if (vcpu->preempted && !vcpu->arch.guest_state_protected) - vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu); + if (vcpu->preempted) { + if (!vcpu->arch.guest_state_protected) + vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu); - /* - * Take the srcu lock as memslots will be accessed to check the gfn - * cache generation against the memslots generation. - */ - idx = srcu_read_lock(&vcpu->kvm->srcu); - if (kvm_xen_msr_enabled(vcpu->kvm)) - kvm_xen_runstate_set_preempted(vcpu); - else - kvm_steal_time_set_preempted(vcpu); - srcu_read_unlock(&vcpu->kvm->srcu, idx); + /* + * Take the srcu lock as memslots will be accessed to check the gfn + * cache generation against the memslots generation. + */ + idx = srcu_read_lock(&vcpu->kvm->srcu); + if (kvm_xen_msr_enabled(vcpu->kvm)) + kvm_xen_runstate_set_preempted(vcpu); + else + kvm_steal_time_set_preempted(vcpu); + srcu_read_unlock(&vcpu->kvm->srcu, idx); + } static_call(kvm_x86_vcpu_put)(vcpu); vcpu->arch.last_host_tsc = rdtsc(); diff --git a/arch/x86/kvm/xen.h b/arch/x86/kvm/xen.h index ee5c4ae0755cd..532a535a9e99f 100644 --- a/arch/x86/kvm/xen.h +++ b/arch/x86/kvm/xen.h @@ -159,8 +159,10 @@ static inline void kvm_xen_runstate_set_preempted(struct kvm_vcpu *vcpu) * behalf of the vCPU. Only if the VMM does actually block * does it need to enter RUNSTATE_blocked. */ - if (vcpu->preempted) - kvm_xen_update_runstate_guest(vcpu, RUNSTATE_runnable); + if (WARN_ON_ONCE(!vcpu->preempted)) + return; + + kvm_xen_update_runstate_guest(vcpu, RUNSTATE_runnable); } /* 32-bit compatibility definitions, also used natively in 32-bit build */ -- GitLab From 6cd88243c7e03845a450795e134b488fc2afb736 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 7 Jun 2022 10:09:03 -0400 Subject: [PATCH 339/942] KVM: x86: do not report a vCPU as preempted outside instruction boundaries If a vCPU is outside guest mode and is scheduled out, it might be in the process of making a memory access. A problem occurs if another vCPU uses the PV TLB flush feature during the period when the vCPU is scheduled out, and a virtual address has already been translated but has not yet been accessed, because this is equivalent to using a stale TLB entry. To avoid this, only report a vCPU as preempted if sure that the guest is at an instruction boundary. A rescheduling request will be delivered to the host physical CPU as an external interrupt, so for simplicity consider any vmexit *not* instruction boundary except for external interrupts. It would in principle be okay to report the vCPU as preempted also if it is sleeping in kvm_vcpu_block(): a TLB flush IPI will incur the vmentry/vmexit overhead unnecessarily, and optimistic spinning is also unlikely to succeed. However, leave it for later because right now kvm_vcpu_check_block() is doing memory accesses. Even though the TLB flush issue only applies to virtual memory address, it's very much preferrable to be conservative. Reported-by: Jann Horn Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/svm/svm.c | 2 ++ arch/x86/kvm/vmx/vmx.c | 1 + arch/x86/kvm/x86.c | 22 ++++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 959d66b9be94d..3a240a64ac68f 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -653,6 +653,7 @@ struct kvm_vcpu_arch { u64 ia32_misc_enable_msr; u64 smbase; u64 smi_count; + bool at_instruction_boundary; bool tpr_access_reporting; bool xsaves_enabled; bool xfd_no_write_intercept; @@ -1300,6 +1301,8 @@ struct kvm_vcpu_stat { u64 nested_run; u64 directed_yield_attempted; u64 directed_yield_successful; + u64 preemption_reported; + u64 preemption_other; u64 guest_mode; }; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 478e6ee81d883..921fcb85a9cdb 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4263,6 +4263,8 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu) { + if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR) + vcpu->arch.at_instruction_boundary = true; } static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index f5aeade623d61..14e01178a753c 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6547,6 +6547,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu) return; handle_interrupt_nmi_irqoff(vcpu, gate_offset(desc)); + vcpu->arch.at_instruction_boundary = true; } static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a8bb635cb76b2..25a517206c4d3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -296,6 +296,8 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { STATS_DESC_COUNTER(VCPU, nested_run), STATS_DESC_COUNTER(VCPU, directed_yield_attempted), STATS_DESC_COUNTER(VCPU, directed_yield_successful), + STATS_DESC_COUNTER(VCPU, preemption_reported), + STATS_DESC_COUNTER(VCPU, preemption_other), STATS_DESC_ICOUNTER(VCPU, guest_mode) }; @@ -4625,6 +4627,19 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) struct kvm_memslots *slots; static const u8 preempted = KVM_VCPU_PREEMPTED; + /* + * The vCPU can be marked preempted if and only if the VM-Exit was on + * an instruction boundary and will not trigger guest emulation of any + * kind (see vcpu_run). Vendor specific code controls (conservatively) + * when this is true, for example allowing the vCPU to be marked + * preempted if and only if the VM-Exit was due to a host interrupt. + */ + if (!vcpu->arch.at_instruction_boundary) { + vcpu->stat.preemption_other++; + return; + } + + vcpu->stat.preemption_reported++; if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return; @@ -10424,6 +10439,13 @@ static int vcpu_run(struct kvm_vcpu *vcpu) vcpu->arch.l1tf_flush_l1d = true; for (;;) { + /* + * If another guest vCPU requests a PV TLB flush in the middle + * of instruction emulation, the rest of the emulation could + * use a stale page translation. Assume that any code after + * this point can start executing an instruction. + */ + vcpu->arch.at_instruction_boundary = false; if (kvm_vcpu_running(vcpu)) { r = vcpu_enter_guest(vcpu); } else { -- GitLab From c1c1204c0d0c1dccc1310b9277fb2bd8b663d8fe Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Mon, 23 May 2022 16:29:10 +0900 Subject: [PATCH 340/942] zonefs: fix zonefs_iomap_begin() for reads If a readahead is issued to a sequential zone file with an offset exactly equal to the current file size, the iomap type is set to IOMAP_UNWRITTEN, which will prevent an IO, but the iomap length is calculated as 0. This causes a WARN_ON() in iomap_iter(): [17309.548939] WARNING: CPU: 3 PID: 2137 at fs/iomap/iter.c:34 iomap_iter+0x9cf/0xe80 [...] [17309.650907] RIP: 0010:iomap_iter+0x9cf/0xe80 [...] [17309.754560] Call Trace: [17309.757078] [17309.759240] ? lock_is_held_type+0xd8/0x130 [17309.763531] iomap_readahead+0x1a8/0x870 [17309.767550] ? iomap_read_folio+0x4c0/0x4c0 [17309.771817] ? lockdep_hardirqs_on_prepare+0x400/0x400 [17309.778848] ? lock_release+0x370/0x750 [17309.784462] ? folio_add_lru+0x217/0x3f0 [17309.790220] ? reacquire_held_locks+0x4e0/0x4e0 [17309.796543] read_pages+0x17d/0xb60 [17309.801854] ? folio_add_lru+0x238/0x3f0 [17309.807573] ? readahead_expand+0x5f0/0x5f0 [17309.813554] ? policy_node+0xb5/0x140 [17309.819018] page_cache_ra_unbounded+0x27d/0x450 [17309.825439] filemap_get_pages+0x500/0x1450 [17309.831444] ? filemap_add_folio+0x140/0x140 [17309.837519] ? lock_is_held_type+0xd8/0x130 [17309.843509] filemap_read+0x28c/0x9f0 [17309.848953] ? zonefs_file_read_iter+0x1ea/0x4d0 [zonefs] [17309.856162] ? trace_contention_end+0xd6/0x130 [17309.862416] ? __mutex_lock+0x221/0x1480 [17309.868151] ? zonefs_file_read_iter+0x166/0x4d0 [zonefs] [17309.875364] ? filemap_get_pages+0x1450/0x1450 [17309.881647] ? __mutex_unlock_slowpath+0x15e/0x620 [17309.888248] ? wait_for_completion_io_timeout+0x20/0x20 [17309.895231] ? lock_is_held_type+0xd8/0x130 [17309.901115] ? lock_is_held_type+0xd8/0x130 [17309.906934] zonefs_file_read_iter+0x356/0x4d0 [zonefs] [17309.913750] new_sync_read+0x2d8/0x520 [17309.919035] ? __x64_sys_lseek+0x1d0/0x1d0 Furthermore, this causes iomap_readahead() to loop forever as iomap_readahead_iter() always returns 0, making no progress. Fix this by treating reads after the file size as access to holes, setting the iomap type to IOMAP_HOLE, the iomap addr to IOMAP_NULL_ADDR and using the length argument as is for the iomap length. To simplify the code with this change, zonefs_iomap_begin() is split into the read variant, zonefs_read_iomap_begin() and zonefs_read_iomap_ops, and the write variant, zonefs_write_iomap_begin() and zonefs_write_iomap_ops. Reported-by: Jorgen Hansen Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") Signed-off-by: Damien Le Moal Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Reviewed-by: Jorgen Hansen --- fs/zonefs/super.c | 94 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 123464d2145aa..053299758deb9 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -110,15 +110,51 @@ static inline void zonefs_i_size_write(struct inode *inode, loff_t isize) } } -static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, - unsigned int flags, struct iomap *iomap, - struct iomap *srcmap) +static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset, + loff_t length, unsigned int flags, + struct iomap *iomap, struct iomap *srcmap) { struct zonefs_inode_info *zi = ZONEFS_I(inode); struct super_block *sb = inode->i_sb; loff_t isize; - /* All I/Os should always be within the file maximum size */ + /* + * All blocks are always mapped below EOF. If reading past EOF, + * act as if there is a hole up to the file maximum size. + */ + mutex_lock(&zi->i_truncate_mutex); + iomap->bdev = inode->i_sb->s_bdev; + iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); + isize = i_size_read(inode); + if (iomap->offset >= isize) { + iomap->type = IOMAP_HOLE; + iomap->addr = IOMAP_NULL_ADDR; + iomap->length = length; + } else { + iomap->type = IOMAP_MAPPED; + iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; + iomap->length = isize - iomap->offset; + } + mutex_unlock(&zi->i_truncate_mutex); + + trace_zonefs_iomap_begin(inode, iomap); + + return 0; +} + +static const struct iomap_ops zonefs_read_iomap_ops = { + .iomap_begin = zonefs_read_iomap_begin, +}; + +static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset, + loff_t length, unsigned int flags, + struct iomap *iomap, struct iomap *srcmap) +{ + struct zonefs_inode_info *zi = ZONEFS_I(inode); + struct super_block *sb = inode->i_sb; + loff_t isize; + + /* All write I/Os should always be within the file maximum size */ if (WARN_ON_ONCE(offset + length > zi->i_max_size)) return -EIO; @@ -128,7 +164,7 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, * operation. */ if (WARN_ON_ONCE(zi->i_ztype == ZONEFS_ZTYPE_SEQ && - (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT))) + !(flags & IOMAP_DIRECT))) return -EIO; /* @@ -137,47 +173,44 @@ static int zonefs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, * write pointer) and unwriten beyond. */ mutex_lock(&zi->i_truncate_mutex); + iomap->bdev = inode->i_sb->s_bdev; + iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); + iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; isize = i_size_read(inode); - if (offset >= isize) + if (iomap->offset >= isize) { iomap->type = IOMAP_UNWRITTEN; - else + iomap->length = zi->i_max_size - iomap->offset; + } else { iomap->type = IOMAP_MAPPED; - if (flags & IOMAP_WRITE) - length = zi->i_max_size - offset; - else - length = min(length, isize - offset); + iomap->length = isize - iomap->offset; + } mutex_unlock(&zi->i_truncate_mutex); - iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize); - iomap->length = ALIGN(offset + length, sb->s_blocksize) - iomap->offset; - iomap->bdev = inode->i_sb->s_bdev; - iomap->addr = (zi->i_zsector << SECTOR_SHIFT) + iomap->offset; - trace_zonefs_iomap_begin(inode, iomap); return 0; } -static const struct iomap_ops zonefs_iomap_ops = { - .iomap_begin = zonefs_iomap_begin, +static const struct iomap_ops zonefs_write_iomap_ops = { + .iomap_begin = zonefs_write_iomap_begin, }; static int zonefs_read_folio(struct file *unused, struct folio *folio) { - return iomap_read_folio(folio, &zonefs_iomap_ops); + return iomap_read_folio(folio, &zonefs_read_iomap_ops); } static void zonefs_readahead(struct readahead_control *rac) { - iomap_readahead(rac, &zonefs_iomap_ops); + iomap_readahead(rac, &zonefs_read_iomap_ops); } /* * Map blocks for page writeback. This is used only on conventional zone files, * which implies that the page range can only be within the fixed inode size. */ -static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc, - struct inode *inode, loff_t offset) +static int zonefs_write_map_blocks(struct iomap_writepage_ctx *wpc, + struct inode *inode, loff_t offset) { struct zonefs_inode_info *zi = ZONEFS_I(inode); @@ -191,12 +224,12 @@ static int zonefs_map_blocks(struct iomap_writepage_ctx *wpc, offset < wpc->iomap.offset + wpc->iomap.length) return 0; - return zonefs_iomap_begin(inode, offset, zi->i_max_size - offset, - IOMAP_WRITE, &wpc->iomap, NULL); + return zonefs_write_iomap_begin(inode, offset, zi->i_max_size - offset, + IOMAP_WRITE, &wpc->iomap, NULL); } static const struct iomap_writeback_ops zonefs_writeback_ops = { - .map_blocks = zonefs_map_blocks, + .map_blocks = zonefs_write_map_blocks, }; static int zonefs_writepage(struct page *page, struct writeback_control *wbc) @@ -226,7 +259,8 @@ static int zonefs_swap_activate(struct swap_info_struct *sis, return -EINVAL; } - return iomap_swapfile_activate(sis, swap_file, span, &zonefs_iomap_ops); + return iomap_swapfile_activate(sis, swap_file, span, + &zonefs_read_iomap_ops); } static const struct address_space_operations zonefs_file_aops = { @@ -647,7 +681,7 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf) /* Serialize against truncates */ filemap_invalidate_lock_shared(inode->i_mapping); - ret = iomap_page_mkwrite(vmf, &zonefs_iomap_ops); + ret = iomap_page_mkwrite(vmf, &zonefs_write_iomap_ops); filemap_invalidate_unlock_shared(inode->i_mapping); sb_end_pagefault(inode->i_sb); @@ -899,7 +933,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) if (append) ret = zonefs_file_dio_append(iocb, from); else - ret = iomap_dio_rw(iocb, from, &zonefs_iomap_ops, + ret = iomap_dio_rw(iocb, from, &zonefs_write_iomap_ops, &zonefs_write_dio_ops, 0, NULL, 0); if (zi->i_ztype == ZONEFS_ZTYPE_SEQ && (ret > 0 || ret == -EIOCBQUEUED)) { @@ -948,7 +982,7 @@ static ssize_t zonefs_file_buffered_write(struct kiocb *iocb, if (ret <= 0) goto inode_unlock; - ret = iomap_file_buffered_write(iocb, from, &zonefs_iomap_ops); + ret = iomap_file_buffered_write(iocb, from, &zonefs_write_iomap_ops); if (ret > 0) iocb->ki_pos += ret; else if (ret == -EIO) @@ -1041,7 +1075,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) goto inode_unlock; } file_accessed(iocb->ki_filp); - ret = iomap_dio_rw(iocb, to, &zonefs_iomap_ops, + ret = iomap_dio_rw(iocb, to, &zonefs_read_iomap_ops, &zonefs_read_dio_ops, 0, NULL, 0); } else { ret = generic_file_read_iter(iocb, to); -- GitLab From b09654e39c89a86680528345f3a95b832236ee82 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 8 Jun 2022 09:23:38 +0100 Subject: [PATCH 341/942] ASoC: mediatek: mt8186: Fix a handful of spelling mistakes There are several spelling mistakes in dev_err messages. Fix them. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220608082338.2083456-1-colin.i.king@gmail.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-gpio.c | 8 ++++---- sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c index 5ba28095b7dad..255ffba637d31 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c @@ -137,25 +137,25 @@ static int mt8186_afe_gpio_adda_dl(struct device *dev, bool enable) if (enable) { ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_ON); if (ret) { - dev_err(dev, "%s(), MOSI CLK ON slect fail!\n", __func__); + dev_err(dev, "%s(), MOSI CLK ON select fail!\n", __func__); return ret; } ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_ON); if (ret) { - dev_err(dev, "%s(), MOSI DAT ON slect fail!\n", __func__); + dev_err(dev, "%s(), MOSI DAT ON select fail!\n", __func__); return ret; } } else { ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_OFF); if (ret) { - dev_err(dev, "%s(), MOSI DAT OFF slect fail!\n", __func__); + dev_err(dev, "%s(), MOSI DAT OFF select fail!\n", __func__); return ret; } ret = mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_OFF); if (ret) { - dev_err(dev, "%s(), MOSI CLK ON slect fail!\n", __func__); + dev_err(dev, "%s(), MOSI CLK ON select fail!\n", __func__); return ret; } } diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c index c66861fd197d3..db71b032770dd 100644 --- a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c @@ -341,7 +341,7 @@ static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, if (afe_priv->mtkaif_chosen_phase[0] < 0 || afe_priv->mtkaif_chosen_phase[1] < 0) { dev_err(afe->dev, - "%s(), skip dealy setting mtkaif_chosen_phase[0/1]:%d/%d\n", + "%s(), skip delay setting mtkaif_chosen_phase[0/1]:%d/%d\n", __func__, afe_priv->mtkaif_chosen_phase[0], afe_priv->mtkaif_chosen_phase[1]); -- GitLab From dda5384313a40ecbaafd8a9a80f47483255e4c4d Mon Sep 17 00:00:00 2001 From: David Safford Date: Tue, 7 Jun 2022 14:07:57 -0400 Subject: [PATCH 342/942] KEYS: trusted: tpm2: Fix migratable logic When creating (sealing) a new trusted key, migratable trusted keys have the FIXED_TPM and FIXED_PARENT attributes set, and non-migratable keys don't. This is backwards, and also causes creation to fail when creating a migratable key under a migratable parent. (The TPM thinks you are trying to seal a non-migratable blob under a migratable parent.) The following simple patch fixes the logic, and has been tested for all four combinations of migratable and non-migratable trusted keys and parent storage keys. With this logic, you will get a proper failure if you try to create a non-migratable trusted key under a migratable parent storage key, and all other combinations work correctly. Cc: stable@vger.kernel.org # v5.13+ Fixes: e5fb5d2c5a03 ("security: keys: trusted: Make sealed key properly interoperable") Signed-off-by: David Safford Reviewed-by: Ahmad Fatoum Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- security/keys/trusted-keys/trusted_tpm2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index 0165da386289c..2b2c8eb258d5b 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -283,8 +283,8 @@ int tpm2_seal_trusted(struct tpm_chip *chip, /* key properties */ flags = 0; flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH; - flags |= payload->migratable ? (TPM2_OA_FIXED_TPM | - TPM2_OA_FIXED_PARENT) : 0; + flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM | + TPM2_OA_FIXED_PARENT); tpm_buf_append_u32(&buf, flags); /* policy */ -- GitLab From 49c3ca34f7dbe5227c0163cba4deb5d29e145fae Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jun 2022 00:18:40 +0900 Subject: [PATCH 343/942] scripts/nsdeps: adjust to the format change of *.mod files Commit 22f26f21774f ("kbuild: get rid of duplication in *.mod files") changed the format of *.mod files to put one object per line, but missed to adjust scripts/nsdeps. Fixes: 22f26f21774f ("kbuild: get rid of duplication in *.mod files") Signed-off-by: Masahiro Yamada --- scripts/nsdeps | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/nsdeps b/scripts/nsdeps index 04c4b96e95ec4..f1718cc0d700b 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -34,9 +34,8 @@ generate_deps() { local mod=${1%.ko:} shift local namespaces="$*" - local mod_source_files="`cat $mod.mod | sed -n 1p \ - | sed -e 's/\.o/\.c/g' \ - | sed "s|[^ ]* *|${src_prefix}&|g"`" + local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod) + for ns in $namespaces; do echo "Adding namespace $ns to module $mod.ko." generate_deps_for_ns $ns "$mod_source_files" -- GitLab From ec3ad554b956d5dbefa1962c419f164ba223e6b3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 8 Jun 2022 02:09:16 +0000 Subject: [PATCH 344/942] ASoC: ak4613: cares Simple-Audio-Card case for TDM Renesas is the only user of ak4613 on upstream for now, and commit f28dbaa958fbd8 ("ASoC: ak4613: add TDM256 support") added TDM256 support. Renesas tested part of it, because of board connection. It was assuming ak4613 is probed via Audio-Graph-Card, but it might be probed via Simple-Audio-Card either. It will indicates WARNING in such case. This patch fixup it. Reported-by: Geert Uytterhoeven Signed-off-by: Kuninori Morimoto Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/87h74v29f7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ak4613.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 55e773f921228..93606e5afd8f1 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -868,10 +868,12 @@ static void ak4613_parse_of(struct ak4613_priv *priv, /* * connected STDI + * TDM support is assuming it is probed via Audio-Graph-Card style here. + * Default is SDTIx1 if it was probed via Simple-Audio-Card for now. */ sdti_num = of_graph_get_endpoint_count(np); - if (WARN_ON((sdti_num > 3) || (sdti_num < 1))) - return; + if ((sdti_num >= SDTx_MAX) || (sdti_num < 1)) + sdti_num = 1; AK4613_CONFIG_SDTI_set(priv, sdti_num); } -- GitLab From 228432551bd8783211e494ab35f42a4344580502 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 8 Jun 2022 14:14:22 +0800 Subject: [PATCH 345/942] virtio-rng: make device ready before making request Current virtio-rng does a entropy request before DRIVER_OK, this violates the spec: virtio spec requires that all drivers set DRIVER_OK before using devices. Further, kernel will ignore the interrupt after commit 8b4ec69d7e09 ("virtio: harden vring IRQ"). Fixing this by making device ready before the request. Cc: stable@vger.kernel.org Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") Fixes: f7f510ec1957 ("virtio: An entropy device, as suggested by hpa.") Reported-and-tested-by: syzbot+5b59d6d459306a556f54@syzkaller.appspotmail.com Signed-off-by: Jason Wang Message-Id: <20220608061422.38437-1-jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin Reviewed-by: Laurent Vivier --- drivers/char/hw_random/virtio-rng.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index e856df7e285c7..a6f3a8a2aca6d 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -159,6 +159,8 @@ static int probe_common(struct virtio_device *vdev) goto err_find; } + virtio_device_ready(vdev); + /* we always have a pending entropy request */ request_entropy(vi); -- GitLab From 2f72b2262d317093596c72bd5b27b9880be7611e Mon Sep 17 00:00:00 2001 From: Xiang wangx Date: Sat, 4 Jun 2022 22:38:58 +0800 Subject: [PATCH 346/942] vdpa/mlx5: Fix syntax errors in comments Delete the redundant word 'is'. Signed-off-by: Xiang wangx Message-Id: <20220604143858.16073-1-wangxiang@cdjrlc.com> Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index b7a9554791560..b878c10955308 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -107,7 +107,7 @@ struct mlx5_vdpa_virtqueue { /* Resources for implementing the notification channel from the device * to the driver. fwqp is the firmware end of an RC connection; the - * other end is vqqp used by the driver. cq is is where completions are + * other end is vqqp used by the driver. cq is where completions are * reported. */ struct mlx5_vdpa_cq cq; -- GitLab From a58a7f97ba11391d2d0d408e0b24f38d86ae748e Mon Sep 17 00:00:00 2001 From: chengkaitao Date: Thu, 2 Jun 2022 08:55:42 +0800 Subject: [PATCH 347/942] virtio-mmio: fix missing put_device() when vm_cmdline_parent registration failed The reference must be released when device_register(&vm_cmdline_parent) failed. Add the corresponding 'put_device()' in the error handling path. Signed-off-by: chengkaitao Message-Id: <20220602005542.16489-1-chengkaitao@didiglobal.com> Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/virtio/virtio_mmio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index f9a36bc7ac27e..5ce79bf9f92b7 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -701,6 +701,7 @@ static int vm_cmdline_set(const char *device, if (!vm_cmdline_parent_registered) { err = device_register(&vm_cmdline_parent); if (err) { + put_device(&vm_cmdline_parent); pr_err("Failed to register parent device!\n"); return err; } -- GitLab From f766c409fcb33cfd0f511e8251831520e089eb89 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Jun 2022 09:49:25 +0300 Subject: [PATCH 348/942] vdpa/mlx5: fix error code for deleting vlan Return success if we were able to delete a vlan. The current code always returns failure. Fixes: baf2ad3f6a98 ("vdpa/mlx5: Add RX MAC VLAN filter support") Signed-off-by: Dan Carpenter Message-Id: Signed-off-by: Michael S. Tsirkin Acked-by: Eli Cohen Acked-by: Si-Wei Liu --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index b878c10955308..51fb15c35e426 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -1814,6 +1814,7 @@ static virtio_net_ctrl_ack handle_ctrl_vlan(struct mlx5_vdpa_dev *mvdev, u8 cmd) id = mlx5vdpa16_to_cpu(mvdev, vlan); mac_vlan_del(ndev, ndev->config.mac, id, true); + status = VIRTIO_NET_OK; break; default: break; -- GitLab From f38b3c6a788f75da151b46c7da61ff26649e1843 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Jun 2022 09:50:09 +0300 Subject: [PATCH 349/942] vdpa/mlx5: clean up indenting in handle_ctrl_vlan() These lines were supposed to be indented. Signed-off-by: Dan Carpenter Message-Id: Signed-off-by: Michael S. Tsirkin Acked-by: Eli Cohen Acked-by: Si-Wei Liu --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index 51fb15c35e426..1b6d46b86f810 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -1817,10 +1817,10 @@ static virtio_net_ctrl_ack handle_ctrl_vlan(struct mlx5_vdpa_dev *mvdev, u8 cmd) status = VIRTIO_NET_OK; break; default: - break; -} + break; + } -return status; + return status; } static void mlx5_cvq_kick_handler(struct work_struct *work) -- GitLab From dbd29e0752286af74243cf891accf472b2f3edd8 Mon Sep 17 00:00:00 2001 From: Xie Yongji Date: Thu, 5 May 2022 18:09:10 +0800 Subject: [PATCH 350/942] vringh: Fix loop descriptors check in the indirect cases We should use size of descriptor chain to test loop condition in the indirect case. And another statistical count is also introduced for indirect descriptors to avoid conflict with the statistical count of direct descriptors. Fixes: f87d0fbb5798 ("vringh: host-side implementation of virtio rings.") Signed-off-by: Xie Yongji Signed-off-by: Fam Zheng Message-Id: <20220505100910.137-1-xieyongji@bytedance.com> Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang --- drivers/vhost/vringh.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 14e2043d76852..eab55accf381f 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -292,7 +292,7 @@ __vringh_iov(struct vringh *vrh, u16 i, int (*copy)(const struct vringh *vrh, void *dst, const void *src, size_t len)) { - int err, count = 0, up_next, desc_max; + int err, count = 0, indirect_count = 0, up_next, desc_max; struct vring_desc desc, *descs; struct vringh_range range = { -1ULL, 0 }, slowrange; bool slow = false; @@ -349,7 +349,12 @@ __vringh_iov(struct vringh *vrh, u16 i, continue; } - if (count++ == vrh->vring.num) { + if (up_next == -1) + count++; + else + indirect_count++; + + if (count > vrh->vring.num || indirect_count > desc_max) { vringh_bad("Descriptor loop in %p", descs); err = -ELOOP; goto fail; @@ -411,6 +416,7 @@ __vringh_iov(struct vringh *vrh, u16 i, i = return_from_indirect(vrh, &up_next, &descs, &desc_max); slow = false; + indirect_count = 0; } else break; } -- GitLab From b27ee76c74dc831d6e092eaebc2dfc9c0beed1c9 Mon Sep 17 00:00:00 2001 From: Xie Yongji Date: Tue, 26 Apr 2022 15:36:56 +0800 Subject: [PATCH 351/942] vduse: Fix NULL pointer dereference on sysfs access The control device has no drvdata. So we will get a NULL pointer dereference when accessing control device's msg_timeout attribute via sysfs: [ 132.841881][ T3644] BUG: kernel NULL pointer dereference, address: 00000000000000f8 [ 132.850619][ T3644] RIP: 0010:msg_timeout_show (drivers/vdpa/vdpa_user/vduse_dev.c:1271) [ 132.869447][ T3644] dev_attr_show (drivers/base/core.c:2094) [ 132.870215][ T3644] sysfs_kf_seq_show (fs/sysfs/file.c:59) [ 132.871164][ T3644] ? device_remove_bin_file (drivers/base/core.c:2088) [ 132.872082][ T3644] kernfs_seq_show (fs/kernfs/file.c:164) [ 132.872838][ T3644] seq_read_iter (fs/seq_file.c:230) [ 132.873578][ T3644] ? __vmalloc_area_node (mm/vmalloc.c:3041) [ 132.874532][ T3644] kernfs_fop_read_iter (fs/kernfs/file.c:238) [ 132.875513][ T3644] __kernel_read (fs/read_write.c:440 (discriminator 1)) [ 132.876319][ T3644] kernel_read (fs/read_write.c:459) [ 132.877129][ T3644] kernel_read_file (fs/kernel_read_file.c:94) [ 132.877978][ T3644] kernel_read_file_from_fd (include/linux/file.h:45 fs/kernel_read_file.c:186) [ 132.879019][ T3644] __do_sys_finit_module (kernel/module.c:4207) [ 132.879930][ T3644] __ia32_sys_finit_module (kernel/module.c:4189) [ 132.880930][ T3644] do_int80_syscall_32 (arch/x86/entry/common.c:112 arch/x86/entry/common.c:132) [ 132.881847][ T3644] entry_INT80_compat (arch/x86/entry/entry_64_compat.S:419) To fix it, don't create the unneeded attribute for control device anymore. Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace") Reported-by: kernel test robot Cc: stable@vger.kernel.org Signed-off-by: Xie Yongji Message-Id: <20220426073656.229-1-xieyongji@bytedance.com> Signed-off-by: Michael S. Tsirkin --- drivers/vdpa/vdpa_user/vduse_dev.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index d503848b3b6ed..776ad7496f534 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1345,9 +1345,9 @@ static int vduse_create_dev(struct vduse_dev_config *config, dev->minor = ret; dev->msg_timeout = VDUSE_MSG_DEFAULT_TIMEOUT; - dev->dev = device_create(vduse_class, NULL, - MKDEV(MAJOR(vduse_major), dev->minor), - dev, "%s", config->name); + dev->dev = device_create_with_groups(vduse_class, NULL, + MKDEV(MAJOR(vduse_major), dev->minor), + dev, vduse_dev_groups, "%s", config->name); if (IS_ERR(dev->dev)) { ret = PTR_ERR(dev->dev); goto err_dev; @@ -1596,7 +1596,6 @@ static int vduse_init(void) return PTR_ERR(vduse_class); vduse_class->devnode = vduse_devnode; - vduse_class->dev_groups = vduse_dev_groups; ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse"); if (ret) -- GitLab From d678cbd2f867a564a3c5b276c454e873f43f02f8 Mon Sep 17 00:00:00 2001 From: Maciej Fijalkowski Date: Tue, 7 Jun 2022 16:22:00 +0200 Subject: [PATCH 352/942] xsk: Fix handling of invalid descriptors in XSK TX batching API xdpxceiver run on a AF_XDP ZC enabled driver revealed a problem with XSK Tx batching API. There is a test that checks how invalid Tx descriptors are handled by AF_XDP. Each valid descriptor is followed by invalid one on Tx side whereas the Rx side expects only to receive a set of valid descriptors. In current xsk_tx_peek_release_desc_batch() function, the amount of available descriptors is hidden inside xskq_cons_peek_desc_batch(). This can be problematic in cases where invalid descriptors are present due to the fact that xskq_cons_peek_desc_batch() returns only a count of valid descriptors. This means that it is impossible to properly update XSK ring state when calling xskq_cons_release_n(). To address this issue, pull out the contents of xskq_cons_peek_desc_batch() so that callers (currently only xsk_tx_peek_release_desc_batch()) will always be able to update the state of ring properly, as total count of entries is now available and use this value as an argument in xskq_cons_release_n(). By doing so, xskq_cons_peek_desc_batch() can be dropped altogether. Fixes: 9349eb3a9d2a ("xsk: Introduce batched Tx descriptor interfaces") Signed-off-by: Maciej Fijalkowski Signed-off-by: Daniel Borkmann Acked-by: Magnus Karlsson Link: https://lore.kernel.org/bpf/20220607142200.576735-1-maciej.fijalkowski@intel.com --- net/xdp/xsk.c | 5 +++-- net/xdp/xsk_queue.h | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index e0a4526ab66b3..19ac872a66240 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -373,7 +373,8 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) goto out; } - nb_pkts = xskq_cons_peek_desc_batch(xs->tx, pool, max_entries); + max_entries = xskq_cons_nb_entries(xs->tx, max_entries); + nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries); if (!nb_pkts) { xs->tx->queue_empty_descs++; goto out; @@ -389,7 +390,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries) if (!nb_pkts) goto out; - xskq_cons_release_n(xs->tx, nb_pkts); + xskq_cons_release_n(xs->tx, max_entries); __xskq_cons_release(xs->tx); xs->sk.sk_write_space(&xs->sk); diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h index a794410989cc8..fb20bf7207cfb 100644 --- a/net/xdp/xsk_queue.h +++ b/net/xdp/xsk_queue.h @@ -282,14 +282,6 @@ static inline bool xskq_cons_peek_desc(struct xsk_queue *q, return xskq_cons_read_desc(q, desc, pool); } -static inline u32 xskq_cons_peek_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool, - u32 max) -{ - u32 entries = xskq_cons_nb_entries(q, max); - - return xskq_cons_read_desc_batch(q, pool, entries); -} - /* To improve performance in the xskq_cons_release functions, only update local state here. * Reflect this to global state when we get new entries from the ring in * xskq_cons_get_entries() and whenever Rx or Tx processing are completed in the NAPI loop. -- GitLab From 7c217aca85dd31dd2c8f45f6a7520767c9fae766 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Wed, 8 Jun 2022 13:14:28 +0100 Subject: [PATCH 353/942] MAINTAINERS: Add a maintainer for bpftool I've been contributing and reviewing patches for bpftool for some time, and I'm taking care of its external mirror. On Alexei, KP, and Daniel's suggestion, I would like to step forwards and become a maintainer for the tool. This patch adds a dedicated entry to MAINTAINERS. Signed-off-by: Quentin Monnet Signed-off-by: Daniel Borkmann Acked-by: Jakub Kicinski Acked-by: KP Singh Acked-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20220608121428.69708-1-quentin@isovalent.com --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 033a01b07f8f2..92c8adc5471bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3731,6 +3731,13 @@ F: include/linux/bpf_lsm.h F: kernel/bpf/bpf_lsm.c F: security/bpf/ +BPFTOOL +M: Quentin Monnet +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/disasm.* +F: tools/bpf/bpftool/ + BROADCOM B44 10/100 ETHERNET DRIVER M: Michael Chan L: netdev@vger.kernel.org -- GitLab From a956a11ee669d069047525c8ec897b4c21a9cda1 Mon Sep 17 00:00:00 2001 From: Jesse Zhang Date: Tue, 7 Jun 2022 10:44:57 +0800 Subject: [PATCH 354/942] drm/amdkfd:Fix fw version for 10.3.6 fix fw error when loading fw for 10.3.6 Signed-off-by: Jesse Zhang Reviewed-by: Alex Deucher Reviewed-by: Mario Limonciello Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.18.x --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index f8635e7685136..bf42004577722 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -182,7 +182,9 @@ static void kfd_device_info_init(struct kfd_dev *kfd, if (gc_version < IP_VERSION(11, 0, 0)) { /* Navi2x+, Navi1x+ */ - if (gc_version >= IP_VERSION(10, 3, 0)) + if (gc_version == IP_VERSION(10, 3, 6)) + kfd->device_info.no_atomic_fw_version = 14; + else if (gc_version >= IP_VERSION(10, 3, 0)) kfd->device_info.no_atomic_fw_version = 92; else if (gc_version >= IP_VERSION(10, 1, 1)) kfd->device_info.no_atomic_fw_version = 145; -- GitLab From 1d2afeb7983081ecf656c2338c7db6fd405c653c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 3 Jun 2022 12:21:06 +0200 Subject: [PATCH 355/942] drm/amdgpu: fix limiting AV1 to the first instance on VCN3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The job is not yet initialized here. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2037 Reviewed-by: Alex Deucher Tested-by: Pierre-Eric Pelloux-Prayer Signed-off-by: Christian König Fixes: cdc7893fc93f ("drm/amdgpu: use job and ib structures directly in CS parsers") Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index 3cabceee5f57a..39405f0db8241 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -1761,23 +1761,21 @@ static const struct amdgpu_ring_funcs vcn_v3_0_dec_sw_ring_vm_funcs = { .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper, }; -static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p, - struct amdgpu_job *job) +static int vcn_v3_0_limit_sched(struct amdgpu_cs_parser *p) { struct drm_gpu_scheduler **scheds; /* The create msg must be in the first IB submitted */ - if (atomic_read(&job->base.entity->fence_seq)) + if (atomic_read(&p->entity->fence_seq)) return -EINVAL; scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_DEC] [AMDGPU_RING_PRIO_DEFAULT].sched; - drm_sched_entity_modify_sched(job->base.entity, scheds, 1); + drm_sched_entity_modify_sched(p->entity, scheds, 1); return 0; } -static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job, - uint64_t addr) +static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, uint64_t addr) { struct ttm_operation_ctx ctx = { false, false }; struct amdgpu_bo_va_mapping *map; @@ -1848,7 +1846,7 @@ static int vcn_v3_0_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job, if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11) continue; - r = vcn_v3_0_limit_sched(p, job); + r = vcn_v3_0_limit_sched(p); if (r) goto out; } @@ -1862,7 +1860,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, struct amdgpu_job *job, struct amdgpu_ib *ib) { - struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); + struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched); uint32_t msg_lo = 0, msg_hi = 0; unsigned i; int r; @@ -1881,8 +1879,7 @@ static int vcn_v3_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p, msg_hi = val; } else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0) && val == 0) { - r = vcn_v3_0_dec_msg(p, job, - ((u64)msg_hi) << 32 | msg_lo); + r = vcn_v3_0_dec_msg(p, ((u64)msg_hi) << 32 | msg_lo); if (r) return r; } -- GitLab From 84205d00934394076552e2f597cf04a835df3364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 3 Jun 2022 15:05:04 +0200 Subject: [PATCH 356/942] drm/amdgpu: always flush the TLB on gfx8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TLB on GFX8 stores each block of 8 PTEs where any of the valid bits are set. Fixes: 5255e146c99a ("drm/amdgpu: rework TLB flushing") Reviewed-by: Alex Deucher Tested-by: Michal Kubecek Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 109d8dd71c116..dc76d2b3ce52f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -793,6 +793,11 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, flush_tlb |= adev->gmc.xgmi.num_physical_nodes && adev->ip_versions[GC_HWIP][0] == IP_VERSION(9, 4, 0); + /* + * On GFX8 and older any 8 PTE block with a valid bit set enters the TLB + */ + flush_tlb |= adev->ip_versions[GC_HWIP][0] < IP_VERSION(9, 0, 0); + memset(¶ms, 0, sizeof(params)); params.adev = adev; params.vm = vm; -- GitLab From 578eb31776df57c81307fb3f96ef0781332c3c7c Mon Sep 17 00:00:00 2001 From: Mohammad Zafar Ziya Date: Tue, 7 Jun 2022 11:38:16 +0800 Subject: [PATCH 357/942] drm/amdgpu/jpeg2: Add jpeg vmid update under IB submit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add jpeg vmid update under IB submit Signed-off-by: Mohammad Zafar Ziya Acked-by: Christian König Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c | 6 +++++- drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c index d2722adabd1ba..f3c1af5130abc 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c @@ -535,6 +535,10 @@ void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring, { unsigned vmid = AMDGPU_JOB_GET_VMID(job); + amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_IH_CTRL_INTERNAL_OFFSET, + 0, 0, PACKETJ_TYPE0)); + amdgpu_ring_write(ring, (vmid << JPEG_IH_CTRL__IH_VMID__SHIFT)); + amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET, 0, 0, PACKETJ_TYPE0)); amdgpu_ring_write(ring, (vmid | (vmid << 4))); @@ -768,7 +772,7 @@ static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = { 8 + /* jpeg_v2_0_dec_ring_emit_vm_flush */ 18 + 18 + /* jpeg_v2_0_dec_ring_emit_fence x2 vm fence */ 8 + 16, - .emit_ib_size = 22, /* jpeg_v2_0_dec_ring_emit_ib */ + .emit_ib_size = 24, /* jpeg_v2_0_dec_ring_emit_ib */ .emit_ib = jpeg_v2_0_dec_ring_emit_ib, .emit_fence = jpeg_v2_0_dec_ring_emit_fence, .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush, diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h index 1a03baa597557..654e43e83e2c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h @@ -41,6 +41,7 @@ #define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET 0x4084 #define mmUVD_JRBC_STATUS_INTERNAL_OFFSET 0x4089 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f +#define mmUVD_JPEG_IH_CTRL_INTERNAL_OFFSET 0x4149 #define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR 0x18000 -- GitLab From 32d4fd5751eadbe1823a37eb38df85ec5c8e6207 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Jun 2022 16:27:27 +0200 Subject: [PATCH 358/942] cpuidle,intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE Commit c227233ad64c ("intel_idle: enable interrupts before C1 on Xeons") wrecked intel_idle in two ways: - must not have tracing in idle functions - must return with IRQs disabled Additionally, it added a branch for no good reason. Fixes: c227233ad64c ("intel_idle: enable interrupts before C1 on Xeons") Signed-off-by: Peter Zijlstra (Intel) [ rjw: Moved the intel_idle() kerneldoc comment next to the function ] Cc: 5.16+ # 5.16+ Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index b9bb94bd0f672..424ef470223df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -115,6 +115,18 @@ static unsigned int mwait_substates __initdata; #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) #define MWAIT2flg(eax) ((eax & 0xFF) << 24) +static __always_inline int __intel_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + struct cpuidle_state *state = &drv->states[index]; + unsigned long eax = flg2MWAIT(state->flags); + unsigned long ecx = 1; /* break on interrupt flag */ + + mwait_idle_with_hints(eax, ecx); + + return index; +} + /** * intel_idle - Ask the processor to enter the given idle state. * @dev: cpuidle device of the target CPU. @@ -132,16 +144,19 @@ static unsigned int mwait_substates __initdata; static __cpuidle int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct cpuidle_state *state = &drv->states[index]; - unsigned long eax = flg2MWAIT(state->flags); - unsigned long ecx = 1; /* break on interrupt flag */ + return __intel_idle(dev, drv, index); +} - if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE) - local_irq_enable(); +static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int ret; - mwait_idle_with_hints(eax, ecx); + raw_local_irq_enable(); + ret = __intel_idle(dev, drv, index); + raw_local_irq_disable(); - return index; + return ret; } /** @@ -1801,6 +1816,9 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv) /* Structure copy. */ drv->states[drv->state_count] = cpuidle_state_table[cstate]; + if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) + drv->states[drv->state_count].enter = intel_idle_irq; + if ((disabled_states_mask & BIT(drv->state_count)) || ((icpu->use_acpi || force_use_acpi) && intel_idle_off_by_default(mwait_hint) && -- GitLab From 6c254bf3b637dd4ef4f78eb78c7447419c0161d7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Jun 2022 16:47:52 -0400 Subject: [PATCH 359/942] SUNRPC: Fix the calculation of xdr->end in xdr_get_next_encode_buffer() I found that NFSD's new NFSv3 READDIRPLUS XDR encoder was screwing up right at the end of the page array. xdr_get_next_encode_buffer() does not compute the value of xdr->end correctly: * The check to see if we're on the final available page in xdr->buf needs to account for the space consumed by @nbytes. * The new xdr->end value needs to account for the portion of @nbytes that is to be encoded into the previous buffer. Fixes: 2825a7f90753 ("nfsd4: allow encoding across page boundaries") Signed-off-by: Chuck Lever Reviewed-by: NeilBrown Reviewed-by: J. Bruce Fields --- net/sunrpc/xdr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index df194cc070350..b57cf9df4de89 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -979,7 +979,11 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, */ xdr->p = (void *)p + frag2bytes; space_left = xdr->buf->buflen - xdr->buf->len; - xdr->end = (void *)p + min_t(int, space_left, PAGE_SIZE); + if (space_left - nbytes >= PAGE_SIZE) + xdr->end = (void *)p + PAGE_SIZE; + else + xdr->end = (void *)p + space_left - frag1bytes; + xdr->buf->page_len += frag2bytes; xdr->buf->len += nbytes; return p; -- GitLab From 62ed448cc53b654036f7d7f3c99f299d79ad14c3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Jun 2022 16:47:58 -0400 Subject: [PATCH 360/942] SUNRPC: Optimize xdr_reserve_space() Transitioning between encode buffers is quite infrequent. It happens about 1 time in 400 calls to xdr_reserve_space(), measured on NFSD with a typical build/test workload. Force the compiler to remove that code from xdr_reserve_space(), which is a hot path on both the server and the client. This change reduces the size of xdr_reserve_space() from 10 cache lines to 2 when compiled with -Os. Signed-off-by: Chuck Lever Reviewed-by: J. Bruce Fields --- include/linux/sunrpc/xdr.h | 16 +++++++++++++++- net/sunrpc/xdr.c | 17 ++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 4417f667c757e..5860f32e39580 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -243,7 +243,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, size_t nbytes); -extern void xdr_commit_encode(struct xdr_stream *xdr); +extern void __xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen); extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, @@ -306,6 +306,20 @@ xdr_reset_scratch_buffer(struct xdr_stream *xdr) xdr_set_scratch_buffer(xdr, NULL, 0); } +/** + * xdr_commit_encode - Ensure all data is written to xdr->buf + * @xdr: pointer to xdr_stream + * + * Handle encoding across page boundaries by giving the caller a + * temporary location to write to, then later copying the data into + * place. __xdr_commit_encode() does that copying. + */ +static inline void xdr_commit_encode(struct xdr_stream *xdr) +{ + if (unlikely(xdr->scratch.iov_len)) + __xdr_commit_encode(xdr); +} + /** * xdr_stream_remaining - Return the number of bytes remaining in the stream * @xdr: pointer to struct xdr_stream diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index b57cf9df4de89..1ad8b4ef14de7 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -919,7 +919,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, EXPORT_SYMBOL_GPL(xdr_init_encode); /** - * xdr_commit_encode - Ensure all data is written to buffer + * __xdr_commit_encode - Ensure all data is written to buffer * @xdr: pointer to xdr_stream * * We handle encoding across page boundaries by giving the caller a @@ -931,22 +931,25 @@ EXPORT_SYMBOL_GPL(xdr_init_encode); * required at the end of encoding, or any other time when the xdr_buf * data might be read. */ -inline void xdr_commit_encode(struct xdr_stream *xdr) +void __xdr_commit_encode(struct xdr_stream *xdr) { int shift = xdr->scratch.iov_len; void *page; - if (shift == 0) - return; page = page_address(*xdr->page_ptr); memcpy(xdr->scratch.iov_base, page, shift); memmove(page, page + shift, (void *)xdr->p - page); xdr_reset_scratch_buffer(xdr); } -EXPORT_SYMBOL_GPL(xdr_commit_encode); +EXPORT_SYMBOL_GPL(__xdr_commit_encode); -static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, - size_t nbytes) +/* + * The buffer space to be reserved crosses the boundary between + * xdr->buf->head and xdr->buf->pages, or between two pages + * in xdr->buf->pages. + */ +static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, + size_t nbytes) { __be32 *p; int space_left; -- GitLab From 90d871b3b9bb7ef8f835d6b53095f01b9c74b7b3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Jun 2022 16:48:05 -0400 Subject: [PATCH 361/942] SUNRPC: Clean up xdr_commit_encode() Both the kvec::iov_len field and the third parameter of memcpy() and memmove() are size_t. There's no reason for the implicit conversion from size_t to int and back. Change the type of @shift to make the code easier to read and understand. Signed-off-by: Chuck Lever Reviewed-by: NeilBrown Reviewed-by: J. Bruce Fields --- net/sunrpc/xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 1ad8b4ef14de7..3c182041e790d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -933,7 +933,7 @@ EXPORT_SYMBOL_GPL(xdr_init_encode); */ void __xdr_commit_encode(struct xdr_stream *xdr) { - int shift = xdr->scratch.iov_len; + size_t shift = xdr->scratch.iov_len; void *page; page = page_address(*xdr->page_ptr); -- GitLab From bd07a64176a2be03f5195c64943063fd119f9f21 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Jun 2022 16:48:11 -0400 Subject: [PATCH 362/942] SUNRPC: Clean up xdr_get_next_encode_buffer() The value of @p is not used until the "location of the next item" is computed. Help human readers by moving its initial assignment to the paragraph where that value is used and by clarifying the antecedents in the documenting comment. Signed-off-by: Chuck Lever Reviewed-by: NeilBrown Reviewed-by: J. Bruce Fields --- net/sunrpc/xdr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 3c182041e790d..eca02d1224763 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -967,6 +967,7 @@ static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, xdr->buf->page_len += frag1bytes; xdr->page_ptr++; xdr->iov = NULL; + /* * If the last encode didn't end exactly on a page boundary, the * next one will straddle boundaries. Encode into the next @@ -975,11 +976,12 @@ static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, * space at the end of the previous buffer: */ xdr_set_scratch_buffer(xdr, xdr->p, frag1bytes); - p = page_address(*xdr->page_ptr); + /* - * Note this is where the next encode will start after we've - * shifted this one back: + * xdr->p is where the next encode will start after + * xdr_commit_encode() has shifted this one back: */ + p = page_address(*xdr->page_ptr); xdr->p = (void *)p + frag2bytes; space_left = xdr->buf->buflen - xdr->buf->len; if (space_left - nbytes >= PAGE_SIZE) -- GitLab From da9e94fe000e11f21d3d6f66012fe5c6379bd93c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 7 Jun 2022 16:48:18 -0400 Subject: [PATCH 363/942] SUNRPC: Remove pointer type casts from xdr_get_next_encode_buffer() To make the code easier to read, remove visual clutter by changing the declared type of @p. Signed-off-by: Chuck Lever Reviewed-by: NeilBrown Reviewed-by: J. Bruce Fields --- net/sunrpc/xdr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index eca02d1224763..f87a2d8f23a72 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -951,9 +951,9 @@ EXPORT_SYMBOL_GPL(__xdr_commit_encode); static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, size_t nbytes) { - __be32 *p; int space_left; int frag1bytes, frag2bytes; + void *p; if (nbytes > PAGE_SIZE) goto out_overflow; /* Bigger buffers require special handling */ @@ -982,12 +982,12 @@ static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, * xdr_commit_encode() has shifted this one back: */ p = page_address(*xdr->page_ptr); - xdr->p = (void *)p + frag2bytes; + xdr->p = p + frag2bytes; space_left = xdr->buf->buflen - xdr->buf->len; if (space_left - nbytes >= PAGE_SIZE) - xdr->end = (void *)p + PAGE_SIZE; + xdr->end = p + PAGE_SIZE; else - xdr->end = (void *)p + space_left - frag1bytes; + xdr->end = p + space_left - frag1bytes; xdr->buf->page_len += frag2bytes; xdr->buf->len += nbytes; -- GitLab From ff87d619ac180444db297f043962a5c325ded47b Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 19 May 2022 20:36:48 +0800 Subject: [PATCH 364/942] ASoC: fsl_sai: Enable MCTL_MCLK_EN bit for master mode On i.MX8MM, the MCTL_MCLK_EN bit it is not only the gate for MCLK output to PAD, but also the gate bit between root clock and SAI module, So it is need to be enabled for master mode, otherwise there is no bclk generated. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1652963808-14515-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index b65c9c7cf54a4..b4dd3122c45e5 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -437,6 +437,12 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP, savediv / 2 - 1); + if (sai->soc_data->max_register >= FSL_SAI_MCTL) { + /* SAI is in master mode at this point, so enable MCLK */ + regmap_update_bits(sai->regmap, FSL_SAI_MCTL, + FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); + } + return 0; } -- GitLab From 35b42dce619701f1300fb8498dae82c9bb1f0263 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 6 Jun 2022 13:53:53 +0900 Subject: [PATCH 365/942] net: mdio: unexport __init-annotated mdio_bus_init() EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic. modpost used to detect it, but it has been broken for a decade. Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds. There are two ways to fix it: - Remove __init - Remove EXPORT_SYMBOL I chose the latter for this case because the only in-tree call-site, drivers/net/phy/phy_device.c is never compiled as modular. (CONFIG_PHYLIB is boolean) Fixes: 90eff9096c01 ("net: phy: Allow splitting MDIO bus/device support from PHYs") Reported-by: Stephen Rothwell Signed-off-by: Masahiro Yamada Reviewed-by: Florian Fainelli Reviewed-by: Russell King (Oracle) Signed-off-by: Jakub Kicinski --- drivers/net/phy/mdio_bus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 58d602985877b..8a2dbe849866d 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -1046,7 +1046,6 @@ int __init mdio_bus_init(void) return ret; } -EXPORT_SYMBOL_GPL(mdio_bus_init); #if IS_ENABLED(CONFIG_PHYLIB) void mdio_bus_exit(void) -- GitLab From 4a388f08d8784af48f352193d2b72aaf167a57a1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 6 Jun 2022 13:53:54 +0900 Subject: [PATCH 366/942] net: xfrm: unexport __init-annotated xfrm4_protocol_init() EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic. modpost used to detect it, but it has been broken for a decade. Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds. There are two ways to fix it: - Remove __init - Remove EXPORT_SYMBOL I chose the latter for this case because the only in-tree call-site, net/ipv4/xfrm4_policy.c is never compiled as modular. (CONFIG_XFRM is boolean) Fixes: 2f32b51b609f ("xfrm: Introduce xfrm_input_afinfo to access the the callbacks properly") Reported-by: Stephen Rothwell Signed-off-by: Masahiro Yamada Acked-by: Steffen Klassert Signed-off-by: Jakub Kicinski --- net/ipv4/xfrm4_protocol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv4/xfrm4_protocol.c b/net/ipv4/xfrm4_protocol.c index 2fe5860c21d6e..b146ce88c5d0c 100644 --- a/net/ipv4/xfrm4_protocol.c +++ b/net/ipv4/xfrm4_protocol.c @@ -304,4 +304,3 @@ void __init xfrm4_protocol_init(void) { xfrm_input_register_afinfo(&xfrm4_input_afinfo); } -EXPORT_SYMBOL(xfrm4_protocol_init); -- GitLab From 5801f064e35181c71857a80ff18af4dbec3c5f5c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 6 Jun 2022 13:53:55 +0900 Subject: [PATCH 367/942] net: ipv6: unexport __init-annotated seg6_hmac_init() EXPORT_SYMBOL and __init is a bad combination because the .init.text section is freed up after the initialization. Hence, modules cannot use symbols annotated __init. The access to a freed symbol may end up with kernel panic. modpost used to detect it, but it has been broken for a decade. Recently, I fixed modpost so it started to warn it again, then this showed up in linux-next builds. There are two ways to fix it: - Remove __init - Remove EXPORT_SYMBOL I chose the latter for this case because the caller (net/ipv6/seg6.c) and the callee (net/ipv6/seg6_hmac.c) belong to the same module. It seems an internal function call in ipv6.ko. Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support") Reported-by: Stephen Rothwell Signed-off-by: Masahiro Yamada Signed-off-by: Jakub Kicinski --- net/ipv6/seg6_hmac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c index 29bc4e7c3046e..6de01185cc68f 100644 --- a/net/ipv6/seg6_hmac.c +++ b/net/ipv6/seg6_hmac.c @@ -399,7 +399,6 @@ int __init seg6_hmac_init(void) { return seg6_hmac_init_algo(); } -EXPORT_SYMBOL(seg6_hmac_init); int __net_init seg6_hmac_net_init(struct net *net) { -- GitLab From 77e5fe8f176a525523ae091d6fd0fbb8834c156d Mon Sep 17 00:00:00 2001 From: Martin Faltesek Date: Mon, 6 Jun 2022 21:57:27 -0500 Subject: [PATCH 368/942] nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION The first validation check for EVT_TRANSACTION has two different checks tied together with logical AND. One is a check for minimum packet length, and the other is for a valid aid_tag. If either condition is true (fails), then an error should be triggered. The fix is to change && to ||. Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support") Cc: stable@vger.kernel.org Signed-off-by: Martin Faltesek Reviewed-by: Guenter Roeck Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jakub Kicinski --- drivers/nfc/st21nfca/se.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index 7e213f8ddc98b..9645777f2544e 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -315,7 +315,7 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, * AID 81 5 to 16 * PARAMETERS 82 0 to 255 */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 && + if (skb->len < NFC_MIN_AID_LENGTH + 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; -- GitLab From 996419e0594abb311fb958553809f24f38e7abbe Mon Sep 17 00:00:00 2001 From: Martin Faltesek Date: Mon, 6 Jun 2022 21:57:28 -0500 Subject: [PATCH 369/942] nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling Error paths do not free previously allocated memory. Add devm_kfree() to those failure paths. Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support") Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION") Cc: stable@vger.kernel.org Signed-off-by: Martin Faltesek Reviewed-by: Guenter Roeck Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jakub Kicinski --- drivers/nfc/st21nfca/se.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index 9645777f2544e..8e1113ce139be 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -326,22 +326,29 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, transaction->aid_len = skb->data[1]; /* Checking if the length of the AID is valid */ - if (transaction->aid_len > sizeof(transaction->aid)) + if (transaction->aid_len > sizeof(transaction->aid)) { + devm_kfree(dev, transaction); return -EINVAL; + } memcpy(transaction->aid, &skb->data[2], transaction->aid_len); /* Check next byte is PARAMETERS tag (82) */ if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) + NFC_EVT_TRANSACTION_PARAMS_TAG) { + devm_kfree(dev, transaction); return -EPROTO; + } transaction->params_len = skb->data[transaction->aid_len + 3]; /* Total size is allocated (skb->len - 2) minus fixed array members */ - if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction))) + if (transaction->params_len > ((skb->len - 2) - + sizeof(struct nfc_evt_transaction))) { + devm_kfree(dev, transaction); return -EINVAL; + } memcpy(transaction->params, skb->data + transaction->aid_len + 4, transaction->params_len); -- GitLab From f2e19b36593caed4c977c2f55aeba7408aeb2132 Mon Sep 17 00:00:00 2001 From: Martin Faltesek Date: Mon, 6 Jun 2022 21:57:29 -0500 Subject: [PATCH 370/942] nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION The transaction buffer is allocated by using the size of the packet buf, and subtracting two which seem intended to remove the two tags which are not present in the target structure. This calculation leads to under counting memory because of differences between the packet contents and the target structure. The aid_len field is a u8 in the packet, but a u32 in the structure, resulting in at least 3 bytes always being under counted. Further, the aid data is a variable length field in the packet, but fixed in the structure, so if this field is less than the max, the difference is added to the under counting. The last validation check for transaction->params_len is also incorrect since it employs the same accounting error. To fix, perform validation checks progressively to safely reach the next field, to determine the size of both buffers and verify both tags. Once all validation checks pass, allocate the buffer and copy the data. This eliminates freeing memory on the error path, as those checks are moved ahead of memory allocation. Fixes: 26fc6c7f02cb ("NFC: st21nfca: Add HCI transaction event support") Fixes: 4fbcc1a4cb20 ("nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION") Cc: stable@vger.kernel.org Signed-off-by: Martin Faltesek Reviewed-by: Guenter Roeck Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jakub Kicinski --- drivers/nfc/st21nfca/se.c | 60 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index 8e1113ce139be..df8d27cf2956b 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -300,6 +300,8 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, int r = 0; struct device *dev = &hdev->ndev->dev; struct nfc_evt_transaction *transaction; + u32 aid_len; + u8 params_len; pr_debug("connectivity gate event: %x\n", event); @@ -308,50 +310,48 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host, r = nfc_se_connectivity(hdev->ndev, host); break; case ST21NFCA_EVT_TRANSACTION: - /* - * According to specification etsi 102 622 + /* According to specification etsi 102 622 * 11.2.2.4 EVT_TRANSACTION Table 52 * Description Tag Length * AID 81 5 to 16 * PARAMETERS 82 0 to 255 + * + * The key differences are aid storage length is variably sized + * in the packet, but fixed in nfc_evt_transaction, and that the aid_len + * is u8 in the packet, but u32 in the structure, and the tags in + * the packet are not included in nfc_evt_transaction. + * + * size in bytes: 1 1 5-16 1 1 0-255 + * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4 + * member name: aid_tag(M) aid_len aid params_tag(M) params_len params + * example: 0x81 5-16 X 0x82 0-255 X */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 || - skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) + if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; - transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); - if (!transaction) - return -ENOMEM; - - transaction->aid_len = skb->data[1]; + aid_len = skb->data[1]; - /* Checking if the length of the AID is valid */ - if (transaction->aid_len > sizeof(transaction->aid)) { - devm_kfree(dev, transaction); - return -EINVAL; - } + if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid)) + return -EPROTO; - memcpy(transaction->aid, &skb->data[2], - transaction->aid_len); + params_len = skb->data[aid_len + 3]; - /* Check next byte is PARAMETERS tag (82) */ - if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) { - devm_kfree(dev, transaction); + /* Verify PARAMETERS tag is (82), and final check that there is enough + * space in the packet to read everything. + */ + if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) || + (skb->len < aid_len + 4 + params_len)) return -EPROTO; - } - transaction->params_len = skb->data[transaction->aid_len + 3]; + transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL); + if (!transaction) + return -ENOMEM; - /* Total size is allocated (skb->len - 2) minus fixed array members */ - if (transaction->params_len > ((skb->len - 2) - - sizeof(struct nfc_evt_transaction))) { - devm_kfree(dev, transaction); - return -EINVAL; - } + transaction->aid_len = aid_len; + transaction->params_len = params_len; - memcpy(transaction->params, skb->data + - transaction->aid_len + 4, transaction->params_len); + memcpy(transaction->aid, &skb->data[2], aid_len); + memcpy(transaction->params, &skb->data[aid_len + 4], params_len); r = nfc_se_transaction(hdev->ndev, host, transaction); break; -- GitLab From 8a4d480702b71184fabcf379b80bf7539716752e Mon Sep 17 00:00:00 2001 From: Xiaohui Zhang Date: Tue, 7 Jun 2022 16:32:30 +0800 Subject: [PATCH 371/942] nfc: nfcmrvl: Fix memory leak in nfcmrvl_play_deferred Similar to the handling of play_deferred in commit 19cfe912c37b ("Bluetooth: btusb: Fix memory leak in play_deferred"), we thought a patch might be needed here as well. Currently usb_submit_urb is called directly to submit deferred tx urbs after unanchor them. So the usb_giveback_urb_bh would failed to unref it in usb_unanchor_urb and cause memory leak. Put those urbs in tx_anchor to avoid the leak, and also fix the error handling. Signed-off-by: Xiaohui Zhang Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220607083230.6182-1-xiaohuizhang@ruc.edu.cn Signed-off-by: Jakub Kicinski --- drivers/nfc/nfcmrvl/usb.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c index a99aedff795dc..ea73094530968 100644 --- a/drivers/nfc/nfcmrvl/usb.c +++ b/drivers/nfc/nfcmrvl/usb.c @@ -388,13 +388,25 @@ static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data) int err; while ((urb = usb_get_from_anchor(&drv_data->deferred))) { + usb_anchor_urb(urb, &drv_data->tx_anchor); + err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) + if (err) { + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + usb_free_urb(urb); break; + } drv_data->tx_in_flight++; + usb_free_urb(urb); + } + + /* Cleanup the rest deferred urbs. */ + while ((urb = usb_get_from_anchor(&drv_data->deferred))) { + kfree(urb->setup_packet); + usb_free_urb(urb); } - usb_scuttle_anchored_urbs(&drv_data->deferred); } static int nfcmrvl_resume(struct usb_interface *intf) -- GitLab From a3d52ac7750025b5a1f99eb1ccea0e31b58bf7bb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Jun 2022 17:51:28 +0100 Subject: [PATCH 372/942] arm64/sme: Fix tests for 0b1111 value ID registers For both ID_AA64SMFR0_EL1.I16I64 and ID_AA64SMFR0_EL1.I8I32 we check for the presence of the feature by looking for a specific ID value of 0x4 but should instead be checking for the value 0xf defined by the architecture. This had no practical effect since we are looking for values >= our define and the only valid values in the architecture are 0b0000 and 0b1111 so we would detect things appropriately with the architecture as it stands even with the incorrect defines. Signed-off-by: Mark Brown Fixes: b4adc83b0770 ("arm64/sme: System register and exception syndrome definitions") Link: https://lore.kernel.org/r/20220607165128.2833157-1-broonie@kernel.org Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/sysreg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 55f998c3dc284..42ff95dba6da4 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -843,9 +843,9 @@ #define ID_AA64SMFR0_F32F32_SHIFT 32 #define ID_AA64SMFR0_FA64 0x1 -#define ID_AA64SMFR0_I16I64 0x4 +#define ID_AA64SMFR0_I16I64 0xf #define ID_AA64SMFR0_F64F64 0x1 -#define ID_AA64SMFR0_I8I32 0x4 +#define ID_AA64SMFR0_I8I32 0xf #define ID_AA64SMFR0_F16F32 0x1 #define ID_AA64SMFR0_B16F32 0x1 #define ID_AA64SMFR0_F32F32 0x1 -- GitLab From f539316fe8106b4f4b4e95c1e70a31b545523b03 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 8 Jun 2022 12:59:15 +0100 Subject: [PATCH 373/942] arm64/sme: Fix SVE/SME typo in ABI documentation Fix a cut'n'paste error. Reported-by: Luis Machado Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220608115915.251870-1-broonie@kernel.org Signed-off-by: Catalin Marinas --- Documentation/arm64/sme.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/arm64/sme.rst b/Documentation/arm64/sme.rst index 8ba677b87e90f..937147f58cc54 100644 --- a/Documentation/arm64/sme.rst +++ b/Documentation/arm64/sme.rst @@ -371,7 +371,7 @@ The regset data starts with struct user_za_header, containing: Appendix A. SME programmer's model (informative) ================================================= -This section provides a minimal description of the additions made by SVE to the +This section provides a minimal description of the additions made by SME to the ARMv8-A programmer's model that are relevant to this document. Note: This section is for information only and not intended to be complete or -- GitLab From f93431c86b631bbca5614c66f966bf3ddb3c2803 Mon Sep 17 00:00:00 2001 From: Wang Yufen Date: Tue, 7 Jun 2022 20:00:27 +0800 Subject: [PATCH 374/942] ipv6: Fix signed integer overflow in __ip6_append_data Resurrect ubsan overflow checks and ubsan report this warning, fix it by change the variable [length] type to size_t. UBSAN: signed-integer-overflow in net/ipv6/ip6_output.c:1489:19 2147479552 + 8567 cannot be represented in type 'int' CPU: 0 PID: 253 Comm: err Not tainted 5.16.0+ #1 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace+0x214/0x230 show_stack+0x30/0x78 dump_stack_lvl+0xf8/0x118 dump_stack+0x18/0x30 ubsan_epilogue+0x18/0x60 handle_overflow+0xd0/0xf0 __ubsan_handle_add_overflow+0x34/0x44 __ip6_append_data.isra.48+0x1598/0x1688 ip6_append_data+0x128/0x260 udpv6_sendmsg+0x680/0xdd0 inet6_sendmsg+0x54/0x90 sock_sendmsg+0x70/0x88 ____sys_sendmsg+0xe8/0x368 ___sys_sendmsg+0x98/0xe0 __sys_sendmmsg+0xf4/0x3b8 __arm64_sys_sendmmsg+0x34/0x48 invoke_syscall+0x64/0x160 el0_svc_common.constprop.4+0x124/0x300 do_el0_svc+0x44/0xc8 el0_svc+0x3c/0x1e8 el0t_64_sync_handler+0x88/0xb0 el0t_64_sync+0x16c/0x170 Changes since v1: -Change the variable [length] type to unsigned, as Eric Dumazet suggested. Changes since v2: -Don't change exthdrlen type in ip6_make_skb, as Paolo Abeni suggested. Changes since v3: -Don't change ulen type in udpv6_sendmsg and l2tp_ip6_sendmsg, as Jakub Kicinski suggested. Reported-by: Hulk Robot Signed-off-by: Wang Yufen Link: https://lore.kernel.org/r/20220607120028.845916-1-wangyufen@huawei.com Signed-off-by: Jakub Kicinski --- include/net/ipv6.h | 4 ++-- net/ipv6/ip6_output.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 5b38bf1a586b9..de9dcc5652c48 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1063,7 +1063,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), - void *from, int length, int transhdrlen, + void *from, size_t length, int transhdrlen, struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct rt6_info *rt, unsigned int flags); @@ -1079,7 +1079,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, struct sk_buff_head *queue, struct sk_buff *ip6_make_skb(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), - void *from, int length, int transhdrlen, + void *from, size_t length, int transhdrlen, struct ipcm6_cookie *ipc6, struct rt6_info *rt, unsigned int flags, struct inet_cork_full *cork); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4081b12a01ff2..77e3f5970ce48 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1450,7 +1450,7 @@ static int __ip6_append_data(struct sock *sk, struct page_frag *pfrag, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), - void *from, int length, int transhdrlen, + void *from, size_t length, int transhdrlen, unsigned int flags, struct ipcm6_cookie *ipc6) { struct sk_buff *skb, *skb_prev = NULL; @@ -1798,7 +1798,7 @@ static int __ip6_append_data(struct sock *sk, int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), - void *from, int length, int transhdrlen, + void *from, size_t length, int transhdrlen, struct ipcm6_cookie *ipc6, struct flowi6 *fl6, struct rt6_info *rt, unsigned int flags) { @@ -1995,7 +1995,7 @@ EXPORT_SYMBOL_GPL(ip6_flush_pending_frames); struct sk_buff *ip6_make_skb(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), - void *from, int length, int transhdrlen, + void *from, size_t length, int transhdrlen, struct ipcm6_cookie *ipc6, struct rt6_info *rt, unsigned int flags, struct inet_cork_full *cork) { -- GitLab From f638a84afef3dfe10554c51820c16e39a278c915 Mon Sep 17 00:00:00 2001 From: Wang Yufen Date: Tue, 7 Jun 2022 20:00:28 +0800 Subject: [PATCH 375/942] ipv6: Fix signed integer overflow in l2tp_ip6_sendmsg When len >= INT_MAX - transhdrlen, ulen = len + transhdrlen will be overflow. To fix, we can follow what udpv6 does and subtract the transhdrlen from the max. Signed-off-by: Wang Yufen Link: https://lore.kernel.org/r/20220607120028.845916-2-wangyufen@huawei.com Signed-off-by: Jakub Kicinski --- net/l2tp/l2tp_ip6.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index c6ff8bf9b55f9..9dbd801ddb98c 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -504,14 +504,15 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) struct ipcm6_cookie ipc6; int addr_len = msg->msg_namelen; int transhdrlen = 4; /* zero session-id */ - int ulen = len + transhdrlen; + int ulen; int err; /* Rough check on arithmetic overflow, * better check is made in ip6_append_data(). */ - if (len > INT_MAX) + if (len > INT_MAX - transhdrlen) return -EMSGSIZE; + ulen = len + transhdrlen; /* Mirror BSD error message compatibility */ if (msg->msg_flags & MSG_OOB) -- GitLab From 29dec90a0f1d961b93f34f910e9319d8cb23edbd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Jun 2022 08:34:06 +0200 Subject: [PATCH 376/942] dm: fix bio_set allocation The use of bioset_init_from_src mean that the pre-allocated pools weren't used for anything except parameter passing, and the integrity pool creation got completely lost for the actual live mapped_device. Fix that by assigning the actual preallocated dm_md_mempools to the mapped_device and using that for I/O instead of creating new mempools. Fixes: 2a2a4c510b76 ("dm: use bioset_init_from_src() to copy bio_set") Signed-off-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- drivers/md/dm-core.h | 11 ++++-- drivers/md/dm-rq.c | 2 +- drivers/md/dm-table.c | 11 ------ drivers/md/dm.c | 84 +++++++++++++------------------------------ drivers/md/dm.h | 2 -- 5 files changed, 35 insertions(+), 75 deletions(-) diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h index d21648a923ea9..54c0473a51dde 100644 --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -33,6 +33,14 @@ struct dm_kobject_holder { * access their members! */ +/* + * For mempools pre-allocation at the table loading time. + */ +struct dm_md_mempools { + struct bio_set bs; + struct bio_set io_bs; +}; + struct mapped_device { struct mutex suspend_lock; @@ -110,8 +118,7 @@ struct mapped_device { /* * io objects are allocated from here. */ - struct bio_set io_bs; - struct bio_set bs; + struct dm_md_mempools *mempools; /* kobject and completion */ struct dm_kobject_holder kobj_holder; diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 6087cdcaad46d..a83b98a8d2a99 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -319,7 +319,7 @@ static int setup_clone(struct request *clone, struct request *rq, { int r; - r = blk_rq_prep_clone(clone, rq, &tio->md->bs, gfp_mask, + r = blk_rq_prep_clone(clone, rq, &tio->md->mempools->bs, gfp_mask, dm_rq_bio_constructor, tio); if (r) return r; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 0e833a154b31d..bd539afbfe88f 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -1038,17 +1038,6 @@ static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device * return 0; } -void dm_table_free_md_mempools(struct dm_table *t) -{ - dm_free_md_mempools(t->mempools); - t->mempools = NULL; -} - -struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t) -{ - return t->mempools; -} - static int setup_indexes(struct dm_table *t) { int i; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index dfb0a551bd880..8b21155d3c4f5 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -136,14 +136,6 @@ static int get_swap_bios(void) return latch; } -/* - * For mempools pre-allocation at the table loading time. - */ -struct dm_md_mempools { - struct bio_set bs; - struct bio_set io_bs; -}; - struct table_device { struct list_head list; refcount_t count; @@ -581,7 +573,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio) struct dm_target_io *tio; struct bio *clone; - clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->io_bs); + clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->mempools->io_bs); /* Set default bdev, but target must bio_set_dev() before issuing IO */ clone->bi_bdev = md->disk->part0; @@ -628,7 +620,8 @@ static struct bio *alloc_tio(struct clone_info *ci, struct dm_target *ti, } else { struct mapped_device *md = ci->io->md; - clone = bio_alloc_clone(NULL, ci->bio, gfp_mask, &md->bs); + clone = bio_alloc_clone(NULL, ci->bio, gfp_mask, + &md->mempools->bs); if (!clone) return NULL; /* Set default bdev, but target must bio_set_dev() before issuing IO */ @@ -1876,8 +1869,7 @@ static void cleanup_mapped_device(struct mapped_device *md) { if (md->wq) destroy_workqueue(md->wq); - bioset_exit(&md->bs); - bioset_exit(&md->io_bs); + dm_free_md_mempools(md->mempools); if (md->dax_dev) { dax_remove_host(md->disk); @@ -2049,48 +2041,6 @@ static void free_dev(struct mapped_device *md) kvfree(md); } -static int __bind_mempools(struct mapped_device *md, struct dm_table *t) -{ - struct dm_md_mempools *p = dm_table_get_md_mempools(t); - int ret = 0; - - if (dm_table_bio_based(t)) { - /* - * The md may already have mempools that need changing. - * If so, reload bioset because front_pad may have changed - * because a different table was loaded. - */ - bioset_exit(&md->bs); - bioset_exit(&md->io_bs); - - } else if (bioset_initialized(&md->bs)) { - /* - * There's no need to reload with request-based dm - * because the size of front_pad doesn't change. - * Note for future: If you are to reload bioset, - * prep-ed requests in the queue may refer - * to bio from the old bioset, so you must walk - * through the queue to unprep. - */ - goto out; - } - - BUG_ON(!p || - bioset_initialized(&md->bs) || - bioset_initialized(&md->io_bs)); - - ret = bioset_init_from_src(&md->bs, &p->bs); - if (ret) - goto out; - ret = bioset_init_from_src(&md->io_bs, &p->io_bs); - if (ret) - bioset_exit(&md->bs); -out: - /* mempool bind completed, no longer need any mempools in the table */ - dm_table_free_md_mempools(t); - return ret; -} - /* * Bind a table to the device. */ @@ -2144,12 +2094,28 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, * immutable singletons - used to optimize dm_mq_queue_rq. */ md->immutable_target = dm_table_get_immutable_target(t); - } - ret = __bind_mempools(md, t); - if (ret) { - old_map = ERR_PTR(ret); - goto out; + /* + * There is no need to reload with request-based dm because the + * size of front_pad doesn't change. + * + * Note for future: If you are to reload bioset, prep-ed + * requests in the queue may refer to bio from the old bioset, + * so you must walk through the queue to unprep. + */ + if (!md->mempools) { + md->mempools = t->mempools; + t->mempools = NULL; + } + } else { + /* + * The md may already have mempools that need changing. + * If so, reload bioset because front_pad may have changed + * because a different table was loaded. + */ + dm_free_md_mempools(md->mempools); + md->mempools = t->mempools; + t->mempools = NULL; } ret = dm_table_set_restrictions(t, md->queue, limits); diff --git a/drivers/md/dm.h b/drivers/md/dm.h index 3f89664fea010..a8405ce305a96 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -71,8 +71,6 @@ struct dm_target *dm_table_get_immutable_target(struct dm_table *t); struct dm_target *dm_table_get_wildcard_target(struct dm_table *t); bool dm_table_bio_based(struct dm_table *t); bool dm_table_request_based(struct dm_table *t); -void dm_table_free_md_mempools(struct dm_table *t); -struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); void dm_lock_md_type(struct mapped_device *md); void dm_unlock_md_type(struct mapped_device *md); -- GitLab From d5a37b19983725d2045588cfa3a4699f5b39ae26 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Jun 2022 08:34:07 +0200 Subject: [PATCH 377/942] block: remove bioset_init_from_src Unused now, and the interface never really made a whole lot of sense to start with. Signed-off-by: Christoph Hellwig Signed-off-by: Mike Snitzer --- block/bio.c | 20 -------------------- include/linux/bio.h | 1 - 2 files changed, 21 deletions(-) diff --git a/block/bio.c b/block/bio.c index f92d0223247b7..51c99f2c5c908 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1747,26 +1747,6 @@ int bioset_init(struct bio_set *bs, } EXPORT_SYMBOL(bioset_init); -/* - * Initialize and setup a new bio_set, based on the settings from - * another bio_set. - */ -int bioset_init_from_src(struct bio_set *bs, struct bio_set *src) -{ - int flags; - - flags = 0; - if (src->bvec_pool.min_nr) - flags |= BIOSET_NEED_BVECS; - if (src->rescue_workqueue) - flags |= BIOSET_NEED_RESCUER; - if (src->cache) - flags |= BIOSET_PERCPU_CACHE; - - return bioset_init(bs, src->bio_pool.min_nr, src->front_pad, flags); -} -EXPORT_SYMBOL(bioset_init_from_src); - static int __init init_bio(void) { int i; diff --git a/include/linux/bio.h b/include/linux/bio.h index 1cf3738ef1ea6..992ee987f2738 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -403,7 +403,6 @@ enum { extern int bioset_init(struct bio_set *, unsigned int, unsigned int, int flags); extern void bioset_exit(struct bio_set *); extern int biovec_init_pool(mempool_t *pool, int pool_entries); -extern int bioset_init_from_src(struct bio_set *bs, struct bio_set *src); struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs, unsigned int opf, gfp_t gfp_mask, -- GitLab From a6958951ebe7db60e84b2437ee53aa4843028726 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 7 Jun 2022 11:01:46 +0200 Subject: [PATCH 378/942] au1000_eth: stop using virt_to_bus() The conversion to the dma-mapping API in linux-2.6.11 was incomplete and left a virt_to_bus() call around. There have been a number of fixes for DMA mapping API abuse in this driver, but this one always slipped through. Change it to just use the existing dma_addr_t pointer, and make it use the correct types throughout the driver to make it easier to understand the virtual vs dma address spaces. Signed-off-by: Arnd Bergmann Tested-by: Manuel Lauss Link: https://lore.kernel.org/r/20220607090206.19830-1-arnd@kernel.org Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/amd/au1000_eth.c | 22 +++++++++++----------- drivers/net/ethernet/amd/au1000_eth.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index c6f003975621b..d5f2c69892210 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -820,7 +820,7 @@ static int au1000_rx(struct net_device *dev) pr_cont("\n"); } } - prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); + prxd->buff_stat = lower_32_bits(pDB->dma_addr) | RX_DMA_ENABLE; aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); wmb(); /* drain writebuffer */ @@ -996,7 +996,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) ps->tx_packets++; ps->tx_bytes += ptxd->len; - ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; + ptxd->buff_stat = lower_32_bits(pDB->dma_addr) | TX_DMA_ENABLE; wmb(); /* drain writebuffer */ dev_kfree_skb(skb); aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1); @@ -1131,9 +1131,9 @@ static int au1000_probe(struct platform_device *pdev) /* Allocate the data buffers * Snooping works fine with eth on all au1xxx */ - aup->vaddr = (u32)dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE * - (NUM_TX_BUFFS + NUM_RX_BUFFS), - &aup->dma_addr, 0); + aup->vaddr = dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE * + (NUM_TX_BUFFS + NUM_RX_BUFFS), + &aup->dma_addr, 0); if (!aup->vaddr) { dev_err(&pdev->dev, "failed to allocate data buffers\n"); err = -ENOMEM; @@ -1234,8 +1234,8 @@ static int au1000_probe(struct platform_device *pdev) for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) { pDB->pnext = pDBfree; pDBfree = pDB; - pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i); - pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); + pDB->vaddr = aup->vaddr + MAX_BUF_SIZE * i; + pDB->dma_addr = aup->dma_addr + MAX_BUF_SIZE * i; pDB++; } aup->pDBfree = pDBfree; @@ -1246,7 +1246,7 @@ static int au1000_probe(struct platform_device *pdev) if (!pDB) goto err_out; - aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; + aup->rx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr); aup->rx_db_inuse[i] = pDB; } @@ -1255,7 +1255,7 @@ static int au1000_probe(struct platform_device *pdev) if (!pDB) goto err_out; - aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; + aup->tx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr); aup->tx_dma_ring[i]->len = 0; aup->tx_db_inuse[i] = pDB; } @@ -1310,7 +1310,7 @@ static int au1000_probe(struct platform_device *pdev) iounmap(aup->mac); err_remap1: dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), - (void *)aup->vaddr, aup->dma_addr); + aup->vaddr, aup->dma_addr); err_vaddr: free_netdev(dev); err_alloc: @@ -1343,7 +1343,7 @@ static int au1000_remove(struct platform_device *pdev) au1000_ReleaseDB(aup, aup->tx_db_inuse[i]); dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), - (void *)aup->vaddr, aup->dma_addr); + aup->vaddr, aup->dma_addr); iounmap(aup->macdma); iounmap(aup->mac); diff --git a/drivers/net/ethernet/amd/au1000_eth.h b/drivers/net/ethernet/amd/au1000_eth.h index e3a3ed29db61d..2489c2f4fd8a6 100644 --- a/drivers/net/ethernet/amd/au1000_eth.h +++ b/drivers/net/ethernet/amd/au1000_eth.h @@ -106,8 +106,8 @@ struct au1000_private { struct mac_reg *mac; /* mac registers */ u32 *enable; /* address of MAC Enable Register */ void __iomem *macdma; /* base of MAC DMA port */ - u32 vaddr; /* virtual address of rx/tx buffers */ - dma_addr_t dma_addr; /* dma address of rx/tx buffers */ + void *vaddr; /* virtual address of rx/tx buffers */ + dma_addr_t dma_addr; /* dma address of rx/tx buffers */ spinlock_t lock; /* Serialise access to device */ -- GitLab From ed872f92fd0946ba30f2acd05fc57e29cac29cd2 Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Wed, 1 Jun 2022 06:57:38 +0200 Subject: [PATCH 379/942] MAINTAINERS: adjust MELLANOX ETHERNET INNOVA DRIVERS to TLS support removal Commit 40379a0084c2 ("net/mlx5_fpga: Drop INNOVA TLS support") removes all files in the directory drivers/net/ethernet/mellanox/mlx5/core/accel/, but misses to adjust its reference in MAINTAINERS. Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a broken reference. Remove the file entry to the removed directory in MELLANOX ETHERNET INNOVA DRIVERS. Signed-off-by: Lukas Bulwahn Signed-off-by: Saeed Mahameed --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 033a01b07f8f2..bab9e131ec9c2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12651,7 +12651,6 @@ L: netdev@vger.kernel.org S: Supported W: http://www.mellanox.com Q: https://patchwork.kernel.org/project/netdevbpf/list/ -F: drivers/net/ethernet/mellanox/mlx5/core/accel/* F: drivers/net/ethernet/mellanox/mlx5/core/en_accel/* F: drivers/net/ethernet/mellanox/mlx5/core/fpga/* F: include/linux/mlx5/mlx5_ifc_fpga.h -- GitLab From 4d995c1b9d49ee657e879745aa5e445f031c0dba Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Fri, 3 Jun 2022 14:33:03 -0700 Subject: [PATCH 380/942] Revert "net/mlx5e: Allow relaxed ordering over VFs" FW is not ready, fix was sent too soon. This reverts commit f05ec8d9d0d62367b6e1f2cb50d7d2a45e7747cf. Fixes: f05ec8d9d0d6 ("net/mlx5e: Allow relaxed ordering over VFs") Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 3 ++- drivers/net/ethernet/mellanox/mlx5/core/en_common.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c index 68364484a4354..3c1edfa33aa79 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c @@ -565,7 +565,8 @@ static void mlx5e_build_rx_cq_param(struct mlx5_core_dev *mdev, static u8 rq_end_pad_mode(struct mlx5_core_dev *mdev, struct mlx5e_params *params) { bool lro_en = params->packet_merge.type == MLX5E_PACKET_MERGE_LRO; - bool ro = MLX5_CAP_GEN(mdev, relaxed_ordering_write); + bool ro = pcie_relaxed_ordering_enabled(mdev->pdev) && + MLX5_CAP_GEN(mdev, relaxed_ordering_write); return ro && lro_en ? MLX5_WQ_END_PAD_MODE_NONE : MLX5_WQ_END_PAD_MODE_ALIGN; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c index 43a536cb81db3..c0f409c195bf8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c @@ -38,11 +38,12 @@ void mlx5e_mkey_set_relaxed_ordering(struct mlx5_core_dev *mdev, void *mkc) { + bool ro_pci_enable = pcie_relaxed_ordering_enabled(mdev->pdev); bool ro_write = MLX5_CAP_GEN(mdev, relaxed_ordering_write); bool ro_read = MLX5_CAP_GEN(mdev, relaxed_ordering_read); - MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_read); - MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_write); + MLX5_SET(mkc, mkc, relaxed_ordering_read, ro_pci_enable && ro_read); + MLX5_SET(mkc, mkc, relaxed_ordering_write, ro_pci_enable && ro_write); } static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, -- GitLab From 15ef9efa855cf405fadd78272e1e5d04e09a1cf3 Mon Sep 17 00:00:00 2001 From: Paul Blakey Date: Tue, 29 Mar 2022 18:37:18 +0300 Subject: [PATCH 381/942] net/mlx5e: CT: Fix cleanup of CT before cleanup of TC ct rules CT cleanup assumes that all tc rules were deleted first, and so is free to delete the CT shared resources (e.g the dr_action fwd_action which is shared for all tuples). But currently for uplink, this is happens in reverse, causing the below trace. CT cleanup is called from: mlx5e_cleanup_rep_tx()->mlx5e_cleanup_uplink_rep_tx()-> mlx5e_rep_tc_cleanup()->mlx5e_tc_esw_cleanup()-> mlx5_tc_ct_clean() Only afterwards, tc cleanup is called from: mlx5e_cleanup_rep_tx()->mlx5e_tc_ht_cleanup() which would have deleted all the tc ct rules, and so delete all the offloaded tuples. Fix this reversing the order of init and on cleanup, which will result in tc cleanup then ct cleanup. [ 9443.593347] WARNING: CPU: 2 PID: 206774 at drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c:1882 mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593349] Modules linked in: act_ct nf_flow_table rdma_ucm(O) rdma_cm(O) iw_cm(O) ib_ipoib(O) ib_cm(O) ib_umad(O) mlx5_core(O-) mlxfw(O) mlxdevm(O) auxiliary(O) ib_uverbs(O) psample ib_core(O) mlx_compat(O) ip_gre gre ip_tunnel act_vlan bonding geneve esp6_offload esp6 esp4_offload esp4 act_tunnel_key vxlan ip6_udp_tunnel udp_tunnel act_mirred act_skbedit act_gact cls_flower sch_ingress nfnetlink_cttimeout nfnetlink xfrm_user xfrm_algo 8021q garp stp ipmi_devintf mrp ipmi_msghandler llc openvswitch nsh nf_conncount nf_nat mst_pciconf(O) dm_multipath sbsa_gwdt uio_pdrv_genirq uio mlxbf_pmc mlxbf_pka mlx_trio mlx_bootctl(O) bluefield_edac sch_fq_codel ip_tables ipv6 crc_ccitt btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor xor_neon raid6_pq raid1 raid0 crct10dif_ce i2c_mlxbf gpio_mlxbf2 mlxbf_gige aes_neon_bs aes_neon_blk [last unloaded: mlx5_ib] [ 9443.593419] CPU: 2 PID: 206774 Comm: modprobe Tainted: G O 5.4.0-1023.24.gc14613d-bluefield #1 [ 9443.593422] Hardware name: https://www.mellanox.com BlueField SoC/BlueField SoC, BIOS BlueField:143ebaf Jan 11 2022 [ 9443.593424] pstate: 20000005 (nzCv daif -PAN -UAO) [ 9443.593489] pc : mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593545] lr : mlx5_ct_fs_smfs_destroy+0x24/0x30 [mlx5_core] [ 9443.593546] sp : ffff8000135dbab0 [ 9443.593548] x29: ffff8000135dbab0 x28: ffff0003a6ab8e80 [ 9443.593550] x27: 0000000000000000 x26: ffff0003e07d7000 [ 9443.593552] x25: ffff800009609de0 x24: ffff000397fb2120 [ 9443.593554] x23: ffff0003975c0000 x22: 0000000000000000 [ 9443.593556] x21: ffff0003975f08c0 x20: ffff800009609de0 [ 9443.593558] x19: ffff0003c8a13380 x18: 0000000000000014 [ 9443.593560] x17: 0000000067f5f125 x16: 000000006529c620 [ 9443.593561] x15: 000000000000000b x14: 0000000000000000 [ 9443.593563] x13: 0000000000000002 x12: 0000000000000001 [ 9443.593565] x11: ffff800011108868 x10: 0000000000000000 [ 9443.593567] x9 : 0000000000000000 x8 : ffff8000117fb270 [ 9443.593569] x7 : ffff0003ebc01288 x6 : 0000000000000000 [ 9443.593571] x5 : ffff800009591ab8 x4 : fffffe000f6d9a20 [ 9443.593572] x3 : 0000000080040001 x2 : fffffe000f6d9a20 [ 9443.593574] x1 : ffff8000095901d8 x0 : 0000000000000025 [ 9443.593577] Call trace: [ 9443.593634] mlx5dr_action_destroy+0x188/0x1a0 [mlx5_core] [ 9443.593688] mlx5_ct_fs_smfs_destroy+0x24/0x30 [mlx5_core] [ 9443.593743] mlx5_tc_ct_clean+0x34/0xa8 [mlx5_core] [ 9443.593797] mlx5e_tc_esw_cleanup+0x58/0x88 [mlx5_core] [ 9443.593851] mlx5e_rep_tc_cleanup+0x24/0x30 [mlx5_core] [ 9443.593905] mlx5e_cleanup_rep_tx+0x6c/0x78 [mlx5_core] [ 9443.593959] mlx5e_detach_netdev+0x74/0x98 [mlx5_core] [ 9443.594013] mlx5e_netdev_change_profile+0x70/0x180 [mlx5_core] [ 9443.594067] mlx5e_netdev_attach_nic_profile+0x34/0x40 [mlx5_core] [ 9443.594122] mlx5e_vport_rep_unload+0x15c/0x1a8 [mlx5_core] [ 9443.594177] mlx5_eswitch_unregister_vport_reps+0x228/0x298 [mlx5_core] [ 9443.594231] mlx5e_rep_remove+0x2c/0x38 [mlx5_core] [ 9443.594236] auxiliary_bus_remove+0x30/0x50 [auxiliary] [ 9443.594246] device_release_driver_internal+0x108/0x1d0 [ 9443.594248] driver_detach+0x5c/0xe8 [ 9443.594250] bus_remove_driver+0x64/0xd8 [ 9443.594253] driver_unregister+0x38/0x60 [ 9443.594255] auxiliary_driver_unregister+0x24/0x38 [auxiliary] [ 9443.594311] mlx5e_rep_cleanup+0x20/0x38 [mlx5_core] [ 9443.594365] mlx5e_cleanup+0x18/0x30 [mlx5_core] [ 9443.594419] cleanup+0xc/0x20cc [mlx5_core] [ 9443.594424] __arm64_sys_delete_module+0x154/0x2b0 [ 9443.594429] el0_svc_common.constprop.0+0xf4/0x200 [ 9443.594432] el0_svc_handler+0x38/0xa8 [ 9443.594435] el0_svc+0x10/0x26c Fixes: d1a3138f7913 ("net/mlx5e: TC, Move flow hashtable to be per rep") Signed-off-by: Paul Blakey Reviewed-by: Oz Shlomo Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_rep.c | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index eb90e79388f19..f797fd97d305b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -950,6 +950,13 @@ static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv) return err; } +static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv) +{ + mlx5e_rep_tc_netdevice_event_unregister(rpriv); + mlx5e_rep_bond_cleanup(rpriv); + mlx5e_rep_tc_cleanup(rpriv); +} + static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) { struct mlx5e_rep_priv *rpriv = priv->ppriv; @@ -961,42 +968,36 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv) return err; } - err = mlx5e_tc_ht_init(&rpriv->tc_ht); - if (err) - goto err_ht_init; - if (rpriv->rep->vport == MLX5_VPORT_UPLINK) { err = mlx5e_init_uplink_rep_tx(rpriv); if (err) goto err_init_tx; } + err = mlx5e_tc_ht_init(&rpriv->tc_ht); + if (err) + goto err_ht_init; + return 0; -err_init_tx: - mlx5e_tc_ht_cleanup(&rpriv->tc_ht); err_ht_init: + if (rpriv->rep->vport == MLX5_VPORT_UPLINK) + mlx5e_cleanup_uplink_rep_tx(rpriv); +err_init_tx: mlx5e_destroy_tises(priv); return err; } -static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv) -{ - mlx5e_rep_tc_netdevice_event_unregister(rpriv); - mlx5e_rep_bond_cleanup(rpriv); - mlx5e_rep_tc_cleanup(rpriv); -} - static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv) { struct mlx5e_rep_priv *rpriv = priv->ppriv; - mlx5e_destroy_tises(priv); + mlx5e_tc_ht_cleanup(&rpriv->tc_ht); if (rpriv->rep->vport == MLX5_VPORT_UPLINK) mlx5e_cleanup_uplink_rep_tx(rpriv); - mlx5e_tc_ht_cleanup(&rpriv->tc_ht); + mlx5e_destroy_tises(priv); } static void mlx5e_rep_enable(struct mlx5e_priv *priv) -- GitLab From 3008e6a0049361e731b803c60fe8f3ab44e1d73f Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Thu, 26 May 2022 08:15:28 +0300 Subject: [PATCH 382/942] net/mlx5: E-Switch, pair only capable devices OFFLOADS paring using devcom is possible only on devices that support LAG. Filter based on lag capabilities. This fixes an issue where mlx5_get_next_phys_dev() was called without holding the interface lock. This issue was found when commit bc4c2f2e0179 ("net/mlx5: Lag, filter non compatible devices") added an assert that verifies the interface lock is held. WARNING: CPU: 9 PID: 1706 at drivers/net/ethernet/mellanox/mlx5/core/dev.c:642 mlx5_get_next_phys_dev+0xd2/0x100 [mlx5_core] Modules linked in: mlx5_vdpa vringh vhost_iotlb vdpa mlx5_ib mlx5_core xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi rdma_cm iw_cm ib_umad ib_ipoib ib_cm ib_uverbs ib_core overlay fuse [last unloaded: mlx5_core] CPU: 9 PID: 1706 Comm: devlink Not tainted 5.18.0-rc7+ #11 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:mlx5_get_next_phys_dev+0xd2/0x100 [mlx5_core] Code: 02 00 75 48 48 8b 85 80 04 00 00 5d c3 31 c0 5d c3 be ff ff ff ff 48 c7 c7 08 41 5b a0 e8 36 87 28 e3 85 c0 0f 85 6f ff ff ff <0f> 0b e9 68 ff ff ff 48 c7 c7 0c 91 cc 84 e8 cb 36 6f e1 e9 4d ff RSP: 0018:ffff88811bf47458 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff88811b398000 RCX: 0000000000000001 RDX: 0000000080000000 RSI: ffffffffa05b4108 RDI: ffff88812daaaa78 RBP: ffff88812d050380 R08: 0000000000000001 R09: ffff88811d6b3437 R10: 0000000000000001 R11: 00000000fddd3581 R12: ffff88815238c000 R13: ffff88812d050380 R14: ffff8881018aa7e0 R15: ffff88811d6b3428 FS: 00007fc82e18ae80(0000) GS:ffff88842e080000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f9630d1b421 CR3: 0000000149802004 CR4: 0000000000370ea0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: mlx5_esw_offloads_devcom_event+0x99/0x3b0 [mlx5_core] mlx5_devcom_send_event+0x167/0x1d0 [mlx5_core] esw_offloads_enable+0x1153/0x1500 [mlx5_core] ? mlx5_esw_offloads_controller_valid+0x170/0x170 [mlx5_core] ? wait_for_completion_io_timeout+0x20/0x20 ? mlx5_rescan_drivers_locked+0x318/0x810 [mlx5_core] mlx5_eswitch_enable_locked+0x586/0xc50 [mlx5_core] ? mlx5_eswitch_disable_pf_vf_vports+0x1d0/0x1d0 [mlx5_core] ? mlx5_esw_try_lock+0x1b/0xb0 [mlx5_core] ? mlx5_eswitch_enable+0x270/0x270 [mlx5_core] ? __debugfs_create_file+0x260/0x3e0 mlx5_devlink_eswitch_mode_set+0x27e/0x870 [mlx5_core] ? mutex_lock_io_nested+0x12c0/0x12c0 ? esw_offloads_disable+0x250/0x250 [mlx5_core] ? devlink_nl_cmd_trap_get_dumpit+0x470/0x470 ? rcu_read_lock_sched_held+0x3f/0x70 devlink_nl_cmd_eswitch_set_doit+0x217/0x620 Fixes: dd3fddb82780 ("net/mlx5: E-Switch, handle devcom events only for ports on the same device") Signed-off-by: Mark Bloch Reviewed-by: Roi Dayan Reviewed-by: Moshe Shemesh Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 18 ------------------ .../mellanox/mlx5/core/eswitch_offloads.c | 9 ++++++--- .../net/ethernet/mellanox/mlx5/core/lag/lag.h | 10 ++++++++++ .../ethernet/mellanox/mlx5/core/mlx5_core.h | 1 - 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index 0eb9d74547f85..50422b56a64de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -579,17 +579,6 @@ static void *pci_get_other_drvdata(struct device *this, struct device *other) return pci_get_drvdata(to_pci_dev(other)); } -static int next_phys_dev(struct device *dev, const void *data) -{ - struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data; - - mdev = pci_get_other_drvdata(this->device, dev); - if (!mdev) - return 0; - - return _next_phys_dev(mdev, data); -} - static int next_phys_dev_lag(struct device *dev, const void *data) { struct mlx5_core_dev *mdev, *this = (struct mlx5_core_dev *)data; @@ -623,13 +612,6 @@ static struct mlx5_core_dev *mlx5_get_next_dev(struct mlx5_core_dev *dev, return pci_get_drvdata(to_pci_dev(next)); } -/* Must be called with intf_mutex held */ -struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev) -{ - lockdep_assert_held(&mlx5_intf_mutex); - return mlx5_get_next_dev(dev, &next_phys_dev); -} - /* Must be called with intf_mutex held */ struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 217cac29057fc..2ce3728576d1a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -2690,9 +2690,6 @@ static int mlx5_esw_offloads_devcom_event(int event, switch (event) { case ESW_OFFLOADS_DEVCOM_PAIR: - if (mlx5_get_next_phys_dev(esw->dev) != peer_esw->dev) - break; - if (mlx5_eswitch_vport_match_metadata_enabled(esw) != mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) break; @@ -2744,6 +2741,9 @@ static void esw_offloads_devcom_init(struct mlx5_eswitch *esw) if (!MLX5_CAP_ESW(esw->dev, merged_eswitch)) return; + if (!mlx5_is_lag_supported(esw->dev)) + return; + mlx5_devcom_register_component(devcom, MLX5_DEVCOM_ESW_OFFLOADS, mlx5_esw_offloads_devcom_event, @@ -2761,6 +2761,9 @@ static void esw_offloads_devcom_cleanup(struct mlx5_eswitch *esw) if (!MLX5_CAP_ESW(esw->dev, merged_eswitch)) return; + if (!mlx5_is_lag_supported(esw->dev)) + return; + mlx5_devcom_send_event(devcom, MLX5_DEVCOM_ESW_OFFLOADS, ESW_OFFLOADS_DEVCOM_UNPAIR, esw); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h index 72f70fad46415..c81b173156d28 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h @@ -74,6 +74,16 @@ struct mlx5_lag { struct lag_mpesw lag_mpesw; }; +static inline bool mlx5_is_lag_supported(struct mlx5_core_dev *dev) +{ + if (!MLX5_CAP_GEN(dev, vport_group_manager) || + !MLX5_CAP_GEN(dev, lag_master) || + MLX5_CAP_GEN(dev, num_lag_ports) < 2 || + MLX5_CAP_GEN(dev, num_lag_ports) > MLX5_MAX_PORTS) + return false; + return true; +} + static inline struct mlx5_lag * mlx5_lag_dev(struct mlx5_core_dev *dev) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index 484cb1e4fc7f6..9cc7afea2758f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h @@ -209,7 +209,6 @@ int mlx5_attach_device(struct mlx5_core_dev *dev); void mlx5_detach_device(struct mlx5_core_dev *dev); int mlx5_register_device(struct mlx5_core_dev *dev); void mlx5_unregister_device(struct mlx5_core_dev *dev); -struct mlx5_core_dev *mlx5_get_next_phys_dev(struct mlx5_core_dev *dev); struct mlx5_core_dev *mlx5_get_next_phys_dev_lag(struct mlx5_core_dev *dev); void mlx5_dev_list_lock(void); void mlx5_dev_list_unlock(void); -- GitLab From 8bf94e6414c9481bfa28269022688ab445d0081d Mon Sep 17 00:00:00 2001 From: Feras Daoud Date: Sat, 19 Mar 2022 21:47:48 +0200 Subject: [PATCH 383/942] net/mlx5: Rearm the FW tracer after each tracer event The current design does not arm the tracer if traces are available before the tracer string database is fully loaded, leading to an unfunctional tracer. This fix will rearm the tracer every time the FW triggers tracer event regardless of the tracer strings database status. Fixes: c71ad41ccb0c ("net/mlx5: FW tracer, events handling") Signed-off-by: Feras Daoud Signed-off-by: Roy Novich Reviewed-by: Moshe Shemesh Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index eae9aa9c08118..978a2bb8e1220 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -675,6 +675,9 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work) if (!tracer->owner) return; + if (unlikely(!tracer->str_db.loaded)) + goto arm; + block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE; start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE; @@ -732,6 +735,7 @@ static void mlx5_fw_tracer_handle_traces(struct work_struct *work) &tmp_trace_block[TRACES_PER_BLOCK - 1]); } +arm: mlx5_fw_tracer_arm(dev); } @@ -1136,8 +1140,7 @@ static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void queue_work(tracer->work_queue, &tracer->ownership_change_work); break; case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE: - if (likely(tracer->str_db.loaded)) - queue_work(tracer->work_queue, &tracer->handle_traces_work); + queue_work(tracer->work_queue, &tracer->handle_traces_work); break; default: mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n", -- GitLab From 8fa5e7b20e01042b14f8cd684d2da9b638460c74 Mon Sep 17 00:00:00 2001 From: Mark Bloch Date: Mon, 30 May 2022 10:46:59 +0300 Subject: [PATCH 384/942] net/mlx5: fs, fail conflicting actions When combining two steering rules into one check not only do they share the same actions but those actions are also the same. This resolves an issue where when creating two different rules with the same match the actions are overwritten and one of the rules is deleted a FW syndrome can be seen in dmesg. mlx5_core 0000:03:00.0: mlx5_cmd_check:819:(pid 2105): DEALLOC_MODIFY_HEADER_CONTEXT(0x941) op_mod(0x0) failed, status bad resource state(0x9), syndrome (0x1ab444) Fixes: 0d235c3fabb7 ("net/mlx5: Add hash table to search FTEs in a flow-group") Signed-off-by: Mark Bloch Reviewed-by: Maor Gottlieb Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/fs_core.c | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index fdcf7f529330a..21e5c709b2d30 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1574,9 +1574,22 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte, return NULL; } -static bool check_conflicting_actions(u32 action1, u32 action2) +static bool check_conflicting_actions_vlan(const struct mlx5_fs_vlan *vlan0, + const struct mlx5_fs_vlan *vlan1) { - u32 xored_actions = action1 ^ action2; + return vlan0->ethtype != vlan1->ethtype || + vlan0->vid != vlan1->vid || + vlan0->prio != vlan1->prio; +} + +static bool check_conflicting_actions(const struct mlx5_flow_act *act1, + const struct mlx5_flow_act *act2) +{ + u32 action1 = act1->action; + u32 action2 = act2->action; + u32 xored_actions; + + xored_actions = action1 ^ action2; /* if one rule only wants to count, it's ok */ if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT || @@ -1593,6 +1606,22 @@ static bool check_conflicting_actions(u32 action1, u32 action2) MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2)) return true; + if (action1 & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT && + act1->pkt_reformat != act2->pkt_reformat) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && + act1->modify_hdr != act2->modify_hdr) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH && + check_conflicting_actions_vlan(&act1->vlan[0], &act2->vlan[0])) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 && + check_conflicting_actions_vlan(&act1->vlan[1], &act2->vlan[1])) + return true; + return false; } @@ -1600,7 +1629,7 @@ static int check_conflicting_ftes(struct fs_fte *fte, const struct mlx5_flow_context *flow_context, const struct mlx5_flow_act *flow_act) { - if (check_conflicting_actions(flow_act->action, fte->action.action)) { + if (check_conflicting_actions(flow_act, &fte->action)) { mlx5_core_warn(get_dev(&fte->node), "Found two FTEs with conflicting actions\n"); return -EEXIST; -- GitLab From 431d071286524bd4f9ba2e46b1be87b479220174 Mon Sep 17 00:00:00 2001 From: Yifan Zhang Date: Fri, 3 Jun 2022 10:24:31 +0800 Subject: [PATCH 385/942] drm/amdgpu/mes: only invalid/prime icache when finish loading both pipe MES FWs. invalid/prime icahce operation takes effect both pipes cuconrrently, therefore CP_MES_IC_BASE_LO/HI and CP_MES_MDBASE_LO/HI both have to be set before prime icache. Otherwise MES hardware gets garbage data in above regsters and causes page fault [ 470.873200] amdgpu 0000:33:00.0: amdgpu: [gfxhub] page fault (src_id:0 ring:217 vmid:0 pasid:0, for process pid 0 thread pid 0) [ 470.873222] amdgpu 0000:33:00.0: amdgpu: in page starting at address 0x000092cb89b00000 from client 10 [ 470.873234] amdgpu 0000:33:00.0: amdgpu: GCVM_L2_PROTECTION_FAULT_STATUS:0x00000BB3 [ 470.873242] amdgpu 0000:33:00.0: amdgpu: Faulty UTCL2 client ID: CPC (0x5) [ 470.873247] amdgpu 0000:33:00.0: amdgpu: MORE_FAULTS: 0x1 [ 470.873251] amdgpu 0000:33:00.0: amdgpu: WALKER_ERROR: 0x1 [ 470.873256] amdgpu 0000:33:00.0: amdgpu: PERMISSION_FAULTS: 0xb [ 470.873260] amdgpu 0000:33:00.0: amdgpu: MAPPING_ERROR: 0x1 [ 470.873264] amdgpu 0000:33:00.0: amdgpu: RW: 0x0 Signed-off-by: Yifan Zhang Acked-by: Alex Deucher Reviewed-by: Tim Huang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 36 ++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index fcf51947bb186..7eee004cf3ce3 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -541,7 +541,7 @@ static void mes_v11_0_enable(struct amdgpu_device *adev, bool enable) /* This function is for backdoor MES firmware */ static int mes_v11_0_load_microcode(struct amdgpu_device *adev, - enum admgpu_mes_pipe pipe) + enum admgpu_mes_pipe pipe, bool prime_icache) { int r; uint32_t data; @@ -593,16 +593,18 @@ static int mes_v11_0_load_microcode(struct amdgpu_device *adev, /* Set 0x3FFFF (256K-1) to CP_MES_MDBOUND_LO */ WREG32_SOC15(GC, 0, regCP_MES_MDBOUND_LO, 0x3FFFF); - /* invalidate ICACHE */ - data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); - data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 0); - data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, INVALIDATE_CACHE, 1); - WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); - - /* prime the ICACHE. */ - data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); - data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 1); - WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); + if (prime_icache) { + /* invalidate ICACHE */ + data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 0); + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, INVALIDATE_CACHE, 1); + WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); + + /* prime the ICACHE. */ + data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 1); + WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); + } soc21_grbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); @@ -1044,17 +1046,19 @@ static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev) int r = 0; if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { - r = mes_v11_0_load_microcode(adev, AMDGPU_MES_KIQ_PIPE); + + r = mes_v11_0_load_microcode(adev, AMDGPU_MES_SCHED_PIPE, false); if (r) { - DRM_ERROR("failed to load MES kiq fw, r=%d\n", r); + DRM_ERROR("failed to load MES fw, r=%d\n", r); return r; } - r = mes_v11_0_load_microcode(adev, AMDGPU_MES_SCHED_PIPE); + r = mes_v11_0_load_microcode(adev, AMDGPU_MES_KIQ_PIPE, true); if (r) { - DRM_ERROR("failed to load MES fw, r=%d\n", r); + DRM_ERROR("failed to load MES kiq fw, r=%d\n", r); return r; } + } mes_v11_0_enable(adev, true); @@ -1086,7 +1090,7 @@ static int mes_v11_0_hw_init(void *handle) if (!adev->enable_mes_kiq) { if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { r = mes_v11_0_load_microcode(adev, - AMDGPU_MES_SCHED_PIPE); + AMDGPU_MES_SCHED_PIPE, true); if (r) { DRM_ERROR("failed to MES fw, r=%d\n", r); return r; -- GitLab From 6bfb56e93bcef41859c2d5ab234ffd80b691be35 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Jun 2022 13:18:39 -0700 Subject: [PATCH 386/942] cert host tools: Stop complaining about deprecated OpenSSL functions OpenSSL 3.0 deprecated the OpenSSL's ENGINE API. That is as may be, but the kernel build host tools still use it. Disable the warning about deprecated declarations until somebody who cares fixes it. Signed-off-by: Linus Torvalds --- certs/extract-cert.c | 7 +++++++ scripts/sign-file.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/certs/extract-cert.c b/certs/extract-cert.c index f7ef7862f207c..8c1fb9a70d66b 100644 --- a/certs/extract-cert.c +++ b/certs/extract-cert.c @@ -23,6 +23,13 @@ #include #include +/* + * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. + * + * Remove this if/when that API is no longer used + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #define PKEY_ID_PKCS7 2 static __attribute__((noreturn)) diff --git a/scripts/sign-file.c b/scripts/sign-file.c index fbd34b8e8f578..7434e9ea926e2 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -29,6 +29,13 @@ #include #include +/* + * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API. + * + * Remove this if/when that API is no longer used + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + /* * Use CMS if we have openssl-1.0.0 or newer available - otherwise we have to * assume that it's not available and its header file is missing and that we -- GitLab From 72aad489f992871e908ff6d9055b26c6366fb864 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 8 Jun 2022 22:51:07 +0300 Subject: [PATCH 387/942] ata: libata-transport: fix {dma|pio|xfer}_mode sysfs files The {dma|pio}_mode sysfs files are incorrectly documented as having a list of the supported DMA/PIO transfer modes, while the corresponding fields of the *struct* ata_device hold the transfer mode IDs, not masks. To match these docs, the {dma|pio}_mode (and even xfer_mode!) sysfs files are handled by the ata_bitfield_name_match() macro which leads to reading such kind of nonsense from them: $ cat /sys/class/ata_device/dev3.0/pio_mode XFER_UDMA_7, XFER_UDMA_6, XFER_UDMA_5, XFER_UDMA_4, XFER_MW_DMA_4, XFER_PIO_6, XFER_PIO_5, XFER_PIO_4, XFER_PIO_3, XFER_PIO_2, XFER_PIO_1, XFER_PIO_0 Using the correct ata_bitfield_name_search() macro fixes that: $ cat /sys/class/ata_device/dev3.0/pio_mode XFER_PIO_4 While fixing the file documentation, somewhat reword the {dma|pio}_mode file doc and add a note about being mostly useful for PATA devices to the xfer_mode file doc... Fixes: d9027470b886 ("[libata] Add ATA transport class") Signed-off-by: Sergey Shtylyov Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal --- Documentation/ABI/testing/sysfs-ata | 11 ++++++----- drivers/ata/libata-transport.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-ata b/Documentation/ABI/testing/sysfs-ata index 2f726c9147522..3daecac48964f 100644 --- a/Documentation/ABI/testing/sysfs-ata +++ b/Documentation/ABI/testing/sysfs-ata @@ -107,13 +107,14 @@ Description: described in ATA8 7.16 and 7.17. Only valid if the device is not a PM. - pio_mode: (RO) Transfer modes supported by the device when - in PIO mode. Mostly used by PATA device. + pio_mode: (RO) PIO transfer mode used by the device. + Mostly used by PATA devices. - xfer_mode: (RO) Current transfer mode + xfer_mode: (RO) Current transfer mode. Mostly used by + PATA devices. - dma_mode: (RO) Transfer modes supported by the device when - in DMA mode. Mostly used by PATA device. + dma_mode: (RO) DMA transfer mode used by the device. + Mostly used by PATA devices. class: (RO) Device class. Can be "ata" for disk, "atapi" for packet device, "pmp" for PM, or diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index ca129854a88c7..c380278874990 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -196,7 +196,7 @@ static struct { { XFER_PIO_0, "XFER_PIO_0" }, { XFER_PIO_SLOW, "XFER_PIO_SLOW" } }; -ata_bitfield_name_match(xfer,ata_xfer_names) +ata_bitfield_name_search(xfer, ata_xfer_names) /* * ATA Port attributes -- GitLab From 481f7017c37a8c722a0b09985db1a35f15749d5d Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 8 Jun 2022 23:37:09 +0300 Subject: [PATCH 388/942] MAINTAINERS: add ATA sysfs file documentation to libata entry Add the (still missing!) ATA sysfs file documentation to the libata subsystem entry in the MAINTAINERS file. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d0..7b14ba508b68b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11257,6 +11257,7 @@ M: Damien Le Moal L: linux-ide@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git +F: Documentation/ABI/testing/sysfs-ata F: Documentation/devicetree/bindings/ata/ F: drivers/ata/ F: include/linux/ata.h -- GitLab From 8d21e9963bec1aad2280cdd034c8993033ef2948 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Mon, 6 Jun 2022 09:21:07 -0400 Subject: [PATCH 389/942] ip_gre: test csum_start instead of transport header GRE with TUNNEL_CSUM will apply local checksum offload on CHECKSUM_PARTIAL packets. ipgre_xmit must validate csum_start after an optional skb_pull, else lco_csum may trigger an overflow. The original check was if (csum && skb_checksum_start(skb) < skb->data) return -EINVAL; This had false positives when skb_checksum_start is undefined: when ip_summed is not CHECKSUM_PARTIAL. A discussed refinement was straightforward if (csum && skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_start(skb) < skb->data) return -EINVAL; But was eventually revised more thoroughly: - restrict the check to the only branch where needed, in an uncommon GRE path that uses header_ops and calls skb_pull. - test skb_transport_header, which is set along with csum_start in skb_partial_csum_set in the normal header_ops datapath. Turns out skbs can arrive in this branch without the transport header set, e.g., through BPF redirection. Revise the check back to check csum_start directly, and only if CHECKSUM_PARTIAL. Do leave the check in the updated location. Check field regardless of whether TUNNEL_CSUM is configured. Link: https://lore.kernel.org/netdev/YS+h%2FtqCJJiQei+W@shredder/ Link: https://lore.kernel.org/all/20210902193447.94039-2-willemdebruijn.kernel@gmail.com/T/#u Fixes: 8a0ed250f911 ("ip_gre: validate csum_start only on pull") Reported-by: syzbot Signed-off-by: Willem de Bruijn Reviewed-by: Eric Dumazet Reviewed-by: Alexander Duyck Link: https://lore.kernel.org/r/20220606132107.3582565-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski --- net/ipv4/ip_gre.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 7e474a85deaf5..3b9cd487075af 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -629,21 +629,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb, } if (dev->header_ops) { - const int pull_len = tunnel->hlen + sizeof(struct iphdr); - if (skb_cow_head(skb, 0)) goto free_skb; tnl_params = (const struct iphdr *)skb->data; - if (pull_len > skb_transport_offset(skb)) - goto free_skb; - /* Pull skb since ip_tunnel_xmit() needs skb->data pointing * to gre header. */ - skb_pull(skb, pull_len); + skb_pull(skb, tunnel->hlen + sizeof(struct iphdr)); skb_reset_mac_header(skb); + + if (skb->ip_summed == CHECKSUM_PARTIAL && + skb_checksum_start(skb) < skb->data) + goto free_skb; } else { if (skb_cow_head(skb, dev->needed_headroom)) goto free_skb; -- GitLab From 2f2c0d2919a14002760f89f4e02960c735a316d2 Mon Sep 17 00:00:00 2001 From: Chen Lin Date: Wed, 8 Jun 2022 20:46:53 +0800 Subject: [PATCH 390/942] net: ethernet: mtk_eth_soc: fix misuse of mem alloc interface netdev[napi]_alloc_frag When rx_flag == MTK_RX_FLAGS_HWLRO, rx_data_len = MTK_MAX_LRO_RX_LENGTH(4096 * 3) > PAGE_SIZE. netdev_alloc_frag is for alloction of page fragment only. Reference to other drivers and Documentation/vm/page_frags.rst Branch to use __get_free_pages when ring->frag_size > PAGE_SIZE. Signed-off-by: Chen Lin Link: https://lore.kernel.org/r/1654692413-2598-1-git-send-email-chen45464546@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index b3b3c079a0faf..59c9a10f83ba5 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -899,6 +899,17 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd, return true; } +static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask) +{ + unsigned int size = mtk_max_frag_size(MTK_MAX_LRO_RX_LENGTH); + unsigned long data; + + data = __get_free_pages(gfp_mask | __GFP_COMP | __GFP_NOWARN, + get_order(size)); + + return (void *)data; +} + /* the qdma core needs scratch memory to be setup */ static int mtk_init_fq_dma(struct mtk_eth *eth) { @@ -1467,7 +1478,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, goto release_desc; /* alloc new buffer */ - new_data = napi_alloc_frag(ring->frag_size); + if (ring->frag_size <= PAGE_SIZE) + new_data = napi_alloc_frag(ring->frag_size); + else + new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); if (unlikely(!new_data)) { netdev->stats.rx_dropped++; goto release_desc; @@ -1914,7 +1928,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) return -ENOMEM; for (i = 0; i < rx_dma_size; i++) { - ring->data[i] = netdev_alloc_frag(ring->frag_size); + if (ring->frag_size <= PAGE_SIZE) + ring->data[i] = netdev_alloc_frag(ring->frag_size); + else + ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL); if (!ring->data[i]) return -ENOMEM; } -- GitLab From 2061ecfdf2350994e5b61c43e50e98a7a70e95ee Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Tue, 7 Jun 2022 00:11:40 +0200 Subject: [PATCH 391/942] net: openvswitch: fix misuse of the cached connection on tuple changes If packet headers changed, the cached nfct is no longer relevant for the packet and attempt to re-use it leads to the incorrect packet classification. This issue is causing broken connectivity in OpenStack deployments with OVS/OVN due to hairpin traffic being unexpectedly dropped. The setup has datapath flows with several conntrack actions and tuple changes between them: actions:ct(commit,zone=8,mark=0/0x1,nat(src)), set(eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:06)), set(ipv4(src=172.18.2.10,dst=192.168.100.6,ttl=62)), ct(zone=8),recirc(0x4) After the first ct() action the packet headers are almost fully re-written. The next ct() tries to re-use the existing nfct entry and marks the packet as invalid, so it gets dropped later in the pipeline. Clearing the cached conntrack entry whenever packet tuple is changed to avoid the issue. The flow key should not be cleared though, because we should still be able to match on the ct_state if the recirculation happens after the tuple change but before the next ct() action. Cc: stable@vger.kernel.org Fixes: 7f8a436eaa2c ("openvswitch: Add conntrack action") Reported-by: Frode Nordahl Link: https://mail.openvswitch.org/pipermail/ovs-discuss/2022-May/051829.html Link: https://bugs.launchpad.net/ubuntu/+source/ovn/+bug/1967856 Signed-off-by: Ilya Maximets Link: https://lore.kernel.org/r/20220606221140.488984-1-i.maximets@ovn.org Signed-off-by: Jakub Kicinski --- net/openvswitch/actions.c | 6 ++++++ net/openvswitch/conntrack.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 1b5d73079dc9b..868db4669a291 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -373,6 +373,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, update_ip_l4_checksum(skb, nh, *addr, new_addr); csum_replace4(&nh->check, *addr, new_addr); skb_clear_hash(skb); + ovs_ct_clear(skb, NULL); *addr = new_addr; } @@ -420,6 +421,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto, update_ipv6_checksum(skb, l4_proto, addr, new_addr); skb_clear_hash(skb); + ovs_ct_clear(skb, NULL); memcpy(addr, new_addr, sizeof(__be32[4])); } @@ -660,6 +662,7 @@ static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key, static void set_tp_port(struct sk_buff *skb, __be16 *port, __be16 new_port, __sum16 *check) { + ovs_ct_clear(skb, NULL); inet_proto_csum_replace2(check, skb, *port, new_port, false); *port = new_port; } @@ -699,6 +702,7 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *flow_key, uh->dest = dst; flow_key->tp.src = src; flow_key->tp.dst = dst; + ovs_ct_clear(skb, NULL); } skb_clear_hash(skb); @@ -761,6 +765,8 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key, sh->checksum = old_csum ^ old_correct_csum ^ new_csum; skb_clear_hash(skb); + ovs_ct_clear(skb, NULL); + flow_key->tp.src = sh->source; flow_key->tp.dst = sh->dest; diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 4a947c13c813a..4e70df91d0f2a 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -1342,7 +1342,9 @@ int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key) nf_ct_put(ct); nf_ct_set(skb, NULL, IP_CT_UNTRACKED); - ovs_ct_fill_key(skb, key, false); + + if (key) + ovs_ct_fill_key(skb, key, false); return 0; } -- GitLab From 11ec18b1d8d92b9df307d31950dcba0b3dd7283c Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Tue, 7 Jun 2022 08:11:43 +0400 Subject: [PATCH 392/942] net: altera: Fix refcount leak in altera_tse_mdio_create Every iteration of for_each_child_of_node() decrements the reference count of the previous node. When break from a for_each_child_of_node() loop, we need to explicitly call of_node_put() on the child node when not need anymore. Add missing of_node_put() to avoid refcount leak. Fixes: bbd2190ce96d ("Altera TSE: Add main and header file for Altera Ethernet Driver") Signed-off-by: Miaoqian Lin Link: https://lore.kernel.org/r/20220607041144.7553-1-linmq006@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/altera/altera_tse_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index a3816264c35cb..8c5828582c21e 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -163,7 +163,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) mdio = mdiobus_alloc(); if (mdio == NULL) { netdev_err(dev, "Error allocating MDIO bus\n"); - return -ENOMEM; + ret = -ENOMEM; + goto put_node; } mdio->name = ALTERA_TSE_RESOURCE_NAME; @@ -180,6 +181,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) mdio->id); goto out_free_mdio; } + of_node_put(mdio_node); if (netif_msg_drv(priv)) netdev_info(dev, "MDIO bus %s: created\n", mdio->id); @@ -189,6 +191,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id) out_free_mdio: mdiobus_free(mdio); mdio = NULL; +put_node: + of_node_put(mdio_node); return ret; } -- GitLab From 47e96930d6e6106d5252e85b868d3c7e29296de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Tue, 7 Jun 2022 12:28:42 +0100 Subject: [PATCH 393/942] net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed") added the ability to link if AN was bypassed, and added filling of state->an_complete field, but set it to true if AN was enabled in BMCR, not when AN was reported complete in BMSR. This was done because for some reason, when I wanted to use BMSR value to infer an_complete, I was looking at BMSR_ANEGCAPABLE bit (which was always 1), instead of BMSR_ANEGCOMPLETE bit. Use BMSR_ANEGCOMPLETE for filling state->an_complete. Fixes: ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed") Signed-off-by: Marek Behún Signed-off-by: Russell King (Oracle) Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/serdes.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 7b37d45bc9fb5..1a19c5284f2cb 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -50,22 +50,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip, } static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, - u16 ctrl, u16 status, u16 lpa, + u16 bmsr, u16 lpa, u16 status, struct phylink_link_state *state) { state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) { /* The Spped and Duplex Resolved register is 1 if AN is enabled * and complete, or if AN is disabled. So with disabled AN we - * still get here on link up. But we want to set an_complete - * only if AN was enabled, thus we look at BMCR_ANENABLE. - * (According to 802.3-2008 section 22.2.4.2.10, we should be - * able to get this same value from BMSR_ANEGCAPABLE, but tests - * show that these Marvell PHYs don't conform to this part of - * the specificaion - BMSR_ANEGCAPABLE is simply always 1.) + * still get here on link up. */ - state->an_complete = !!(ctrl & BMCR_ANENABLE); state->duplex = status & MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ? DUPLEX_FULL : DUPLEX_HALF; @@ -191,12 +186,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, int lane, struct phylink_link_state *state) { - u16 lpa, status, ctrl; + u16 bmsr, lpa, status; int err; - err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl); + err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); if (err) { - dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); + dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); return err; } @@ -212,7 +207,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, return err; } - return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); + return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); } int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, @@ -918,13 +913,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, int port, int lane, struct phylink_link_state *state) { - u16 lpa, status, ctrl; + u16 bmsr, lpa, status; int err; err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS, - MV88E6390_SGMII_BMCR, &ctrl); + MV88E6390_SGMII_BMSR, &bmsr); if (err) { - dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err); + dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err); return err; } @@ -942,7 +937,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip, return err; } - return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state); + return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state); } static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip, -- GitLab From 2b4bb9cd9bcdbe1f791fec18a7c8728cb6989bf8 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Tue, 7 Jun 2022 12:28:47 +0100 Subject: [PATCH 394/942] net: dsa: mv88e6xxx: fix BMSR error to be consistent with others Other errors accessing the registers in mv88e6352_serdes_pcs_get_state() print "PHY " before the register name, except for the BMSR. Make this consistent with the other error messages. Signed-off-by: Russell King (Oracle) Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/serdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 1a19c5284f2cb..47bf87d530b09 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -191,7 +191,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr); if (err) { - dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err); + dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err); return err; } -- GitLab From b4d78731b34bd6bfd1bfedce26a55e3582b0bc14 Mon Sep 17 00:00:00 2001 From: "Russell King (Oracle)" Date: Tue, 7 Jun 2022 12:28:52 +0100 Subject: [PATCH 395/942] net: dsa: mv88e6xxx: correctly report serdes link failure Phylink wants to know if the link has dropped since the last time state was retrieved, and the BMSR gives us that. Read the BMSR and use it when deciding the link state. Fill in the an_complete member as well for the emulated PHY state. Signed-off-by: Russell King (Oracle) Signed-off-by: Jakub Kicinski --- drivers/net/dsa/mv88e6xxx/serdes.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 47bf87d530b09..d94150d8f3f47 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -53,6 +53,14 @@ static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, u16 bmsr, u16 lpa, u16 status, struct phylink_link_state *state) { + state->link = false; + + /* If the BMSR reports that the link had failed, report this to + * phylink. + */ + if (!(bmsr & BMSR_LSTATUS)) + return 0; + state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK); state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -- GitLab From 487994ff75880569d32504d7e70da8b3328e0693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Tue, 7 Jun 2022 20:46:24 +0200 Subject: [PATCH 396/942] net: dsa: realtek: rtl8365mb: fix GMII caps for ports with internal PHY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit a18e6521a7d9 ("net: phylink: handle NA interface mode in phylink_fwnode_phy_connect()"), phylib defaults to GMII when no phy-mode or phy-connection-type property is specified in a DSA port node of the device tree. The same commit caused a regression in rtl8365mb whereby phylink would fail to connect, because the driver did not advertise support for GMII for ports with internal PHY. It should be noted that the aforementioned regression is not because the blamed commit was incorrect: on the contrary, the blamed commit is correcting the previous behaviour whereby unspecified phy-mode would cause the internal interface mode to be PHY_INTERFACE_MODE_NA. The rtl8365mb driver only worked by accident before because it _did_ advertise support for PHY_INTERFACE_MODE_NA, despite NA being reserved for internal use by phylink. With one mistake fixed, the other was exposed. Commit a5dba0f207e5 ("net: dsa: rtl8365mb: add GMII as user port mode") then introduced implicit support for GMII mode on ports with internal PHY to allow a PHY connection for device trees where the phy-mode is not explicitly set to "internal". At this point everything was working OK again. Subsequently, commit 6ff6064605e9 ("net: dsa: realtek: convert to phylink_generic_validate()") broke this behaviour again by discarding the usage of rtl8365mb_phy_mode_supported() - where this GMII support was indicated - while switching to the new .phylink_get_caps API. With the new API, rtl8365mb_phy_mode_supported() is no longer needed. Remove it altogether and add back the GMII capability - this time to rtl8365mb_phylink_get_caps() - so that the above default behaviour works for ports with internal PHY again. Fixes: 6ff6064605e9 ("net: dsa: realtek: convert to phylink_generic_validate()") Signed-off-by: Alvin Šipraga Reviewed-by: Russell King (Oracle) Link: https://lore.kernel.org/r/20220607184624.417641-1-alvin@pqrs.dk Signed-off-by: Jakub Kicinski --- drivers/net/dsa/realtek/rtl8365mb.c | 38 +++++++---------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index 3bb42a9f236d2..769f672e91284 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -955,35 +955,21 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port, return 0; } -static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port, - phy_interface_t interface) -{ - int ext_int; - - ext_int = rtl8365mb_extint_port_map[port]; - - if (ext_int < 0 && - (interface == PHY_INTERFACE_MODE_NA || - interface == PHY_INTERFACE_MODE_INTERNAL || - interface == PHY_INTERFACE_MODE_GMII)) - /* Internal PHY */ - return true; - else if ((ext_int >= 1) && - phy_interface_mode_is_rgmii(interface)) - /* Extension MAC */ - return true; - - return false; -} - static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { - if (dsa_is_user_port(ds, port)) + if (dsa_is_user_port(ds, port)) { __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); - else if (dsa_is_cpu_port(ds, port)) + + /* GMII is the default interface mode for phylib, so + * we have to support it for ports with integrated PHY. + */ + __set_bit(PHY_INTERFACE_MODE_GMII, + config->supported_interfaces); + } else if (dsa_is_cpu_port(ds, port)) { phy_interface_set_rgmii(config->supported_interfaces); + } config->mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD; @@ -996,12 +982,6 @@ static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port, struct realtek_priv *priv = ds->priv; int ret; - if (!rtl8365mb_phy_mode_supported(ds, port, state->interface)) { - dev_err(priv->dev, "phy mode %s is unsupported on port %d\n", - phy_modes(state->interface), port); - return; - } - if (mode != MLO_AN_PHY && mode != MLO_AN_FIXED) { dev_err(priv->dev, "port %d supports only conventional PHY or fixed-link\n", -- GitLab From e67b72b90b7e19a4be4d9c29f3feea6f58ab43f8 Mon Sep 17 00:00:00 2001 From: Muchun Song Date: Tue, 7 Jun 2022 15:02:14 +0800 Subject: [PATCH 397/942] tcp: use alloc_large_system_hash() to allocate table_perturb In our server, there may be no high order (>= 6) memory since we reserve lots of HugeTLB pages when booting. Then the system panic. So use alloc_large_system_hash() to allocate table_perturb. Fixes: e9261476184b ("tcp: dynamically allocate the perturb table used by source ports") Signed-off-by: Muchun Song Reviewed-by: Eric Dumazet Link: https://lore.kernel.org/r/20220607070214.94443-1-songmuchun@bytedance.com Signed-off-by: Jakub Kicinski --- net/ipv4/inet_hashtables.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index e8de5e699b3f5..545f91b6cb5e7 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -1026,10 +1026,12 @@ void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name, init_hashinfo_lhash2(h); /* this one is used for source ports of outgoing connections */ - table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE, - sizeof(*table_perturb), GFP_KERNEL); - if (!table_perturb) - panic("TCP: failed to alloc table_perturb"); + table_perturb = alloc_large_system_hash("Table-perturb", + sizeof(*table_perturb), + INET_TABLE_PERTURB_SIZE, + 0, 0, NULL, NULL, + INET_TABLE_PERTURB_SIZE, + INET_TABLE_PERTURB_SIZE); } int inet_hashinfo2_init_mod(struct inet_hashinfo *h) -- GitLab From 647df0d41b6bd8f4987dde6e8d8d0aba5b082985 Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Tue, 7 Jun 2022 12:11:19 -0700 Subject: [PATCH 398/942] net: amd-xgbe: fix clang -Wformat warning see warning: | drivers/net/ethernet/amd/xgbe/xgbe-drv.c:2787:43: warning: format specifies | type 'unsigned short' but the argument has type 'int' [-Wformat] | netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto)); | ~~~~~~ ^~~~~~~~~~~~~~~~~~~ Variadic functions (printf-like) undergo default argument promotion. Documentation/core-api/printk-formats.rst specifically recommends using the promoted-to-type's format flag. Also, as per C11 6.3.1.1: (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf) `If an int can represent all values of the original type ..., the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.` Since the argument is a u16 it will get promoted to an int and thus it is most accurate to use the %x format specifier here. It should be noted that the `#06` formatting sugar does not alter the promotion rules. Link: https://github.com/ClangBuiltLinux/linux/issues/378 Signed-off-by: Justin Stitt Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20220607191119.20686-1-jstitt007@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index a3593290886f8..4d46780fad131 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -2784,7 +2784,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx) netdev_dbg(netdev, "Dst MAC addr: %pM\n", eth->h_dest); netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source); - netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto)); + netdev_dbg(netdev, "Protocol: %#06x\n", ntohs(eth->h_proto)); for (i = 0; i < skb->len; i += 32) { unsigned int len = min(skb->len - i, 32U); -- GitLab From acb0055e187334554398a381a16de72f1a3d47bb Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Wed, 8 Jun 2022 23:11:06 -0400 Subject: [PATCH 399/942] virtio: Fix all occurences of the "the the" typo There are double "the" in message in file virtio_mmio.c and virtio_pci_modern_dev.c, fix it. Signed-off-by: Bo Liu Message-Id: <20220609031106.2161-1-liubo03@inspur.com> Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_mmio.c | 2 +- drivers/virtio/virtio_pci_modern_dev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 5ce79bf9f92b7..c9bec3813e949 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -255,7 +255,7 @@ static void vm_set_status(struct virtio_device *vdev, u8 status) /* * Per memory-barriers.txt, wmb() is not needed to guarantee - * that the the cache coherent memory writes have completed + * that the cache coherent memory writes have completed * before writing to the MMIO region. */ writel(status, vm_dev->base + VIRTIO_MMIO_STATUS); diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c index a0fa14f28a7fc..b790f30b2b566 100644 --- a/drivers/virtio/virtio_pci_modern_dev.c +++ b/drivers/virtio/virtio_pci_modern_dev.c @@ -469,7 +469,7 @@ void vp_modern_set_status(struct virtio_pci_modern_device *mdev, /* * Per memory-barriers.txt, wmb() is not needed to guarantee - * that the the cache coherent memory writes have completed + * that the cache coherent memory writes have completed * before writing to the MMIO region. */ vp_iowrite8(status, &cfg->device_status); -- GitLab From 00d1f546470d89e072dd3cda12b5c794341e7268 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 9 Jun 2022 12:19:01 +0800 Subject: [PATCH 400/942] vdpa: make get_vq_group and set_group_asid optional This patch makes get_vq_group and set_group_asid optional. This is needed to unbreak the vDPA parent that doesn't support multiple address spaces. Cc: Gautam Dawar Fixes: aaca8373c4b1 ("vhost-vdpa: support ASID based IOTLB API") Signed-off-by: Jason Wang Message-Id: <20220609041901.2029-1-jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vdpa.c | 2 ++ include/linux/vdpa.h | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 935a1d0ddb97e..5ad2596c6e8a1 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -499,6 +499,8 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, ops->set_vq_ready(vdpa, idx, s.num); return 0; case VHOST_VDPA_GET_VRING_GROUP: + if (!ops->get_vq_group) + return -EOPNOTSUPP; s.index = idx; s.num = ops->get_vq_group(vdpa, idx); if (s.num >= vdpa->ngroups) diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h index 4700a88a28f6c..7b4a13d3bd919 100644 --- a/include/linux/vdpa.h +++ b/include/linux/vdpa.h @@ -178,7 +178,8 @@ struct vdpa_map_file { * for the device * @vdev: vdpa device * Returns virtqueue algin requirement - * @get_vq_group: Get the group id for a specific virtqueue + * @get_vq_group: Get the group id for a specific + * virtqueue (optional) * @vdev: vdpa device * @idx: virtqueue index * Returns u32: group id for this virtqueue @@ -243,7 +244,7 @@ struct vdpa_map_file { * Returns the iova range supported by * the device. * @set_group_asid: Set address space identifier for a - * virtqueue group + * virtqueue group (optional) * @vdev: vdpa device * @group: virtqueue group * @asid: address space id for this group -- GitLab From 477277c7fd43d48ae68cbdcaa7c0f82024a87421 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 7 Jun 2022 11:20:04 +0200 Subject: [PATCH 401/942] drm/ast: Support multiple outputs Systems with AST graphics can have multiple output; typically VGA plus some other port. Record detected output chips in a bitmask and initialize each output on its own. Assume a VGA output by default and use SIL164 and DP501 if available. For ASTDP assume that it can run in parallel with VGA. Tested on AST2100. v3: * define a macro for each BIT(ast_tx_chip) (Patrik) v2: * make VGA/SIL164/DP501 mutually exclusive Signed-off-by: Thomas Zimmermann Reviewed-by: Patrik Jakobsson Fixes: a59b026419f3 ("drm/ast: Initialize encoder and connector for VGA in helper function") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Dave Airlie Cc: dri-devel@lists.freedesktop.org Link: https://patchwork.freedesktop.org/patch/msgid/20220607092008.22123-2-tzimmermann@suse.de (cherry picked from commit 7f35680ada234ce00828b8ea841ba7ca1e00ff52) Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/ast/ast_dp.c | 5 ++--- drivers/gpu/drm/ast/ast_dp501.c | 2 +- drivers/gpu/drm/ast/ast_drv.h | 9 ++++++-- drivers/gpu/drm/ast/ast_main.c | 21 ++++++++---------- drivers/gpu/drm/ast/ast_mode.c | 38 ++++++++++++++++++--------------- drivers/gpu/drm/ast/ast_post.c | 2 +- 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 4551bc8a3ecff..f573d582407e0 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -160,13 +160,12 @@ void ast_dp_launch(struct drm_device *dev, u8 bPower) } if (bDPExecute) - ast->tx_chip_type = AST_TX_ASTDP; + ast->tx_chip_types |= BIT(AST_TX_ASTDP); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); - } else - ast->tx_chip_type = AST_TX_NONE; + } } diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index 204c926a18ea7..4f75a9efb610a 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -450,7 +450,7 @@ void ast_init_3rdtx(struct drm_device *dev) ast_init_dvo(dev); break; default: - if (ast->tx_chip_type == AST_TX_SIL164) + if (ast->tx_chip_types & BIT(AST_TX_SIL164)) ast_init_dvo(dev); else ast_init_analog(dev); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index afebe35f205e4..a34db4380f686 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -73,6 +73,11 @@ enum ast_tx_chip { AST_TX_ASTDP, }; +#define AST_TX_NONE_BIT BIT(AST_TX_NONE) +#define AST_TX_SIL164_BIT BIT(AST_TX_SIL164) +#define AST_TX_DP501_BIT BIT(AST_TX_DP501) +#define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP) + #define AST_DRAM_512Mx16 0 #define AST_DRAM_1Gx16 1 #define AST_DRAM_512Mx32 2 @@ -173,7 +178,7 @@ struct ast_private { struct drm_plane primary_plane; struct ast_cursor_plane cursor_plane; struct drm_crtc crtc; - union { + struct { struct { struct drm_encoder encoder; struct ast_vga_connector vga_connector; @@ -199,7 +204,7 @@ struct ast_private { ast_use_defaults } config_mode; - enum ast_tx_chip tx_chip_type; + unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */ u8 *dp501_fw_addr; const struct firmware *dp501_fw; /* dp501 fw */ }; diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index d770d5a23c1af..067453266897f 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -216,7 +216,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) } /* Check 3rd Tx option (digital output afaik) */ - ast->tx_chip_type = AST_TX_NONE; + ast->tx_chip_types |= AST_TX_NONE_BIT; /* * VGACRA3 Enhanced Color Mode Register, check if DVO is already @@ -229,7 +229,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) if (!*need_post) { jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); if (jreg & 0x80) - ast->tx_chip_type = AST_TX_SIL164; + ast->tx_chip_types = AST_TX_SIL164_BIT; } if ((ast->chip == AST2300) || (ast->chip == AST2400) || (ast->chip == AST2500)) { @@ -241,7 +241,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); switch (jreg) { case 0x04: - ast->tx_chip_type = AST_TX_SIL164; + ast->tx_chip_types = AST_TX_SIL164_BIT; break; case 0x08: ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL); @@ -254,22 +254,19 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) } fallthrough; case 0x0c: - ast->tx_chip_type = AST_TX_DP501; + ast->tx_chip_types = AST_TX_DP501_BIT; } } else if (ast->chip == AST2600) ast_dp_launch(&ast->base, 0); /* Print stuff for diagnostic purposes */ - switch(ast->tx_chip_type) { - case AST_TX_SIL164: + if (ast->tx_chip_types & AST_TX_NONE_BIT) + drm_info(dev, "Using analog VGA\n"); + if (ast->tx_chip_types & AST_TX_SIL164_BIT) drm_info(dev, "Using Sil164 TMDS transmitter\n"); - break; - case AST_TX_DP501: + if (ast->tx_chip_types & AST_TX_DP501_BIT) drm_info(dev, "Using DP501 DisplayPort transmitter\n"); - break; - default: - drm_info(dev, "Analog VGA only\n"); - } + return 0; } diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 323af2746aa92..db2010a556744 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -997,10 +997,10 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_ON: ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); - if (ast->tx_chip_type == AST_TX_DP501) + if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); - if (ast->tx_chip_type == AST_TX_ASTDP) { + if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON); ast_wait_for_vretrace(ast); ast_dp_set_on_off(crtc->dev, 1); @@ -1012,17 +1012,17 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: ch = mode; - if (ast->tx_chip_type == AST_TX_DP501) + if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 0); - break; - if (ast->tx_chip_type == AST_TX_ASTDP) { + if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { ast_dp_set_on_off(crtc->dev, 0); ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); } ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); + break; } } @@ -1155,7 +1155,7 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, ast_crtc_load_lut(ast, crtc); //Set Aspeed Display-Port - if (ast->tx_chip_type == AST_TX_ASTDP) + if (ast->tx_chip_types & AST_TX_ASTDP_BIT) ast_dp_set_mode(crtc, vbios_mode_info); mutex_unlock(&ast->ioregs_lock); @@ -1739,22 +1739,26 @@ int ast_mode_config_init(struct ast_private *ast) ast_crtc_init(dev); - switch (ast->tx_chip_type) { - case AST_TX_NONE: + if (ast->tx_chip_types & AST_TX_NONE_BIT) { ret = ast_vga_output_init(ast); - break; - case AST_TX_SIL164: + if (ret) + return ret; + } + if (ast->tx_chip_types & AST_TX_SIL164_BIT) { ret = ast_sil164_output_init(ast); - break; - case AST_TX_DP501: + if (ret) + return ret; + } + if (ast->tx_chip_types & AST_TX_DP501_BIT) { ret = ast_dp501_output_init(ast); - break; - case AST_TX_ASTDP: + if (ret) + return ret; + } + if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { ret = ast_astdp_output_init(ast); - break; + if (ret) + return ret; } - if (ret) - return ret; drm_mode_config_reset(dev); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 0aa9cf0fb5c3f..82fd3c8adee13 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -391,7 +391,7 @@ void ast_post_gpu(struct drm_device *dev) ast_init_3rdtx(dev); } else { - if (ast->tx_chip_type != AST_TX_NONE) + if (ast->tx_chip_types & AST_TX_SIL164_BIT) ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } -- GitLab From 537b4a0c8b9490d762e70c0ecec38144c83d0c37 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:47 +0300 Subject: [PATCH 402/942] ASoC: SOF: Intel: hda-dsp: Expose hda_dsp_core_power_up() The hda_dsp_core_power_up() needs to be exposed so that it can be used in hda-loader.c to correct the boot flow. The first step must not unstall the core, it should only power up the core(s). Add sanity check for the core_mask while exposing it to be safe. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 10 +++++++++- sound/soc/sof/intel/hda.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 000ea906670cb..e24eea725acb4 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -181,12 +181,20 @@ int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask) * Power Management. */ -static int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) +int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) { + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; unsigned int cpa; u32 adspcs; int ret; + /* restrict core_mask to host managed cores mask */ + core_mask &= chip->host_managed_cores_mask; + /* return if core_mask is not valid */ + if (!core_mask) + return 0; + /* update bits */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS, HDA_DSP_ADSPCS_SPA_MASK(core_mask), diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 3e0f7b0c586a2..0f57ef5d9b8e9 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -497,6 +497,7 @@ struct sof_intel_hda_stream { */ int hda_dsp_probe(struct snd_sof_dev *sdev); int hda_dsp_remove(struct snd_sof_dev *sdev); +int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev, -- GitLab From fcb3c775f7073410965ce9414ddb2a1f339c502b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:48 +0300 Subject: [PATCH 403/942] ASoC: SOF: Intel: hda-loader: Make sure that the fw load sequence is followed The hda_dsp_enable_core() is powering up _and_ unstall the core in one call while the first step of the firmware loading must not unstall the core. The core can be unstalled only after the set cpb_cfp and the configuration of the IPC register for the ROM_CONTROL message. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 64290125d7cd8..103e62bcfa82d 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -110,7 +110,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) int ret; /* step 1: power up corex */ - ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask); + ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); -- GitLab From 4643e10a17e549467420aaeeb35c9b3480716618 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:49 +0300 Subject: [PATCH 404/942] ASoC: SOF: Intel: hda-loader: Clarify the cl_dsp_init() flow Update the comment for the cl_dsp_init() to clarify what is done by the function and use the chip->init_core_mask instead of BIT(0) when unstalling/running the init core. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 103e62bcfa82d..d3ec5996a9a3d 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -95,9 +95,9 @@ struct hdac_ext_stream *hda_cl_stream_prepare(struct snd_sof_dev *sdev, unsigned } /* - * first boot sequence has some extra steps. core 0 waits for power - * status on core 1, so power up core 1 also momentarily, keep it in - * reset/stall and then turn it off + * first boot sequence has some extra steps. + * power on all host managed cores and only unstall/run the boot core to boot the + * DSP then turn off all non boot cores (if any) is powered on. */ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) { @@ -127,7 +127,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, ipc_hdr); /* step 3: unset core 0 reset state & unstall/run core 0 */ - ret = hda_dsp_core_run(sdev, BIT(0)); + ret = hda_dsp_core_run(sdev, chip->init_core_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, -- GitLab From 142d456204cf4dabe18be59e043d806440f609d4 Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Mon, 6 Jun 2022 03:37:05 +0000 Subject: [PATCH 405/942] ASoC: imx-audmux: remove unnecessary check of clk_disable_unprepare/clk_prepare_enable Because clk_disable_unprepare/clk_prepare_enable already checked NULL clock parameter, so the additional checks are unnecessary, just remove them. Reported-by: Zeal Robot Signed-off-by: Minghao Chi Acked-by: Shengjiu Wang Link: https://lore.kernel.org/r/20220606033705.291048-1-chi.minghao@zte.com.cn Signed-off-by: Mark Brown --- sound/soc/fsl/imx-audmux.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index a8e5e0f57faf9..50b71e5d45897 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -62,17 +62,14 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, uintptr_t port = (uintptr_t)file->private_data; u32 pdcr, ptcr; - if (audmux_clk) { - ret = clk_prepare_enable(audmux_clk); - if (ret) - return ret; - } + ret = clk_prepare_enable(audmux_clk); + if (ret) + return ret; ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); - if (audmux_clk) - clk_disable_unprepare(audmux_clk); + clk_disable_unprepare(audmux_clk); buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) @@ -209,17 +206,14 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, if (!audmux_base) return -ENOSYS; - if (audmux_clk) { - ret = clk_prepare_enable(audmux_clk); - if (ret) - return ret; - } + ret = clk_prepare_enable(audmux_clk); + if (ret) + return ret; writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); - if (audmux_clk) - clk_disable_unprepare(audmux_clk); + clk_disable_unprepare(audmux_clk); return 0; } -- GitLab From 8e1278444446fc97778a5e5c99bca1ce0bbc5ec9 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 7 Jun 2022 00:34:56 +1000 Subject: [PATCH 406/942] powerpc/32: Fix overread/overwrite of thread_struct via ptrace The ptrace PEEKUSR/POKEUSR (aka PEEKUSER/POKEUSER) API allows a process to read/write registers of another process. To get/set a register, the API takes an index into an imaginary address space called the "USER area", where the registers of the process are laid out in some fashion. The kernel then maps that index to a particular register in its own data structures and gets/sets the value. The API only allows a single machine-word to be read/written at a time. So 4 bytes on 32-bit kernels and 8 bytes on 64-bit kernels. The way floating point registers (FPRs) are addressed is somewhat complicated, because double precision float values are 64-bit even on 32-bit CPUs. That means on 32-bit kernels each FPR occupies two word-sized locations in the USER area. On 64-bit kernels each FPR occupies one word-sized location in the USER area. Internally the kernel stores the FPRs in an array of u64s, or if VSX is enabled, an array of pairs of u64s where one half of each pair stores the FPR. Which half of the pair stores the FPR depends on the kernel's endianness. To handle the different layouts of the FPRs depending on VSX/no-VSX and big/little endian, the TS_FPR() macro was introduced. Unfortunately the TS_FPR() macro does not take into account the fact that the addressing of each FPR differs between 32-bit and 64-bit kernels. It just takes the index into the "USER area" passed from userspace and indexes into the fp_state.fpr array. On 32-bit there are 64 indexes that address FPRs, but only 32 entries in the fp_state.fpr array, meaning the user can read/write 256 bytes past the end of the array. Because the fp_state sits in the middle of the thread_struct there are various fields than can be overwritten, including some pointers. As such it may be exploitable. It has also been observed to cause systems to hang or otherwise misbehave when using gdbserver, and is probably the root cause of this report which could not be easily reproduced: https://lore.kernel.org/linuxppc-dev/dc38afe9-6b78-f3f5-666b-986939e40fc6@keymile.com/ Rather than trying to make the TS_FPR() macro even more complicated to fix the bug, or add more macros, instead add a special-case for 32-bit kernels. This is more obvious and hopefully avoids a similar bug happening again in future. Note that because 32-bit kernels never have VSX enabled the code doesn't need to consider TS_FPRWIDTH/OFFSET at all. Add a BUILD_BUG_ON() to ensure that 32-bit && VSX is never enabled. Fixes: 87fec0514f61 ("powerpc: PTRACE_PEEKUSR/PTRACE_POKEUSER of FPR registers in little endian builds") Cc: stable@vger.kernel.org # v3.13+ Reported-by: Ariel Miculas Tested-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220609133245.573565-1-mpe@ellerman.id.au --- arch/powerpc/kernel/ptrace/ptrace-fpu.c | 20 ++++++++++++++------ arch/powerpc/kernel/ptrace/ptrace.c | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c index 5dca19361316e..09c49632bfe59 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-fpu.c +++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c @@ -17,9 +17,13 @@ int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) #ifdef CONFIG_PPC_FPU_REGS flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); - else + if (fpidx < (PT_FPSCR - PT_FPR0)) { + if (IS_ENABLED(CONFIG_PPC32)) + // On 32-bit the index we are passed refers to 32-bit words + *data = ((u32 *)child->thread.fp_state.fpr)[fpidx]; + else + memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); + } else *data = child->thread.fp_state.fpscr; #else *data = 0; @@ -39,9 +43,13 @@ int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) #ifdef CONFIG_PPC_FPU_REGS flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); - else + if (fpidx < (PT_FPSCR - PT_FPR0)) { + if (IS_ENABLED(CONFIG_PPC32)) + // On 32-bit the index we are passed refers to 32-bit words + ((u32 *)child->thread.fp_state.fpr)[fpidx] = data; + else + memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); + } else child->thread.fp_state.fpscr = data; #endif diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c index 4d2dc22d4a2d5..5d7a72b41ae71 100644 --- a/arch/powerpc/kernel/ptrace/ptrace.c +++ b/arch/powerpc/kernel/ptrace/ptrace.c @@ -444,4 +444,7 @@ void __init pt_regs_check(void) * real registers. */ BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long)); + + // ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible + BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX)); } -- GitLab From 5860800e8696d2cbbd1a0dd60b433549d176e668 Mon Sep 17 00:00:00 2001 From: Zheng Zengkai Date: Thu, 9 Jun 2022 10:56:56 +0800 Subject: [PATCH 407/942] Documentation/features: Update the arch support status files The arch support status files don't match reality as of v5.19-rc1, use the features-refresh.sh to refresh all the arch-support.txt files in place. The main effect is to add entries for the new loong architecture. Signed-off-by: Zheng Zengkai Link: https://lore.kernel.org/r/20220609025656.143460-1-zhengzengkai@huawei.com Signed-off-by: Jonathan Corbet --- Documentation/features/core/cBPF-JIT/arch-support.txt | 1 + Documentation/features/core/eBPF-JIT/arch-support.txt | 1 + .../features/core/generic-idle-thread/arch-support.txt | 1 + Documentation/features/core/jump-labels/arch-support.txt | 1 + .../features/core/thread-info-in-task/arch-support.txt | 1 + Documentation/features/core/tracehook/arch-support.txt | 1 + Documentation/features/debug/KASAN/arch-support.txt | 1 + Documentation/features/debug/debug-vm-pgtable/arch-support.txt | 3 ++- Documentation/features/debug/gcov-profile-all/arch-support.txt | 3 ++- Documentation/features/debug/kcov/arch-support.txt | 1 + Documentation/features/debug/kgdb/arch-support.txt | 1 + Documentation/features/debug/kmemleak/arch-support.txt | 1 + .../features/debug/kprobes-on-ftrace/arch-support.txt | 1 + Documentation/features/debug/kprobes/arch-support.txt | 1 + Documentation/features/debug/kretprobes/arch-support.txt | 1 + Documentation/features/debug/optprobes/arch-support.txt | 1 + Documentation/features/debug/stackprotector/arch-support.txt | 1 + Documentation/features/debug/uprobes/arch-support.txt | 1 + .../features/debug/user-ret-profiler/arch-support.txt | 1 + Documentation/features/io/dma-contiguous/arch-support.txt | 1 + Documentation/features/locking/cmpxchg-local/arch-support.txt | 1 + Documentation/features/locking/lockdep/arch-support.txt | 1 + Documentation/features/locking/queued-rwlocks/arch-support.txt | 3 ++- .../features/locking/queued-spinlocks/arch-support.txt | 1 + Documentation/features/perf/kprobes-event/arch-support.txt | 3 ++- Documentation/features/perf/perf-regs/arch-support.txt | 1 + Documentation/features/perf/perf-stackdump/arch-support.txt | 1 + .../features/sched/membarrier-sync-core/arch-support.txt | 1 + Documentation/features/sched/numa-balancing/arch-support.txt | 1 + Documentation/features/seccomp/seccomp-filter/arch-support.txt | 1 + .../features/time/arch-tick-broadcast/arch-support.txt | 1 + Documentation/features/time/clockevents/arch-support.txt | 1 + Documentation/features/time/context-tracking/arch-support.txt | 1 + Documentation/features/time/irq-time-acct/arch-support.txt | 1 + Documentation/features/time/virt-cpuacct/arch-support.txt | 1 + Documentation/features/vm/ELF-ASLR/arch-support.txt | 1 + Documentation/features/vm/PG_uncached/arch-support.txt | 1 + Documentation/features/vm/THP/arch-support.txt | 1 + Documentation/features/vm/TLB/arch-support.txt | 1 + Documentation/features/vm/huge-vmap/arch-support.txt | 1 + Documentation/features/vm/ioremap_prot/arch-support.txt | 1 + Documentation/features/vm/pte_special/arch-support.txt | 3 ++- 42 files changed, 47 insertions(+), 5 deletions(-) diff --git a/Documentation/features/core/cBPF-JIT/arch-support.txt b/Documentation/features/core/cBPF-JIT/arch-support.txt index 10482dee8703c..a053667a7a8c1 100644 --- a/Documentation/features/core/cBPF-JIT/arch-support.txt +++ b/Documentation/features/core/cBPF-JIT/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/core/eBPF-JIT/arch-support.txt b/Documentation/features/core/eBPF-JIT/arch-support.txt index bcefb5afc7d65..c0bb9c92937f0 100644 --- a/Documentation/features/core/eBPF-JIT/arch-support.txt +++ b/Documentation/features/core/eBPF-JIT/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/core/generic-idle-thread/arch-support.txt b/Documentation/features/core/generic-idle-thread/arch-support.txt index d80d99449ac15..c9bfff292816a 100644 --- a/Documentation/features/core/generic-idle-thread/arch-support.txt +++ b/Documentation/features/core/generic-idle-thread/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | ok | | ia64: | ok | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/core/jump-labels/arch-support.txt b/Documentation/features/core/jump-labels/arch-support.txt index 53eab154925d5..35e2a44b1448b 100644 --- a/Documentation/features/core/jump-labels/arch-support.txt +++ b/Documentation/features/core/jump-labels/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/core/thread-info-in-task/arch-support.txt b/Documentation/features/core/thread-info-in-task/arch-support.txt index 94926451afb90..9b3e2ce12b440 100644 --- a/Documentation/features/core/thread-info-in-task/arch-support.txt +++ b/Documentation/features/core/thread-info-in-task/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt index b4274b8141b67..9c7ffec5d51d5 100644 --- a/Documentation/features/core/tracehook/arch-support.txt +++ b/Documentation/features/core/tracehook/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | ok | | ia64: | ok | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/KASAN/arch-support.txt b/Documentation/features/debug/KASAN/arch-support.txt index c15bb4b21b6fd..2fd5fb6f5f236 100644 --- a/Documentation/features/debug/KASAN/arch-support.txt +++ b/Documentation/features/debug/KASAN/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt index 4c31fc92a3124..c45711e55c7bf 100644 --- a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt +++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt @@ -13,12 +13,13 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | | nios2: | TODO | | openrisc: | TODO | - | parisc: | TODO | + | parisc: | ok | | powerpc: | ok | | riscv: | ok | | s390: | ok | diff --git a/Documentation/features/debug/gcov-profile-all/arch-support.txt b/Documentation/features/debug/gcov-profile-all/arch-support.txt index d7a5ac4bc1fef..502c1d4096488 100644 --- a/Documentation/features/debug/gcov-profile-all/arch-support.txt +++ b/Documentation/features/debug/gcov-profile-all/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | ok | | mips: | ok | @@ -24,7 +25,7 @@ | s390: | ok | | sh: | ok | | sparc: | TODO | - | um: | TODO | + | um: | ok | | x86: | ok | | xtensa: | TODO | ----------------------- diff --git a/Documentation/features/debug/kcov/arch-support.txt b/Documentation/features/debug/kcov/arch-support.txt index 136e14c2b6039..afb90bebded23 100644 --- a/Documentation/features/debug/kcov/arch-support.txt +++ b/Documentation/features/debug/kcov/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/kgdb/arch-support.txt b/Documentation/features/debug/kgdb/arch-support.txt index 5b3f3d8ae4622..04120d278c221 100644 --- a/Documentation/features/debug/kgdb/arch-support.txt +++ b/Documentation/features/debug/kgdb/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | ok | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | ok | | mips: | ok | diff --git a/Documentation/features/debug/kmemleak/arch-support.txt b/Documentation/features/debug/kmemleak/arch-support.txt index 7a2eab4fdf9d9..e487c356ab206 100644 --- a/Documentation/features/debug/kmemleak/arch-support.txt +++ b/Documentation/features/debug/kmemleak/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | ok | | mips: | ok | diff --git a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt index db02ab1941386..b3697f4c806e8 100644 --- a/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt +++ b/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/debug/kprobes/arch-support.txt b/Documentation/features/debug/kprobes/arch-support.txt index ec186e7deebc7..452385ac9e067 100644 --- a/Documentation/features/debug/kprobes/arch-support.txt +++ b/Documentation/features/debug/kprobes/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | ok | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/kretprobes/arch-support.txt b/Documentation/features/debug/kretprobes/arch-support.txt index 4b7865e693f60..daecf046e72b4 100644 --- a/Documentation/features/debug/kretprobes/arch-support.txt +++ b/Documentation/features/debug/kretprobes/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | ok | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/optprobes/arch-support.txt b/Documentation/features/debug/optprobes/arch-support.txt index 5d9befa041c73..adb1bd055bfdd 100644 --- a/Documentation/features/debug/optprobes/arch-support.txt +++ b/Documentation/features/debug/optprobes/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/debug/stackprotector/arch-support.txt b/Documentation/features/debug/stackprotector/arch-support.txt index d97fd38460e69..ddcd7161d14ce 100644 --- a/Documentation/features/debug/stackprotector/arch-support.txt +++ b/Documentation/features/debug/stackprotector/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/uprobes/arch-support.txt b/Documentation/features/debug/uprobes/arch-support.txt index d30e3475904ec..25121200f9f9e 100644 --- a/Documentation/features/debug/uprobes/arch-support.txt +++ b/Documentation/features/debug/uprobes/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/debug/user-ret-profiler/arch-support.txt b/Documentation/features/debug/user-ret-profiler/arch-support.txt index 9ae1fa2eb27cb..f2fcff8e77b79 100644 --- a/Documentation/features/debug/user-ret-profiler/arch-support.txt +++ b/Documentation/features/debug/user-ret-profiler/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/io/dma-contiguous/arch-support.txt b/Documentation/features/io/dma-contiguous/arch-support.txt index 9e09988eb6545..95e485c87e36d 100644 --- a/Documentation/features/io/dma-contiguous/arch-support.txt +++ b/Documentation/features/io/dma-contiguous/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | ok | | mips: | ok | diff --git a/Documentation/features/locking/cmpxchg-local/arch-support.txt b/Documentation/features/locking/cmpxchg-local/arch-support.txt index 5c4ec316dbac0..8b1a8d9e1c797 100644 --- a/Documentation/features/locking/cmpxchg-local/arch-support.txt +++ b/Documentation/features/locking/cmpxchg-local/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/locking/lockdep/arch-support.txt b/Documentation/features/locking/lockdep/arch-support.txt index 65007c1ac44f6..ab69e8f56a377 100644 --- a/Documentation/features/locking/lockdep/arch-support.txt +++ b/Documentation/features/locking/lockdep/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | ok | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | ok | | mips: | ok | diff --git a/Documentation/features/locking/queued-rwlocks/arch-support.txt b/Documentation/features/locking/queued-rwlocks/arch-support.txt index 20056670fb09e..0bfb72a08d82d 100644 --- a/Documentation/features/locking/queued-rwlocks/arch-support.txt +++ b/Documentation/features/locking/queued-rwlocks/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | @@ -20,7 +21,7 @@ | openrisc: | ok | | parisc: | TODO | | powerpc: | ok | - | riscv: | TODO | + | riscv: | ok | | s390: | TODO | | sh: | TODO | | sparc: | ok | diff --git a/Documentation/features/locking/queued-spinlocks/arch-support.txt b/Documentation/features/locking/queued-spinlocks/arch-support.txt index 707514faac7be..d2f2201febc8f 100644 --- a/Documentation/features/locking/queued-spinlocks/arch-support.txt +++ b/Documentation/features/locking/queued-spinlocks/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt index 9f31ce9b9f2a4..0d0647b067624 100644 --- a/Documentation/features/perf/kprobes-event/arch-support.txt +++ b/Documentation/features/perf/kprobes-event/arch-support.txt @@ -7,12 +7,13 @@ | arch |status| ----------------------- | alpha: | TODO | - | arc: | TODO | + | arc: | ok | | arm: | ok | | arm64: | ok | | csky: | ok | | hexagon: | ok | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/perf/perf-regs/arch-support.txt b/Documentation/features/perf/perf-regs/arch-support.txt index f148c4329c7ad..13c297bbf05cc 100644 --- a/Documentation/features/perf/perf-regs/arch-support.txt +++ b/Documentation/features/perf/perf-regs/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/perf/perf-stackdump/arch-support.txt b/Documentation/features/perf/perf-stackdump/arch-support.txt index 32c88b6a910cf..931687eec6719 100644 --- a/Documentation/features/perf/perf-stackdump/arch-support.txt +++ b/Documentation/features/perf/perf-stackdump/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt index d82a1f0cdc910..336d728b8a455 100644 --- a/Documentation/features/sched/membarrier-sync-core/arch-support.txt +++ b/Documentation/features/sched/membarrier-sync-core/arch-support.txt @@ -36,6 +36,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/sched/numa-balancing/arch-support.txt b/Documentation/features/sched/numa-balancing/arch-support.txt index 2687564e5fa87..76d0121183723 100644 --- a/Documentation/features/sched/numa-balancing/arch-support.txt +++ b/Documentation/features/sched/numa-balancing/arch-support.txt @@ -13,6 +13,7 @@ | csky: | .. | | hexagon: | .. | | ia64: | TODO | + | loong: | ok | | m68k: | .. | | microblaze: | .. | | mips: | TODO | diff --git a/Documentation/features/seccomp/seccomp-filter/arch-support.txt b/Documentation/features/seccomp/seccomp-filter/arch-support.txt index 1b4109199e9d1..a86b8b1f3d10a 100644 --- a/Documentation/features/seccomp/seccomp-filter/arch-support.txt +++ b/Documentation/features/seccomp/seccomp-filter/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/time/arch-tick-broadcast/arch-support.txt b/Documentation/features/time/arch-tick-broadcast/arch-support.txt index 27327256bd058..364169f00ee2f 100644 --- a/Documentation/features/time/arch-tick-broadcast/arch-support.txt +++ b/Documentation/features/time/arch-tick-broadcast/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/time/clockevents/arch-support.txt b/Documentation/features/time/clockevents/arch-support.txt index b9a4bda2c8f55..6ea274790e471 100644 --- a/Documentation/features/time/clockevents/arch-support.txt +++ b/Documentation/features/time/clockevents/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | ok | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | ok | | mips: | ok | diff --git a/Documentation/features/time/context-tracking/arch-support.txt b/Documentation/features/time/context-tracking/arch-support.txt index 4aa51c9fa32b0..c9e0a16290e68 100644 --- a/Documentation/features/time/context-tracking/arch-support.txt +++ b/Documentation/features/time/context-tracking/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/time/irq-time-acct/arch-support.txt b/Documentation/features/time/irq-time-acct/arch-support.txt index 0306ece41faae..fd17d8de5ef1e 100644 --- a/Documentation/features/time/irq-time-acct/arch-support.txt +++ b/Documentation/features/time/irq-time-acct/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | .. | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/time/virt-cpuacct/arch-support.txt b/Documentation/features/time/virt-cpuacct/arch-support.txt index 5d64e40c0092e..1a859ac05e9ef 100644 --- a/Documentation/features/time/virt-cpuacct/arch-support.txt +++ b/Documentation/features/time/virt-cpuacct/arch-support.txt @@ -13,6 +13,7 @@ | csky: | ok | | hexagon: | TODO | | ia64: | ok | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/vm/ELF-ASLR/arch-support.txt b/Documentation/features/vm/ELF-ASLR/arch-support.txt index 92c9db24a6a39..b1229953391b2 100644 --- a/Documentation/features/vm/ELF-ASLR/arch-support.txt +++ b/Documentation/features/vm/ELF-ASLR/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/vm/PG_uncached/arch-support.txt b/Documentation/features/vm/PG_uncached/arch-support.txt index 7424fea37614b..02f325fbfcd0d 100644 --- a/Documentation/features/vm/PG_uncached/arch-support.txt +++ b/Documentation/features/vm/PG_uncached/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | ok | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/vm/THP/arch-support.txt b/Documentation/features/vm/THP/arch-support.txt index 60985067626b0..9bfff977ef55b 100644 --- a/Documentation/features/vm/THP/arch-support.txt +++ b/Documentation/features/vm/THP/arch-support.txt @@ -13,6 +13,7 @@ | csky: | .. | | hexagon: | .. | | ia64: | TODO | + | loong: | ok | | m68k: | .. | | microblaze: | .. | | mips: | ok | diff --git a/Documentation/features/vm/TLB/arch-support.txt b/Documentation/features/vm/TLB/arch-support.txt index f2dcbec6020ea..039e4e91ada33 100644 --- a/Documentation/features/vm/TLB/arch-support.txt +++ b/Documentation/features/vm/TLB/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | .. | | microblaze: | .. | | mips: | TODO | diff --git a/Documentation/features/vm/huge-vmap/arch-support.txt b/Documentation/features/vm/huge-vmap/arch-support.txt index 680090df03e19..13b4940e0c3a7 100644 --- a/Documentation/features/vm/huge-vmap/arch-support.txt +++ b/Documentation/features/vm/huge-vmap/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | TODO | | m68k: | TODO | | microblaze: | TODO | | mips: | TODO | diff --git a/Documentation/features/vm/ioremap_prot/arch-support.txt b/Documentation/features/vm/ioremap_prot/arch-support.txt index 205a90e820501..b01bf7bca3e6d 100644 --- a/Documentation/features/vm/ioremap_prot/arch-support.txt +++ b/Documentation/features/vm/ioremap_prot/arch-support.txt @@ -13,6 +13,7 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | diff --git a/Documentation/features/vm/pte_special/arch-support.txt b/Documentation/features/vm/pte_special/arch-support.txt index 9f16d6e4e11e0..fc3687b5e89bf 100644 --- a/Documentation/features/vm/pte_special/arch-support.txt +++ b/Documentation/features/vm/pte_special/arch-support.txt @@ -13,12 +13,13 @@ | csky: | TODO | | hexagon: | TODO | | ia64: | TODO | + | loong: | ok | | m68k: | TODO | | microblaze: | TODO | | mips: | ok | | nios2: | TODO | | openrisc: | TODO | - | parisc: | TODO | + | parisc: | ok | | powerpc: | ok | | riscv: | ok | | s390: | ok | -- GitLab From 788183a6e8b098b90e15214e800ae5194591018a Mon Sep 17 00:00:00 2001 From: Justin Swartz Date: Sat, 4 Jun 2022 17:54:31 +0200 Subject: [PATCH 408/942] docs: usb: fix literal block marker in usbmon verification example The "Verify that bus sockets are present" example was not properly formatted due to a typo in the literal block marker. Signed-off-by: Justin Swartz Link: https://lore.kernel.org/r/20220604155431.23246-1-justin.swartz@risingedge.co.za Signed-off-by: Jonathan Corbet --- Documentation/usb/usbmon.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/usbmon.rst b/Documentation/usb/usbmon.rst index b0bd510807993..6d5ec1e62d093 100644 --- a/Documentation/usb/usbmon.rst +++ b/Documentation/usb/usbmon.rst @@ -42,7 +42,7 @@ if usbmon is built into the kernel:: # modprobe usbmon # -Verify that bus sockets are present: +Verify that bus sockets are present:: # ls /sys/kernel/debug/usb/usbmon 0s 0u 1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u -- GitLab From 9c73e1e06e0d6d72c445a1b1f50493da260b0c4e Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 6 Jun 2022 08:40:55 -0600 Subject: [PATCH 409/942] docs: Move the HTE documentation to driver-api/ The hardware timestamp engine documentation is driver API material, and really belongs in the driver-API book; move it there. Cc: Thierry Reding Acked-by: Dipen Patel Signed-off-by: Jonathan Corbet --- Documentation/{ => driver-api}/hte/hte.rst | 0 Documentation/{ => driver-api}/hte/index.rst | 0 Documentation/{ => driver-api}/hte/tegra194-hte.rst | 0 Documentation/driver-api/index.rst | 1 + Documentation/index.rst | 1 - MAINTAINERS | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) rename Documentation/{ => driver-api}/hte/hte.rst (100%) rename Documentation/{ => driver-api}/hte/index.rst (100%) rename Documentation/{ => driver-api}/hte/tegra194-hte.rst (100%) diff --git a/Documentation/hte/hte.rst b/Documentation/driver-api/hte/hte.rst similarity index 100% rename from Documentation/hte/hte.rst rename to Documentation/driver-api/hte/hte.rst diff --git a/Documentation/hte/index.rst b/Documentation/driver-api/hte/index.rst similarity index 100% rename from Documentation/hte/index.rst rename to Documentation/driver-api/hte/index.rst diff --git a/Documentation/hte/tegra194-hte.rst b/Documentation/driver-api/hte/tegra194-hte.rst similarity index 100% rename from Documentation/hte/tegra194-hte.rst rename to Documentation/driver-api/hte/tegra194-hte.rst diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index d76a60d95b588..a6d525cd9fc45 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -108,6 +108,7 @@ available subsections can be seen below. xilinx/index xillybus zorro + hte/index .. only:: subproject and html diff --git a/Documentation/index.rst b/Documentation/index.rst index 8f9be0e658b4d..67036a05b771f 100644 --- a/Documentation/index.rst +++ b/Documentation/index.rst @@ -137,7 +137,6 @@ needed). scheduler/index mhi/index peci/index - hte/index Architecture-agnostic documentation ----------------------------------- diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d0..e5b7b78d62d35 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9081,7 +9081,7 @@ HTE SUBSYSTEM M: Dipen Patel S: Maintained F: Documentation/devicetree/bindings/timestamp/ -F: Documentation/hte/ +F: Documentation/driver-api/hte/ F: drivers/hte/ F: include/linux/hte.h -- GitLab From 7aefd8b53815274f3ef398d370a3c9b27dd9f00c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Jun 2022 16:59:29 -0700 Subject: [PATCH 410/942] drm: imx: fix compiler warning with gcc-12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gcc-12 correctly warned about this code using a non-NULL pointer as a truth value: drivers/gpu/drm/imx/ipuv3-crtc.c: In function ‘ipu_crtc_disable_planes’: drivers/gpu/drm/imx/ipuv3-crtc.c:72:21: error: the comparison will always evaluate as ‘true’ for the address of ‘plane’ will never be NULL [-Werror=address] 72 | if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) | ^ due to the extraneous '&' address-of operator. Philipp Zabel points out that The mistake had no adverse effect since the following condition doesn't actually dereference the NULL pointer, but the intent of the code was obviously to check for it, not to take the address of the member. Fixes: eb8c88808c83 ("drm/imx: add deferred plane disabling") Acked-by: Philipp Zabel Signed-off-by: Linus Torvalds --- drivers/gpu/drm/imx/ipuv3-crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 9c8829f945b23..f7863d6dea804 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -69,7 +69,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) { if (plane == &ipu_crtc->plane[0]->base) disable_full = true; - if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) + if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) disable_partial = true; } -- GitLab From 49beadbd47c270a00754c107a837b4f29df4c822 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jun 2022 09:41:42 -0700 Subject: [PATCH 411/942] gcc-12: disable '-Wdangling-pointer' warning for now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the concept of checking for dangling pointers to local variables at function exit is really interesting, the gcc-12 implementation is not compatible with reality, and results in false positives. For example, gcc sees us putting things on a local list head allocated on the stack, which involves exactly those kinds of pointers to the local stack entry: In function ‘__list_add’, inlined from ‘list_add_tail’ at include/linux/list.h:102:2, inlined from ‘rebuild_snap_realms’ at fs/ceph/snap.c:434:2: include/linux/list.h:74:19: warning: storing the address of local variable ‘realm_queue’ in ‘*&realm_27(D)->rebuild_item.prev’ [-Wdangling-pointer=] 74 | new->prev = prev; | ~~~~~~~~~~^~~~~~ But then gcc - understandably - doesn't really understand the big picture how the doubly linked list works, so doesn't see how we then end up emptying said list head in a loop and the pointer we added has been removed. Gcc also complains about us (intentionally) using this as a way to store a kind of fake stack trace, eg drivers/acpi/acpica/utdebug.c:40:38: warning: storing the address of local variable ‘current_sp’ in ‘acpi_gbl_entry_stack_pointer’ [-Wdangling-pointer=] 40 | acpi_gbl_entry_stack_pointer = ¤t_sp; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~ which is entirely reasonable from a compiler standpoint, and we may want to change those kinds of patterns, but not not. So this is one of those "it would be lovely if the compiler were to complain about us leaving dangling pointers to the stack", but not this way. Signed-off-by: Linus Torvalds --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index c43d825a3c4c5..09208ffca353e 100644 --- a/Makefile +++ b/Makefile @@ -805,6 +805,9 @@ endif KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) +# These result in bogus false positives +KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer) + ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls else -- GitLab From 842c3b3ddc5f4d17275edbaa09e23d712bf8b915 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jun 2022 10:03:28 -0700 Subject: [PATCH 412/942] mellanox: mlx5: avoid uninitialized variable warning with gcc-12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc-12 started warning about 'tracker' being used uninitialized: drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c: In function ‘mlx5_do_bond’: drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c:786:28: warning: ‘tracker’ is used uninitialized [-Wuninitialized] 786 | struct lag_tracker tracker; | ^~~~~~~ which seems to be because it doesn't track how the use (and initialization) is bound by the 'do_bond' flag. But admittedly that 'do_bond' usage is fairly complicated, and involves passing it around as an argument to helper functions, so it's somewhat understandable that gcc doesn't see how that all works. This function could be rewritten to make the use of that tracker variable more obviously safe, but for now I'm just adding the forced initialization of it. Signed-off-by: Linus Torvalds --- drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c index 552b6e26e7019..2a8fc547eb37c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c @@ -783,7 +783,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev) { struct mlx5_core_dev *dev0 = ldev->pf[MLX5_LAG_P1].dev; struct mlx5_core_dev *dev1 = ldev->pf[MLX5_LAG_P2].dev; - struct lag_tracker tracker; + struct lag_tracker tracker = { }; bool do_bond, roce_lag; int err; int i; -- GitLab From f0be87c42cbd341d436d06da4792e6b0c83c3aeb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jun 2022 10:11:12 -0700 Subject: [PATCH 413/942] gcc-12: disable '-Warray-bounds' universally for now In commit 8b202ee21839 ("s390: disable -Warray-bounds") the s390 people disabled the '-Warray-bounds' warning for gcc-12, because the new logic in gcc would cause warnings for their use of the S390_lowcore macro, which accesses absolute pointers. It turns out gcc-12 has many other issues in this area, so this takes that s390 warning disable logic, and turns it into a kernel build config entry instead. Part of the intent is that we can make this all much more targeted, and use this conflig flag to disable it in only particular configurations that cause problems, with the s390 case as an example: select GCC12_NO_ARRAY_BOUNDS and we could do that for other configuration cases that cause issues. Or we could possibly use the CONFIG_CC_NO_ARRAY_BOUNDS thing in a more targeted way, and disable the warning only for particular uses: again the s390 case as an example: KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds) but this ends up just doing it globally in the top-level Makefile, since the current issues are spread fairly widely all over: KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds We'll try to limit this later, since the gcc-12 problems are rare enough that *much* of the kernel can be built with it without disabling this warning. Cc: Kees Cook Cc: Nathan Chancellor Signed-off-by: Linus Torvalds --- Makefile | 1 + arch/s390/Kconfig | 1 + arch/s390/Makefile | 10 +--------- init/Kconfig | 9 +++++++++ 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 09208ffca353e..b2e93c1a80218 100644 --- a/Makefile +++ b/Makefile @@ -788,6 +788,7 @@ stackp-flags-$(CONFIG_STACKPROTECTOR_STRONG) := -fstack-protector-strong KBUILD_CFLAGS += $(stackp-flags-y) KBUILD_CFLAGS-$(CONFIG_WERROR) += -Werror +KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) ifdef CONFIG_CC_IS_CLANG diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b1a88f6cc3494..5126a5db41fd0 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -125,6 +125,7 @@ config S390 select CLONE_BACKWARDS2 select DMA_OPS if PCI select DYNAMIC_FTRACE if FUNCTION_TRACER + select GCC12_NO_ARRAY_BOUNDS select GENERIC_ALLOCATOR select GENERIC_CPU_AUTOPROBE select GENERIC_CPU_VULNERABILITIES diff --git a/arch/s390/Makefile b/arch/s390/Makefile index d73611b35164f..495c68a4df1e9 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -32,15 +32,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) - -ifdef CONFIG_CC_IS_GCC - ifeq ($(call cc-ifversion, -ge, 1200, y), y) - ifeq ($(call cc-ifversion, -lt, 1300, y), y) - KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) - KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, array-bounds) - endif - endif -endif +KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds) UTS_MACHINE := s390x STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384) diff --git a/init/Kconfig b/init/Kconfig index c984afc489dea..c7900e8975f18 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -885,6 +885,15 @@ config CC_IMPLICIT_FALLTHROUGH default "-Wimplicit-fallthrough=5" if CC_IS_GCC && $(cc-option,-Wimplicit-fallthrough=5) default "-Wimplicit-fallthrough" if CC_IS_CLANG && $(cc-option,-Wunreachable-code-fallthrough) +# Currently, disable gcc-12 array-bounds globally. +# We may want to target only particular configurations some day. +config GCC12_NO_ARRAY_BOUNDS + def_bool y + +config CC_NO_ARRAY_BOUNDS + bool + default y if CC_IS_GCC && GCC_VERSION >= 120000 && GCC_VERSION < 130000 && GCC12_NO_ARRAY_BOUNDS + # # For architectures that know their GCC __int128 support is sound # -- GitLab From 507160f46c55913955d272ebf559d63809a8e560 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jun 2022 11:29:36 -0700 Subject: [PATCH 414/942] netfs: gcc-12: temporarily disable '-Wattribute-warning' for now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a pure band-aid so that I can continue merging stuff from people while some of the gcc-12 fallout gets sorted out. In particular, gcc-12 is very unhappy about the kinds of pointer arithmetic tricks that netfs does, and that makes the fortify checks trigger in afs and ceph: In function ‘fortify_memset_chk’, inlined from ‘netfs_i_context_init’ at include/linux/netfs.h:327:2, inlined from ‘afs_set_netfs_context’ at fs/afs/inode.c:61:2, inlined from ‘afs_root_iget’ at fs/afs/inode.c:543:2: include/linux/fortify-string.h:258:25: warning: call to ‘__write_overflow_field’ declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning] 258 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and the reason is that netfs_i_context_init() is passed a 'struct inode' pointer, and then it does struct netfs_i_context *ctx = netfs_i_context(inode); memset(ctx, 0, sizeof(*ctx)); where that netfs_i_context() function just does pointer arithmetic on the inode pointer, knowing that the netfs_i_context is laid out immediately after it in memory. This is all truly disgusting, since the whole "netfs_i_context is laid out immediately after it in memory" is not actually remotely true in general, but is just made to be that way for afs and ceph. See for example fs/cifs/cifsglob.h: struct cifsInodeInfo { struct { /* These must be contiguous */ struct inode vfs_inode; /* the VFS's inode record */ struct netfs_i_context netfs_ctx; /* Netfslib context */ }; [...] and realize that this is all entirely wrong, and the pointer arithmetic that netfs_i_context() is doing is also very very wrong and wouldn't give the right answer if netfs_ctx had different alignment rules from a 'struct inode', for example). Anyway, that's just a long-winded way to say "the gcc-12 warning is actually quite reasonable, and our code happens to work but is pretty disgusting". This is getting fixed properly, but for now I made the mistake of thinking "the week right after the merge window tends to be calm for me as people take a breather" and I did a sustem upgrade. And I got gcc-12 as a result, so to continue merging fixes from people and not have the end result drown in warnings, I am fixing all these gcc-12 issues I hit. Including with these kinds of temporary fixes. Cc: Kees Cook Cc: David Howells Link: https://lore.kernel.org/all/AEEBCF5D-8402-441D-940B-105AA718C71F@chromium.org/ Signed-off-by: Linus Torvalds --- fs/afs/inode.c | 3 +++ fs/ceph/inode.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 30b066299d39f..65b439cd53d29 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -25,6 +25,9 @@ #include "internal.h" #include "afs_fs.h" +// Temporary: netfs does disgusting things with inode pointers +#pragma GCC diagnostic ignored "-Wattribute-warning" + static const struct inode_operations afs_symlink_inode_operations = { .get_link = page_get_link, }; diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index b7e9cac3aeef0..5f1cc2b4ed068 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -20,6 +20,9 @@ #include "cache.h" #include +// Temporary: netfs does disgusting things with inode pointers +#pragma GCC diagnostic ignored "-Wattribute-warning" + /* * Ceph inode operations * -- GitLab From da4288b95baa1c7c9aa8a476f58b37eb238745b0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 8 Jun 2022 10:11:00 +0900 Subject: [PATCH 415/942] scripts/check-local-export: avoid 'wait $!' for process substitution Bash 4.4, released in 2016, supports 'wait $!' to check the exit status of a process substitution, but it seems too new. Some people using older bash versions (on CentOS 7, Ubuntu 16.04, etc.) reported an error like this: ./scripts/check-local-export: line 54: wait: pid 17328 is not a child of this shell I used the process substitution to avoid a pipeline, which executes each command in a subshell. If the while-loop is executed in the subshell context, variable changes within are lost after the subshell terminates. Fortunately, Bash 4.2, released in 2011, supports the 'lastpipe' option, which makes the last element of a pipeline run in the current shell process. Switch to the pipeline with 'lastpipe' solution, and also set 'pipefail' to catch errors from ${NM}. Add the bash requirement to Documentation/process/changes.rst. Fixes: 31cb50b5590f ("kbuild: check static EXPORT_SYMBOL* by script instead of modpost") Reported-by: Tetsuo Handa Reported-by: Michael Ellerman Reported-by: Wang Yugui Tested-by: Tetsuo Handa Tested-by: Jon Hunter Acked-by: Nick Desaulniers Tested-by: Sedat Dilek # LLVM-14 (x86-64) Signed-off-by: Masahiro Yamada --- Documentation/process/changes.rst | 12 +++++++++++ scripts/check-local-export | 36 ++++++++++++++++++------------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 34415ae1af1b5..19c286c23786f 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -32,6 +32,7 @@ you probably needn't concern yourself with pcmciautils. GNU C 5.1 gcc --version Clang/LLVM (optional) 11.0.0 clang --version GNU make 3.81 make --version +bash 4.2 bash --version binutils 2.23 ld -v flex 2.5.35 flex --version bison 2.0 bison --version @@ -84,6 +85,12 @@ Make You will need GNU make 3.81 or later to build the kernel. +Bash +---- + +Some bash scripts are used for the kernel build. +Bash 4.2 or newer is needed. + Binutils -------- @@ -362,6 +369,11 @@ Make - +Bash +---- + +- + Binutils -------- diff --git a/scripts/check-local-export b/scripts/check-local-export index da745e2743b74..6ccc2f4674166 100755 --- a/scripts/check-local-export +++ b/scripts/check-local-export @@ -8,11 +8,31 @@ set -e +# catch errors from ${NM} +set -o pipefail + +# Run the last element of a pipeline in the current shell. +# Without this, the while-loop would be executed in a subshell, and +# the changes made to 'symbol_types' and 'export_symbols' would be lost. +shopt -s lastpipe + declare -A symbol_types declare -a export_symbols exit_code=0 +# If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) shows +# 'no symbols' diagnostic (but exits with 0). It is harmless and hidden by +# '2>/dev/null'. However, it suppresses real error messages as well. Add a +# hand-crafted error message here. +# +# TODO: +# Use --quiet instead of 2>/dev/null when we upgrade the minimum version of +# binutils to 2.37, llvm to 13.0.0. +# Then, the following line will be really simple: +# ${NM} --quiet ${1} | + +{ ${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } } | while read value type name do # Skip the line if the number of fields is less than 3. @@ -37,21 +57,7 @@ do if [[ ${name} == __ksymtab_* ]]; then export_symbols+=(${name#__ksymtab_}) fi - - # If there is no symbol in the object, ${NM} (both GNU nm and llvm-nm) - # shows 'no symbols' diagnostic (but exits with 0). It is harmless and - # hidden by '2>/dev/null'. However, it suppresses real error messages - # as well. Add a hand-crafted error message here. - # - # Use --quiet instead of 2>/dev/null when we upgrade the minimum version - # of binutils to 2.37, llvm to 13.0.0. - # - # Then, the following line will be really simple: - # done < <(${NM} --quiet ${1}) -done < <(${NM} ${1} 2>/dev/null || { echo "${0}: ${NM} failed" >&2; false; } ) - -# Catch error in the process substitution -wait $! +done for name in "${export_symbols[@]}" do -- GitLab From 387c67afccbb271707cbe6de2817f4e4c76287ad Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 9 Jun 2022 20:42:30 +0200 Subject: [PATCH 416/942] docs: arm: tcm: Fix typo in description of TCM and MMU usage Correct a typo in the description of interaction between the TCM and MMU. Found by inspection. Signed-off-by: Simon Horman Link: https://lore.kernel.org/r/20220609184230.627958-1-simon.horman@corigine.com Signed-off-by: Jonathan Corbet --- Documentation/arm/tcm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/arm/tcm.rst b/Documentation/arm/tcm.rst index b256f97838839..1dc6c39220f98 100644 --- a/Documentation/arm/tcm.rst +++ b/Documentation/arm/tcm.rst @@ -34,7 +34,7 @@ CPU so it is usually wise not to overlap any physical RAM with the TCM. The TCM memory can then be remapped to another address again using -the MMU, but notice that the TCM if often used in situations where +the MMU, but notice that the TCM is often used in situations where the MMU is turned off. To avoid confusion the current Linux implementation will map the TCM 1 to 1 from physical to virtual memory in the location specified by the kernel. Currently Linux -- GitLab From 41e456400212803704e82691716e1d7b0865114a Mon Sep 17 00:00:00 2001 From: Yupeng Li Date: Wed, 8 Jun 2022 09:12:29 +0800 Subject: [PATCH 417/942] MIPS: Loongson-3: fix compile mips cpu_hwmon as module build error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit set cpu_hwmon as a module build with loongson_sysconf, loongson_chiptemp undefined error,fix cpu_hwmon compile options to be bool.Some kernel compilation error information is as follows: Checking missing-syscalls for N32 CALL scripts/checksyscalls.sh Checking missing-syscalls for O32 CALL scripts/checksyscalls.sh CALL scripts/checksyscalls.sh CHK include/generated/compile.h CC [M] drivers/platform/mips/cpu_hwmon.o Building modules, stage 2. MODPOST 200 modules ERROR: "loongson_sysconf" [drivers/platform/mips/cpu_hwmon.ko] undefined! ERROR: "loongson_chiptemp" [drivers/platform/mips/cpu_hwmon.ko] undefined! make[1]: *** [scripts/Makefile.modpost:92:__modpost] 错误 1 make: *** [Makefile:1261:modules] 错误 2 Signed-off-by: Yupeng Li Reviewed-by: Guenter Roeck Reviewed-by: Huacai Chen Signed-off-by: Thomas Bogendoerfer --- drivers/platform/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mips/Kconfig b/drivers/platform/mips/Kconfig index d421e14823957..6b51ad01f7915 100644 --- a/drivers/platform/mips/Kconfig +++ b/drivers/platform/mips/Kconfig @@ -17,7 +17,7 @@ menuconfig MIPS_PLATFORM_DEVICES if MIPS_PLATFORM_DEVICES config CPU_HWMON - tristate "Loongson-3 CPU HWMon Driver" + bool "Loongson-3 CPU HWMon Driver" depends on MACH_LOONGSON64 select HWMON default y -- GitLab From 6bf74cddcffac0bc5ee0fad724aac778d2e53f75 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Tue, 7 Jun 2022 15:45:53 -0400 Subject: [PATCH 418/942] filemap: Don't release a locked folio We must hold a reference over the call to filemap_release_folio(), otherwise the page cache will put the last reference to the folio before we unlock it, leading to splats like this: BUG: Bad page state in process u8:5 pfn:1ab1f4 page:ffffea0006ac7d00 refcount:0 mapcount:0 mapping:0000000000000000 index:0x28b1de pfn:0x1ab1f4 flags: 0x17ff80000040001(locked|reclaim|node=0|zone=2|lastcpupid=0xfff) raw: 017ff80000040001 dead000000000100 dead000000000122 0000000000000000 raw: 000000000028b1de 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set It's an error path, so it doesn't see much testing. Reported-by: Darrick J. Wong Fixes: a42634a6c07d ("readahead: Use a folio in read_pages()") Signed-off-by: Matthew Wilcox (Oracle) --- mm/readahead.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/readahead.c b/mm/readahead.c index 415c39d764eae..57a0151082543 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -164,12 +164,14 @@ static void read_pages(struct readahead_control *rac) while ((folio = readahead_folio(rac)) != NULL) { unsigned long nr = folio_nr_pages(folio); + folio_get(folio); rac->ra->size -= nr; if (rac->ra->async_size >= nr) { rac->ra->async_size -= nr; filemap_remove_folio(folio); } folio_unlock(folio); + folio_put(folio); } } else { while ((folio = readahead_folio(rac)) != NULL) -- GitLab From dcfa24ba68991ab69a48254a18377b45180ae664 Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Wed, 25 May 2022 14:23:45 -0400 Subject: [PATCH 419/942] filemap: Cache the value of vm_flags After we have unlocked the mmap_lock for I/O, the file is pinned, but the VMA is not. Checking this flag after that can be a use-after-free. It's not a terribly interesting use-after-free as it can only read one bit, and it's used to decide whether to read 2MB or 4MB. But it upsets the automated tools and it's generally bad practice anyway, so let's fix it. Reported-by: syzbot+5b96d55e5b54924c77ad@syzkaller.appspotmail.com Fixes: 4687fdbb805a ("mm/filemap: Support VM_HUGEPAGE for file mappings") Cc: stable@vger.kernel.org Signed-off-by: Matthew Wilcox (Oracle) --- mm/filemap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 9daeaab36081f..ac3775c1ce4cd 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2991,11 +2991,12 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) struct address_space *mapping = file->f_mapping; DEFINE_READAHEAD(ractl, file, ra, mapping, vmf->pgoff); struct file *fpin = NULL; + unsigned long vm_flags = vmf->vma->vm_flags; unsigned int mmap_miss; #ifdef CONFIG_TRANSPARENT_HUGEPAGE /* Use the readahead code, even if readahead is disabled */ - if (vmf->vma->vm_flags & VM_HUGEPAGE) { + if (vm_flags & VM_HUGEPAGE) { fpin = maybe_unlock_mmap_for_io(vmf, fpin); ractl._index &= ~((unsigned long)HPAGE_PMD_NR - 1); ra->size = HPAGE_PMD_NR; @@ -3003,7 +3004,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) * Fetch two PMD folios, so we get the chance to actually * readahead, unless we've been told not to. */ - if (!(vmf->vma->vm_flags & VM_RAND_READ)) + if (!(vm_flags & VM_RAND_READ)) ra->size *= 2; ra->async_size = HPAGE_PMD_NR; page_cache_ra_order(&ractl, ra, HPAGE_PMD_ORDER); @@ -3012,12 +3013,12 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf) #endif /* If we don't want any read-ahead, don't bother */ - if (vmf->vma->vm_flags & VM_RAND_READ) + if (vm_flags & VM_RAND_READ) return fpin; if (!ra->ra_pages) return fpin; - if (vmf->vma->vm_flags & VM_SEQ_READ) { + if (vm_flags & VM_SEQ_READ) { fpin = maybe_unlock_mmap_for_io(vmf, fpin); page_cache_sync_ra(&ractl, ra->ra_pages); return fpin; -- GitLab From 69a37a8ba1b408a1c7616494aa7018e4b3844cbe Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Wed, 8 Jun 2022 15:18:34 -0400 Subject: [PATCH 420/942] mm/huge_memory: Fix xarray node memory leak If xas_split_alloc() fails to allocate the necessary nodes to complete the xarray entry split, it sets the xa_state to -ENOMEM, which xas_nomem() then interprets as "Please allocate more memory", not as "Please free any unnecessary memory" (which was the intended outcome). It's confusing to use xas_nomem() to free memory in this context, so call xas_destroy() instead. Reported-by: syzbot+9e27a75a8c24f3fe75c1@syzkaller.appspotmail.com Fixes: 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache") Cc: stable@vger.kernel.org Signed-off-by: Matthew Wilcox (Oracle) --- include/linux/xarray.h | 1 + lib/xarray.c | 5 +++-- mm/huge_memory.c | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/xarray.h b/include/linux/xarray.h index 72feab5ea8d4a..c29e11b2c0739 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -1508,6 +1508,7 @@ void *xas_find_marked(struct xa_state *, unsigned long max, xa_mark_t); void xas_init_marks(const struct xa_state *); bool xas_nomem(struct xa_state *, gfp_t); +void xas_destroy(struct xa_state *); void xas_pause(struct xa_state *); void xas_create_range(struct xa_state *); diff --git a/lib/xarray.c b/lib/xarray.c index 54e646e8e6ee7..ea9ce1f0b3863 100644 --- a/lib/xarray.c +++ b/lib/xarray.c @@ -264,9 +264,10 @@ static void xa_node_free(struct xa_node *node) * xas_destroy() - Free any resources allocated during the XArray operation. * @xas: XArray operation state. * - * This function is now internal-only. + * Most users will not need to call this function; it is called for you + * by xas_nomem(). */ -static void xas_destroy(struct xa_state *xas) +void xas_destroy(struct xa_state *xas) { struct xa_node *next, *node = xas->xa_alloc; diff --git a/mm/huge_memory.c b/mm/huge_memory.c index a77c78a2b6b55..f7248002dad98 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2672,8 +2672,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) if (mapping) i_mmap_unlock_read(mapping); out: - /* Free any memory we didn't use */ - xas_nomem(&xas, 0); + xas_destroy(&xas); count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED); return ret; } -- GitLab From 334f6f53abcf57782bd2fe81da1cbd893e4ef05c Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" Date: Thu, 9 Jun 2022 09:13:57 -0400 Subject: [PATCH 421/942] mm: Add kernel-doc for folio->mlock_count Fix "./include/linux/mm_types.h:279: warning: Function parameter or member 'mlock_count' not described in 'folio'". Also neaten the html by hiding the anon struct. Signed-off-by: Matthew Wilcox (Oracle) --- include/linux/mm_types.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index b34ff2cdbc4fa..c29ab4c0cd5c6 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -227,6 +227,7 @@ struct page { * struct folio - Represents a contiguous set of bytes. * @flags: Identical to the page flags. * @lru: Least Recently Used list; tracks how recently this folio was used. + * @mlock_count: Number of times this folio has been pinned by mlock(). * @mapping: The file this page belongs to, or refers to the anon_vma for * anonymous memory. * @index: Offset within the file, in units of pages. For anonymous memory, @@ -255,10 +256,14 @@ struct folio { unsigned long flags; union { struct list_head lru; + /* private: avoid cluttering the output */ struct { void *__filler; + /* public: */ unsigned int mlock_count; + /* private: */ }; + /* public: */ }; struct address_space *mapping; pgoff_t index; -- GitLab From 874c8ca1e60b2c564a48f7e7acc40d328d5c8733 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 9 Jun 2022 21:46:04 +0100 Subject: [PATCH 422/942] netfs: Fix gcc-12 warning by embedding vfs inode in netfs_i_context While randstruct was satisfied with using an open-coded "void *" offset cast for the netfs_i_context <-> inode casting, __builtin_object_size() as used by FORTIFY_SOURCE was not as easily fooled. This was causing the following complaint[1] from gcc v12: In file included from include/linux/string.h:253, from include/linux/ceph/ceph_debug.h:7, from fs/ceph/inode.c:2: In function 'fortify_memset_chk', inlined from 'netfs_i_context_init' at include/linux/netfs.h:326:2, inlined from 'ceph_alloc_inode' at fs/ceph/inode.c:463:2: include/linux/fortify-string.h:242:25: warning: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning] 242 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix this by embedding a struct inode into struct netfs_i_context (which should perhaps be renamed to struct netfs_inode). The struct inode vfs_inode fields are then removed from the 9p, afs, ceph and cifs inode structs and vfs_inode is then simply changed to "netfs.inode" in those filesystems. Further, rename netfs_i_context to netfs_inode, get rid of the netfs_inode() function that converted a netfs_i_context pointer to an inode pointer (that can now be done with &ctx->inode) and rename the netfs_i_context() function to netfs_inode() (which is now a wrapper around container_of()). Most of the changes were done with: perl -p -i -e 's/vfs_inode/netfs.inode/'g \ `git grep -l 'vfs_inode' -- fs/{9p,afs,ceph,cifs}/*.[ch]` Kees suggested doing it with a pair structure[2] and a special declarator to insert that into the network filesystem's inode wrapper[3], but I think it's cleaner to embed it - and then it doesn't matter if struct randomisation reorders things. Dave Chinner suggested using a filesystem-specific VFS_I() function in each filesystem to convert that filesystem's own inode wrapper struct into the VFS inode struct[4]. Version #2: - Fix a couple of missed name changes due to a disabled cifs option. - Rename nfs_i_context to nfs_inode - Use "netfs" instead of "nic" as the member name in per-fs inode wrapper structs. [ This also undoes commit 507160f46c55 ("netfs: gcc-12: temporarily disable '-Wattribute-warning' for now") that is no longer needed ] Fixes: bc899ee1c898 ("netfs: Add a netfs inode context") Reported-by: Jeff Layton Signed-off-by: David Howells Reviewed-by: Jeff Layton Reviewed-by: Kees Cook Reviewed-by: Xiubo Li cc: Jonathan Corbet cc: Eric Van Hensbergen cc: Latchesar Ionkov cc: Dominique Martinet cc: Christian Schoenebeck cc: Marc Dionne cc: Ilya Dryomov cc: Steve French cc: William Kucharski cc: "Matthew Wilcox (Oracle)" cc: Dave Chinner cc: linux-doc@vger.kernel.org cc: v9fs-developer@lists.sourceforge.net cc: linux-afs@lists.infradead.org cc: ceph-devel@vger.kernel.org cc: linux-cifs@vger.kernel.org cc: samba-technical@lists.samba.org cc: linux-fsdevel@vger.kernel.org cc: linux-hardening@vger.kernel.org Link: https://lore.kernel.org/r/d2ad3a3d7bdd794c6efb562d2f2b655fb67756b9.camel@kernel.org/ [1] Link: https://lore.kernel.org/r/20220517210230.864239-1-keescook@chromium.org/ [2] Link: https://lore.kernel.org/r/20220518202212.2322058-1-keescook@chromium.org/ [3] Link: https://lore.kernel.org/r/20220524101205.GI2306852@dread.disaster.area/ [4] Link: https://lore.kernel.org/r/165296786831.3591209.12111293034669289733.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/165305805651.4094995.7763502506786714216.stgit@warthog.procyon.org.uk # v2 Signed-off-by: Linus Torvalds --- Documentation/filesystems/netfs_library.rst | 37 ++++--- fs/9p/cache.c | 4 +- fs/9p/v9fs.c | 2 +- fs/9p/v9fs.h | 10 +- fs/9p/vfs_addr.c | 2 +- fs/9p/vfs_inode.c | 4 +- fs/afs/callback.c | 2 +- fs/afs/dir.c | 32 +++--- fs/afs/dir_edit.c | 10 +- fs/afs/dir_silly.c | 4 +- fs/afs/dynroot.c | 2 +- fs/afs/file.c | 4 +- fs/afs/fs_operation.c | 6 +- fs/afs/inode.c | 41 ++++---- fs/afs/internal.h | 23 ++--- fs/afs/super.c | 6 +- fs/afs/write.c | 21 ++-- fs/ceph/addr.c | 4 +- fs/ceph/cache.c | 4 +- fs/ceph/cache.h | 2 +- fs/ceph/caps.c | 104 ++++++++++---------- fs/ceph/file.c | 2 +- fs/ceph/inode.c | 13 +-- fs/ceph/mds_client.c | 4 +- fs/ceph/snap.c | 8 +- fs/ceph/super.c | 2 +- fs/ceph/super.h | 10 +- fs/ceph/xattr.c | 14 +-- fs/cifs/cifsfs.c | 8 +- fs/cifs/cifsglob.h | 12 +-- fs/cifs/file.c | 8 +- fs/cifs/fscache.c | 8 +- fs/cifs/fscache.h | 8 +- fs/cifs/inode.c | 4 +- fs/cifs/misc.c | 4 +- fs/cifs/smb2ops.c | 8 +- fs/netfs/buffered_read.c | 6 +- fs/netfs/internal.h | 2 +- fs/netfs/objects.c | 2 +- include/linux/netfs.h | 41 +++----- 40 files changed, 227 insertions(+), 261 deletions(-) diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst index a80a59941d2fe..3276c3d551426 100644 --- a/Documentation/filesystems/netfs_library.rst +++ b/Documentation/filesystems/netfs_library.rst @@ -37,30 +37,31 @@ The network filesystem helper library needs a place to store a bit of state for its use on each netfs inode it is helping to manage. To this end, a context structure is defined:: - struct netfs_i_context { + struct netfs_inode { + struct inode inode; const struct netfs_request_ops *ops; - struct fscache_cookie *cache; + struct fscache_cookie *cache; }; -A network filesystem that wants to use netfs lib must place one of these -directly after the VFS ``struct inode`` it allocates, usually as part of its -own struct. This can be done in a way similar to the following:: +A network filesystem that wants to use netfs lib must place one of these in its +inode wrapper struct instead of the VFS ``struct inode``. This can be done in +a way similar to the following:: struct my_inode { - struct { - /* These must be contiguous */ - struct inode vfs_inode; - struct netfs_i_context netfs_ctx; - }; + struct netfs_inode netfs; /* Netfslib context and vfs inode */ ... }; -This allows netfslib to find its state by simple offset from the inode pointer, -thereby allowing the netfslib helper functions to be pointed to directly by the -VFS/VM operation tables. +This allows netfslib to find its state by using ``container_of()`` from the +inode pointer, thereby allowing the netfslib helper functions to be pointed to +directly by the VFS/VM operation tables. The structure contains the following fields: + * ``inode`` + + The VFS inode structure. + * ``ops`` The set of operations provided by the network filesystem to netfslib. @@ -78,14 +79,12 @@ To help deal with the per-inode context, a number helper functions are provided. Firstly, a function to perform basic initialisation on a context and set the operations table pointer:: - void netfs_i_context_init(struct inode *inode, - const struct netfs_request_ops *ops); + void netfs_inode_init(struct inode *inode, + const struct netfs_request_ops *ops); -then two functions to cast between the VFS inode structure and the netfs -context:: +then a function to cast from the VFS inode structure to the netfs context:: - struct netfs_i_context *netfs_i_context(struct inode *inode); - struct inode *netfs_inode(struct netfs_i_context *ctx); + struct netfs_inode *netfs_node(struct inode *inode); and finally, a function to get the cache cookie pointer from the context attached to an inode (or NULL if fscache is disabled):: diff --git a/fs/9p/cache.c b/fs/9p/cache.c index 1c8dc696d516f..cebba4eaa0b57 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c @@ -62,12 +62,12 @@ void v9fs_cache_inode_get_cookie(struct inode *inode) version = cpu_to_le32(v9inode->qid.version); path = cpu_to_le64(v9inode->qid.path); v9ses = v9fs_inode2v9ses(inode); - v9inode->netfs_ctx.cache = + v9inode->netfs.cache = fscache_acquire_cookie(v9fs_session_cache(v9ses), 0, &path, sizeof(path), &version, sizeof(version), - i_size_read(&v9inode->vfs_inode)); + i_size_read(&v9inode->netfs.inode)); p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n", inode, v9fs_inode_cookie(v9inode)); diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index e28ddf763b3b9..0129de2ea31ae 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -625,7 +625,7 @@ static void v9fs_inode_init_once(void *foo) struct v9fs_inode *v9inode = (struct v9fs_inode *)foo; memset(&v9inode->qid, 0, sizeof(v9inode->qid)); - inode_init_once(&v9inode->vfs_inode); + inode_init_once(&v9inode->netfs.inode); } /** diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index ec0e8df3b2eb2..1b219c21d15eb 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -109,11 +109,7 @@ struct v9fs_session_info { #define V9FS_INO_INVALID_ATTR 0x01 struct v9fs_inode { - struct { - /* These must be contiguous */ - struct inode vfs_inode; /* the VFS's inode record */ - struct netfs_i_context netfs_ctx; /* Netfslib context */ - }; + struct netfs_inode netfs; /* Netfslib context and vfs inode */ struct p9_qid qid; unsigned int cache_validity; struct p9_fid *writeback_fid; @@ -122,13 +118,13 @@ struct v9fs_inode { static inline struct v9fs_inode *V9FS_I(const struct inode *inode) { - return container_of(inode, struct v9fs_inode, vfs_inode); + return container_of(inode, struct v9fs_inode, netfs.inode); } static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode) { #ifdef CONFIG_9P_FSCACHE - return netfs_i_cookie(&v9inode->vfs_inode); + return netfs_i_cookie(&v9inode->netfs.inode); #else return NULL; #endif diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 8ce82ff1e40af..90c6c1ba03ab7 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -140,7 +140,7 @@ static void v9fs_write_to_cache_done(void *priv, ssize_t transferred_or_error, transferred_or_error != -ENOBUFS) { version = cpu_to_le32(v9inode->qid.version); fscache_invalidate(v9fs_inode_cookie(v9inode), &version, - i_size_read(&v9inode->vfs_inode), 0); + i_size_read(&v9inode->netfs.inode), 0); } } diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 55367ecb9442e..e660c6348b9da 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -234,7 +234,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb) v9inode->writeback_fid = NULL; v9inode->cache_validity = 0; mutex_init(&v9inode->v_mutex); - return &v9inode->vfs_inode; + return &v9inode->netfs.inode; } /** @@ -252,7 +252,7 @@ void v9fs_free_inode(struct inode *inode) */ static void v9fs_set_netfs_context(struct inode *inode) { - netfs_i_context_init(inode, &v9fs_req_ops); + netfs_inode_init(inode, &v9fs_req_ops); } int v9fs_init_inode(struct v9fs_session_info *v9ses, diff --git a/fs/afs/callback.c b/fs/afs/callback.c index 1b4d5809808d0..a484fa6428081 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c @@ -30,7 +30,7 @@ void afs_invalidate_mmap_work(struct work_struct *work) { struct afs_vnode *vnode = container_of(work, struct afs_vnode, cb_work); - unmap_mapping_pages(vnode->vfs_inode.i_mapping, 0, 0, false); + unmap_mapping_pages(vnode->netfs.inode.i_mapping, 0, 0, false); } void afs_server_init_callback_work(struct work_struct *work) diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 79f6b74336d28..56ae5cd5184f0 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -109,7 +109,7 @@ struct afs_lookup_cookie { */ static void afs_dir_read_cleanup(struct afs_read *req) { - struct address_space *mapping = req->vnode->vfs_inode.i_mapping; + struct address_space *mapping = req->vnode->netfs.inode.i_mapping; struct folio *folio; pgoff_t last = req->nr_pages - 1; @@ -153,7 +153,7 @@ static bool afs_dir_check_folio(struct afs_vnode *dvnode, struct folio *folio, block = kmap_local_folio(folio, offset); if (block->hdr.magic != AFS_DIR_MAGIC) { printk("kAFS: %s(%lx): [%llx] bad magic %zx/%zx is %04hx\n", - __func__, dvnode->vfs_inode.i_ino, + __func__, dvnode->netfs.inode.i_ino, pos, offset, size, ntohs(block->hdr.magic)); trace_afs_dir_check_failed(dvnode, pos + offset, i_size); kunmap_local(block); @@ -183,7 +183,7 @@ static bool afs_dir_check_folio(struct afs_vnode *dvnode, struct folio *folio, static void afs_dir_dump(struct afs_vnode *dvnode, struct afs_read *req) { union afs_xdr_dir_block *block; - struct address_space *mapping = dvnode->vfs_inode.i_mapping; + struct address_space *mapping = dvnode->netfs.inode.i_mapping; struct folio *folio; pgoff_t last = req->nr_pages - 1; size_t offset, size; @@ -217,7 +217,7 @@ static void afs_dir_dump(struct afs_vnode *dvnode, struct afs_read *req) */ static int afs_dir_check(struct afs_vnode *dvnode, struct afs_read *req) { - struct address_space *mapping = dvnode->vfs_inode.i_mapping; + struct address_space *mapping = dvnode->netfs.inode.i_mapping; struct folio *folio; pgoff_t last = req->nr_pages - 1; int ret = 0; @@ -269,7 +269,7 @@ static int afs_dir_open(struct inode *inode, struct file *file) static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) __acquires(&dvnode->validate_lock) { - struct address_space *mapping = dvnode->vfs_inode.i_mapping; + struct address_space *mapping = dvnode->netfs.inode.i_mapping; struct afs_read *req; loff_t i_size; int nr_pages, i; @@ -287,7 +287,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) req->cleanup = afs_dir_read_cleanup; expand: - i_size = i_size_read(&dvnode->vfs_inode); + i_size = i_size_read(&dvnode->netfs.inode); if (i_size < 2048) { ret = afs_bad(dvnode, afs_file_error_dir_small); goto error; @@ -305,7 +305,7 @@ static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key) req->actual_len = i_size; /* May change */ req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */ req->data_version = dvnode->status.data_version; /* May change */ - iov_iter_xarray(&req->def_iter, READ, &dvnode->vfs_inode.i_mapping->i_pages, + iov_iter_xarray(&req->def_iter, READ, &dvnode->netfs.inode.i_mapping->i_pages, 0, i_size); req->iter = &req->def_iter; @@ -897,7 +897,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry, out_op: if (op->error == 0) { - inode = &op->file[1].vnode->vfs_inode; + inode = &op->file[1].vnode->netfs.inode; op->file[1].vnode = NULL; } @@ -1139,7 +1139,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) afs_stat_v(dir, n_reval); /* search the directory for this vnode */ - ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version); + ret = afs_do_lookup_one(&dir->netfs.inode, dentry, &fid, key, &dir_version); switch (ret) { case 0: /* the filename maps to something */ @@ -1170,7 +1170,7 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) _debug("%pd: file deleted (uq %u -> %u I:%u)", dentry, fid.unique, vnode->fid.unique, - vnode->vfs_inode.i_generation); + vnode->netfs.inode.i_generation); goto not_found; } goto out_valid; @@ -1368,7 +1368,7 @@ static void afs_dir_remove_subdir(struct dentry *dentry) if (d_really_is_positive(dentry)) { struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); - clear_nlink(&vnode->vfs_inode); + clear_nlink(&vnode->netfs.inode); set_bit(AFS_VNODE_DELETED, &vnode->flags); clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags); clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); @@ -1487,8 +1487,8 @@ static void afs_dir_remove_link(struct afs_operation *op) /* Already done */ } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) { write_seqlock(&vnode->cb_lock); - drop_nlink(&vnode->vfs_inode); - if (vnode->vfs_inode.i_nlink == 0) { + drop_nlink(&vnode->netfs.inode); + if (vnode->netfs.inode.i_nlink == 0) { set_bit(AFS_VNODE_DELETED, &vnode->flags); __afs_break_callback(vnode, afs_cb_break_for_unlink); } @@ -1504,7 +1504,7 @@ static void afs_dir_remove_link(struct afs_operation *op) op->error = ret; } - _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, op->error); + _debug("nlink %d [val %d]", vnode->netfs.inode.i_nlink, op->error); } static void afs_unlink_success(struct afs_operation *op) @@ -1680,8 +1680,8 @@ static void afs_link_success(struct afs_operation *op) afs_update_dentry_version(op, dvp, op->dentry); if (op->dentry_2->d_parent == op->dentry->d_parent) afs_update_dentry_version(op, dvp, op->dentry_2); - ihold(&vp->vnode->vfs_inode); - d_instantiate(op->dentry, &vp->vnode->vfs_inode); + ihold(&vp->vnode->netfs.inode); + d_instantiate(op->dentry, &vp->vnode->netfs.inode); } static void afs_link_put(struct afs_operation *op) diff --git a/fs/afs/dir_edit.c b/fs/afs/dir_edit.c index d98e109ecee9a..0ab7752d1b758 100644 --- a/fs/afs/dir_edit.c +++ b/fs/afs/dir_edit.c @@ -109,7 +109,7 @@ static void afs_clear_contig_bits(union afs_xdr_dir_block *block, */ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index) { - struct address_space *mapping = vnode->vfs_inode.i_mapping; + struct address_space *mapping = vnode->netfs.inode.i_mapping; struct folio *folio; folio = __filemap_get_folio(mapping, index, @@ -216,7 +216,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, _enter(",,{%d,%s},", name->len, name->name); - i_size = i_size_read(&vnode->vfs_inode); + i_size = i_size_read(&vnode->netfs.inode); if (i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS || (i_size & (AFS_DIR_BLOCK_SIZE - 1))) { clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags); @@ -336,7 +336,7 @@ void afs_edit_dir_add(struct afs_vnode *vnode, if (b < AFS_DIR_BLOCKS_WITH_CTR) meta->meta.alloc_ctrs[b] -= need_slots; - inode_inc_iversion_raw(&vnode->vfs_inode); + inode_inc_iversion_raw(&vnode->netfs.inode); afs_stat_v(vnode, n_dir_cr); _debug("Insert %s in %u[%u]", name->name, b, slot); @@ -383,7 +383,7 @@ void afs_edit_dir_remove(struct afs_vnode *vnode, _enter(",,{%d,%s},", name->len, name->name); - i_size = i_size_read(&vnode->vfs_inode); + i_size = i_size_read(&vnode->netfs.inode); if (i_size < AFS_DIR_BLOCK_SIZE || i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS || (i_size & (AFS_DIR_BLOCK_SIZE - 1))) { @@ -463,7 +463,7 @@ void afs_edit_dir_remove(struct afs_vnode *vnode, if (b < AFS_DIR_BLOCKS_WITH_CTR) meta->meta.alloc_ctrs[b] += need_slots; - inode_set_iversion_raw(&vnode->vfs_inode, vnode->status.data_version); + inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version); afs_stat_v(vnode, n_dir_rm); _debug("Remove %s from %u[%u]", name->name, b, slot); diff --git a/fs/afs/dir_silly.c b/fs/afs/dir_silly.c index 45cfd50a95210..bb5807e87fa4c 100644 --- a/fs/afs/dir_silly.c +++ b/fs/afs/dir_silly.c @@ -131,7 +131,7 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode, goto out; } while (!d_is_negative(sdentry)); - ihold(&vnode->vfs_inode); + ihold(&vnode->netfs.inode); ret = afs_do_silly_rename(dvnode, vnode, dentry, sdentry, key); switch (ret) { @@ -148,7 +148,7 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode, d_drop(sdentry); } - iput(&vnode->vfs_inode); + iput(&vnode->netfs.inode); dput(sdentry); out: _leave(" = %d", ret); diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c index f120bcb8bf738..3a5bbffdf0534 100644 --- a/fs/afs/dynroot.c +++ b/fs/afs/dynroot.c @@ -76,7 +76,7 @@ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) /* there shouldn't be an existing inode */ BUG_ON(!(inode->i_state & I_NEW)); - netfs_i_context_init(inode, NULL); + netfs_inode_init(inode, NULL); inode->i_size = 0; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; if (root) { diff --git a/fs/afs/file.c b/fs/afs/file.c index a8e8832179e4e..4de7af7c2f09e 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -194,7 +194,7 @@ int afs_release(struct inode *inode, struct file *file) afs_put_wb_key(af->wb); if ((file->f_mode & FMODE_WRITE)) { - i_size = i_size_read(&vnode->vfs_inode); + i_size = i_size_read(&vnode->netfs.inode); afs_set_cache_aux(vnode, &aux); fscache_unuse_cookie(afs_vnode_cache(vnode), &aux, &i_size); } else { @@ -325,7 +325,7 @@ static void afs_issue_read(struct netfs_io_subrequest *subreq) fsreq->iter = &fsreq->def_iter; iov_iter_xarray(&fsreq->def_iter, READ, - &fsreq->vnode->vfs_inode.i_mapping->i_pages, + &fsreq->vnode->netfs.inode.i_mapping->i_pages, fsreq->pos, fsreq->len); afs_fetch_data(fsreq->vnode, fsreq); diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c index d222dfbe976be..7a3803ce3a229 100644 --- a/fs/afs/fs_operation.c +++ b/fs/afs/fs_operation.c @@ -232,14 +232,14 @@ int afs_put_operation(struct afs_operation *op) if (op->file[1].modification && op->file[1].vnode != op->file[0].vnode) clear_bit(AFS_VNODE_MODIFYING, &op->file[1].vnode->flags); if (op->file[0].put_vnode) - iput(&op->file[0].vnode->vfs_inode); + iput(&op->file[0].vnode->netfs.inode); if (op->file[1].put_vnode) - iput(&op->file[1].vnode->vfs_inode); + iput(&op->file[1].vnode->netfs.inode); if (op->more_files) { for (i = 0; i < op->nr_files - 2; i++) if (op->more_files[i].put_vnode) - iput(&op->more_files[i].vnode->vfs_inode); + iput(&op->more_files[i].vnode->netfs.inode); kfree(op->more_files); } diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 65b439cd53d29..22811e9eacf58 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -25,9 +25,6 @@ #include "internal.h" #include "afs_fs.h" -// Temporary: netfs does disgusting things with inode pointers -#pragma GCC diagnostic ignored "-Wattribute-warning" - static const struct inode_operations afs_symlink_inode_operations = { .get_link = page_get_link, }; @@ -61,7 +58,7 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren */ static void afs_set_netfs_context(struct afs_vnode *vnode) { - netfs_i_context_init(&vnode->vfs_inode, &afs_req_ops); + netfs_inode_init(&vnode->netfs.inode, &afs_req_ops); } /* @@ -99,7 +96,7 @@ static int afs_inode_init_from_status(struct afs_operation *op, inode->i_flags |= S_NOATIME; inode->i_uid = make_kuid(&init_user_ns, status->owner); inode->i_gid = make_kgid(&init_user_ns, status->group); - set_nlink(&vnode->vfs_inode, status->nlink); + set_nlink(&vnode->netfs.inode, status->nlink); switch (status->type) { case AFS_FTYPE_FILE: @@ -142,7 +139,7 @@ static int afs_inode_init_from_status(struct afs_operation *op, afs_set_netfs_context(vnode); vnode->invalid_before = status->data_version; - inode_set_iversion_raw(&vnode->vfs_inode, status->data_version); + inode_set_iversion_raw(&vnode->netfs.inode, status->data_version); if (!vp->scb.have_cb) { /* it's a symlink we just created (the fileserver @@ -166,7 +163,7 @@ static void afs_apply_status(struct afs_operation *op, { struct afs_file_status *status = &vp->scb.status; struct afs_vnode *vnode = vp->vnode; - struct inode *inode = &vnode->vfs_inode; + struct inode *inode = &vnode->netfs.inode; struct timespec64 t; umode_t mode; bool data_changed = false; @@ -249,7 +246,7 @@ static void afs_apply_status(struct afs_operation *op, * idea of what the size should be that's not the same as * what's on the server. */ - vnode->netfs_ctx.remote_i_size = status->size; + vnode->netfs.remote_i_size = status->size; if (change_size) { afs_set_i_size(vnode, status->size); inode->i_ctime = t; @@ -292,7 +289,7 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v */ if (vp->scb.status.abort_code == VNOVNODE) { set_bit(AFS_VNODE_DELETED, &vnode->flags); - clear_nlink(&vnode->vfs_inode); + clear_nlink(&vnode->netfs.inode); __afs_break_callback(vnode, afs_cb_break_for_deleted); op->flags &= ~AFS_OPERATION_DIR_CONFLICT; } @@ -309,8 +306,8 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v if (vp->scb.have_cb) afs_apply_callback(op, vp); } else if (vp->op_unlinked && !(op->flags & AFS_OPERATION_DIR_CONFLICT)) { - drop_nlink(&vnode->vfs_inode); - if (vnode->vfs_inode.i_nlink == 0) { + drop_nlink(&vnode->netfs.inode); + if (vnode->netfs.inode.i_nlink == 0) { set_bit(AFS_VNODE_DELETED, &vnode->flags); __afs_break_callback(vnode, afs_cb_break_for_deleted); } @@ -329,7 +326,7 @@ static void afs_fetch_status_success(struct afs_operation *op) struct afs_vnode *vnode = vp->vnode; int ret; - if (vnode->vfs_inode.i_state & I_NEW) { + if (vnode->netfs.inode.i_state & I_NEW) { ret = afs_inode_init_from_status(op, vp, vnode); op->error = ret; if (ret == 0) @@ -433,7 +430,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) struct afs_vnode_cache_aux aux; if (vnode->status.type != AFS_FTYPE_FILE) { - vnode->netfs_ctx.cache = NULL; + vnode->netfs.cache = NULL; return; } @@ -460,7 +457,7 @@ static void afs_get_inode_cache(struct afs_vnode *vnode) struct inode *afs_iget(struct afs_operation *op, struct afs_vnode_param *vp) { struct afs_vnode_param *dvp = &op->file[0]; - struct super_block *sb = dvp->vnode->vfs_inode.i_sb; + struct super_block *sb = dvp->vnode->netfs.inode.i_sb; struct afs_vnode *vnode; struct inode *inode; int ret; @@ -585,10 +582,10 @@ static void afs_zap_data(struct afs_vnode *vnode) /* nuke all the non-dirty pages that aren't locked, mapped or being * written back in a regular file and completely discard the pages in a * directory or symlink */ - if (S_ISREG(vnode->vfs_inode.i_mode)) - invalidate_remote_inode(&vnode->vfs_inode); + if (S_ISREG(vnode->netfs.inode.i_mode)) + invalidate_remote_inode(&vnode->netfs.inode); else - invalidate_inode_pages2(vnode->vfs_inode.i_mapping); + invalidate_inode_pages2(vnode->netfs.inode.i_mapping); } /* @@ -686,8 +683,8 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) key_serial(key)); if (unlikely(test_bit(AFS_VNODE_DELETED, &vnode->flags))) { - if (vnode->vfs_inode.i_nlink) - clear_nlink(&vnode->vfs_inode); + if (vnode->netfs.inode.i_nlink) + clear_nlink(&vnode->netfs.inode); goto valid; } @@ -829,7 +826,7 @@ void afs_evict_inode(struct inode *inode) static void afs_setattr_success(struct afs_operation *op) { struct afs_vnode_param *vp = &op->file[0]; - struct inode *inode = &vp->vnode->vfs_inode; + struct inode *inode = &vp->vnode->netfs.inode; loff_t old_i_size = i_size_read(inode); op->setattr.old_i_size = old_i_size; @@ -846,7 +843,7 @@ static void afs_setattr_success(struct afs_operation *op) static void afs_setattr_edit_file(struct afs_operation *op) { struct afs_vnode_param *vp = &op->file[0]; - struct inode *inode = &vp->vnode->vfs_inode; + struct inode *inode = &vp->vnode->netfs.inode; if (op->setattr.attr->ia_valid & ATTR_SIZE) { loff_t size = op->setattr.attr->ia_size; @@ -878,7 +875,7 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET | ATTR_TOUCH; struct afs_operation *op; struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); - struct inode *inode = &vnode->vfs_inode; + struct inode *inode = &vnode->netfs.inode; loff_t i_size; int ret; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index a30995901266f..984b113a91075 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -619,12 +619,7 @@ enum afs_lock_state { * leak from one inode to another. */ struct afs_vnode { - struct { - /* These must be contiguous */ - struct inode vfs_inode; /* the VFS's inode record */ - struct netfs_i_context netfs_ctx; /* Netfslib context */ - }; - + struct netfs_inode netfs; /* Netfslib context and vfs inode */ struct afs_volume *volume; /* volume on which vnode resides */ struct afs_fid fid; /* the file identifier for this inode */ struct afs_file_status status; /* AFS status info for this file */ @@ -675,7 +670,7 @@ struct afs_vnode { static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode) { #ifdef CONFIG_AFS_FSCACHE - return netfs_i_cookie(&vnode->vfs_inode); + return netfs_i_cookie(&vnode->netfs.inode); #else return NULL; #endif @@ -685,7 +680,7 @@ static inline void afs_vnode_set_cache(struct afs_vnode *vnode, struct fscache_cookie *cookie) { #ifdef CONFIG_AFS_FSCACHE - vnode->netfs_ctx.cache = cookie; + vnode->netfs.cache = cookie; #endif } @@ -892,7 +887,7 @@ static inline void afs_invalidate_cache(struct afs_vnode *vnode, unsigned int fl afs_set_cache_aux(vnode, &aux); fscache_invalidate(afs_vnode_cache(vnode), &aux, - i_size_read(&vnode->vfs_inode), flags); + i_size_read(&vnode->netfs.inode), flags); } /* @@ -1217,7 +1212,7 @@ static inline struct afs_net *afs_i2net(struct inode *inode) static inline struct afs_net *afs_v2net(struct afs_vnode *vnode) { - return afs_i2net(&vnode->vfs_inode); + return afs_i2net(&vnode->netfs.inode); } static inline struct afs_net *afs_sock2net(struct sock *sk) @@ -1593,12 +1588,12 @@ extern void yfs_fs_store_opaque_acl2(struct afs_operation *); */ static inline struct afs_vnode *AFS_FS_I(struct inode *inode) { - return container_of(inode, struct afs_vnode, vfs_inode); + return container_of(inode, struct afs_vnode, netfs.inode); } static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode) { - return &vnode->vfs_inode; + return &vnode->netfs.inode; } /* @@ -1621,8 +1616,8 @@ static inline void afs_update_dentry_version(struct afs_operation *op, */ static inline void afs_set_i_size(struct afs_vnode *vnode, u64 size) { - i_size_write(&vnode->vfs_inode, size); - vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1; + i_size_write(&vnode->netfs.inode, size); + vnode->netfs.inode.i_blocks = ((size + 1023) >> 10) << 1; } /* diff --git a/fs/afs/super.c b/fs/afs/super.c index 1fea195b0b275..95d713074dc81 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -659,7 +659,7 @@ static void afs_i_init_once(void *_vnode) struct afs_vnode *vnode = _vnode; memset(vnode, 0, sizeof(*vnode)); - inode_init_once(&vnode->vfs_inode); + inode_init_once(&vnode->netfs.inode); mutex_init(&vnode->io_lock); init_rwsem(&vnode->validate_lock); spin_lock_init(&vnode->wb_lock); @@ -700,8 +700,8 @@ static struct inode *afs_alloc_inode(struct super_block *sb) init_rwsem(&vnode->rmdir_lock); INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work); - _leave(" = %p", &vnode->vfs_inode); - return &vnode->vfs_inode; + _leave(" = %p", &vnode->netfs.inode); + return &vnode->netfs.inode; } static void afs_free_inode(struct inode *inode) diff --git a/fs/afs/write.c b/fs/afs/write.c index 2236b2165e375..f80a6096d91c7 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -146,10 +146,10 @@ int afs_write_end(struct file *file, struct address_space *mapping, write_end_pos = pos + copied; - i_size = i_size_read(&vnode->vfs_inode); + i_size = i_size_read(&vnode->netfs.inode); if (write_end_pos > i_size) { write_seqlock(&vnode->cb_lock); - i_size = i_size_read(&vnode->vfs_inode); + i_size = i_size_read(&vnode->netfs.inode); if (write_end_pos > i_size) afs_set_i_size(vnode, write_end_pos); write_sequnlock(&vnode->cb_lock); @@ -257,7 +257,7 @@ static void afs_redirty_pages(struct writeback_control *wbc, */ static void afs_pages_written_back(struct afs_vnode *vnode, loff_t start, unsigned int len) { - struct address_space *mapping = vnode->vfs_inode.i_mapping; + struct address_space *mapping = vnode->netfs.inode.i_mapping; struct folio *folio; pgoff_t end; @@ -354,7 +354,6 @@ static const struct afs_operation_ops afs_store_data_operation = { static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t pos, bool laundering) { - struct netfs_i_context *ictx = &vnode->netfs_ctx; struct afs_operation *op; struct afs_wb_key *wbk = NULL; loff_t size = iov_iter_count(iter); @@ -385,9 +384,9 @@ static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t op->store.write_iter = iter; op->store.pos = pos; op->store.size = size; - op->store.i_size = max(pos + size, ictx->remote_i_size); + op->store.i_size = max(pos + size, vnode->netfs.remote_i_size); op->store.laundering = laundering; - op->mtime = vnode->vfs_inode.i_mtime; + op->mtime = vnode->netfs.inode.i_mtime; op->flags |= AFS_OPERATION_UNINTR; op->ops = &afs_store_data_operation; @@ -554,7 +553,7 @@ static ssize_t afs_write_back_from_locked_folio(struct address_space *mapping, struct iov_iter iter; unsigned long priv; unsigned int offset, to, len, max_len; - loff_t i_size = i_size_read(&vnode->vfs_inode); + loff_t i_size = i_size_read(&vnode->netfs.inode); bool new_content = test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); bool caching = fscache_cookie_enabled(afs_vnode_cache(vnode)); long count = wbc->nr_to_write; @@ -845,7 +844,7 @@ ssize_t afs_file_write(struct kiocb *iocb, struct iov_iter *from) _enter("{%llx:%llu},{%zu},", vnode->fid.vid, vnode->fid.vnode, count); - if (IS_SWAPFILE(&vnode->vfs_inode)) { + if (IS_SWAPFILE(&vnode->netfs.inode)) { printk(KERN_INFO "AFS: Attempt to write to active swap file!\n"); return -EBUSY; @@ -958,8 +957,8 @@ void afs_prune_wb_keys(struct afs_vnode *vnode) /* Discard unused keys */ spin_lock(&vnode->wb_lock); - if (!mapping_tagged(&vnode->vfs_inode.i_data, PAGECACHE_TAG_WRITEBACK) && - !mapping_tagged(&vnode->vfs_inode.i_data, PAGECACHE_TAG_DIRTY)) { + if (!mapping_tagged(&vnode->netfs.inode.i_data, PAGECACHE_TAG_WRITEBACK) && + !mapping_tagged(&vnode->netfs.inode.i_data, PAGECACHE_TAG_DIRTY)) { list_for_each_entry_safe(wbk, tmp, &vnode->wb_keys, vnode_link) { if (refcount_read(&wbk->usage) == 1) list_move(&wbk->vnode_link, &graveyard); @@ -1034,6 +1033,6 @@ static void afs_write_to_cache(struct afs_vnode *vnode, bool caching) { fscache_write_to_cache(afs_vnode_cache(vnode), - vnode->vfs_inode.i_mapping, start, len, i_size, + vnode->netfs.inode.i_mapping, start, len, i_size, afs_write_to_cache_done, vnode, caching); } diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index e5221be6eb555..f5f116ed1b9e9 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -1798,7 +1798,7 @@ enum { static int __ceph_pool_perm_get(struct ceph_inode_info *ci, s64 pool, struct ceph_string *pool_ns) { - struct ceph_fs_client *fsc = ceph_inode_to_client(&ci->vfs_inode); + struct ceph_fs_client *fsc = ceph_inode_to_client(&ci->netfs.inode); struct ceph_mds_client *mdsc = fsc->mdsc; struct ceph_osd_request *rd_req = NULL, *wr_req = NULL; struct rb_node **p, *parent; @@ -1913,7 +1913,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, 0, false, true); err = ceph_osdc_start_request(&fsc->client->osdc, rd_req, false); - wr_req->r_mtime = ci->vfs_inode.i_mtime; + wr_req->r_mtime = ci->netfs.inode.i_mtime; err2 = ceph_osdc_start_request(&fsc->client->osdc, wr_req, false); if (!err) diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c index ddea999220739..177d8e8d73fe4 100644 --- a/fs/ceph/cache.c +++ b/fs/ceph/cache.c @@ -29,9 +29,9 @@ void ceph_fscache_register_inode_cookie(struct inode *inode) if (!(inode->i_state & I_NEW)) return; - WARN_ON_ONCE(ci->netfs_ctx.cache); + WARN_ON_ONCE(ci->netfs.cache); - ci->netfs_ctx.cache = + ci->netfs.cache = fscache_acquire_cookie(fsc->fscache, 0, &ci->i_vino, sizeof(ci->i_vino), &ci->i_version, sizeof(ci->i_version), diff --git a/fs/ceph/cache.h b/fs/ceph/cache.h index 7255b790a4c1c..26c6ae06e2f41 100644 --- a/fs/ceph/cache.h +++ b/fs/ceph/cache.h @@ -28,7 +28,7 @@ void ceph_fscache_invalidate(struct inode *inode, bool dio_write); static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci) { - return netfs_i_cookie(&ci->vfs_inode); + return netfs_i_cookie(&ci->netfs.inode); } static inline void ceph_fscache_resize(struct inode *inode, loff_t to) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index bf2e940055984..38c930384d417 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -492,7 +492,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, struct ceph_mount_options *opt = mdsc->fsc->mount_options; ci->i_hold_caps_max = round_jiffies(jiffies + opt->caps_wanted_delay_max * HZ); - dout("__cap_set_timeouts %p %lu\n", &ci->vfs_inode, + dout("__cap_set_timeouts %p %lu\n", &ci->netfs.inode, ci->i_hold_caps_max - jiffies); } @@ -507,7 +507,7 @@ static void __cap_set_timeouts(struct ceph_mds_client *mdsc, static void __cap_delay_requeue(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci) { - dout("__cap_delay_requeue %p flags 0x%lx at %lu\n", &ci->vfs_inode, + dout("__cap_delay_requeue %p flags 0x%lx at %lu\n", &ci->netfs.inode, ci->i_ceph_flags, ci->i_hold_caps_max); if (!mdsc->stopping) { spin_lock(&mdsc->cap_delay_lock); @@ -531,7 +531,7 @@ static void __cap_delay_requeue(struct ceph_mds_client *mdsc, static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci) { - dout("__cap_delay_requeue_front %p\n", &ci->vfs_inode); + dout("__cap_delay_requeue_front %p\n", &ci->netfs.inode); spin_lock(&mdsc->cap_delay_lock); ci->i_ceph_flags |= CEPH_I_FLUSH; if (!list_empty(&ci->i_cap_delay_list)) @@ -548,7 +548,7 @@ static void __cap_delay_requeue_front(struct ceph_mds_client *mdsc, static void __cap_delay_cancel(struct ceph_mds_client *mdsc, struct ceph_inode_info *ci) { - dout("__cap_delay_cancel %p\n", &ci->vfs_inode); + dout("__cap_delay_cancel %p\n", &ci->netfs.inode); if (list_empty(&ci->i_cap_delay_list)) return; spin_lock(&mdsc->cap_delay_lock); @@ -568,7 +568,7 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap, * Each time we receive FILE_CACHE anew, we increment * i_rdcache_gen. */ - if (S_ISREG(ci->vfs_inode.i_mode) && + if (S_ISREG(ci->netfs.inode.i_mode) && (issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) && (had & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0) { ci->i_rdcache_gen++; @@ -583,14 +583,14 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap, if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) { if (issued & CEPH_CAP_FILE_SHARED) atomic_inc(&ci->i_shared_gen); - if (S_ISDIR(ci->vfs_inode.i_mode)) { - dout(" marking %p NOT complete\n", &ci->vfs_inode); + if (S_ISDIR(ci->netfs.inode.i_mode)) { + dout(" marking %p NOT complete\n", &ci->netfs.inode); __ceph_dir_clear_complete(ci); } } /* Wipe saved layout if we're losing DIR_CREATE caps */ - if (S_ISDIR(ci->vfs_inode.i_mode) && (had & CEPH_CAP_DIR_CREATE) && + if (S_ISDIR(ci->netfs.inode.i_mode) && (had & CEPH_CAP_DIR_CREATE) && !(issued & CEPH_CAP_DIR_CREATE)) { ceph_put_string(rcu_dereference_raw(ci->i_cached_layout.pool_ns)); memset(&ci->i_cached_layout, 0, sizeof(ci->i_cached_layout)); @@ -771,7 +771,7 @@ static int __cap_is_valid(struct ceph_cap *cap) if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { dout("__cap_is_valid %p cap %p issued %s " - "but STALE (gen %u vs %u)\n", &cap->ci->vfs_inode, + "but STALE (gen %u vs %u)\n", &cap->ci->netfs.inode, cap, ceph_cap_string(cap->issued), cap->cap_gen, gen); return 0; } @@ -797,7 +797,7 @@ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) if (!__cap_is_valid(cap)) continue; dout("__ceph_caps_issued %p cap %p issued %s\n", - &ci->vfs_inode, cap, ceph_cap_string(cap->issued)); + &ci->netfs.inode, cap, ceph_cap_string(cap->issued)); have |= cap->issued; if (implemented) *implemented |= cap->implemented; @@ -844,12 +844,12 @@ static void __touch_cap(struct ceph_cap *cap) spin_lock(&s->s_cap_lock); if (!s->s_cap_iterator) { - dout("__touch_cap %p cap %p mds%d\n", &cap->ci->vfs_inode, cap, + dout("__touch_cap %p cap %p mds%d\n", &cap->ci->netfs.inode, cap, s->s_mds); list_move_tail(&cap->session_caps, &s->s_caps); } else { dout("__touch_cap %p cap %p mds%d NOP, iterating over caps\n", - &cap->ci->vfs_inode, cap, s->s_mds); + &cap->ci->netfs.inode, cap, s->s_mds); } spin_unlock(&s->s_cap_lock); } @@ -867,7 +867,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) if ((have & mask) == mask) { dout("__ceph_caps_issued_mask ino 0x%llx snap issued %s" - " (mask %s)\n", ceph_ino(&ci->vfs_inode), + " (mask %s)\n", ceph_ino(&ci->netfs.inode), ceph_cap_string(have), ceph_cap_string(mask)); return 1; @@ -879,7 +879,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) continue; if ((cap->issued & mask) == mask) { dout("__ceph_caps_issued_mask ino 0x%llx cap %p issued %s" - " (mask %s)\n", ceph_ino(&ci->vfs_inode), cap, + " (mask %s)\n", ceph_ino(&ci->netfs.inode), cap, ceph_cap_string(cap->issued), ceph_cap_string(mask)); if (touch) @@ -891,7 +891,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) have |= cap->issued; if ((have & mask) == mask) { dout("__ceph_caps_issued_mask ino 0x%llx combo issued %s" - " (mask %s)\n", ceph_ino(&ci->vfs_inode), + " (mask %s)\n", ceph_ino(&ci->netfs.inode), ceph_cap_string(cap->issued), ceph_cap_string(mask)); if (touch) { @@ -919,7 +919,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) int __ceph_caps_issued_mask_metric(struct ceph_inode_info *ci, int mask, int touch) { - struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb); int r; r = __ceph_caps_issued_mask(ci, mask, touch); @@ -950,7 +950,7 @@ int __ceph_caps_revoking_other(struct ceph_inode_info *ci, int ceph_caps_revoking(struct ceph_inode_info *ci, int mask) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; int ret; spin_lock(&ci->i_ceph_lock); @@ -969,8 +969,8 @@ int __ceph_caps_used(struct ceph_inode_info *ci) if (ci->i_rd_ref) used |= CEPH_CAP_FILE_RD; if (ci->i_rdcache_ref || - (S_ISREG(ci->vfs_inode.i_mode) && - ci->vfs_inode.i_data.nrpages)) + (S_ISREG(ci->netfs.inode.i_mode) && + ci->netfs.inode.i_data.nrpages)) used |= CEPH_CAP_FILE_CACHE; if (ci->i_wr_ref) used |= CEPH_CAP_FILE_WR; @@ -993,11 +993,11 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci) const int WR_SHIFT = ffs(CEPH_FILE_MODE_WR); const int LAZY_SHIFT = ffs(CEPH_FILE_MODE_LAZY); struct ceph_mount_options *opt = - ceph_inode_to_client(&ci->vfs_inode)->mount_options; + ceph_inode_to_client(&ci->netfs.inode)->mount_options; unsigned long used_cutoff = jiffies - opt->caps_wanted_delay_max * HZ; unsigned long idle_cutoff = jiffies - opt->caps_wanted_delay_min * HZ; - if (S_ISDIR(ci->vfs_inode.i_mode)) { + if (S_ISDIR(ci->netfs.inode.i_mode)) { int want = 0; /* use used_cutoff here, to keep dir's wanted caps longer */ @@ -1050,7 +1050,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci) int __ceph_caps_wanted(struct ceph_inode_info *ci) { int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci); - if (S_ISDIR(ci->vfs_inode.i_mode)) { + if (S_ISDIR(ci->netfs.inode.i_mode)) { /* we want EXCL if holding caps of dir ops */ if (w & CEPH_CAP_ANY_DIR_OPS) w |= CEPH_CAP_FILE_EXCL; @@ -1116,9 +1116,9 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) lockdep_assert_held(&ci->i_ceph_lock); - dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + dout("__ceph_remove_cap %p from %p\n", cap, &ci->netfs.inode); - mdsc = ceph_inode_to_client(&ci->vfs_inode)->mdsc; + mdsc = ceph_inode_to_client(&ci->netfs.inode)->mdsc; /* remove from inode's cap rbtree, and clear auth cap */ rb_erase(&cap->ci_node, &ci->i_caps); @@ -1169,7 +1169,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) * keep i_snap_realm. */ if (ci->i_wr_ref == 0 && ci->i_snap_realm) - ceph_change_snap_realm(&ci->vfs_inode, NULL); + ceph_change_snap_realm(&ci->netfs.inode, NULL); __cap_delay_cancel(mdsc, ci); } @@ -1188,11 +1188,11 @@ void ceph_remove_cap(struct ceph_cap *cap, bool queue_release) lockdep_assert_held(&ci->i_ceph_lock); - fsc = ceph_inode_to_client(&ci->vfs_inode); + fsc = ceph_inode_to_client(&ci->netfs.inode); WARN_ON_ONCE(ci->i_auth_cap == cap && !list_empty(&ci->i_dirty_item) && !fsc->blocklisted && - !ceph_inode_is_shutdown(&ci->vfs_inode)); + !ceph_inode_is_shutdown(&ci->netfs.inode)); __ceph_remove_cap(cap, queue_release); } @@ -1343,7 +1343,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap, int flushing, u64 flush_tid, u64 oldest_flush_tid) { struct ceph_inode_info *ci = cap->ci; - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; int held, revoking; lockdep_assert_held(&ci->i_ceph_lock); @@ -1440,7 +1440,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap, static void __send_cap(struct cap_msg_args *arg, struct ceph_inode_info *ci) { struct ceph_msg *msg; - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, CAP_MSG_SIZE, GFP_NOFS, false); if (!msg) { @@ -1528,7 +1528,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci, __releases(ci->i_ceph_lock) __acquires(ci->i_ceph_lock) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_mds_client *mdsc = session->s_mdsc; struct ceph_cap_snap *capsnap; u64 oldest_flush_tid = 0; @@ -1622,7 +1622,7 @@ static void __ceph_flush_snaps(struct ceph_inode_info *ci, void ceph_flush_snaps(struct ceph_inode_info *ci, struct ceph_mds_session **psession) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; struct ceph_mds_session *session = NULL; int mds; @@ -1682,8 +1682,8 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, struct ceph_cap_flush **pcf) { struct ceph_mds_client *mdsc = - ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc; - struct inode *inode = &ci->vfs_inode; + ceph_sb_to_client(ci->netfs.inode.i_sb)->mdsc; + struct inode *inode = &ci->netfs.inode; int was = ci->i_dirty_caps; int dirty = 0; @@ -1696,7 +1696,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, return 0; } - dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->vfs_inode, + dout("__mark_dirty_caps %p %s dirty %s -> %s\n", &ci->netfs.inode, ceph_cap_string(mask), ceph_cap_string(was), ceph_cap_string(was | mask)); ci->i_dirty_caps |= mask; @@ -1712,7 +1712,7 @@ int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask, ci->i_snap_realm->cached_context); } dout(" inode %p now dirty snapc %p auth cap %p\n", - &ci->vfs_inode, ci->i_head_snapc, ci->i_auth_cap); + &ci->netfs.inode, ci->i_head_snapc, ci->i_auth_cap); BUG_ON(!list_empty(&ci->i_dirty_item)); spin_lock(&mdsc->cap_dirty_lock); list_add(&ci->i_dirty_item, &session->s_cap_dirty); @@ -1875,7 +1875,7 @@ static int try_nonblocking_invalidate(struct inode *inode) bool __ceph_should_report_size(struct ceph_inode_info *ci) { - loff_t size = i_size_read(&ci->vfs_inode); + loff_t size = i_size_read(&ci->netfs.inode); /* mds will adjust max size according to the reported size */ if (ci->i_flushing_caps & CEPH_CAP_FILE_WR) return false; @@ -1900,7 +1900,7 @@ bool __ceph_should_report_size(struct ceph_inode_info *ci) void ceph_check_caps(struct ceph_inode_info *ci, int flags, struct ceph_mds_session *session) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb); struct ceph_cap *cap; u64 flush_tid, oldest_flush_tid; @@ -2467,7 +2467,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, __releases(ci->i_ceph_lock) __acquires(ci->i_ceph_lock) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_cap *cap; struct ceph_cap_flush *cf; int ret; @@ -2560,7 +2560,7 @@ void ceph_early_kick_flushing_caps(struct ceph_mds_client *mdsc, cap = ci->i_auth_cap; if (!(cap && cap->session == session)) { pr_err("%p auth cap %p not mds%d ???\n", - &ci->vfs_inode, cap, session->s_mds); + &ci->netfs.inode, cap, session->s_mds); spin_unlock(&ci->i_ceph_lock); continue; } @@ -2610,7 +2610,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, cap = ci->i_auth_cap; if (!(cap && cap->session == session)) { pr_err("%p auth cap %p not mds%d ???\n", - &ci->vfs_inode, cap, session->s_mds); + &ci->netfs.inode, cap, session->s_mds); spin_unlock(&ci->i_ceph_lock); continue; } @@ -2630,7 +2630,7 @@ void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session, lockdep_assert_held(&ci->i_ceph_lock); - dout("%s %p flushing %s\n", __func__, &ci->vfs_inode, + dout("%s %p flushing %s\n", __func__, &ci->netfs.inode, ceph_cap_string(ci->i_flushing_caps)); if (!list_empty(&ci->i_cap_flush_list)) { @@ -2673,10 +2673,10 @@ void ceph_take_cap_refs(struct ceph_inode_info *ci, int got, } if (got & CEPH_CAP_FILE_BUFFER) { if (ci->i_wb_ref == 0) - ihold(&ci->vfs_inode); + ihold(&ci->netfs.inode); ci->i_wb_ref++; dout("%s %p wb %d -> %d (?)\n", __func__, - &ci->vfs_inode, ci->i_wb_ref-1, ci->i_wb_ref); + &ci->netfs.inode, ci->i_wb_ref-1, ci->i_wb_ref); } } @@ -3004,7 +3004,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got return ret; } - if (S_ISREG(ci->vfs_inode.i_mode) && + if (S_ISREG(ci->netfs.inode.i_mode) && ci->i_inline_version != CEPH_INLINE_NONE && (_got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) && i_size_read(inode) > 0) { @@ -3094,7 +3094,7 @@ enum put_cap_refs_mode { static void __ceph_put_cap_refs(struct ceph_inode_info *ci, int had, enum put_cap_refs_mode mode) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; int last = 0, put = 0, flushsnaps = 0, wake = 0; bool check_flushsnaps = false; @@ -3202,7 +3202,7 @@ void ceph_put_cap_refs_no_check_caps(struct ceph_inode_info *ci, int had) void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, struct ceph_snap_context *snapc) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_cap_snap *capsnap = NULL, *iter; int put = 0; bool last = false; @@ -3698,7 +3698,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, session->s_mds, &list_first_entry(&session->s_cap_flushing, struct ceph_inode_info, - i_flushing_item)->vfs_inode); + i_flushing_item)->netfs.inode); } } mdsc->num_cap_flushing--; @@ -4345,7 +4345,7 @@ unsigned long ceph_check_delayed_caps(struct ceph_mds_client *mdsc) break; list_del_init(&ci->i_cap_delay_list); - inode = igrab(&ci->vfs_inode); + inode = igrab(&ci->netfs.inode); if (inode) { spin_unlock(&mdsc->cap_delay_lock); dout("check_delayed_caps on %p\n", inode); @@ -4373,7 +4373,7 @@ static void flush_dirty_session_caps(struct ceph_mds_session *s) while (!list_empty(&s->s_cap_dirty)) { ci = list_first_entry(&s->s_cap_dirty, struct ceph_inode_info, i_dirty_item); - inode = &ci->vfs_inode; + inode = &ci->netfs.inode; ihold(inode); dout("flush_dirty_caps %llx.%llx\n", ceph_vinop(inode)); spin_unlock(&mdsc->cap_dirty_lock); @@ -4407,7 +4407,7 @@ void __ceph_touch_fmode(struct ceph_inode_info *ci, void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count) { - struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb); + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->netfs.inode.i_sb); int bits = (fmode << 1) | 1; bool already_opened = false; int i; @@ -4441,7 +4441,7 @@ void ceph_get_fmode(struct ceph_inode_info *ci, int fmode, int count) */ void ceph_put_fmode(struct ceph_inode_info *ci, int fmode, int count) { - struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->vfs_inode.i_sb); + struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(ci->netfs.inode.i_sb); int bits = (fmode << 1) | 1; bool is_closed = true; int i; @@ -4656,7 +4656,7 @@ int ceph_purge_inode_cap(struct inode *inode, struct ceph_cap *cap, bool *invali lockdep_assert_held(&ci->i_ceph_lock); dout("removing cap %p, ci is %p, inode is %p\n", - cap, ci, &ci->vfs_inode); + cap, ci, &ci->netfs.inode); is_auth = (cap == ci->i_auth_cap); __ceph_remove_cap(cap, false); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 8c8226c0feacc..da59e836a06eb 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -205,7 +205,7 @@ static int ceph_init_file_info(struct inode *inode, struct file *file, { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mount_options *opt = - ceph_inode_to_client(&ci->vfs_inode)->mount_options; + ceph_inode_to_client(&ci->netfs.inode)->mount_options; struct ceph_file_info *fi; int ret; diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 5f1cc2b4ed068..650746b3ba999 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -20,9 +20,6 @@ #include "cache.h" #include -// Temporary: netfs does disgusting things with inode pointers -#pragma GCC diagnostic ignored "-Wattribute-warning" - /* * Ceph inode operations * @@ -179,7 +176,7 @@ static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci, rb_insert_color(&frag->node, &ci->i_fragtree); dout("get_or_create_frag added %llx.%llx frag %x\n", - ceph_vinop(&ci->vfs_inode), f); + ceph_vinop(&ci->netfs.inode), f); return frag; } @@ -460,10 +457,10 @@ struct inode *ceph_alloc_inode(struct super_block *sb) if (!ci) return NULL; - dout("alloc_inode %p\n", &ci->vfs_inode); + dout("alloc_inode %p\n", &ci->netfs.inode); /* Set parameters for the netfs library */ - netfs_i_context_init(&ci->vfs_inode, &ceph_netfs_ops); + netfs_inode_init(&ci->netfs.inode, &ceph_netfs_ops); spin_lock_init(&ci->i_ceph_lock); @@ -550,7 +547,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb) INIT_WORK(&ci->i_work, ceph_inode_work); ci->i_work_mask = 0; memset(&ci->i_btime, '\0', sizeof(ci->i_btime)); - return &ci->vfs_inode; + return &ci->netfs.inode; } void ceph_free_inode(struct inode *inode) @@ -1981,7 +1978,7 @@ static void ceph_inode_work(struct work_struct *work) { struct ceph_inode_info *ci = container_of(work, struct ceph_inode_info, i_work); - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; if (test_and_clear_bit(CEPH_I_WORK_WRITEBACK, &ci->i_work_mask)) { dout("writeback %p\n", inode); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index f5d110d90b770..33f517d549ce5 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -1564,7 +1564,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session, p = session->s_caps.next; while (p != &session->s_caps) { cap = list_entry(p, struct ceph_cap, session_caps); - inode = igrab(&cap->ci->vfs_inode); + inode = igrab(&cap->ci->netfs.inode); if (!inode) { p = p->next; continue; @@ -1622,7 +1622,7 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap, int iputs; dout("removing cap %p, ci is %p, inode is %p\n", - cap, ci, &ci->vfs_inode); + cap, ci, &ci->netfs.inode); spin_lock(&ci->i_ceph_lock); iputs = ceph_purge_inode_cap(inode, cap, &invalidate); spin_unlock(&ci->i_ceph_lock); diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 322ee5add9426..864cdaa0d2bd6 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -521,7 +521,7 @@ static bool has_new_snaps(struct ceph_snap_context *o, static void ceph_queue_cap_snap(struct ceph_inode_info *ci, struct ceph_cap_snap **pcapsnap) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_snap_context *old_snapc, *new_snapc; struct ceph_cap_snap *capsnap = *pcapsnap; struct ceph_buffer *old_blob = NULL; @@ -652,7 +652,7 @@ static void ceph_queue_cap_snap(struct ceph_inode_info *ci, int __ceph_finish_cap_snap(struct ceph_inode_info *ci, struct ceph_cap_snap *capsnap) { - struct inode *inode = &ci->vfs_inode; + struct inode *inode = &ci->netfs.inode; struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb); BUG_ON(capsnap->writing); @@ -712,7 +712,7 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) spin_lock(&realm->inodes_with_caps_lock); list_for_each_entry(ci, &realm->inodes_with_caps, i_snap_realm_item) { - struct inode *inode = igrab(&ci->vfs_inode); + struct inode *inode = igrab(&ci->netfs.inode); if (!inode) continue; spin_unlock(&realm->inodes_with_caps_lock); @@ -904,7 +904,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) while (!list_empty(&mdsc->snap_flush_list)) { ci = list_first_entry(&mdsc->snap_flush_list, struct ceph_inode_info, i_snap_flush_item); - inode = &ci->vfs_inode; + inode = &ci->netfs.inode; ihold(inode); spin_unlock(&mdsc->snap_flush_lock); ceph_flush_snaps(ci, &session); diff --git a/fs/ceph/super.c b/fs/ceph/super.c index b73b4f75462c3..40140805bdcfe 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -876,7 +876,7 @@ mempool_t *ceph_wb_pagevec_pool; static void ceph_inode_init_once(void *foo) { struct ceph_inode_info *ci = foo; - inode_init_once(&ci->vfs_inode); + inode_init_once(&ci->netfs.inode); } static int __init init_caches(void) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index dd7dac0f984a8..f59dac66955bb 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -316,11 +316,7 @@ struct ceph_inode_xattrs_info { * Ceph inode. */ struct ceph_inode_info { - struct { - /* These must be contiguous */ - struct inode vfs_inode; - struct netfs_i_context netfs_ctx; /* Netfslib context */ - }; + struct netfs_inode netfs; /* Netfslib context and vfs inode */ struct ceph_vino i_vino; /* ceph ino + snap */ spinlock_t i_ceph_lock; @@ -436,7 +432,7 @@ struct ceph_inode_info { static inline struct ceph_inode_info * ceph_inode(const struct inode *inode) { - return container_of(inode, struct ceph_inode_info, vfs_inode); + return container_of(inode, struct ceph_inode_info, netfs.inode); } static inline struct ceph_fs_client * @@ -1316,7 +1312,7 @@ static inline void __ceph_update_quota(struct ceph_inode_info *ci, has_quota = __ceph_has_quota(ci, QUOTA_GET_ANY); if (had_quota != has_quota) - ceph_adjust_quota_realms_count(&ci->vfs_inode, has_quota); + ceph_adjust_quota_realms_count(&ci->netfs.inode, has_quota); } extern void ceph_handle_quota(struct ceph_mds_client *mdsc, diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 8c2dc2c762a4e..f141f5246163d 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -57,7 +57,7 @@ static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci) static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, size_t size) { - struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb); struct ceph_osd_client *osdc = &fsc->client->osdc; struct ceph_string *pool_ns; s64 pool = ci->i_layout.pool_id; @@ -69,7 +69,7 @@ static ssize_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, pool_ns = ceph_try_get_string(ci->i_layout.pool_ns); - dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode); + dout("ceph_vxattrcb_layout %p\n", &ci->netfs.inode); down_read(&osdc->lock); pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool); if (pool_name) { @@ -161,7 +161,7 @@ static ssize_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci, char *val, size_t size) { ssize_t ret; - struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb); struct ceph_osd_client *osdc = &fsc->client->osdc; s64 pool = ci->i_layout.pool_id; const char *pool_name; @@ -313,7 +313,7 @@ static ssize_t ceph_vxattrcb_snap_btime(struct ceph_inode_info *ci, char *val, static ssize_t ceph_vxattrcb_cluster_fsid(struct ceph_inode_info *ci, char *val, size_t size) { - struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb); return ceph_fmt_xattr(val, size, "%pU", &fsc->client->fsid); } @@ -321,7 +321,7 @@ static ssize_t ceph_vxattrcb_cluster_fsid(struct ceph_inode_info *ci, static ssize_t ceph_vxattrcb_client_id(struct ceph_inode_info *ci, char *val, size_t size) { - struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(ci->netfs.inode.i_sb); return ceph_fmt_xattr(val, size, "client%lld", ceph_client_gid(fsc->client)); @@ -629,7 +629,7 @@ static int __set_xattr(struct ceph_inode_info *ci, } dout("__set_xattr_val added %llx.%llx xattr %p %.*s=%.*s\n", - ceph_vinop(&ci->vfs_inode), xattr, name_len, name, val_len, val); + ceph_vinop(&ci->netfs.inode), xattr, name_len, name, val_len, val); return 0; } @@ -871,7 +871,7 @@ struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci) struct ceph_buffer *old_blob = NULL; void *dest; - dout("__build_xattrs_blob %p\n", &ci->vfs_inode); + dout("__build_xattrs_blob %p\n", &ci->netfs.inode); if (ci->i_xattrs.dirty) { int need = __get_required_blob_size(ci, 0, 0); diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 12c872800326f..c85d9a3783251 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -377,7 +377,7 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->flags = 0; spin_lock_init(&cifs_inode->writers_lock); cifs_inode->writers = 0; - cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ + cifs_inode->netfs.inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ cifs_inode->server_eof = 0; cifs_inode->uniqueid = 0; cifs_inode->createtime = 0; @@ -389,12 +389,12 @@ cifs_alloc_inode(struct super_block *sb) * Can not set i_flags here - they get immediately overwritten to zero * by the VFS. */ - /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */ + /* cifs_inode->netfs.inode.i_flags = S_NOATIME | S_NOCMTIME; */ INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->llist); INIT_LIST_HEAD(&cifs_inode->deferred_closes); spin_lock_init(&cifs_inode->deferred_lock); - return &cifs_inode->vfs_inode; + return &cifs_inode->netfs.inode; } static void @@ -1418,7 +1418,7 @@ cifs_init_once(void *inode) { struct cifsInodeInfo *cifsi = inode; - inode_init_once(&cifsi->vfs_inode); + inode_init_once(&cifsi->netfs.inode); init_rwsem(&cifsi->lock_sem); } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f873379066c71..e7737166e5b86 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1479,20 +1479,16 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); #define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) #define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) +#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)) +#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)) /* * One of these for each file inode */ struct cifsInodeInfo { - struct { - /* These must be contiguous */ - struct inode vfs_inode; /* the VFS's inode record */ - struct netfs_i_context netfs_ctx; /* Netfslib context */ - }; + struct netfs_inode netfs; /* Netfslib context and vfs inode */ bool can_cache_brlcks; struct list_head llist; /* locks helb by this inode */ /* @@ -1531,7 +1527,7 @@ struct cifsInodeInfo { static inline struct cifsInodeInfo * CIFS_I(struct inode *inode) { - return container_of(inode, struct cifsInodeInfo, vfs_inode); + return container_of(inode, struct cifsInodeInfo, netfs.inode); } static inline struct cifs_sb_info * diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 1618e0537d58c..e64cda7a76101 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2004,7 +2004,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) { struct cifsFileInfo *open_file = NULL; - struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb); /* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) @@ -2060,7 +2060,7 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, return rc; } - cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); + cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb); /* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) @@ -4669,14 +4669,14 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) /* This inode is open for write at least once */ struct cifs_sb_info *cifs_sb; - cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); + cifs_sb = CIFS_SB(cifsInode->netfs.inode.i_sb); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { /* since no page cache to corrupt on directio we can change size safely */ return true; } - if (i_size_read(&cifsInode->vfs_inode) < end_of_file) + if (i_size_read(&cifsInode->netfs.inode) < end_of_file) return true; return false; diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index a638b29e90620..23ef56f55ce50 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c @@ -101,13 +101,13 @@ void cifs_fscache_get_inode_cookie(struct inode *inode) struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); - cifs_fscache_fill_coherency(&cifsi->vfs_inode, &cd); + cifs_fscache_fill_coherency(&cifsi->netfs.inode, &cd); - cifsi->netfs_ctx.cache = + cifsi->netfs.cache = fscache_acquire_cookie(tcon->fscache, 0, &cifsi->uniqueid, sizeof(cifsi->uniqueid), &cd, sizeof(cd), - i_size_read(&cifsi->vfs_inode)); + i_size_read(&cifsi->netfs.inode)); } void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) @@ -131,7 +131,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode) if (cookie) { cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cookie); fscache_relinquish_cookie(cookie, false); - cifsi->netfs_ctx.cache = NULL; + cifsi->netfs.cache = NULL; } } diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h index 52355c0912aee..ab9a51d0125cd 100644 --- a/fs/cifs/fscache.h +++ b/fs/cifs/fscache.h @@ -52,10 +52,10 @@ void cifs_fscache_fill_coherency(struct inode *inode, struct cifsInodeInfo *cifsi = CIFS_I(inode); memset(cd, 0, sizeof(*cd)); - cd->last_write_time_sec = cpu_to_le64(cifsi->vfs_inode.i_mtime.tv_sec); - cd->last_write_time_nsec = cpu_to_le32(cifsi->vfs_inode.i_mtime.tv_nsec); - cd->last_change_time_sec = cpu_to_le64(cifsi->vfs_inode.i_ctime.tv_sec); - cd->last_change_time_nsec = cpu_to_le32(cifsi->vfs_inode.i_ctime.tv_nsec); + cd->last_write_time_sec = cpu_to_le64(cifsi->netfs.inode.i_mtime.tv_sec); + cd->last_write_time_nsec = cpu_to_le32(cifsi->netfs.inode.i_mtime.tv_nsec); + cd->last_change_time_sec = cpu_to_le64(cifsi->netfs.inode.i_ctime.tv_sec); + cd->last_change_time_nsec = cpu_to_le32(cifsi->netfs.inode.i_ctime.tv_nsec); } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 2f9e7d2f81b6f..81da81e185538 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -115,7 +115,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) __func__, cifs_i->uniqueid); set_bit(CIFS_INO_INVALID_MAPPING, &cifs_i->flags); /* Invalidate fscache cookie */ - cifs_fscache_fill_coherency(&cifs_i->vfs_inode, &cd); + cifs_fscache_fill_coherency(&cifs_i->netfs.inode, &cd); fscache_invalidate(cifs_inode_cookie(inode), &cd, i_size_read(inode), 0); } @@ -2499,7 +2499,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, u64 len) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->vfs_inode.i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->netfs.inode.i_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct TCP_Server_Info *server = tcon->ses->server; struct cifsFileInfo *cfile; diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 35962a1a23b90..cbc3b433f5023 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -537,11 +537,11 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) if (oplock == OPLOCK_EXCLUSIVE) { cinode->oplock = CIFS_CACHE_WRITE_FLG | CIFS_CACHE_READ_FLG; cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", - &cinode->vfs_inode); + &cinode->netfs.inode); } else if (oplock == OPLOCK_READ) { cinode->oplock = CIFS_CACHE_READ_FLG; cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", - &cinode->vfs_inode); + &cinode->netfs.inode); } else cinode->oplock = 0; } diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 98a76fa791c06..8543cafdfd341 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4260,15 +4260,15 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { cinode->oplock = CIFS_CACHE_RHW_FLG; cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", - &cinode->vfs_inode); + &cinode->netfs.inode); } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { cinode->oplock = CIFS_CACHE_RW_FLG; cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", - &cinode->vfs_inode); + &cinode->netfs.inode); } else if (oplock == SMB2_OPLOCK_LEVEL_II) { cinode->oplock = CIFS_CACHE_READ_FLG; cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", - &cinode->vfs_inode); + &cinode->netfs.inode); } else cinode->oplock = 0; } @@ -4307,7 +4307,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, cinode->oplock = new_oplock; cifs_dbg(FYI, "%s Lease granted on inode %p\n", message, - &cinode->vfs_inode); + &cinode->netfs.inode); } static void diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c index 8742d22dfd2b2..d37e012386f34 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -155,7 +155,7 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq, void netfs_readahead(struct readahead_control *ractl) { struct netfs_io_request *rreq; - struct netfs_i_context *ctx = netfs_i_context(ractl->mapping->host); + struct netfs_inode *ctx = netfs_inode(ractl->mapping->host); int ret; _enter("%lx,%x", readahead_index(ractl), readahead_count(ractl)); @@ -215,7 +215,7 @@ int netfs_read_folio(struct file *file, struct folio *folio) { struct address_space *mapping = folio_file_mapping(folio); struct netfs_io_request *rreq; - struct netfs_i_context *ctx = netfs_i_context(mapping->host); + struct netfs_inode *ctx = netfs_inode(mapping->host); int ret; _enter("%lx", folio_index(folio)); @@ -331,7 +331,7 @@ int netfs_write_begin(struct file *file, struct address_space *mapping, void **_fsdata) { struct netfs_io_request *rreq; - struct netfs_i_context *ctx = netfs_i_context(file_inode(file )); + struct netfs_inode *ctx = netfs_inode(file_inode(file )); struct folio *folio; unsigned int fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE; pgoff_t index = pos >> PAGE_SHIFT; diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h index b7b0e3d18d9e8..43fac1b14e40c 100644 --- a/fs/netfs/internal.h +++ b/fs/netfs/internal.h @@ -91,7 +91,7 @@ static inline void netfs_stat_d(atomic_t *stat) /* * Miscellaneous functions. */ -static inline bool netfs_is_cache_enabled(struct netfs_i_context *ctx) +static inline bool netfs_is_cache_enabled(struct netfs_inode *ctx) { #if IS_ENABLED(CONFIG_FSCACHE) struct fscache_cookie *cookie = ctx->cache; diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c index e86107b30ba44..c6afa605b63b8 100644 --- a/fs/netfs/objects.c +++ b/fs/netfs/objects.c @@ -18,7 +18,7 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping, { static atomic_t debug_ids; struct inode *inode = file ? file_inode(file) : mapping->host; - struct netfs_i_context *ctx = netfs_i_context(inode); + struct netfs_inode *ctx = netfs_inode(inode); struct netfs_io_request *rreq; int ret; diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 77fa6a61706a5..6dbb4c9ce50d7 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -119,9 +119,10 @@ typedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error, bool was_async); /* - * Per-inode description. This must be directly after the inode struct. + * Per-inode context. This wraps the VFS inode. */ -struct netfs_i_context { +struct netfs_inode { + struct inode inode; /* The VFS inode */ const struct netfs_request_ops *ops; #if IS_ENABLED(CONFIG_FSCACHE) struct fscache_cookie *cache; @@ -256,7 +257,7 @@ struct netfs_cache_ops { * boundary as appropriate. */ enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq, - loff_t i_size); + loff_t i_size); /* Prepare a write operation, working out what part of the write we can * actually do. @@ -288,45 +289,35 @@ extern void netfs_put_subrequest(struct netfs_io_subrequest *subreq, extern void netfs_stats_show(struct seq_file *); /** - * netfs_i_context - Get the netfs inode context from the inode + * netfs_inode - Get the netfs inode context from the inode * @inode: The inode to query * * Get the netfs lib inode context from the network filesystem's inode. The * context struct is expected to directly follow on from the VFS inode struct. */ -static inline struct netfs_i_context *netfs_i_context(struct inode *inode) +static inline struct netfs_inode *netfs_inode(struct inode *inode) { - return (void *)inode + sizeof(*inode); + return container_of(inode, struct netfs_inode, inode); } /** - * netfs_inode - Get the netfs inode from the inode context - * @ctx: The context to query - * - * Get the netfs inode from the netfs library's inode context. The VFS inode - * is expected to directly precede the context struct. - */ -static inline struct inode *netfs_inode(struct netfs_i_context *ctx) -{ - return (void *)ctx - sizeof(struct inode); -} - -/** - * netfs_i_context_init - Initialise a netfs lib context + * netfs_inode_init - Initialise a netfslib inode context * @inode: The inode with which the context is associated * @ops: The netfs's operations list * * Initialise the netfs library context struct. This is expected to follow on * directly from the VFS inode struct. */ -static inline void netfs_i_context_init(struct inode *inode, - const struct netfs_request_ops *ops) +static inline void netfs_inode_init(struct inode *inode, + const struct netfs_request_ops *ops) { - struct netfs_i_context *ctx = netfs_i_context(inode); + struct netfs_inode *ctx = netfs_inode(inode); - memset(ctx, 0, sizeof(*ctx)); ctx->ops = ops; ctx->remote_i_size = i_size_read(inode); +#if IS_ENABLED(CONFIG_FSCACHE) + ctx->cache = NULL; +#endif } /** @@ -338,7 +329,7 @@ static inline void netfs_i_context_init(struct inode *inode, */ static inline void netfs_resize_file(struct inode *inode, loff_t new_i_size) { - struct netfs_i_context *ctx = netfs_i_context(inode); + struct netfs_inode *ctx = netfs_inode(inode); ctx->remote_i_size = new_i_size; } @@ -352,7 +343,7 @@ static inline void netfs_resize_file(struct inode *inode, loff_t new_i_size) static inline struct fscache_cookie *netfs_i_cookie(struct inode *inode) { #if IS_ENABLED(CONFIG_FSCACHE) - struct netfs_i_context *ctx = netfs_i_context(inode); + struct netfs_inode *ctx = netfs_inode(inode); return ctx->cache; #else return NULL; -- GitLab From b489a6e5871690735752f8875f411e4d0cd8e5df Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Wed, 8 Jun 2022 18:34:25 +0300 Subject: [PATCH 423/942] tls: Rename TLS_INFO_ZC_SENDFILE to TLS_INFO_ZC_TX To embrace possible future optimizations of TLS, rename zerocopy sendfile definitions to more generic ones: * setsockopt: TLS_TX_ZEROCOPY_SENDFILE- > TLS_TX_ZEROCOPY_RO * sock_diag: TLS_INFO_ZC_SENDFILE -> TLS_INFO_ZC_RO_TX RO stands for readonly and emphasizes that the application shouldn't modify the data being transmitted with zerocopy to avoid potential disconnection. Fixes: c1318b39c7d3 ("tls: Add opt-in zerocopy mode of sendfile()") Signed-off-by: Maxim Mikityanskiy Link: https://lore.kernel.org/r/20220608153425.3151146-1-maximmi@nvidia.com Signed-off-by: Jakub Kicinski --- include/uapi/linux/tls.h | 4 ++-- net/tls/tls_main.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h index ac39328eabe73..bb8f80812b0bd 100644 --- a/include/uapi/linux/tls.h +++ b/include/uapi/linux/tls.h @@ -39,7 +39,7 @@ /* TLS socket options */ #define TLS_TX 1 /* Set transmit parameters */ #define TLS_RX 2 /* Set receive parameters */ -#define TLS_TX_ZEROCOPY_SENDFILE 3 /* transmit zerocopy sendfile */ +#define TLS_TX_ZEROCOPY_RO 3 /* TX zerocopy (only sendfile now) */ /* Supported versions */ #define TLS_VERSION_MINOR(ver) ((ver) & 0xFF) @@ -161,7 +161,7 @@ enum { TLS_INFO_CIPHER, TLS_INFO_TXCONF, TLS_INFO_RXCONF, - TLS_INFO_ZC_SENDFILE, + TLS_INFO_ZC_RO_TX, __TLS_INFO_MAX, }; #define TLS_INFO_MAX (__TLS_INFO_MAX - 1) diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index b91ddc110786e..da176411c1b5f 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -544,7 +544,7 @@ static int do_tls_getsockopt(struct sock *sk, int optname, rc = do_tls_getsockopt_conf(sk, optval, optlen, optname == TLS_TX); break; - case TLS_TX_ZEROCOPY_SENDFILE: + case TLS_TX_ZEROCOPY_RO: rc = do_tls_getsockopt_tx_zc(sk, optval, optlen); break; default: @@ -731,7 +731,7 @@ static int do_tls_setsockopt(struct sock *sk, int optname, sockptr_t optval, optname == TLS_TX); release_sock(sk); break; - case TLS_TX_ZEROCOPY_SENDFILE: + case TLS_TX_ZEROCOPY_RO: lock_sock(sk); rc = do_tls_setsockopt_tx_zc(sk, optval, optlen); release_sock(sk); @@ -970,7 +970,7 @@ static int tls_get_info(const struct sock *sk, struct sk_buff *skb) goto nla_failure; if (ctx->tx_conf == TLS_HW && ctx->zerocopy_sendfile) { - err = nla_put_flag(skb, TLS_INFO_ZC_SENDFILE); + err = nla_put_flag(skb, TLS_INFO_ZC_RO_TX); if (err) goto nla_failure; } @@ -994,7 +994,7 @@ static size_t tls_get_info_size(const struct sock *sk) nla_total_size(sizeof(u16)) + /* TLS_INFO_CIPHER */ nla_total_size(sizeof(u16)) + /* TLS_INFO_RXCONF */ nla_total_size(sizeof(u16)) + /* TLS_INFO_TXCONF */ - nla_total_size(0) + /* TLS_INFO_ZC_SENDFILE */ + nla_total_size(0) + /* TLS_INFO_ZC_RO_TX */ 0; return size; -- GitLab From 03d5005ff7356a9952a21da20a3d7828fd559fee Mon Sep 17 00:00:00 2001 From: Fei Qin Date: Wed, 8 Jun 2022 11:29:00 +0200 Subject: [PATCH 424/942] nfp: avoid unnecessary check warnings in nfp_app_get_vf_config nfp_net_sriov_check is added in nfp_app_get_vf_config which intends to ensure ivi->vlan_proto and ivi->max_tx_rate/min_tx_rate can be read from VF config table only when firmware supports corresponding capability. However, "nfp_app_get_vf_config" can be called by commands like "ip a", "ip link set $DEV up" and "ip link set $DEV vf $NUM vlan $param" (with VF). When using commands above, many warnings "ndo_set_vf_ not supported" would appear if firmware doesn't support VF rate limit and 802.1ad VLAN assingment. If more VFs are created, things could get worse. Thus, this patch add an extra bool parameter for nfp_net_sriov_check to enable/disable the cap check warning report. Unnecessary warnings in nfp_app_get_vf_config can be avoided. Valid warnings in kinds of vf setting function can be reserved. Fixes: e0d0e1fdf1ed ("nfp: VF rate limit support") Fixes: 59359597b010 ("nfp: support 802.1ad VLAN assingment to VF") Signed-off-by: Fei Qin Signed-off-by: Yinjun Zhang Signed-off-by: Louis Peens Signed-off-by: Simon Horman Signed-off-by: Jakub Kicinski --- .../ethernet/netronome/nfp/nfp_net_sriov.c | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c b/drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c index 54af309613510..6eeeb0fda91fa 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_sriov.c @@ -15,7 +15,7 @@ #include "nfp_net_sriov.h" static int -nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg) +nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg, bool warn) { u16 cap_vf; @@ -24,12 +24,14 @@ nfp_net_sriov_check(struct nfp_app *app, int vf, u16 cap, const char *msg) cap_vf = readw(app->pf->vfcfg_tbl2 + NFP_NET_VF_CFG_MB_CAP); if ((cap_vf & cap) != cap) { - nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg); + if (warn) + nfp_warn(app->pf->cpp, "ndo_set_vf_%s not supported\n", msg); return -EOPNOTSUPP; } if (vf < 0 || vf >= app->pf->num_vfs) { - nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf); + if (warn) + nfp_warn(app->pf->cpp, "invalid VF id %d\n", vf); return -EINVAL; } @@ -65,7 +67,7 @@ int nfp_app_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) unsigned int vf_offset; int err; - err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac"); + err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_MAC, "mac", true); if (err) return err; @@ -101,7 +103,7 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, u32 vlan_tag; int err; - err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan"); + err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN, "vlan", true); if (err) return err; @@ -115,7 +117,7 @@ int nfp_app_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, } /* Check if fw supports or not */ - err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto"); + err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", true); if (err) is_proto_sup = false; @@ -149,7 +151,7 @@ int nfp_app_set_vf_rate(struct net_device *netdev, int vf, u32 vf_offset, ratevalue; int err; - err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate"); + err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", true); if (err) return err; @@ -181,7 +183,7 @@ int nfp_app_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable) int err; err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_SPOOF, - "spoofchk"); + "spoofchk", true); if (err) return err; @@ -205,7 +207,7 @@ int nfp_app_set_vf_trust(struct net_device *netdev, int vf, bool enable) int err; err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_TRUST, - "trust"); + "trust", true); if (err) return err; @@ -230,7 +232,7 @@ int nfp_app_set_vf_link_state(struct net_device *netdev, int vf, int err; err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_LINK_STATE, - "link_state"); + "link_state", true); if (err) return err; @@ -265,7 +267,7 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf, u8 flags; int err; - err = nfp_net_sriov_check(app, vf, 0, ""); + err = nfp_net_sriov_check(app, vf, 0, "", true); if (err) return err; @@ -285,13 +287,13 @@ int nfp_app_get_vf_config(struct net_device *netdev, int vf, ivi->vlan = FIELD_GET(NFP_NET_VF_CFG_VLAN_VID, vlan_tag); ivi->qos = FIELD_GET(NFP_NET_VF_CFG_VLAN_QOS, vlan_tag); - if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto")) + if (!nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_VLAN_PROTO, "vlan_proto", false)) ivi->vlan_proto = htons(FIELD_GET(NFP_NET_VF_CFG_VLAN_PROT, vlan_tag)); ivi->spoofchk = FIELD_GET(NFP_NET_VF_CFG_CTRL_SPOOF, flags); ivi->trusted = FIELD_GET(NFP_NET_VF_CFG_CTRL_TRUST, flags); ivi->linkstate = FIELD_GET(NFP_NET_VF_CFG_CTRL_LINK_STATE, flags); - err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate"); + err = nfp_net_sriov_check(app, vf, NFP_NET_VF_CFG_MB_CAP_RATE, "rate", false); if (!err) { rate = readl(app->pf->vfcfg_tbl2 + vf_offset + NFP_NET_VF_CFG_RATE); -- GitLab From a0b843340dae704e17c1ddfad0f85c583c36757f Mon Sep 17 00:00:00 2001 From: Etienne van der Linde Date: Wed, 8 Jun 2022 11:29:01 +0200 Subject: [PATCH 425/942] nfp: flower: restructure flow-key for gre+vlan combination Swap around the GRE and VLAN parts in the flow-key offloaded by the driver to fit in with other tunnel types and the firmware. Without this change used cases with GRE+VLAN on the outer header does not get offloaded as the flow-key mismatches what the firmware expect. Fixes: 0d630f58989a ("nfp: flower: add support to offload QinQ match") Fixes: 5a2b93041646 ("nfp: flower-ct: compile match sections of flow_payload") Signed-off-by: Etienne van der Linde Signed-off-by: Louis Peens Signed-off-by: Yinjun Zhang Signed-off-by: Simon Horman Signed-off-by: Jakub Kicinski --- .../ethernet/netronome/nfp/flower/conntrack.c | 32 +++++++++---------- .../net/ethernet/netronome/nfp/flower/match.c | 16 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c index 443a5d6eb57be..7c31a46195b26 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c +++ b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c @@ -507,6 +507,11 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map) key_size += sizeof(struct nfp_flower_ipv6); } + if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_QINQ) { + map[FLOW_PAY_QINQ] = key_size; + key_size += sizeof(struct nfp_flower_vlan); + } + if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GRE) { map[FLOW_PAY_GRE] = key_size; if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) @@ -515,11 +520,6 @@ nfp_fl_calc_key_layers_sz(struct nfp_fl_key_ls in_key_ls, uint16_t *map) key_size += sizeof(struct nfp_flower_ipv4_gre_tun); } - if (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_QINQ) { - map[FLOW_PAY_QINQ] = key_size; - key_size += sizeof(struct nfp_flower_vlan); - } - if ((in_key_ls.key_layer & NFP_FLOWER_LAYER_VXLAN) || (in_key_ls.key_layer_two & NFP_FLOWER_LAYER2_GENEVE)) { map[FLOW_PAY_UDP_TUN] = key_size; @@ -758,6 +758,17 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry) } } + if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) { + offset = key_map[FLOW_PAY_QINQ]; + key = kdata + offset; + msk = mdata + offset; + for (i = 0; i < _CT_TYPE_MAX; i++) { + nfp_flower_compile_vlan((struct nfp_flower_vlan *)key, + (struct nfp_flower_vlan *)msk, + rules[i]); + } + } + if (key_layer.key_layer_two & NFP_FLOWER_LAYER2_GRE) { offset = key_map[FLOW_PAY_GRE]; key = kdata + offset; @@ -798,17 +809,6 @@ static int nfp_fl_ct_add_offload(struct nfp_fl_nft_tc_merge *m_entry) } } - if (NFP_FLOWER_LAYER2_QINQ & key_layer.key_layer_two) { - offset = key_map[FLOW_PAY_QINQ]; - key = kdata + offset; - msk = mdata + offset; - for (i = 0; i < _CT_TYPE_MAX; i++) { - nfp_flower_compile_vlan((struct nfp_flower_vlan *)key, - (struct nfp_flower_vlan *)msk, - rules[i]); - } - } - if (key_layer.key_layer & NFP_FLOWER_LAYER_VXLAN || key_layer.key_layer_two & NFP_FLOWER_LAYER2_GENEVE) { offset = key_map[FLOW_PAY_UDP_TUN]; diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c index 193a167a6762e..e01430139b6d8 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/match.c +++ b/drivers/net/ethernet/netronome/nfp/flower/match.c @@ -625,6 +625,14 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, msk += sizeof(struct nfp_flower_ipv6); } + if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) { + nfp_flower_compile_vlan((struct nfp_flower_vlan *)ext, + (struct nfp_flower_vlan *)msk, + rule); + ext += sizeof(struct nfp_flower_vlan); + msk += sizeof(struct nfp_flower_vlan); + } + if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GRE) { if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) { struct nfp_flower_ipv6_gre_tun *gre_match; @@ -660,14 +668,6 @@ int nfp_flower_compile_flow_match(struct nfp_app *app, } } - if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) { - nfp_flower_compile_vlan((struct nfp_flower_vlan *)ext, - (struct nfp_flower_vlan *)msk, - rule); - ext += sizeof(struct nfp_flower_vlan); - msk += sizeof(struct nfp_flower_vlan); - } - if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN || key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) { if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) { -- GitLab From a3bd2102e464202b58d57390a538d96f57ffc361 Mon Sep 17 00:00:00 2001 From: Andrea Mayer Date: Wed, 8 Jun 2022 11:19:17 +0200 Subject: [PATCH 426/942] net: seg6: fix seg6_lookup_any_nexthop() to handle VRFs using flowi_l3mdev Commit 40867d74c374 ("net: Add l3mdev index to flow struct and avoid oif reset for port devices") adds a new entry (flowi_l3mdev) in the common flow struct used for indicating the l3mdev index for later rule and table matching. The l3mdev_update_flow() has been adapted to properly set the flowi_l3mdev based on the flowi_oif/flowi_iif. In fact, when a valid flowi_iif is supplied to the l3mdev_update_flow(), this function can update the flowi_l3mdev entry only if it has not yet been set (i.e., the flowi_l3mdev entry is equal to 0). The SRv6 End.DT6 behavior in VRF mode leverages a VRF device in order to force the routing lookup into the associated routing table. This routing operation is performed by seg6_lookup_any_nextop() preparing a flowi6 data structure used by ip6_route_input_lookup() which, in turn, (indirectly) invokes l3mdev_update_flow(). However, seg6_lookup_any_nexthop() does not initialize the new flowi_l3mdev entry which is filled with random garbage data. This prevents l3mdev_update_flow() from properly updating the flowi_l3mdev with the VRF index, and thus SRv6 End.DT6 (VRF mode)/DT46 behaviors are broken. This patch correctly initializes the flowi6 instance allocated and used by seg6_lookup_any_nexhtop(). Specifically, the entire flowi6 instance is wiped out: in case new entries are added to flowi/flowi6 (as happened with the flowi_l3mdev entry), we should no longer have incorrectly initialized values. As a result of this operation, the value of flowi_l3mdev is also set to 0. The proposed fix can be tested easily. Starting from the commit referenced in the Fixes, selftests [1],[2] indicate that the SRv6 End.DT6 (VRF mode)/DT46 behaviors no longer work correctly. By applying this patch, those behaviors are back to work properly again. [1] - tools/testing/selftests/net/srv6_end_dt46_l3vpn_test.sh [2] - tools/testing/selftests/net/srv6_end_dt6_l3vpn_test.sh Fixes: 40867d74c374 ("net: Add l3mdev index to flow struct and avoid oif reset for port devices") Reported-by: Anton Makarov Signed-off-by: Andrea Mayer Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20220608091917.20345-1-andrea.mayer@uniroma2.it Signed-off-by: Jakub Kicinski --- net/ipv6/seg6_local.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c index 9fbe243a0e810..98a34287439cc 100644 --- a/net/ipv6/seg6_local.c +++ b/net/ipv6/seg6_local.c @@ -218,6 +218,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, struct flowi6 fl6; int dev_flags = 0; + memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_iif = skb->dev->ifindex; fl6.daddr = nhaddr ? *nhaddr : hdr->daddr; fl6.saddr = hdr->saddr; -- GitLab From 9b29b6b20376ab64e1b043df6301d8a92378e631 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 7 Jun 2022 09:44:07 +0200 Subject: [PATCH 427/942] random: avoid checking crng_ready() twice in random_init() The current flow expands to: if (crng_ready()) ... else if (...) if (!crng_ready()) ... The second crng_ready() call is redundant, but can't so easily be optimized out by the compiler. This commit simplifies that to: if (crng_ready() ... else if (...) ... Fixes: 560181c27b58 ("random: move initialization functions out of hot pages") Cc: stable@vger.kernel.org Cc: Dominik Brodowski Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index b691b9d595033..4862d4d3ec49c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -801,7 +801,7 @@ int __init random_init(const char *command_line) if (crng_ready()) crng_reseed(); else if (trust_cpu) - credit_init_bits(arch_bytes * 8); + _credit_init_bits(arch_bytes * 8); used_arch_random = arch_bytes * 8 >= POOL_READY_BITS; WARN_ON(register_pm_notifier(&pm_notifier)); -- GitLab From 39e0f991a62ed5efabd20711a7b6e7da92603170 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 7 Jun 2022 17:00:16 +0200 Subject: [PATCH 428/942] random: mark bootloader randomness code as __init add_bootloader_randomness() and the variables it touches are only used during __init and not after, so mark these as __init. At the same time, unexport this, since it's only called by other __init code that's built-in. Cc: stable@vger.kernel.org Fixes: 428826f5358c ("fdt: add support for rng-seed") Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 7 +++---- include/linux/random.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 4862d4d3ec49c..0d6fb3eaf609e 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -725,8 +725,8 @@ static void __cold _credit_init_bits(size_t bits) **********************************************************************/ static bool used_arch_random; -static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); -static bool trust_bootloader __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); +static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); +static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); static int __init parse_trust_cpu(char *arg) { return kstrtobool(arg, &trust_cpu); @@ -865,13 +865,12 @@ EXPORT_SYMBOL_GPL(add_hwgenerator_randomness); * Handle random seed passed by bootloader, and credit it if * CONFIG_RANDOM_TRUST_BOOTLOADER is set. */ -void __cold add_bootloader_randomness(const void *buf, size_t len) +void __init add_bootloader_randomness(const void *buf, size_t len) { mix_pool_bytes(buf, len); if (trust_bootloader) credit_init_bits(len * 8); } -EXPORT_SYMBOL_GPL(add_bootloader_randomness); #if IS_ENABLED(CONFIG_VMGENID) static BLOCKING_NOTIFIER_HEAD(vmfork_chain); diff --git a/include/linux/random.h b/include/linux/random.h index fae0c84027fdc..223b4bd584e79 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -13,7 +13,7 @@ struct notifier_block; void add_device_randomness(const void *buf, size_t len); -void add_bootloader_randomness(const void *buf, size_t len); +void __init add_bootloader_randomness(const void *buf, size_t len); void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) __latent_entropy; void add_interrupt_randomness(int irq) __latent_entropy; -- GitLab From 77fc95f8c0dc9e1f8e620ec14d2fb65028fb7adc Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 7 Jun 2022 17:04:38 +0200 Subject: [PATCH 429/942] random: account for arch randomness in bits Rather than accounting in bytes and multiplying (shifting), we can just account in bits and avoid the shift. The main motivation for this is there are other patches in flux that expand this code a bit, and avoiding the duplication of "* 8" everywhere makes things a bit clearer. Cc: stable@vger.kernel.org Fixes: 12e45a2a6308 ("random: credit architectural init the exact amount") Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 0d6fb3eaf609e..60d701a2516b1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -776,7 +776,7 @@ static struct notifier_block pm_notifier = { .notifier_call = random_pm_notifica int __init random_init(const char *command_line) { ktime_t now = ktime_get_real(); - unsigned int i, arch_bytes; + unsigned int i, arch_bits; unsigned long entropy; #if defined(LATENT_ENTROPY_PLUGIN) @@ -784,12 +784,12 @@ int __init random_init(const char *command_line) _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed)); #endif - for (i = 0, arch_bytes = BLAKE2S_BLOCK_SIZE; + for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8; i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) { if (!arch_get_random_seed_long_early(&entropy) && !arch_get_random_long_early(&entropy)) { entropy = random_get_entropy(); - arch_bytes -= sizeof(entropy); + arch_bits -= sizeof(entropy) * 8; } _mix_pool_bytes(&entropy, sizeof(entropy)); } @@ -801,8 +801,8 @@ int __init random_init(const char *command_line) if (crng_ready()) crng_reseed(); else if (trust_cpu) - _credit_init_bits(arch_bytes * 8); - used_arch_random = arch_bytes * 8 >= POOL_READY_BITS; + _credit_init_bits(arch_bits); + used_arch_random = arch_bits >= POOL_READY_BITS; WARN_ON(register_pm_notifier(&pm_notifier)); -- GitLab From 60e5b2886b92afa9e7af56bba7f5fa5f057e1e97 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 7 Jun 2022 17:28:06 +0200 Subject: [PATCH 430/942] random: do not use jump labels before they are initialized Stephen reported that a static key warning splat appears during early boot on systems that credit randomness from device trees that contain an "rng-seed" property, because because setup_machine_fdt() is called before jump_label_init() during setup_arch(): static_key_enable_cpuslocked(): static key '0xffffffe51c6fcfc0' used before call to jump_label_init() WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:166 static_key_enable_cpuslocked+0xb0/0xb8 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0+ #224 44b43e377bfc84bc99bb5ab885ff694984ee09ff pstate: 600001c9 (nZCv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : static_key_enable_cpuslocked+0xb0/0xb8 lr : static_key_enable_cpuslocked+0xb0/0xb8 sp : ffffffe51c393cf0 x29: ffffffe51c393cf0 x28: 000000008185054c x27: 00000000f1042f10 x26: 0000000000000000 x25: 00000000f10302b2 x24: 0000002513200000 x23: 0000002513200000 x22: ffffffe51c1c9000 x21: fffffffdfdc00000 x20: ffffffe51c2f0831 x19: ffffffe51c6fcfc0 x18: 00000000ffff1020 x17: 00000000e1e2ac90 x16: 00000000000000e0 x15: ffffffe51b710708 x14: 0000000000000066 x13: 0000000000000018 x12: 0000000000000000 x11: 0000000000000000 x10: 00000000ffffffff x9 : 0000000000000000 x8 : 0000000000000000 x7 : 61632065726f6665 x6 : 6220646573752027 x5 : ffffffe51c641d25 x4 : ffffffe51c13142c x3 : ffff0a00ffffff05 x2 : 40000000ffffe003 x1 : 00000000000001c0 x0 : 0000000000000065 Call trace: static_key_enable_cpuslocked+0xb0/0xb8 static_key_enable+0x2c/0x40 crng_set_ready+0x24/0x30 execute_in_process_context+0x80/0x90 _credit_init_bits+0x100/0x154 add_bootloader_randomness+0x64/0x78 early_init_dt_scan_chosen+0x140/0x184 early_init_dt_scan_nodes+0x28/0x4c early_init_dt_scan+0x40/0x44 setup_machine_fdt+0x7c/0x120 setup_arch+0x74/0x1d8 start_kernel+0x84/0x44c __primary_switched+0xc0/0xc8 ---[ end trace 0000000000000000 ]--- random: crng init done Machine model: Google Lazor (rev1 - 2) with LTE A trivial fix went in to address this on arm64, 73e2d827a501 ("arm64: Initialize jump labels before setup_machine_fdt()"). I wrote patches as well for arm32 and risc-v. But still patches are needed on xtensa, powerpc, arc, and mips. So that's 7 platforms where things aren't quite right. This sort of points to larger issues that might need a larger solution. Instead, this commit just defers setting the static branch until later in the boot process. random_init() is called after jump_label_init() has been called, and so is always a safe place from which to adjust the static branch. Fixes: f5bda35fba61 ("random: use static branch for crng_ready()") Reported-by: Stephen Boyd Reported-by: Phil Elwell Tested-by: Phil Elwell Reviewed-by: Ard Biesheuvel Cc: Catalin Marinas Cc: Russell King Cc: Arnd Bergmann Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 60d701a2516b1..0b78b9c4acf54 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -650,7 +650,8 @@ static void __cold _credit_init_bits(size_t bits) if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */ - execute_in_process_context(crng_set_ready, &set_ready); + if (static_key_initialized) + execute_in_process_context(crng_set_ready, &set_ready); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN); pr_notice("crng init done\n"); @@ -798,6 +799,14 @@ int __init random_init(const char *command_line) _mix_pool_bytes(command_line, strlen(command_line)); add_latent_entropy(); + /* + * If we were initialized by the bootloader before jump labels are + * initialized, then we should enable the static branch here, where + * it's guaranteed that jump labels have been initialized. + */ + if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY) + crng_set_ready(NULL); + if (crng_ready()) crng_reseed(); else if (trust_cpu) -- GitLab From 846bb97e131d7938847963cca00657c995b1fce1 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 5 Jun 2022 18:30:46 +0200 Subject: [PATCH 431/942] random: credit cpu and bootloader seeds by default This commit changes the default Kconfig values of RANDOM_TRUST_CPU and RANDOM_TRUST_BOOTLOADER to be Y by default. It does not change any existing configs or change any kernel behavior. The reason for this is several fold. As background, I recently had an email thread with the kernel maintainers of Fedora/RHEL, Debian, Ubuntu, Gentoo, Arch, NixOS, Alpine, SUSE, and Void as recipients. I noted that some distros trust RDRAND, some trust EFI, and some trust both, and I asked why or why not. There wasn't really much of a "debate" but rather an interesting discussion of what the historical reasons have been for this, and it came up that some distros just missed the introduction of the bootloader Kconfig knob, while another didn't want to enable it until there was a boot time switch to turn it off for more concerned users (which has since been added). The result of the rather uneventful discussion is that every major Linux distro enables these two options by default. While I didn't have really too strong of an opinion going into this thread -- and I mostly wanted to learn what the distros' thinking was one way or another -- ultimately I think their choice was a decent enough one for a default option (which can be disabled at boot time). I'll try to summarize the pros and cons: Pros: - The RNG machinery gets initialized super quickly, and there's no messing around with subsequent blocking behavior. - The bootloader mechanism is used by kexec in order for the prior kernel to initialize the RNG of the next kernel, which increases the entropy available to early boot daemons of the next kernel. - Previous objections related to backdoors centered around Dual_EC_DRBG-like kleptographic systems, in which observing some amount of the output stream enables an adversary holding the right key to determine the entire output stream. This used to be a partially justified concern, because RDRAND output was mixed into the output stream in varying ways, some of which may have lacked pre-image resistance (e.g. XOR or an LFSR). But this is no longer the case. Now, all usage of RDRAND and bootloader seeds go through a cryptographic hash function. This means that the CPU would have to compute a hash pre-image, which is not considered to be feasible (otherwise the hash function would be terribly broken). - More generally, if the CPU is backdoored, the RNG is probably not the realistic vector of choice for an attacker. - These CPU or bootloader seeds are far from being the only source of entropy. Rather, there is generally a pretty huge amount of entropy, not all of which is credited, especially on CPUs that support instructions like RDRAND. In other words, assuming RDRAND outputs all zeros, an attacker would *still* have to accurately model every single other entropy source also in use. - The RNG now reseeds itself quite rapidly during boot, starting at 2 seconds, then 4, then 8, then 16, and so forth, so that other sources of entropy get used without much delay. - Paranoid users can set random.trust_{cpu,bootloader}=no in the kernel command line, and paranoid system builders can set the Kconfig options to N, so there's no reduction or restriction of optionality. - It's a practical default. - All the distros have it set this way. Microsoft and Apple trust it too. Bandwagon. Cons: - RDRAND *could* still be backdoored with something like a fixed key or limited space serial number seed or another indexable scheme like that. (However, it's hard to imagine threat models where the CPU is backdoored like this, yet people are still okay making *any* computations with it or connecting it to networks, etc.) - RDRAND *could* be defective, rather than backdoored, and produce garbage that is in one way or another insufficient for crypto. - Suggesting a *reduction* in paranoia, as this commit effectively does, may cause some to question my personal integrity as a "security person". - Bootloader seeds and RDRAND are generally very difficult if not all together impossible to audit. Keep in mind that this doesn't actually change any behavior. This is just a change in the default Kconfig value. The distros already are shipping kernels that set things this way. Ard made an additional argument in [1]: We're at the mercy of firmware and micro-architecture anyway, given that we are also relying on it to ensure that every instruction in the kernel's executable image has been faithfully copied to memory, and that the CPU implements those instructions as documented. So I don't think firmware or ISA bugs related to RNGs deserve special treatment - if they are broken, we should quirk around them like we usually do. So enabling these by default is a step in the right direction IMHO. In [2], Phil pointed out that having this disabled masked a bug that CI otherwise would have caught: A clean 5.15.45 boots cleanly, whereas a downstream kernel shows the static key warning (but it does go on to boot). The significant difference is that our defconfigs set CONFIG_RANDOM_TRUST_BOOTLOADER=y defining that on top of multi_v7_defconfig demonstrates the issue on a clean 5.15.45. Conversely, not setting that option in a downstream kernel build avoids the warning [1] https://lore.kernel.org/lkml/CAMj1kXGi+ieviFjXv9zQBSaGyyzeGW_VpMpTLJK8PJb2QHEQ-w@mail.gmail.com/ [2] https://lore.kernel.org/lkml/c47c42e3-1d56-5859-a6ad-976a1a3381c6@raspberrypi.com/ Cc: Theodore Ts'o Reviewed-by: Ard Biesheuvel Signed-off-by: Jason A. Donenfeld --- drivers/char/Kconfig | 50 +++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 69fd31ffb8474..0b6c03643ddc6 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -429,28 +429,40 @@ config ADI driver include crash and makedumpfile. config RANDOM_TRUST_CPU - bool "Trust the CPU manufacturer to initialize Linux's CRNG" + bool "Initialize RNG using CPU RNG instructions" + default y depends on ARCH_RANDOM - default n help - Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or - RDRAND, IBM for the S390 and Power PC architectures) is trustworthy - for the purposes of initializing Linux's CRNG. Since this is not - something that can be independently audited, this amounts to trusting - that CPU manufacturer (perhaps with the insistence or mandate - of a Nation State's intelligence or law enforcement agencies) - has not installed a hidden back door to compromise the CPU's - random number generation facilities. This can also be configured - at boot with "random.trust_cpu=on/off". + Initialize the RNG using random numbers supplied by the CPU's + RNG instructions (e.g. RDRAND), if supported and available. These + random numbers are never used directly, but are rather hashed into + the main input pool, and this happens regardless of whether or not + this option is enabled. Instead, this option controls whether the + they are credited and hence can initialize the RNG. Additionally, + other sources of randomness are always used, regardless of this + setting. Enabling this implies trusting that the CPU can supply high + quality and non-backdoored random numbers. + + Say Y here unless you have reason to mistrust your CPU or believe + its RNG facilities may be faulty. This may also be configured at + boot time with "random.trust_cpu=on/off". config RANDOM_TRUST_BOOTLOADER - bool "Trust the bootloader to initialize Linux's CRNG" - help - Some bootloaders can provide entropy to increase the kernel's initial - device randomness. Say Y here to assume the entropy provided by the - booloader is trustworthy so it will be added to the kernel's entropy - pool. Otherwise, say N here so it will be regarded as device input that - only mixes the entropy pool. This can also be configured at boot with - "random.trust_bootloader=on/off". + bool "Initialize RNG using bootloader-supplied seed" + default y + help + Initialize the RNG using a seed supplied by the bootloader or boot + environment (e.g. EFI or a bootloader-generated device tree). This + seed is not used directly, but is rather hashed into the main input + pool, and this happens regardless of whether or not this option is + enabled. Instead, this option controls whether the seed is credited + and hence can initialize the RNG. Additionally, other sources of + randomness are always used, regardless of this setting. Enabling + this implies trusting that the bootloader can supply high quality and + non-backdoored seeds. + + Say Y here unless you have reason to mistrust your bootloader or + believe its RNG facilities may be faulty. This may also be configured + at boot time with "random.trust_bootloader=on/off". endmenu -- GitLab From e052a478a7daeca67664f7addd308ff51dd40654 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 8 Jun 2022 10:31:25 +0200 Subject: [PATCH 432/942] random: remove rng_has_arch_random() With arch randomness being used by every distro and enabled in defconfigs, the distinction between rng_has_arch_random() and rng_is_initialized() is now rather small. In fact, the places where they differ are now places where paranoid users and system builders really don't want arch randomness to be used, in which case we should respect that choice, or places where arch randomness is known to be broken, in which case that choice is all the more important. So this commit just removes the function and its one user. Reviewed-by: Petr Mladek # for vsprintf.c Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 13 ------------- include/linux/random.h | 1 - lib/vsprintf.c | 3 +-- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 0b78b9c4acf54..655e327d425ec 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -725,7 +725,6 @@ static void __cold _credit_init_bits(size_t bits) * **********************************************************************/ -static bool used_arch_random; static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); static int __init parse_trust_cpu(char *arg) @@ -811,7 +810,6 @@ int __init random_init(const char *command_line) crng_reseed(); else if (trust_cpu) _credit_init_bits(arch_bits); - used_arch_random = arch_bits >= POOL_READY_BITS; WARN_ON(register_pm_notifier(&pm_notifier)); @@ -820,17 +818,6 @@ int __init random_init(const char *command_line) return 0; } -/* - * Returns whether arch randomness has been mixed into the initial - * state of the RNG, regardless of whether or not that randomness - * was credited. Knowing this is only good for a very limited set - * of uses, such as early init printk pointer obfuscation. - */ -bool rng_has_arch_random(void) -{ - return used_arch_random; -} - /* * Add device- or boot-specific data to the input pool to help * initialize it. diff --git a/include/linux/random.h b/include/linux/random.h index 223b4bd584e79..20e389a14e5c7 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -74,7 +74,6 @@ static inline unsigned long get_random_canary(void) int __init random_init(const char *command_line); bool rng_is_initialized(void); -bool rng_has_arch_random(void); int wait_for_random_bytes(void); /* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes). diff --git a/lib/vsprintf.c b/lib/vsprintf.c index fb77f7bfd126b..3c1853a9d1c09 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -769,8 +769,7 @@ static inline int __ptr_to_hashval(const void *ptr, unsigned long *hashval_out) static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); unsigned long flags; - if (!system_unbound_wq || - (!rng_is_initialized() && !rng_has_arch_random()) || + if (!system_unbound_wq || !rng_is_initialized() || !spin_trylock_irqsave(&filling, flags)) return -EAGAIN; -- GitLab From 77006f6edc0e0f58617eb25e53731f78641e820d Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Fri, 10 Jun 2022 13:45:00 +0300 Subject: [PATCH 433/942] gpio: dwapb: Don't print error on -EPROBE_DEFER Currently if the APB or Debounce clocks aren't yet ready to be requested the DW GPIO driver will correctly handle that by deferring the probe procedure, but the error is still printed to the system log. It needlessly pollutes the log since there was no real error but a request to postpone the clock request procedure since the clocks subsystem hasn't been fully initialized yet. Let's fix that by using the dev_err_probe method to print the APB/clock request error status. It will correctly handle the deferred probe situation and print the error if it actually happens. Signed-off-by: Serge Semin Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-dwapb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 04afe728e1874..c22fcaa44a614 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -662,10 +662,9 @@ static int dwapb_get_clks(struct dwapb_gpio *gpio) gpio->clks[1].id = "db"; err = devm_clk_bulk_get_optional(gpio->dev, DWAPB_NR_CLOCKS, gpio->clks); - if (err) { - dev_err(gpio->dev, "Cannot get APB/Debounce clocks\n"); - return err; - } + if (err) + return dev_err_probe(gpio->dev, err, + "Cannot get APB/Debounce clocks\n"); err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks); if (err) { -- GitLab From 5702b838dd9a8be634f9c6bdfd769422c26e9162 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:47:35 +0300 Subject: [PATCH 434/942] ASoC: SOF: ipc3-topology: Move and correct size checks in sof_ipc3_control_load_bytes() Move the size checks prior to allocating memory as these checks do not need the data to be allocated and in case of an error we would not need to free the allocation. The max size must not be less than the size of struct sof_ipc_ctrl_data + struct sof_abi_hdr as the ABI header needs to be present under all circumstances. The check was incorrectly used or between the two size checks. Fixes: b5cee8feb1d4 ("ASoC: SOF: topology: Make control parsing IPC agnostic") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220610084735.19397-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 043554d7cb4a6..10740c55294dc 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1577,24 +1577,23 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ struct sof_ipc_ctrl_data *cdata; int ret; - scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); - if (!scontrol->ipc_control_data) - return -ENOMEM; - - if (scontrol->max_size < sizeof(*cdata) || - scontrol->max_size < sizeof(struct sof_abi_hdr)) { - ret = -EINVAL; - goto err; + if (scontrol->max_size < (sizeof(*cdata) + sizeof(struct sof_abi_hdr))) { + dev_err(sdev->dev, "%s: insufficient size for a bytes control: %zu.\n", + __func__, scontrol->max_size); + return -EINVAL; } - /* init the get/put bytes data */ if (scontrol->priv_size > scontrol->max_size - sizeof(*cdata)) { - dev_err(sdev->dev, "err: bytes data size %zu exceeds max %zu.\n", + dev_err(sdev->dev, + "%s: bytes data size %zu exceeds max %zu.\n", __func__, scontrol->priv_size, scontrol->max_size - sizeof(*cdata)); - ret = -EINVAL; - goto err; + return -EINVAL; } + scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); + if (!scontrol->ipc_control_data) + return -ENOMEM; + scontrol->size = sizeof(struct sof_ipc_ctrl_data) + scontrol->priv_size; cdata = scontrol->ipc_control_data; -- GitLab From 03f69725749f453b9a4d454a92805f8eb5f095c2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:44 +0300 Subject: [PATCH 435/942] ASoC: SOF: make ctx_store and ctx_restore as optional Commit 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic") did not marked ctx_store and ctx_restore as Optional. Fixes: 657774acd00f ("ASoC: SOF: Make sof_suspend/resume IPC agnostic") Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-priv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 9d7f53ff9c70e..58bcb8d6f72b3 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -376,8 +376,8 @@ struct sof_ipc_fw_tracing_ops { /** * struct sof_ipc_pm_ops - IPC-specific PM ops - * @ctx_save: Function pointer for context save - * @ctx_restore: Function pointer for context restore + * @ctx_save: Optional function pointer for context save + * @ctx_restore: Optional function pointer for context restore */ struct sof_ipc_pm_ops { int (*ctx_save)(struct snd_sof_dev *sdev); -- GitLab From b41252d8820c7009078c3d401a807a9da899075f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:45 +0300 Subject: [PATCH 436/942] ASoC: SOF: sof_ipc_pm_ops: Add support for DSP core power management Add a new ops for handling DSP core power state which can be used to tell the DSP to turn on/off a core (or to inform it that a core is going to be turned on/off if the core is host managed). Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-priv.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 58bcb8d6f72b3..0544eb6a23223 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -378,10 +378,12 @@ struct sof_ipc_fw_tracing_ops { * struct sof_ipc_pm_ops - IPC-specific PM ops * @ctx_save: Optional function pointer for context save * @ctx_restore: Optional function pointer for context restore + * @set_core_state: Optional function pointer for turning on/off a DSP core */ struct sof_ipc_pm_ops { int (*ctx_save)(struct snd_sof_dev *sdev); int (*ctx_restore)(struct snd_sof_dev *sdev); + int (*set_core_state)(struct snd_sof_dev *sdev, int core_idx, bool on); }; /** -- GitLab From 0a047dafefafbccc931fab2d187ce75c302088d5 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:46 +0300 Subject: [PATCH 437/942] ASoC: SOF: ipc3: Add set_core_state pm_ops implementation IPC3 uses sof_ipc_pm_core_config message (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE) to enable/disable cores managed by the DSP. The core state is set via a single bitfield, if the bit is 1 the core should be on, if it is 0 then it is off. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index dff5feaad3703..ba81a6c490e94 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -1037,6 +1037,23 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev) ipc3_log_header(sdev->dev, "ipc rx done", hdr.cmd); } +static int sof_ipc3_set_core_state(struct snd_sof_dev *sdev, int core_idx, bool on) +{ + struct sof_ipc_pm_core_config core_cfg = { + .hdr.size = sizeof(core_cfg), + .hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE, + }; + struct sof_ipc_reply reply; + + if (on) + core_cfg.enable_mask = sdev->enabled_cores_mask | BIT(core_idx); + else + core_cfg.enable_mask = sdev->enabled_cores_mask & ~BIT(core_idx); + + return sof_ipc3_tx_msg(sdev, &core_cfg, sizeof(core_cfg), + &reply, sizeof(reply), false); +} + static int sof_ipc3_ctx_ipc(struct snd_sof_dev *sdev, int cmd) { struct sof_ipc_pm_ctx pm_ctx = { @@ -1063,6 +1080,7 @@ static int sof_ipc3_ctx_restore(struct snd_sof_dev *sdev) static const struct sof_ipc_pm_ops ipc3_pm_ops = { .ctx_save = sof_ipc3_ctx_save, .ctx_restore = sof_ipc3_ctx_restore, + .set_core_state = sof_ipc3_set_core_state, }; const struct sof_ipc_ops ipc3_ops = { -- GitLab From bd3df9ff25b32b66630c283bb2e065e8bb822e72 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:47 +0300 Subject: [PATCH 438/942] ASoC: SOF: ipc4: Add set_core_state pm_ops implementation IPC4 uses the SET_DX message to enable/disable cores managed by the DSP. The dx_state.core_mask indicates which core is going to change state, the dx_state.dx_mask is to power on (1) or off (0) the core. In the dx_mask only those bits (cores) checked which bit is set in the core_mask, other bits (cores) ignored. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof/ipc4/header.h | 8 ++++++++ sound/soc/sof/ipc4.c | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index b8b8e5b5e3e1c..a795deacc2eae 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -385,6 +385,14 @@ struct sof_ipc4_fw_version { uint16_t build; } __packed; +/* Payload data for SOF_IPC4_MOD_SET_DX */ +struct sof_ipc4_dx_state_info { + /* core(s) to apply the change */ + uint32_t core_mask; + /* core state: 0: put core_id to D3; 1: put core_id to D0 */ + uint32_t dx_mask; +} __packed __aligned(4); + /* Reply messages */ /* diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 658802c86685a..b2cb92745ec6e 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -597,10 +597,36 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev) } } +static int sof_ipc4_set_core_state(struct snd_sof_dev *sdev, int core_idx, bool on) +{ + struct sof_ipc4_dx_state_info dx_state; + struct sof_ipc4_msg msg; + + dx_state.core_mask = BIT(core_idx); + if (on) + dx_state.dx_mask = BIT(core_idx); + else + dx_state.dx_mask = 0; + + msg.primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_SET_DX); + msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + msg.extension = 0; + msg.data_ptr = &dx_state; + msg.data_size = sizeof(dx_state); + + return sof_ipc4_tx_msg(sdev, &msg, msg.data_size, NULL, 0, false); +} + +static const struct sof_ipc_pm_ops ipc4_pm_ops = { + .set_core_state = sof_ipc4_set_core_state, +}; + const struct sof_ipc_ops ipc4_ops = { .tx_msg = sof_ipc4_tx_msg, .rx_msg = sof_ipc4_rx_msg, .set_get_data = sof_ipc4_set_get_data, .get_reply = sof_ipc4_get_reply, + .pm = &ipc4_pm_ops, .fw_loader = &ipc4_loader_ops, }; -- GitLab From 7a5677407300e8ba6af95e66f4e8cfe23059f4a7 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:48 +0300 Subject: [PATCH 439/942] ASoC: SOF: Intel: Switch to use the generic pm_ops.set_core_state Instead of craft and send an IPC(3) message in hda_dsp_core_get(), tgl_dsp_core_get() and tgl_dsp_core_put(), use the generic ops for handling the IPC dependent implementation of core power on/off. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-6-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 15 ++++++--------- sound/soc/sof/intel/tgl.c | 30 ++++++++++-------------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 000ea906670cb..3a70f441a8d5a 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -932,13 +932,7 @@ void hda_dsp_d0i3_work(struct work_struct *work) int hda_dsp_core_get(struct snd_sof_dev *sdev, int core) { - struct sof_ipc_pm_core_config pm_core_config = { - .hdr = { - .cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE, - .size = sizeof(pm_core_config), - }, - .enable_mask = sdev->enabled_cores_mask | BIT(core), - }; + const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; int ret, ret1; /* power up core */ @@ -953,9 +947,12 @@ int hda_dsp_core_get(struct snd_sof_dev *sdev, int core) if (sdev->fw_state != SOF_FW_BOOT_COMPLETE || core == SOF_DSP_PRIMARY_CORE) return 0; + /* No need to continue the set_core_state ops is not available */ + if (!pm_ops->set_core_state) + return 0; + /* Now notify DSP for secondary cores */ - ret = sof_ipc_tx_message(sdev->ipc, &pm_core_config, sizeof(pm_core_config), - &pm_core_config, sizeof(pm_core_config)); + ret = pm_ops->set_core_state(sdev, core, true); if (ret < 0) { dev_err(sdev->dev, "failed to enable secondary core '%d' failed with %d\n", core, ret); diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index 1ddc492f1b13a..dcad7c382de69 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -24,40 +24,30 @@ static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = { static int tgl_dsp_core_get(struct snd_sof_dev *sdev, int core) { - struct sof_ipc_pm_core_config pm_core_config = { - .hdr = { - .cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE, - .size = sizeof(pm_core_config), - }, - .enable_mask = sdev->enabled_cores_mask | BIT(core), - }; + const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; /* power up primary core if not already powered up and return */ if (core == SOF_DSP_PRIMARY_CORE) return hda_dsp_enable_core(sdev, BIT(core)); - /* notify DSP for secondary cores */ - return sof_ipc_tx_message(sdev->ipc, &pm_core_config, sizeof(pm_core_config), - &pm_core_config, sizeof(pm_core_config)); + if (pm_ops->set_core_state) + return pm_ops->set_core_state(sdev, core, true); + + return 0; } static int tgl_dsp_core_put(struct snd_sof_dev *sdev, int core) { - struct sof_ipc_pm_core_config pm_core_config = { - .hdr = { - .cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CORE_ENABLE, - .size = sizeof(pm_core_config), - }, - .enable_mask = sdev->enabled_cores_mask & ~BIT(core), - }; + const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; /* power down primary core and return */ if (core == SOF_DSP_PRIMARY_CORE) return hda_dsp_core_reset_power_down(sdev, BIT(core)); - /* notify DSP for secondary cores */ - return sof_ipc_tx_message(sdev->ipc, &pm_core_config, sizeof(pm_core_config), - &pm_core_config, sizeof(pm_core_config)); + if (pm_ops->set_core_state) + return pm_ops->set_core_state(sdev, core, false); + + return 0; } /* Tigerlake ops */ -- GitLab From 63b9069653a710b08d5fd174ac05d43711356541 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:35:49 +0300 Subject: [PATCH 440/942] ASoC: SOF: ipc4: implement pm ctx_save callback Use the context save callback to power down the primary core which is used by the firmware as an indication that the DSP is going to be turned off. The IMR boot setup is done in response to the primary core power down. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610083549.16773-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index b2cb92745ec6e..5dd22f6a06055 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -618,7 +618,22 @@ static int sof_ipc4_set_core_state(struct snd_sof_dev *sdev, int core_idx, bool return sof_ipc4_tx_msg(sdev, &msg, msg.data_size, NULL, 0, false); } +/* + * The context save callback is used to send a message to the firmware notifying + * it that the primary core is going to be turned off, which is used as an + * indication to prepare for a full power down, thus preparing for IMR boot + * (when supported) + * + * Note: in IPC4 there is no message used to restore context, thus no context + * restore callback is implemented + */ +static int sof_ipc4_ctx_save(struct snd_sof_dev *sdev) +{ + return sof_ipc4_set_core_state(sdev, SOF_DSP_PRIMARY_CORE, false); +} + static const struct sof_ipc_pm_ops ipc4_pm_ops = { + .ctx_save = sof_ipc4_ctx_save, .set_core_state = sof_ipc4_set_core_state, }; -- GitLab From 135786c32ed057068bec56f67a54064cfc845bde Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:01:17 +0300 Subject: [PATCH 441/942] ASoC: SOF: ipc3-dtrace: Introduce SOF_DTRACE_INITIALIZING state With the new state we can make sure we are not missing the first host_offset update. In case the dtrace is small, the DMA copy will be fast and depending on the moonphase it might be done before we set the sdev->dtrace_state to SOF_DTRACE_ENABLED. The DMA will start the copy as soon as the host starts the DMA. Set the dtrace to enabled before we let the DMA to run in order to avoid missing the position update. The new state is needed to cover architectures where the host side snd_sof_dma_trace_trigger() is a NOP and the dtrace in the firmware is ready as soon as the IPC message has been processed. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220610080119.30880-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index b4e1343f9138f..9292ff7ce1e8a 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -18,6 +18,7 @@ enum sof_dtrace_state { SOF_DTRACE_DISABLED, SOF_DTRACE_STOPPED, + SOF_DTRACE_INITIALIZING, SOF_DTRACE_ENABLED, }; @@ -32,6 +33,15 @@ struct sof_dtrace_priv { enum sof_dtrace_state dtrace_state; }; +static bool trace_pos_update_expected(struct sof_dtrace_priv *priv) +{ + if (priv->dtrace_state == SOF_DTRACE_ENABLED || + priv->dtrace_state == SOF_DTRACE_INITIALIZING) + return true; + + return false; +} + static int trace_filter_append_elem(struct snd_sof_dev *sdev, u32 key, u32 value, struct sof_ipc_trace_filter_elem *elem_list, int capacity, int *counter) @@ -274,7 +284,7 @@ static size_t sof_wait_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, if (ret) return ret; - if (priv->dtrace_state != SOF_DTRACE_ENABLED && priv->dtrace_draining) { + if (priv->dtrace_draining && !trace_pos_update_expected(priv)) { /* * tracing has ended and all traces have been * read by client, return EOF @@ -445,6 +455,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "%s: stream_tag: %d\n", __func__, params.stream_tag); /* send IPC to the DSP */ + priv->dtrace_state = SOF_DTRACE_INITIALIZING; ret = sof_ipc_tx_message(sdev->ipc, ¶ms, sizeof(params), &ipc_reply, sizeof(ipc_reply)); if (ret < 0) { dev_err(sdev->dev, "can't set params for DMA for trace %d\n", ret); @@ -452,17 +463,18 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) } start: + priv->dtrace_state = SOF_DTRACE_ENABLED; + ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_START); if (ret < 0) { dev_err(sdev->dev, "Host dtrace trigger start failed: %d\n", ret); goto trace_release; } - priv->dtrace_state = SOF_DTRACE_ENABLED; - return 0; trace_release: + priv->dtrace_state = SOF_DTRACE_DISABLED; sof_dtrace_host_release(sdev); return ret; } @@ -546,7 +558,7 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, if (!sdev->fw_trace_is_supported) return 0; - if (priv->dtrace_state == SOF_DTRACE_ENABLED && + if (trace_pos_update_expected(priv) && priv->host_offset != posn->host_offset) { priv->host_offset = posn->host_offset; wake_up(&priv->trace_sleep); -- GitLab From b66f9e703f0bee4e1aa7010299914b7b2009b4e0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:01:18 +0300 Subject: [PATCH 442/942] ASoC: SOF: ipc3-dtrace: Add helper function to update the sdev->host_offset We are using the READ_ONCE() on the debugfs read path for accessing sdev->host_offset, but the set is not atomic or protected in any way. Add a small helper to do the host_offset update and be really paranoid about the a possible race in update Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220610080119.30880-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 9292ff7ce1e8a..1f4d7a98c8fca 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -252,6 +252,21 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev) return 0; } +static bool sof_dtrace_set_host_offset(struct sof_dtrace_priv *priv, u32 new_offset) +{ + u32 host_offset = READ_ONCE(priv->host_offset); + + if (host_offset != new_offset) { + /* This is a bit paranoid and unlikely that it is needed */ + u32 ret = cmpxchg(&priv->host_offset, host_offset, new_offset); + + if (ret == host_offset) + return true; + } + + return false; +} + static size_t sof_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos, size_t buffer_size) { @@ -368,7 +383,7 @@ static int dfsentry_dtrace_release(struct inode *inode, struct file *file) /* avoid duplicate traces at next open */ if (priv->dtrace_state != SOF_DTRACE_ENABLED) - priv->host_offset = 0; + sof_dtrace_set_host_offset(priv, 0); return 0; } @@ -444,7 +459,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) params.buffer.pages = priv->dma_trace_pages; params.stream_tag = 0; - priv->host_offset = 0; + sof_dtrace_set_host_offset(priv, 0); priv->dtrace_draining = false; ret = sof_dtrace_host_init(sdev, &priv->dmatb, ¶ms); @@ -559,10 +574,8 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev, return 0; if (trace_pos_update_expected(priv) && - priv->host_offset != posn->host_offset) { - priv->host_offset = posn->host_offset; + sof_dtrace_set_host_offset(priv, posn->host_offset)) wake_up(&priv->trace_sleep); - } if (posn->overflow != 0) dev_err(sdev->dev, -- GitLab From 1e90de2c9a40d7d0af5c7b0a6e2d362ffba94772 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:01:19 +0300 Subject: [PATCH 443/942] ASoC: SOF: ipc3-dtrace: Return from dtrace_read if there is no new data available If no new trace data is available then return immediately, there is no need to continue with the execution of the trace_read() function. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220610080119.30880-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 1f4d7a98c8fca..f59931d818c18 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -353,6 +353,10 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer, return -EIO; } + /* no new trace data */ + if (!avail) + return 0; + /* make sure count is <= avail */ if (count > avail) count = avail; -- GitLab From bd10cd5ec54616a488d0bda695f78694ad79f779 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:21 -0700 Subject: [PATCH 444/942] ASoC: SOF: Add topology tokens for IPC4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the required tokens for parsing the topology for IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-2-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- include/uapi/sound/sof/tokens.h | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index b72fa385bebf5..f7b2019065ad1 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -52,11 +52,17 @@ #define SOF_TKN_SCHED_FRAMES 204 #define SOF_TKN_SCHED_TIME_DOMAIN 205 #define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206 +#define SOF_TKN_SCHED_LP_MODE 207 +#define SOF_TKN_SCHED_MEM_USAGE 208 /* volume */ #define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250 #define SOF_TKN_VOLUME_RAMP_STEP_MS 251 +#define SOF_TKN_GAIN_RAMP_TYPE 260 +#define SOF_TKN_GAIN_RAMP_DURATION 261 +#define SOF_TKN_GAIN_VAL 262 + /* SRC */ #define SOF_TKN_SRC_RATE_IN 300 #define SOF_TKN_SRC_RATE_OUT 301 @@ -79,6 +85,9 @@ */ #define SOF_TKN_COMP_CORE_ID 404 #define SOF_TKN_COMP_UUID 405 +#define SOF_TKN_COMP_CPC 406 +#define SOF_TKN_COMP_IS_PAGES 409 +#define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410 /* SSP */ #define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500 @@ -145,4 +154,35 @@ #define SOF_TKN_MEDIATEK_AFE_CH 1601 #define SOF_TKN_MEDIATEK_AFE_FORMAT 1602 +/* MIXER */ +#define SOF_TKN_MIXER_TYPE 1700 + +/* CAVS AUDIO FORMAT */ +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907 +#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908 +/* intentional token numbering discontinuity, reserved for future use */ +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE 1936 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG 1937 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_SAMPLE_TYPE 1938 +/* intentional token numbering discontinuity, reserved for future use */ +#define SOF_TKN_CAVS_AUDIO_FORMAT_IBS 1970 +#define SOF_TKN_CAVS_AUDIO_FORMAT_OBS 1971 +#define SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE 1972 + +/* COPIER */ +#define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980 + #endif -- GitLab From 90e891551fb4949daeb3df20d43e7da838ef89a3 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:22 -0700 Subject: [PATCH 445/942] ASoC: SOF: IPC4: Introduce topology ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce the topology ops for IPC4. Set the widget_ops and token_list for parsing the scheduler type widget. Support for other widget types will be added in the follow up patches. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Paul Olaru Link: https://lore.kernel.org/r/20220609032643.916882-3-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/Makefile | 2 +- sound/soc/sof/ipc4-priv.h | 1 + sound/soc/sof/ipc4-topology.c | 102 ++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 30 ++++++++++ sound/soc/sof/ipc4.c | 1 + 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/ipc4-topology.c create mode 100644 sound/soc/sof/ipc4-topology.h diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 92b5e83601be5..73524fadb3ce7 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -4,7 +4,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ ipc3-topology.o ipc3-control.o ipc3.o ipc3-pcm.o ipc3-loader.o\ ipc3-dtrace.o\ - ipc4.o ipc4-loader.o + ipc4.o ipc4-loader.o ipc4-topology.o ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),) snd-sof-objs += sof-client.o endif diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index 2b71d5675933d..5388b888fefa8 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -40,5 +40,6 @@ struct sof_ipc4_fw_module { }; extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; +extern const struct sof_ipc_tplg_ops ipc4_tplg_ops; #endif diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c new file mode 100644 index 0000000000000..bccf576c8edd9 --- /dev/null +++ b/sound/soc/sof/ipc4-topology.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// +#include +#include +#include +#include "sof-priv.h" +#include "sof-audio.h" +#include "ipc4-priv.h" +#include "ipc4-topology.h" +#include "ops.h" + +static const struct sof_topology_token ipc4_sched_tokens[] = { + {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_pipeline, lp_mode)} +}; + +static const struct sof_topology_token pipeline_tokens[] = { + {SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, + offsetof(struct snd_sof_widget, dynamic_pipeline_widget)}, +}; + +static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { + [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)}, + [SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens, + ARRAY_SIZE(ipc4_sched_tokens)}, +}; + +static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget) +{ + kfree(swidget->private); +} + +static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct sof_ipc4_pipeline *pipeline; + int ret; + + pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); + if (!pipeline) + return -ENOMEM; + + ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*pipeline), 1); + if (ret) { + dev_err(scomp->dev, "parsing scheduler tokens failed\n"); + goto err; + } + + /* parse one set of pipeline tokens */ + ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*swidget), 1); + if (ret) { + dev_err(scomp->dev, "parsing pipeline tokens failed\n"); + goto err; + } + + /* TODO: Get priority from topology */ + pipeline->priority = 0; + + dev_dbg(scomp->dev, "pipeline '%s': id %d pri %d lp mode %d\n", + swidget->widget->name, swidget->pipeline_id, + pipeline->priority, pipeline->lp_mode); + + swidget->private = pipeline; + + pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); + pipeline->msg.primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->pipeline_id); + pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); + pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); + + pipeline->msg.extension = pipeline->lp_mode; + pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; + + return 0; +err: + kfree(pipeline); + return ret; +} + +static enum sof_tokens pipeline_token_list[] = { + SOF_SCHED_TOKENS, + SOF_PIPELINE_TOKENS, +}; + +static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { + [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, + pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, + NULL, NULL}, +}; + +const struct sof_ipc_tplg_ops ipc4_tplg_ops = { + .widget = tplg_ipc4_widget_ops, + .token_list = ipc4_token_list, +}; diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h new file mode 100644 index 0000000000000..0e9be2b2d8a18 --- /dev/null +++ b/sound/soc/sof/ipc4-topology.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2022 Intel Corporation. All rights reserved. + */ + +#ifndef __INCLUDE_SOUND_SOF_IPC4_TOPOLOGY_H__ +#define __INCLUDE_SOUND_SOF_IPC4_TOPOLOGY_H__ + +#include + +/** + * struct sof_ipc4_pipeline - pipeline config data + * @priority: Priority of this pipeline + * @lp_mode: Low power mode + * @mem_usage: Memory usage + * @state: Pipeline state + * @msg: message structure for pipeline + */ +struct sof_ipc4_pipeline { + uint32_t priority; + uint32_t lp_mode; + uint32_t mem_usage; + int state; + struct sof_ipc4_msg msg; +}; + +#endif diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 658802c86685a..be677a33882de 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -603,4 +603,5 @@ const struct sof_ipc_ops ipc4_ops = { .set_get_data = sof_ipc4_set_get_data, .get_reply = sof_ipc4_get_reply, .fw_loader = &ipc4_loader_ops, + .tplg = &ipc4_tplg_ops, }; -- GitLab From 2cabd02b60901f4ceda4daf8c194905259797702 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:23 -0700 Subject: [PATCH 446/942] ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for parsing AIF_IN/AIF_OUT type widgets in IPC4. Add all the new required token ID's for parsing these widgets to the list of tokens in enum sof_tokens and the definitions of the token arrays corresponding to each of the token ID's. Also, upgrade the sof_widget_parse_tokens() function in the common topology parser to be able to parse multiple sets of tokens for the audio format and copier gateway config tokens. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Paul Olaru Link: https://lore.kernel.org/r/20220609032643.916882-4-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 370 ++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 83 ++++++++ sound/soc/sof/sof-audio.h | 7 + sound/soc/sof/topology.c | 69 +++++-- 4 files changed, 511 insertions(+), 18 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index bccf576c8edd9..559148f5644c2 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -25,17 +25,370 @@ static const struct sof_topology_token pipeline_tokens[] = { offsetof(struct snd_sof_widget, dynamic_pipeline_widget)}, }; +static const struct sof_topology_token ipc4_comp_tokens[] = { + {SOF_TKN_COMP_CPC, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_base_module_cfg, cpc)}, + {SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_base_module_cfg, is_pages)}, +}; + +static const struct sof_topology_token ipc4_audio_format_buffer_size_tokens[] = { + {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_base_module_cfg, ibs)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_base_module_cfg, obs)}, +}; + +static const struct sof_topology_token ipc4_in_audio_format_tokens[] = { + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, sampling_frequency)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, bit_depth)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, ch_map)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, ch_cfg)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, fmt_cfg)}, +}; + +static const struct sof_topology_token ipc4_out_audio_format_tokens[] = { + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, sampling_frequency)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, bit_depth)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, ch_map)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, ch_cfg)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)}, + {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_audio_format, fmt_cfg)}, +}; + +static const struct sof_topology_token ipc4_copier_gateway_cfg_tokens[] = { + {SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, +}; + +static const struct sof_topology_token ipc4_copier_tokens[] = { + {SOF_TKN_INTEL_COPIER_NODE_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, +}; + +static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = { + {SOF_TKN_COMP_NUM_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + 0}, +}; + +/* Component extended tokens */ +static const struct sof_topology_token comp_ext_tokens[] = { + {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, + offsetof(struct snd_sof_widget, uuid)}, +}; + static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)}, [SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens, ARRAY_SIZE(ipc4_sched_tokens)}, + [SOF_COMP_EXT_TOKENS] = {"Comp extended tokens", comp_ext_tokens, + ARRAY_SIZE(comp_ext_tokens)}, + [SOF_COMP_TOKENS] = {"IPC4 Component tokens", + ipc4_comp_tokens, ARRAY_SIZE(ipc4_comp_tokens)}, + [SOF_IN_AUDIO_FORMAT_TOKENS] = {"IPC4 Input Audio format tokens", + ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)}, + [SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens", + ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)}, + [SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS] = {"IPC4 Audio format buffer size tokens", + ipc4_audio_format_buffer_size_tokens, + ARRAY_SIZE(ipc4_audio_format_buffer_size_tokens)}, + [SOF_COPIER_GATEWAY_CFG_TOKENS] = {"IPC4 Copier gateway config tokens", + ipc4_copier_gateway_cfg_tokens, ARRAY_SIZE(ipc4_copier_gateway_cfg_tokens)}, + [SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens, + ARRAY_SIZE(ipc4_copier_tokens)}, + [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens", + ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)}, }; +static void sof_ipc4_dbg_audio_format(struct device *dev, + struct sof_ipc4_audio_format *format, + size_t object_size, int num_format) +{ + struct sof_ipc4_audio_format *fmt; + void *ptr = format; + int i; + + for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) { + fmt = ptr; + dev_dbg(dev, + " #%d: %uKHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n", + i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, + fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg); + } +} + +/** + * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples + * @scomp: pointer to pointer to SOC component + * @swidget: pointer to struct snd_sof_widget containing tuples + * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in + * @has_out_format: true if available_fmt contains output format + * + * Return: 0 if successful + */ +static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, + struct snd_sof_widget *swidget, + struct sof_ipc4_available_audio_format *available_fmt, + bool has_out_format) +{ + struct sof_ipc4_base_module_cfg *base_config; + struct sof_ipc4_audio_format *out_format; + int audio_fmt_num = 0; + int ret, i; + + ret = sof_update_ipc_object(scomp, &audio_fmt_num, + SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(audio_fmt_num), 1); + if (ret || audio_fmt_num <= 0) { + dev_err(scomp->dev, "Invalid number of audio formats: %d\n", audio_fmt_num); + return -EINVAL; + } + available_fmt->audio_fmt_num = audio_fmt_num; + + dev_dbg(scomp->dev, "Number of audio formats: %d\n", available_fmt->audio_fmt_num); + + base_config = kcalloc(available_fmt->audio_fmt_num, sizeof(*base_config), GFP_KERNEL); + if (!base_config) + return -ENOMEM; + + /* set cpc and is_pages for all base_cfg */ + for (i = 0; i < available_fmt->audio_fmt_num; i++) { + ret = sof_update_ipc_object(scomp, &base_config[i], + SOF_COMP_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*base_config), 1); + if (ret) { + dev_err(scomp->dev, "parse comp tokens failed %d\n", ret); + goto err_in; + } + } + + /* copy the ibs/obs for each base_cfg */ + ret = sof_update_ipc_object(scomp, base_config, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*base_config), + available_fmt->audio_fmt_num); + if (ret) { + dev_err(scomp->dev, "parse buffer size tokens failed %d\n", ret); + goto err_in; + } + + for (i = 0; i < available_fmt->audio_fmt_num; i++) + dev_dbg(scomp->dev, "%d: ibs: %d obs: %d cpc: %d is_pages: %d\n", i, + base_config[i].ibs, base_config[i].obs, + base_config[i].cpc, base_config[i].is_pages); + + ret = sof_update_ipc_object(scomp, &base_config->audio_fmt, + SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*base_config), + available_fmt->audio_fmt_num); + if (ret) { + dev_err(scomp->dev, "parse base_config audio_fmt tokens failed %d\n", ret); + goto err_in; + } + + dev_dbg(scomp->dev, "Get input audio formats for %s\n", swidget->widget->name); + sof_ipc4_dbg_audio_format(scomp->dev, &base_config->audio_fmt, + sizeof(*base_config), + available_fmt->audio_fmt_num); + + available_fmt->base_config = base_config; + + if (!has_out_format) + return 0; + + out_format = kcalloc(available_fmt->audio_fmt_num, sizeof(*out_format), GFP_KERNEL); + if (!out_format) { + ret = -ENOMEM; + goto err_in; + } + + ret = sof_update_ipc_object(scomp, out_format, + SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(*out_format), + available_fmt->audio_fmt_num); + + if (ret) { + dev_err(scomp->dev, "parse output audio_fmt tokens failed\n"); + goto err_out; + } + + available_fmt->out_audio_fmt = out_format; + dev_dbg(scomp->dev, "Get output audio formats for %s\n", swidget->widget->name); + sof_ipc4_dbg_audio_format(scomp->dev, out_format, sizeof(*out_format), + available_fmt->audio_fmt_num); + + return 0; + +err_out: + kfree(out_format); +err_in: + kfree(base_config); + + return ret; +} + static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget) { kfree(swidget->private); } +static int sof_ipc4_widget_set_module_info(struct snd_sof_widget *swidget) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + struct sof_ipc4_fw_module *fw_modules = ipc4_data->fw_modules; + int i; + + if (!fw_modules) { + dev_err(sdev->dev, "no fw_module information\n"); + return -EINVAL; + } + + /* set module info */ + for (i = 0; i < ipc4_data->num_fw_modules; i++) { + if (guid_equal(&swidget->uuid, &fw_modules[i].man4_module_entry.uuid)) { + swidget->module_info = &fw_modules[i]; + return 0; + } + } + + dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", + swidget->widget->name, &swidget->uuid); + return -EINVAL; +} + +static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_ipc4_msg *msg) +{ + struct sof_ipc4_fw_module *fw_module; + int ret; + + ret = sof_ipc4_widget_set_module_info(swidget); + if (ret) + return ret; + + fw_module = swidget->module_info; + + msg->primary = fw_module->man4_module_entry.id; + msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); + msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + + msg->extension = SOF_IPC4_MOD_EXT_PPL_ID(swidget->pipeline_id); + msg->extension |= SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); + + return 0; +} + +static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_available_audio_format *available_fmt; + struct snd_soc_component *scomp = swidget->scomp; + struct sof_ipc4_copier *ipc4_copier; + int node_type = 0; + int ret, i; + + ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); + if (!ipc4_copier) + return -ENOMEM; + + swidget->private = ipc4_copier; + available_fmt = &ipc4_copier->available_fmt; + + dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); + + ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true); + if (ret) + goto free_copier; + + available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32), + GFP_KERNEL); + if (!available_fmt->dma_buffer_size) { + ret = -ENOMEM; + goto free_copier; + } + + ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, + SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(u32), + available_fmt->audio_fmt_num); + if (ret) { + dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n", + swidget->widget->name); + goto err; + } + + dev_dbg(scomp->dev, "dma buffer size:\n"); + for (i = 0; i < available_fmt->audio_fmt_num; i++) + dev_dbg(scomp->dev, "%d: %u\n", i, + available_fmt->dma_buffer_size[i]); + + ret = sof_update_ipc_object(scomp, &node_type, + SOF_COPIER_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(node_type), 1); + + if (ret) { + dev_err(scomp->dev, "parse host copier node type token failed %d\n", + ret); + goto err; + } + dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); + + ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); + ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); + if (!ipc4_copier->gtw_attr) { + ret = -ENOMEM; + goto err; + } + + ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; + ipc4_copier->data.gtw_cfg.config_length = + sizeof(struct sof_ipc4_gtw_attributes) >> 2; + + /* set up module info and message header */ + ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); + if (ret) + goto free_gtw_attr; + + return 0; + +free_gtw_attr: + kfree(ipc4_copier->gtw_attr); +err: + kfree(available_fmt->dma_buffer_size); +free_copier: + kfree(ipc4_copier); + return ret; +} + +static void sof_ipc4_widget_free_comp_pcm(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_copier *ipc4_copier = swidget->private; + struct sof_ipc4_available_audio_format *available_fmt; + + if (!ipc4_copier) + return; + + available_fmt = &ipc4_copier->available_fmt; + kfree(available_fmt->dma_buffer_size); + kfree(available_fmt->base_config); + kfree(available_fmt->out_audio_fmt); + kfree(ipc4_copier->gtw_attr); + kfree(ipc4_copier); + swidget->private = NULL; +} + static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) { struct snd_soc_component *scomp = swidget->scomp; @@ -85,12 +438,29 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) return ret; } +static enum sof_tokens host_token_list[] = { + SOF_COMP_TOKENS, + SOF_AUDIO_FMT_NUM_TOKENS, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, + SOF_IN_AUDIO_FORMAT_TOKENS, + SOF_OUT_AUDIO_FORMAT_TOKENS, + SOF_COPIER_GATEWAY_CFG_TOKENS, + SOF_COPIER_TOKENS, + SOF_COMP_EXT_TOKENS, +}; + static enum sof_tokens pipeline_token_list[] = { SOF_SCHED_TOKENS, SOF_PIPELINE_TOKENS, }; static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { + [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, + host_token_list, ARRAY_SIZE(host_token_list), NULL, + NULL, NULL}, + [snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, + host_token_list, ARRAY_SIZE(host_token_list), NULL, + NULL, NULL}, [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 0e9be2b2d8a18..f4f62dda63a37 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -11,6 +11,8 @@ #include +#define SOF_IPC4_NODE_TYPE(x) ((x) << 8) + /** * struct sof_ipc4_pipeline - pipeline config data * @priority: Priority of this pipeline @@ -27,4 +29,85 @@ struct sof_ipc4_pipeline { struct sof_ipc4_msg msg; }; +/** + * struct sof_ipc4_available_audio_format - Available audio formats + * @base_config: Available base config + * @out_audio_fmt: Available output audio format + * @ref_audio_fmt: Reference audio format to match runtime audio format + * @dma_buffer_size: Available Gateway DMA buffer size (in bytes) + * @audio_fmt_num: Number of available audio formats + */ +struct sof_ipc4_available_audio_format { + struct sof_ipc4_base_module_cfg *base_config; + struct sof_ipc4_audio_format *out_audio_fmt; + struct sof_ipc4_audio_format *ref_audio_fmt; + u32 *dma_buffer_size; + int audio_fmt_num; +}; + +/** + * struct sof_copier_gateway_cfg - IPC gateway configuration + * @node_id: ID of Gateway Node + * @dma_buffer_size: Preferred Gateway DMA buffer size (in bytes) + * @config_length: Length of gateway node configuration blob specified in #config_data + * config_data: Gateway node configuration blob + */ +struct sof_copier_gateway_cfg { + uint32_t node_id; + uint32_t dma_buffer_size; + uint32_t config_length; + uint32_t config_data[]; +}; + +/** + * struct sof_ipc4_copier_data - IPC data for copier + * @base_config: Base configuration including input audio format + * @out_format: Output audio format + * @copier_feature_mask: Copier feature mask + * @gtw_cfg: Gateway configuration + */ +struct sof_ipc4_copier_data { + struct sof_ipc4_base_module_cfg base_config; + struct sof_ipc4_audio_format out_format; + uint32_t copier_feature_mask; + struct sof_copier_gateway_cfg gtw_cfg; +}; + +/** + * struct sof_ipc4_gtw_attributes: Gateway attributes + * @lp_buffer_alloc: Gateway data requested in low power memory + * @alloc_from_reg_file: Gateway data requested in register file memory + * @rsvd: reserved for future use + */ +struct sof_ipc4_gtw_attributes { + uint32_t lp_buffer_alloc : 1; + uint32_t alloc_from_reg_file : 1; + uint32_t rsvd : 30; +}; + +/** + * struct sof_ipc4_copier - copier config data + * @data: IPC copier data + * @copier_config: Copier + blob + * @ipc_config_size: Size of copier_config + * @available_fmt: Available audio format + * @frame_fmt: frame format + * @msg: message structure for copier + * @gtw_attr: Gateway attributes for copier blob + * @dai_type: DAI type + * @dai_index: DAI index + */ +struct sof_ipc4_copier { + struct sof_ipc4_copier_data data; + u32 *copier_config; + uint32_t ipc_config_size; + void *ipc_config_data; + struct sof_ipc4_available_audio_format available_fmt; + u32 frame_fmt; + struct sof_ipc4_msg msg; + struct sof_ipc4_gtw_attributes *gtw_attr; + u32 dai_type; + int dai_index; +}; + #endif diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 27cc5fb642e57..c38b4bdd685ae 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -225,6 +225,13 @@ enum sof_tokens { SOF_AFE_TOKENS, SOF_CORE_TOKENS, SOF_COMP_EXT_TOKENS, + SOF_IN_AUDIO_FORMAT_TOKENS, + SOF_OUT_AUDIO_FORMAT_TOKENS, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, + SOF_COPIER_GATEWAY_CFG_TOKENS, + SOF_COPIER_TOKENS, + SOF_AUDIO_FMT_NUM_TOKENS, + SOF_COPIER_FORMAT_TOKENS, /* this should be the last */ SOF_TOKEN_COUNT, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b1fcab7ce48e8..606dbca942460 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1141,6 +1141,21 @@ static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm, return 0; } +static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples) +{ + int i; + + if (!tuples) + return -EINVAL; + + for (i = 0; i < num_tuples; i++) { + if (tuples[i].token == token_id) + return tuples[i].value.v; + } + + return -EINVAL; +} + static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_sof_widget *swidget, struct snd_soc_tplg_dapm_widget *tw, enum sof_tokens *object_token_list, int count) @@ -1168,6 +1183,8 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s /* parse token list for widget */ for (i = 0; i < count; i++) { + int num_sets = 1; + if (object_token_list[i] >= SOF_TOKEN_COUNT) { dev_err(scomp->dev, "Invalid token id %d for widget %s\n", object_token_list[i], swidget->widget->name); @@ -1175,8 +1192,9 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s goto err; } - /* parse and save UUID in swidget */ - if (object_token_list[i] == SOF_COMP_EXT_TOKENS) { + switch (object_token_list[i]) { + case SOF_COMP_EXT_TOKENS: + /* parse and save UUID in swidget */ ret = sof_parse_tokens(scomp, swidget, token_list[object_token_list[i]].tokens, token_list[object_token_list[i]].count, @@ -1189,11 +1207,41 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s } continue; + case SOF_IN_AUDIO_FORMAT_TOKENS: + case SOF_OUT_AUDIO_FORMAT_TOKENS: + case SOF_COPIER_GATEWAY_CFG_TOKENS: + case SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS: + num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_AUDIO_FORMATS, + swidget->tuples, swidget->num_tuples); + + if (num_sets < 0) { + dev_err(sdev->dev, "Invalid audio format count for %s\n", + swidget->widget->name); + ret = num_sets; + goto err; + } + + if (num_sets > 1) { + struct snd_sof_tuple *new_tuples; + + num_tuples += token_list[object_token_list[i]].count * num_sets; + new_tuples = krealloc(swidget->tuples, + sizeof(*new_tuples) * num_tuples, GFP_KERNEL); + if (!new_tuples) { + ret = -ENOMEM; + goto err; + } + + swidget->tuples = new_tuples; + } + break; + default: + break; } /* copy one set of tuples per token ID into swidget->tuples */ ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), - object_token_list[i], 1, swidget->tuples, + object_token_list[i], num_sets, swidget->tuples, num_tuples, &swidget->num_tuples); if (ret < 0) { dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n", @@ -1208,21 +1256,6 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s return ret; } -static int sof_get_token_value(u32 token_id, struct snd_sof_tuple *tuples, int num_tuples) -{ - int i; - - if (!tuples) - return -EINVAL; - - for (i = 0; i < num_tuples; i++) { - if (tuples[i].token == token_id) - return tuples[i].value.v; - } - - return -EINVAL; -} - /* external widget init - used for any driver specific init */ static int sof_widget_ready(struct snd_soc_component *scomp, int index, struct snd_soc_dapm_widget *w, -- GitLab From abfb536bd116d3148e92bf38255fc0989ca9b7d4 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:24 -0700 Subject: [PATCH 447/942] ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for parsing and setting up the IPC structure for DAI_IN/DAI_OUT type widgets in IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-5-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 135 ++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 559148f5644c2..5bb80306794b1 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -82,6 +82,13 @@ static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = { 0}, }; +static const struct sof_topology_token dai_tokens[] = { + {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, + offsetof(struct sof_ipc4_copier, dai_type)}, + {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_copier, dai_index)}, +}; + /* Component extended tokens */ static const struct sof_topology_token comp_ext_tokens[] = { {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, @@ -89,6 +96,7 @@ static const struct sof_topology_token comp_ext_tokens[] = { }; static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { + [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)}, [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)}, [SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens, ARRAY_SIZE(ipc4_sched_tokens)}, @@ -389,6 +397,117 @@ static void sof_ipc4_widget_free_comp_pcm(struct snd_sof_widget *swidget) swidget->private = NULL; } +static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_available_audio_format *available_fmt; + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dai *dai = swidget->private; + struct sof_ipc4_copier *ipc4_copier; + int node_type = 0; + int ret, i; + + ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); + if (!ipc4_copier) + return -ENOMEM; + + available_fmt = &ipc4_copier->available_fmt; + + dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); + + ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true); + if (ret) + goto free_copier; + + available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32), + GFP_KERNEL); + if (!available_fmt->dma_buffer_size) { + ret = -ENOMEM; + goto free_copier; + } + + ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, + SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(u32), + available_fmt->audio_fmt_num); + if (ret) { + dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n", + swidget->widget->name); + goto err; + } + + for (i = 0; i < available_fmt->audio_fmt_num; i++) + dev_dbg(scomp->dev, "%d: dma buffer size: %u\n", i, + available_fmt->dma_buffer_size[i]); + + ret = sof_update_ipc_object(scomp, &node_type, + SOF_COPIER_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(node_type), 1); + if (ret) { + dev_err(scomp->dev, "parse dai node type failed %d\n", ret); + goto err; + } + + ret = sof_update_ipc_object(scomp, ipc4_copier, + SOF_DAI_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(u32), 1); + if (ret) { + dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); + goto err; + } + + dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name, + node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); + + ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); + ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); + if (!ipc4_copier->gtw_attr) { + ret = -ENOMEM; + goto err; + } + + ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; + ipc4_copier->data.gtw_cfg.config_length = sizeof(struct sof_ipc4_gtw_attributes) >> 2; + + dai->scomp = scomp; + dai->private = ipc4_copier; + + /* set up module info and message header */ + ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); + if (ret) + goto free_copier_config; + + return 0; + +free_copier_config: + kfree(ipc4_copier->copier_config); +err: + kfree(available_fmt->dma_buffer_size); +free_copier: + kfree(ipc4_copier); + return ret; +} + +static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_available_audio_format *available_fmt; + struct snd_sof_dai *dai = swidget->private; + struct sof_ipc4_copier *ipc4_copier; + + if (!dai) + return; + + ipc4_copier = dai->private; + available_fmt = &ipc4_copier->available_fmt; + + kfree(available_fmt->dma_buffer_size); + kfree(available_fmt->base_config); + kfree(available_fmt->out_audio_fmt); + kfree(ipc4_copier->copier_config); + kfree(dai->private); + kfree(dai); + swidget->private = NULL; +} + static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) { struct snd_soc_component *scomp = swidget->scomp; @@ -454,6 +573,18 @@ static enum sof_tokens pipeline_token_list[] = { SOF_PIPELINE_TOKENS, }; +static enum sof_tokens dai_token_list[] = { + SOF_COMP_TOKENS, + SOF_AUDIO_FMT_NUM_TOKENS, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, + SOF_IN_AUDIO_FORMAT_TOKENS, + SOF_OUT_AUDIO_FORMAT_TOKENS, + SOF_COPIER_GATEWAY_CFG_TOKENS, + SOF_COPIER_TOKENS, + SOF_DAI_TOKENS, + SOF_COMP_EXT_TOKENS, +}; + static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, @@ -461,6 +592,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY [snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, NULL, NULL}, + [snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, + dai_token_list, ARRAY_SIZE(dai_token_list), NULL, NULL, NULL}, + [snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, + dai_token_list, ARRAY_SIZE(dai_token_list), NULL, NULL, NULL}, [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, -- GitLab From 904c48c40c66c524df90fb660bdbc514ed802e67 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:25 -0700 Subject: [PATCH 448/942] ASoC: SOF: ipc4-topology: Add prepare op for AIF type widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the prepare op for the AIF type widgets for IPC4. The prepare op is responsible for choosing the input/output audio formats for these widgets based on the runtime PCM params, assigning the instance ID and updating the total memory usage for the pipelines these widgets belong to. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220609032643.916882-6-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 290 +++++++++++++++++++++++++++++++++- sound/soc/sof/ipc4-topology.h | 18 +++ 2 files changed, 306 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 5bb80306794b1..1a73c16f16242 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -557,6 +557,290 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) return ret; } +static void +sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, + struct sof_ipc4_base_module_cfg *base_config) +{ + struct sof_ipc4_fw_module *fw_module = swidget->module_info; + struct snd_sof_widget *pipe_widget; + struct sof_ipc4_pipeline *pipeline; + int task_mem, queue_mem; + int ibs, bss, total; + + ibs = base_config->ibs; + bss = base_config->is_pages; + + task_mem = SOF_IPC4_PIPELINE_OBJECT_SIZE; + task_mem += SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE + bss; + + if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { + task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_LL_TASK_OBJECT_SIZE); + task_mem += SOF_IPC4_FW_MAX_QUEUE_COUNT * SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE; + task_mem += SOF_IPC4_LL_TASK_LIST_ITEM_SIZE; + } else { + task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_DP_TASK_OBJECT_SIZE); + task_mem += SOF_IPC4_DP_TASK_LIST_SIZE; + } + + ibs = SOF_IPC4_FW_ROUNDUP(ibs); + queue_mem = SOF_IPC4_FW_MAX_QUEUE_COUNT * (SOF_IPC4_DATA_QUEUE_OBJECT_SIZE + ibs); + + total = SOF_IPC4_FW_PAGE(task_mem + queue_mem); + + pipe_widget = swidget->pipe_widget; + pipeline = pipe_widget->private; + pipeline->mem_usage += total; +} + +static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev, + struct snd_sof_widget *swidget) +{ + struct sof_ipc4_fw_module *fw_module = swidget->module_info; + int max_instances = fw_module->man4_module_entry.instance_max_count; + + swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); + if (swidget->instance_id < 0) { + dev_err(sdev->dev, "failed to assign instance id for widget %s", + swidget->widget->name); + return swidget->instance_id; + } + + return 0; +} + +static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev, + struct snd_sof_widget *swidget, + struct sof_ipc4_base_module_cfg *base_config, + struct sof_ipc4_audio_format *out_format, + struct snd_pcm_hw_params *params, + struct sof_ipc4_available_audio_format *available_fmt, + size_t object_offset) +{ + void *ptr = available_fmt->ref_audio_fmt; + u32 valid_bits; + u32 channels; + u32 rate; + int sample_valid_bits; + int i; + + if (!ptr) { + dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name); + return -EINVAL; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + sample_valid_bits = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + sample_valid_bits = 24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + sample_valid_bits = 32; + break; + default: + dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); + return -EINVAL; + } + + if (!available_fmt->audio_fmt_num) { + dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name); + return -EINVAL; + } + + /* + * Search supported audio formats to match rate, channels ,and + * sample_valid_bytes from runtime params + */ + for (i = 0; i < available_fmt->audio_fmt_num; i++, ptr = (u8 *)ptr + object_offset) { + struct sof_ipc4_audio_format *fmt = ptr; + + rate = fmt->sampling_frequency; + channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); + valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); + if (params_rate(params) == rate && params_channels(params) == channels && + sample_valid_bits == valid_bits) { + dev_dbg(sdev->dev, "%s: matching audio format index for %uHz, %ubit, %u channels: %d\n", + __func__, rate, valid_bits, channels, i); + + /* copy ibs/obs and input format */ + memcpy(base_config, &available_fmt->base_config[i], + sizeof(struct sof_ipc4_base_module_cfg)); + + /* copy output format */ + if (out_format) + memcpy(out_format, &available_fmt->out_audio_fmt[i], + sizeof(struct sof_ipc4_audio_format)); + break; + } + } + + if (i == available_fmt->audio_fmt_num) { + dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", + __func__, params_rate(params), sample_valid_bits, params_channels(params)); + return -EINVAL; + } + + dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); + sof_ipc4_dbg_audio_format(sdev->dev, &base_config->audio_fmt, + sizeof(*base_config), 1); + if (out_format) { + dev_dbg(sdev->dev, "Init output audio formats for %s\n", swidget->widget->name); + sof_ipc4_dbg_audio_format(sdev->dev, out_format, + sizeof(*out_format), 1); + } + + /* Return the index of the matched format */ + return i; +} + +static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_fw_module *fw_module = swidget->module_info; + struct sof_ipc4_copier *ipc4_copier = NULL; + struct snd_sof_widget *pipe_widget; + struct sof_ipc4_pipeline *pipeline; + + /* reset pipeline memory usage */ + pipe_widget = swidget->pipe_widget; + pipeline = pipe_widget->private; + pipeline->mem_usage = 0; + + if (WIDGET_IS_AIF(swidget->id)) + ipc4_copier = swidget->private; + + if (ipc4_copier) { + kfree(ipc4_copier->ipc_config_data); + ipc4_copier->ipc_config_data = NULL; + ipc4_copier->ipc_config_size = 0; + } + + ida_free(&fw_module->m_ida, swidget->instance_id); +} + +static int +sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, + struct snd_pcm_hw_params *fe_params, + struct snd_sof_platform_stream_params *platform_params, + struct snd_pcm_hw_params *pipeline_params, int dir) +{ + struct sof_ipc4_available_audio_format *available_fmt; + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_copier_data *copier_data; + struct snd_pcm_hw_params *ref_params; + struct sof_ipc4_copier *ipc4_copier; + struct snd_mask *fmt; + int out_sample_valid_bits; + size_t ref_audio_fmt_size; + void **ipc_config_data; + int *ipc_config_size; + u32 **data; + int ipc_size, ret; + + dev_dbg(sdev->dev, "%s: copier %s, type %d", __func__, swidget->widget->name, swidget->id); + + switch (swidget->id) { + case snd_soc_dapm_aif_in: + case snd_soc_dapm_aif_out: + { + struct sof_ipc4_gtw_attributes *gtw_attr; + struct snd_sof_widget *pipe_widget; + struct sof_ipc4_pipeline *pipeline; + + pipe_widget = swidget->pipe_widget; + pipeline = pipe_widget->private; + ipc4_copier = (struct sof_ipc4_copier *)swidget->private; + gtw_attr = ipc4_copier->gtw_attr; + copier_data = &ipc4_copier->data; + available_fmt = &ipc4_copier->available_fmt; + + /* + * base_config->audio_fmt and out_audio_fmt represent the input and output audio + * formats. Use the input format as the reference to match pcm params for playback + * and the output format as reference for capture. + */ + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { + available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt; + ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg); + } else { + available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt; + ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format); + } + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; + copier_data->gtw_cfg.node_id |= + SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); + + /* set gateway attributes */ + gtw_attr->lp_buffer_alloc = pipeline->lp_mode; + ref_params = fe_params; + break; + } + default: + dev_err(sdev->dev, "unsupported type %d for copier %s", + swidget->id, swidget->widget->name); + return -EINVAL; + } + + /* set input and output audio formats */ + ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config, + &copier_data->out_format, ref_params, + available_fmt, ref_audio_fmt_size); + if (ret < 0) + return ret; + + /* modify the input params for the next widget */ + fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT); + out_sample_valid_bits = + SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(copier_data->out_format.fmt_cfg); + snd_mask_none(fmt); + switch (out_sample_valid_bits) { + case 16: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + break; + case 24: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE); + break; + case 32: + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); + break; + default: + dev_err(sdev->dev, "invalid sample frame format %d\n", + params_format(pipeline_params)); + return -EINVAL; + } + + /* set the gateway dma_buffer_size using the matched ID returned above */ + copier_data->gtw_cfg.dma_buffer_size = available_fmt->dma_buffer_size[ret]; + + data = &ipc4_copier->copier_config; + ipc_config_size = &ipc4_copier->ipc_config_size; + ipc_config_data = &ipc4_copier->ipc_config_data; + + /* config_length is DWORD based */ + ipc_size = sizeof(*copier_data) + copier_data->gtw_cfg.config_length * 4; + + dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); + + *ipc_config_data = kzalloc(ipc_size, GFP_KERNEL); + if (!*ipc_config_data) + return -ENOMEM; + + *ipc_config_size = ipc_size; + + /* copy IPC data */ + memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data)); + if (copier_data->gtw_cfg.config_length) + memcpy(*ipc_config_data + sizeof(*copier_data), + *data, copier_data->gtw_cfg.config_length * 4); + + /* update pipeline memory usage */ + sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &copier_data->base_config); + + /* assign instance ID */ + return sof_ipc4_widget_assign_instance_id(sdev, swidget); +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -588,10 +872,12 @@ static enum sof_tokens dai_token_list[] = { static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, - NULL, NULL}, + sof_ipc4_prepare_copier_module, + sof_ipc4_unprepare_copier_module}, [snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, - NULL, NULL}, + sof_ipc4_prepare_copier_module, + sof_ipc4_unprepare_copier_module}, [snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, dai_token_list, ARRAY_SIZE(dai_token_list), NULL, NULL, NULL}, [snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index f4f62dda63a37..5f4c463f329e0 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -11,6 +11,24 @@ #include +#define SOF_IPC4_FW_PAGE_SIZE BIT(12) +#define SOF_IPC4_FW_PAGE(x) ((((x) + BIT(12) - 1) & ~(BIT(12) - 1)) >> 12) +#define SOF_IPC4_FW_ROUNDUP(x) (((x) + BIT(6) - 1) & (~(BIT(6) - 1))) + +#define SOF_IPC4_MODULE_LL BIT(5) +#define SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE 12 +#define SOF_IPC4_PIPELINE_OBJECT_SIZE 448 +#define SOF_IPC4_DATA_QUEUE_OBJECT_SIZE 128 +#define SOF_IPC4_LL_TASK_OBJECT_SIZE 72 +#define SOF_IPC4_DP_TASK_OBJECT_SIZE 104 +#define SOF_IPC4_DP_TASK_LIST_SIZE (12 + 8) +#define SOF_IPC4_LL_TASK_LIST_ITEM_SIZE 12 +#define SOF_IPC4_FW_MAX_PAGE_COUNT 20 +#define SOF_IPC4_FW_MAX_QUEUE_COUNT 8 + +/* Node index and mask applicable for host copier */ +#define SOF_IPC4_NODE_INDEX_MASK 0xFF +#define SOF_IPC4_NODE_INDEX(x) ((x) & SOF_IPC4_NODE_INDEX_MASK) #define SOF_IPC4_NODE_TYPE(x) ((x) << 8) /** -- GitLab From acf525942077213e9bc00eee8a73af360ab2fc08 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:26 -0700 Subject: [PATCH 449/942] ASoC: SOF: ipc4-topology: Add prepare op for DAI type widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the prepare op for the DAI type widgets for IPC4. The prepare op is responsible for choosing the input/output audio formats for these widgets based on the runtime PCM params, assigning the instance ID and updating the total memory usage for the pipelines these widgets belong to. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-7-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 43 ++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 1a73c16f16242..1bc5ff0154c58 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -706,8 +706,13 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) pipeline = pipe_widget->private; pipeline->mem_usage = 0; - if (WIDGET_IS_AIF(swidget->id)) + if (WIDGET_IS_AIF(swidget->id)) { ipc4_copier = swidget->private; + } else if (WIDGET_IS_DAI(swidget->id)) { + struct snd_sof_dai *dai = swidget->private; + + ipc4_copier = dai->private; + } if (ipc4_copier) { kfree(ipc4_copier->ipc_config_data); @@ -776,6 +781,34 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ref_params = fe_params; break; } + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: + { + struct snd_sof_dai *dai = swidget->private; + + ipc4_copier = (struct sof_ipc4_copier *)dai->private; + copier_data = &ipc4_copier->data; + available_fmt = &ipc4_copier->available_fmt; + if (dir == SNDRV_PCM_STREAM_CAPTURE) { + available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt; + ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format); + + /* + * modify the input params for the dai copier as it only supports + * 32-bit always + */ + fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT); + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); + } else { + available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt; + ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg); + } + + ref_params = pipeline_params; + + break; + } default: dev_err(sdev->dev, "unsupported type %d for copier %s", swidget->id, swidget->widget->name); @@ -879,9 +912,13 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY sof_ipc4_prepare_copier_module, sof_ipc4_unprepare_copier_module}, [snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, - dai_token_list, ARRAY_SIZE(dai_token_list), NULL, NULL, NULL}, + dai_token_list, ARRAY_SIZE(dai_token_list), NULL, + sof_ipc4_prepare_copier_module, + sof_ipc4_unprepare_copier_module}, [snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, - dai_token_list, ARRAY_SIZE(dai_token_list), NULL, NULL, NULL}, + dai_token_list, ARRAY_SIZE(dai_token_list), NULL, + sof_ipc4_prepare_copier_module, + sof_ipc4_unprepare_copier_module}, [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, -- GitLab From 4f838ab2081260119677df3ba94dbbd4f8cb7183 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:27 -0700 Subject: [PATCH 450/942] ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for parsing and preparing pga type widgets. Define the token ID's and the associated token arrays needed to parse these widgets. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Paul Olaru Link: https://lore.kernel.org/r/20220609032643.916882-8-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 113 ++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 60 ++++++++++++++++++ sound/soc/sof/sof-audio.h | 1 + 3 files changed, 174 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 1bc5ff0154c58..30549573bd342 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -95,6 +95,16 @@ static const struct sof_topology_token comp_ext_tokens[] = { offsetof(struct snd_sof_widget, uuid)}, }; +static const struct sof_topology_token gain_tokens[] = { + {SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)}, + {SOF_TKN_GAIN_RAMP_DURATION, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc4_gain_data, curve_duration)}, + {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD, + get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)}, +}; + static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)}, [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)}, @@ -117,6 +127,7 @@ static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { ARRAY_SIZE(ipc4_copier_tokens)}, [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens", ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)}, + [SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)}, }; static void sof_ipc4_dbg_audio_format(struct device *dev, @@ -557,6 +568,62 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) return ret; } +static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_fw_module *fw_module; + struct snd_sof_control *scontrol; + struct sof_ipc4_gain *gain; + int ret; + + gain = kzalloc(sizeof(*gain), GFP_KERNEL); + if (!gain) + return -ENOMEM; + + swidget->private = gain; + + gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; + gain->data.init_val = SOF_IPC4_VOL_ZERO_DB; + + /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */ + ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, false); + if (ret) + goto err; + + ret = sof_update_ipc_object(scomp, &gain->data, SOF_GAIN_TOKENS, swidget->tuples, + swidget->num_tuples, sizeof(gain->data), 1); + if (ret) { + dev_err(scomp->dev, "Parsing gain tokens failed\n"); + goto err; + } + + dev_dbg(scomp->dev, + "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x, cpc %d\n", + swidget->widget->name, gain->data.curve_type, gain->data.curve_duration, + gain->data.init_val, gain->base_config.cpc); + + ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); + if (ret) + goto err; + + fw_module = swidget->module_info; + + /* update module ID for all kcontrols for this widget */ + list_for_each_entry(scontrol, &sdev->kcontrol_list, list) + if (scontrol->comp_id == swidget->comp_id) { + struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; + struct sof_ipc4_msg *msg = &cdata->msg; + + msg->primary |= fw_module->man4_module_entry.id; + } + + return 0; +err: + kfree(gain); + return ret; +} + static void sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, struct sof_ipc4_base_module_cfg *base_config) @@ -874,6 +941,39 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, return sof_ipc4_widget_assign_instance_id(sdev, swidget); } +static void sof_ipc4_unprepare_generic_module(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_fw_module *fw_module = swidget->module_info; + + ida_free(&fw_module->m_ida, swidget->instance_id); +} + +static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget, + struct snd_pcm_hw_params *fe_params, + struct snd_sof_platform_stream_params *platform_params, + struct snd_pcm_hw_params *pipeline_params, int dir) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_gain *gain = swidget->private; + int ret; + + gain->available_fmt.ref_audio_fmt = &gain->available_fmt.base_config->audio_fmt; + + /* output format is not required to be sent to the FW for gain */ + ret = sof_ipc4_init_audio_fmt(sdev, swidget, &gain->base_config, + NULL, pipeline_params, &gain->available_fmt, + sizeof(gain->base_config)); + if (ret < 0) + return ret; + + /* update pipeline memory usage */ + sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &gain->base_config); + + /* assign instance ID */ + return sof_ipc4_widget_assign_instance_id(sdev, swidget); +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -902,6 +1002,15 @@ static enum sof_tokens dai_token_list[] = { SOF_COMP_EXT_TOKENS, }; +static enum sof_tokens pga_token_list[] = { + SOF_COMP_TOKENS, + SOF_GAIN_TOKENS, + SOF_AUDIO_FMT_NUM_TOKENS, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, + SOF_IN_AUDIO_FORMAT_TOKENS, + SOF_COMP_EXT_TOKENS, +}; + static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, @@ -922,6 +1031,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, + [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp, + pga_token_list, ARRAY_SIZE(pga_token_list), NULL, + sof_ipc4_prepare_gain_module, + sof_ipc4_unprepare_generic_module}, }; const struct sof_ipc_tplg_ops ipc4_tplg_ops = { diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 5f4c463f329e0..060123826db45 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -31,6 +31,9 @@ #define SOF_IPC4_NODE_INDEX(x) ((x) & SOF_IPC4_NODE_INDEX_MASK) #define SOF_IPC4_NODE_TYPE(x) ((x) << 8) +#define SOF_IPC4_GAIN_ALL_CHANNELS_MASK 0xffffffff +#define SOF_IPC4_VOL_ZERO_DB 0x7fffffff + /** * struct sof_ipc4_pipeline - pipeline config data * @priority: Priority of this pipeline @@ -128,4 +131,61 @@ struct sof_ipc4_copier { int dai_index; }; +/** + * struct sof_ipc4_ctrl_value_chan: generic channel mapped value data + * @channel: Channel ID + * @value: gain value + */ +struct sof_ipc4_ctrl_value_chan { + u32 channel; + u32 value; +}; + +/** + * struct sof_ipc4_control_data - IPC data for kcontrol IO + * @msg: message structure for kcontrol IO + * @index: pipeline ID + * @chanv: channel ID and value array used by volume type controls + * @data: data for binary kcontrols + */ +struct sof_ipc4_control_data { + struct sof_ipc4_msg msg; + int index; + + union { + struct sof_ipc4_ctrl_value_chan chanv[0]; + struct sof_abi_hdr data[0]; + }; +}; + +/** + * struct sof_ipc4_gain_data - IPC gain blob + * @channels: Channels + * @init_val: Initial value + * @curve_type: Curve type + * @reserved: reserved for future use + * @curve_duration: Curve duration + */ +struct sof_ipc4_gain_data { + uint32_t channels; + uint32_t init_val; + uint32_t curve_type; + uint32_t reserved; + uint32_t curve_duration; +} __aligned(8); + +/** + * struct sof_ipc4_gain - gain config data + * @base_config: IPC base config data + * @data: IPC gain blob + * @available_fmt: Available audio format + * @msg: message structure for gain + */ +struct sof_ipc4_gain { + struct sof_ipc4_base_module_cfg base_config; + struct sof_ipc4_gain_data data; + struct sof_ipc4_available_audio_format available_fmt; + struct sof_ipc4_msg msg; +}; + #endif diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index c38b4bdd685ae..d896da1192c5e 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -232,6 +232,7 @@ enum sof_tokens { SOF_COPIER_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, SOF_COPIER_FORMAT_TOKENS, + SOF_GAIN_TOKENS, /* this should be the last */ SOF_TOKEN_COUNT, -- GitLab From 4d4ba014ac4b3772ed39c15cd2ceacbb071c26f6 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:28 -0700 Subject: [PATCH 451/942] ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for parsing and preparing mixer type widgets. Define the token ID's and the associated token arrays needed to parse these widgets. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Paul Olaru Link: https://lore.kernel.org/r/20220609032643.916882-9-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 68 +++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 12 +++++++ 2 files changed, 80 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 30549573bd342..35457fe4edd91 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -624,6 +624,35 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) return ret; } +static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct sof_ipc4_mixer *mixer; + int ret; + + dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); + + mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); + if (!mixer) + return -ENOMEM; + + swidget->private = mixer; + + /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */ + ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, false); + if (ret) + goto err; + + ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); + if (ret) + goto err; + + return 0; +err: + kfree(mixer); + return ret; +} + static void sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, struct sof_ipc4_base_module_cfg *base_config) @@ -974,6 +1003,33 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget, return sof_ipc4_widget_assign_instance_id(sdev, swidget); } +static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget, + struct snd_pcm_hw_params *fe_params, + struct snd_sof_platform_stream_params *platform_params, + struct snd_pcm_hw_params *pipeline_params, int dir) +{ + struct snd_soc_component *scomp = swidget->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_mixer *mixer = swidget->private; + int ret; + + /* only 32bit is supported by mixer */ + mixer->available_fmt.ref_audio_fmt = &mixer->available_fmt.base_config->audio_fmt; + + /* output format is not required to be sent to the FW for mixer */ + ret = sof_ipc4_init_audio_fmt(sdev, swidget, &mixer->base_config, + NULL, pipeline_params, &mixer->available_fmt, + sizeof(mixer->base_config)); + if (ret < 0) + return ret; + + /* update pipeline memory usage */ + sof_ipc4_update_pipeline_mem_usage(sdev, swidget, &mixer->base_config); + + /* assign instance ID */ + return sof_ipc4_widget_assign_instance_id(sdev, swidget); +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1011,6 +1067,14 @@ static enum sof_tokens pga_token_list[] = { SOF_COMP_EXT_TOKENS, }; +static enum sof_tokens mixer_token_list[] = { + SOF_COMP_TOKENS, + SOF_AUDIO_FMT_NUM_TOKENS, + SOF_IN_AUDIO_FORMAT_TOKENS, + SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, + SOF_COMP_EXT_TOKENS, +}; + static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, host_token_list, ARRAY_SIZE(host_token_list), NULL, @@ -1035,6 +1099,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY pga_token_list, ARRAY_SIZE(pga_token_list), NULL, sof_ipc4_prepare_gain_module, sof_ipc4_unprepare_generic_module}, + [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp, + mixer_token_list, ARRAY_SIZE(mixer_token_list), + NULL, sof_ipc4_prepare_mixer_module, + sof_ipc4_unprepare_generic_module}, }; const struct sof_ipc_tplg_ops ipc4_tplg_ops = { diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 060123826db45..eebf46b244307 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -188,4 +188,16 @@ struct sof_ipc4_gain { struct sof_ipc4_msg msg; }; +/** + * struct sof_ipc4_mixer - mixer config data + * @base_config: IPC base config data + * @available_fmt: Available audio format + * @msg: IPC4 message struct containing header and data info + */ +struct sof_ipc4_mixer { + struct sof_ipc4_base_module_cfg base_config; + struct sof_ipc4_available_audio_format available_fmt; + struct sof_ipc4_msg msg; +}; + #endif -- GitLab From d97964f870786389f4c399a507ffa5d1ebf2a9e4 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:29 -0700 Subject: [PATCH 452/942] ASoC: SOF: ipc4-topology: Add control_setup op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the control_setup op for IPC4 topology IPC ops to handle the volume kcontrol types. Support for other kcontrol types will be added in the follow up patches. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-10-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 35457fe4edd91..0c36b7cb6e797 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -15,6 +15,8 @@ #include "ipc4-topology.h" #include "ops.h" +#define SOF_IPC4_GAIN_PARAM_ID 0 + static const struct sof_topology_token ipc4_sched_tokens[] = { {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, offsetof(struct sof_ipc4_pipeline, lp_mode)} @@ -1030,6 +1032,52 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget, return sof_ipc4_widget_assign_instance_id(sdev, swidget); } +static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) +{ + struct sof_ipc4_control_data *control_data; + struct sof_ipc4_msg *msg; + int i; + + scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); + + /* scontrol->ipc_control_data will be freed in sof_control_unload */ + scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); + if (!scontrol->ipc_control_data) + return -ENOMEM; + + control_data = scontrol->ipc_control_data; + control_data->index = scontrol->index; + + msg = &control_data->msg; + msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); + msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + + msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); + + /* set default volume values to 0dB in control */ + for (i = 0; i < scontrol->num_channels; i++) { + control_data->chanv[i].channel = i; + control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; + } + + return 0; +} + +static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) +{ + switch (scontrol->info_type) { + case SND_SOC_TPLG_CTL_VOLSW: + case SND_SOC_TPLG_CTL_VOLSW_SX: + case SND_SOC_TPLG_CTL_VOLSW_XR_SX: + return sof_ipc4_control_load_volume(sdev, scontrol); + default: + break; + } + + return 0; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1108,4 +1156,5 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .widget = tplg_ipc4_widget_ops, .token_list = ipc4_token_list, + .control_setup = sof_ipc4_control_setup, }; -- GitLab From 955e84fc0b6df6cfb95ee6f569be809af49d8287 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:30 -0700 Subject: [PATCH 453/942] ASoC: SOF: ipc4-topology: Add control IO ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the kcontrol IO ops for volume type controls for IPC4. Support for other kcontrol types will be added later. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-11-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/Makefile | 2 +- sound/soc/sof/ipc4-control.c | 216 ++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-priv.h | 1 + sound/soc/sof/ipc4-topology.c | 1 + 4 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/ipc4-control.c diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 73524fadb3ce7..1e15937f2bde7 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -4,7 +4,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ ipc3-topology.o ipc3-control.o ipc3.o ipc3-pcm.o ipc3-loader.o\ ipc3-dtrace.o\ - ipc4.o ipc4-loader.o ipc4-topology.o + ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),) snd-sof-objs += sof-client.o endif diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c new file mode 100644 index 0000000000000..95ee121dd3cf0 --- /dev/null +++ b/sound/soc/sof/ipc4-control.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// + +#include "sof-priv.h" +#include "sof-audio.h" +#include "ipc4-priv.h" +#include "ipc4-topology.h" + +static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, bool set) +{ + struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_ops *iops = sdev->ipc->ops; + struct sof_ipc4_msg *msg = &cdata->msg; + struct snd_sof_widget *swidget; + bool widget_found = false; + + /* find widget associated with the control */ + list_for_each_entry(swidget, &sdev->widget_list, list) { + if (swidget->comp_id == scontrol->comp_id) { + widget_found = true; + break; + } + } + + if (!widget_found) { + dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); + return -ENOENT; + } + + /* + * Volatile controls should always be part of static pipelines and the widget use_count + * would always be > 0 in this case. For the others, just return the cached value if the + * widget is not set up. + */ + if (!swidget->use_count) + return 0; + + msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; + msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); + + return iops->set_get_data(sdev, msg, msg->data_size, set); +} + +static int +sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, + struct snd_sof_control *scontrol) +{ + struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; + struct sof_ipc4_gain *gain = swidget->private; + struct sof_ipc4_msg *msg = &cdata->msg; + struct sof_ipc4_gain_data data; + bool all_channels_equal = true; + u32 value; + int ret, i; + + /* check if all channel values are equal */ + value = cdata->chanv[0].value; + for (i = 1; i < scontrol->num_channels; i++) { + if (cdata->chanv[i].value != value) { + all_channels_equal = false; + break; + } + } + + /* + * notify DSP with a single IPC message if all channel values are equal. Otherwise send + * a separate IPC for each channel. + */ + for (i = 0; i < scontrol->num_channels; i++) { + if (all_channels_equal) { + data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; + data.init_val = cdata->chanv[0].value; + } else { + data.channels = cdata->chanv[i].channel; + data.init_val = cdata->chanv[i].value; + } + + /* set curve type and duration from topology */ + data.curve_duration = gain->data.curve_duration; + data.curve_type = gain->data.curve_type; + + msg->data_ptr = &data; + msg->data_size = sizeof(data); + + ret = sof_ipc4_set_get_kcontrol_data(scontrol, true); + msg->data_ptr = NULL; + msg->data_size = 0; + if (ret < 0) { + dev_err(sdev->dev, "Failed to set volume update for %s\n", + scontrol->name); + return ret; + } + + if (all_channels_equal) + break; + } + + return 0; +} + +static bool sof_ipc4_volume_put(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; + struct snd_soc_component *scomp = scontrol->scomp; + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + unsigned int channels = scontrol->num_channels; + struct snd_sof_widget *swidget; + bool widget_found = false; + bool change = false; + unsigned int i; + int ret; + + /* update each channel */ + for (i = 0; i < channels; i++) { + u32 value = mixer_to_ipc(ucontrol->value.integer.value[i], + scontrol->volume_table, scontrol->max + 1); + + change = change || (value != cdata->chanv[i].value); + cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; + } + + if (!pm_runtime_active(scomp->dev)) + return change; + + /* find widget associated with the control */ + list_for_each_entry(swidget, &sdev->widget_list, list) { + if (swidget->comp_id == scontrol->comp_id) { + widget_found = true; + break; + } + } + + if (!widget_found) { + dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); + return -ENOENT; + } + + ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol); + if (ret < 0) + return false; + + return change; +} + +static int sof_ipc4_volume_get(struct snd_sof_control *scontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; + unsigned int channels = scontrol->num_channels; + unsigned int i; + + for (i = 0; i < channels; i++) + ucontrol->value.integer.value[i] = ipc_to_mixer(cdata->chanv[i].value, + scontrol->volume_table, + scontrol->max + 1); + + return 0; +} + +/* set up all controls for the widget */ +static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +{ + struct snd_sof_control *scontrol; + int ret; + + list_for_each_entry(scontrol, &sdev->kcontrol_list, list) + if (scontrol->comp_id == swidget->comp_id) { + ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol); + if (ret < 0) { + dev_err(sdev->dev, "%s: kcontrol %d set up failed for widget %s\n", + __func__, scontrol->comp_id, swidget->widget->name); + return ret; + } + } + + return 0; +} + +static int +sof_ipc4_set_up_volume_table(struct snd_sof_control *scontrol, int tlv[SOF_TLV_ITEMS], int size) +{ + int i; + + /* init the volume table */ + scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL); + if (!scontrol->volume_table) + return -ENOMEM; + + /* populate the volume table */ + for (i = 0; i < size ; i++) { + u32 val = vol_compute_gain(i, tlv); + u64 q31val = ((u64)val) << 15; /* Can be over Q1.31, need to saturate */ + + scontrol->volume_table[i] = q31val > SOF_IPC4_VOL_ZERO_DB ? + SOF_IPC4_VOL_ZERO_DB : q31val; + } + + return 0; +} + +const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops = { + .volume_put = sof_ipc4_volume_put, + .volume_get = sof_ipc4_volume_get, + .widget_kcontrol_setup = sof_ipc4_widget_kcontrol_setup, + .set_up_volume_table = sof_ipc4_set_up_volume_table, +}; diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index 5388b888fefa8..d0b110811aebc 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -41,5 +41,6 @@ struct sof_ipc4_fw_module { extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; extern const struct sof_ipc_tplg_ops ipc4_tplg_ops; +extern const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops; #endif diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 0c36b7cb6e797..3cebd6fe7cd1d 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1157,4 +1157,5 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .widget = tplg_ipc4_widget_ops, .token_list = ipc4_token_list, .control_setup = sof_ipc4_control_setup, + .control = &tplg_ipc4_control_ops, }; -- GitLab From e75e5db8f8ac5b9d4e8968060822bed4671f22ec Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:31 -0700 Subject: [PATCH 454/942] ASoC: SOF: IPC4: Add pcm ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define and set the PCM ops for IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Yaochun Hung Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-12-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/Makefile | 2 +- sound/soc/sof/ipc4-pcm.c | 229 ++++++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-priv.h | 1 + sound/soc/sof/ipc4.c | 1 + 4 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/ipc4-pcm.c diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 1e15937f2bde7..2fa8088707a8a 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -4,7 +4,7 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ ipc3-topology.o ipc3-control.o ipc3.o ipc3-pcm.o ipc3-loader.o\ ipc3-dtrace.o\ - ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o + ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),) snd-sof-objs += sof-client.o endif diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c new file mode 100644 index 0000000000000..7a56fba8f1d98 --- /dev/null +++ b/sound/soc/sof/ipc4-pcm.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// + +#include +#include +#include "sof-audio.h" +#include "sof-priv.h" +#include "ipc4-priv.h" +#include "ipc4-topology.h" + +static int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state) +{ + struct sof_ipc4_msg msg = {{ 0 }}; + u32 primary; + + dev_dbg(sdev->dev, "ipc4 set pipeline %d state %d", id, state); + + primary = state; + primary |= SOF_IPC4_GLB_PIPE_STATE_ID(id); + primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_SET_PIPELINE_STATE); + primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); + + msg.primary = primary; + + return sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0); +} + +static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int state) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_sof_widget *pipeline_widget; + struct snd_soc_dapm_widget_list *list; + struct snd_soc_dapm_widget *widget; + struct sof_ipc4_pipeline *pipeline; + struct snd_sof_widget *swidget; + struct snd_sof_pcm *spcm; + int ret = 0; + int num_widgets; + + spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) + return -EINVAL; + + list = spcm->stream[substream->stream].list; + + for_each_dapm_widgets(list, num_widgets, widget) { + swidget = widget->dobj.private; + + if (!swidget) + continue; + + /* + * set pipeline state for both FE and BE pipelines for RUNNING state. + * For PAUSE/RESET, set the pipeline state only for the FE pipeline. + */ + switch (state) { + case SOF_IPC4_PIPE_PAUSED: + case SOF_IPC4_PIPE_RESET: + if (!WIDGET_IS_AIF(swidget->id)) + continue; + break; + default: + break; + } + + /* find pipeline widget for the pipeline that this widget belongs to */ + pipeline_widget = swidget->pipe_widget; + pipeline = (struct sof_ipc4_pipeline *)pipeline_widget->private; + + if (pipeline->state == state) + continue; + + /* first set the pipeline to PAUSED state */ + if (pipeline->state != SOF_IPC4_PIPE_PAUSED) { + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) { + dev_err(sdev->dev, "failed to pause pipeline %d\n", + swidget->pipeline_id); + return ret; + } + } + + pipeline->state = SOF_IPC4_PIPE_PAUSED; + + if (pipeline->state == state) + continue; + + /* then set the final state */ + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, state); + if (ret < 0) { + dev_err(sdev->dev, "failed to set state %d for pipeline %d\n", + state, swidget->pipeline_id); + break; + } + + pipeline->state = state; + } + + return ret; +} + +static int sof_ipc4_pcm_trigger(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int cmd) +{ + int state; + + /* determine the pipeline state */ + switch (cmd) { + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + state = SOF_IPC4_PIPE_PAUSED; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_START: + state = SOF_IPC4_PIPE_RUNNING; + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + state = SOF_IPC4_PIPE_PAUSED; + break; + default: + dev_err(component->dev, "%s: unhandled trigger cmd %d\n", __func__, cmd); + return -EINVAL; + } + + /* set the pipeline state */ + return sof_ipc4_trigger_pipelines(component, substream, state); +} + +static int sof_ipc4_pcm_hw_free(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET); +} + +static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name, + struct snd_pcm_hw_params *params) +{ + struct snd_sof_dai_link *slink; + struct snd_sof_dai *dai; + bool dai_link_found = false; + int i; + + list_for_each_entry(slink, &sdev->dai_link_list, list) { + if (!strcmp(slink->link->name, link_name)) { + dai_link_found = true; + break; + } + } + + if (!dai_link_found) + return; + + for (i = 0; i < slink->num_hw_configs; i++) { + struct snd_soc_tplg_hw_config *hw_config = &slink->hw_configs[i]; + + if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate)) { + /* set current config for all DAI's with matching name */ + list_for_each_entry(dai, &sdev->dai_list, list) + if (!strcmp(slink->link->name, dai->name)) + dai->current_config = le32_to_cpu(hw_config->id); + break; + } + } +} + +static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME); + struct snd_sof_dai *dai = snd_sof_find_dai(component, rtd->dai_link->name); + struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); + struct sof_ipc4_copier *ipc4_copier; + struct snd_soc_dpcm *dpcm; + + if (!dai) { + dev_err(component->dev, "%s: No DAI found with name %s\n", __func__, + rtd->dai_link->name); + return -EINVAL; + } + + ipc4_copier = dai->private; + if (!ipc4_copier) { + dev_err(component->dev, "%s: No private data found for DAI %s\n", + __func__, rtd->dai_link->name); + return -EINVAL; + } + + /* always set BE format to 32-bits for both playback and capture */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); + + /* + * Set trigger order for capture to SND_SOC_DPCM_TRIGGER_PRE. This is required + * to ensure that the BE DAI pipeline gets stopped/suspended before the FE DAI + * pipeline gets triggered and the pipeline widgets are freed. + */ + for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) { + struct snd_soc_pcm_runtime *fe = dpcm->fe; + + fe->dai_link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; + } + + switch (ipc4_copier->dai_type) { + case SOF_DAI_INTEL_SSP: + ipc4_ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params); + break; + default: + break; + } + + return 0; +} + +const struct sof_ipc_pcm_ops ipc4_pcm_ops = { + .trigger = sof_ipc4_pcm_trigger, + .hw_free = sof_ipc4_pcm_hw_free, + .dai_link_fixup = sof_ipc4_pcm_dai_link_fixup, +}; diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index d0b110811aebc..e4381a74516c8 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -42,5 +42,6 @@ struct sof_ipc4_fw_module { extern const struct sof_ipc_fw_loader_ops ipc4_loader_ops; extern const struct sof_ipc_tplg_ops ipc4_tplg_ops; extern const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops; +extern const struct sof_ipc_pcm_ops ipc4_pcm_ops; #endif diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index be677a33882de..700069e759c44 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -604,4 +604,5 @@ const struct sof_ipc_ops ipc4_ops = { .get_reply = sof_ipc4_get_reply, .fw_loader = &ipc4_loader_ops, .tplg = &ipc4_tplg_ops, + .pcm = &ipc4_pcm_ops, }; -- GitLab From 6e9257a13c75b2e4fc33477f9de4912fdfae81e1 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:32 -0700 Subject: [PATCH 455/942] ASoC: SOF: ipc4-topology: Add widget_setup/widget_free ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define and set the widget_setup/widget_free ops for IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220609032643.916882-13-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 123 ++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 3cebd6fe7cd1d..44f65b8b526a0 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1078,6 +1078,127 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr return 0; } +static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +{ + struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct sof_ipc4_pipeline *pipeline; + struct sof_ipc4_msg *msg; + void *ipc_data = NULL; + u32 ipc_size = 0; + int ret; + + dev_dbg(sdev->dev, "Create widget %s instance %d - pipe %d - core %d\n", + swidget->widget->name, swidget->instance_id, swidget->pipeline_id, swidget->core); + + switch (swidget->id) { + case snd_soc_dapm_scheduler: + pipeline = swidget->private; + + dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, + pipeline->mem_usage); + + msg = &pipeline->msg; + msg->primary |= pipeline->mem_usage; + break; + case snd_soc_dapm_aif_in: + case snd_soc_dapm_aif_out: + { + struct sof_ipc4_copier *ipc4_copier = swidget->private; + + ipc_size = ipc4_copier->ipc_config_size; + ipc_data = ipc4_copier->ipc_config_data; + + msg = &ipc4_copier->msg; + break; + } + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: + { + struct snd_sof_dai *dai = swidget->private; + struct sof_ipc4_copier *ipc4_copier = dai->private; + + ipc_size = ipc4_copier->ipc_config_size; + ipc_data = ipc4_copier->ipc_config_data; + + msg = &ipc4_copier->msg; + break; + } + case snd_soc_dapm_pga: + { + struct sof_ipc4_gain *gain = swidget->private; + + ipc_size = sizeof(struct sof_ipc4_base_module_cfg) + + sizeof(struct sof_ipc4_gain_data); + ipc_data = gain; + + msg = &gain->msg; + break; + } + case snd_soc_dapm_mixer: + { + struct sof_ipc4_mixer *mixer = swidget->private; + + ipc_size = sizeof(mixer->base_config); + ipc_data = &mixer->base_config; + + msg = &mixer->msg; + break; + } + default: + dev_err(sdev->dev, "widget type %d not supported", swidget->id); + return -EINVAL; + } + + if (swidget->id != snd_soc_dapm_scheduler) { + pipeline = pipe_widget->private; + msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; + msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); + + msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; + msg->extension |= ipc_size >> 2; + msg->extension &= ~SOF_IPC4_MOD_EXT_DOMAIN_MASK; + msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(pipeline->lp_mode); + } + + msg->data_size = ipc_size; + msg->data_ptr = ipc_data; + + ret = sof_ipc_tx_message(sdev->ipc, msg, ipc_size, NULL, 0); + if (ret < 0) + dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); + + return ret; +} + +static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) +{ + int ret = 0; + + /* freeing a pipeline frees all the widgets associated with it */ + if (swidget->id == snd_soc_dapm_scheduler) { + struct sof_ipc4_pipeline *pipeline = swidget->private; + struct sof_ipc4_msg msg = {{ 0 }}; + u32 header; + + header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->pipeline_id); + header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE); + header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); + + msg.primary = header; + + ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0); + if (ret < 0) + dev_err(sdev->dev, "failed to free pipeline widget %s\n", + swidget->widget->name); + + pipeline->mem_usage = 0; + pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; + } + + return ret; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1158,4 +1279,6 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .token_list = ipc4_token_list, .control_setup = sof_ipc4_control_setup, .control = &tplg_ipc4_control_ops, + .widget_setup = sof_ipc4_widget_setup, + .widget_free = sof_ipc4_widget_free, }; -- GitLab From 3acd527089463742a3dd95e274d53c2fdd834716 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:33 -0700 Subject: [PATCH 456/942] ASoC: SOF: ipc4-topology: Add route_setup/route_free ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define and set the route_setup/route_free ops for IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220609032643.916882-14-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 76 +++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 44f65b8b526a0..f5067d630f2db 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1199,6 +1199,80 @@ static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget return ret; } +static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *sroute) +{ + struct snd_sof_widget *src_widget = sroute->src_widget; + struct snd_sof_widget *sink_widget = sroute->sink_widget; + struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; + struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; + struct sof_ipc4_msg msg = {{ 0 }}; + u32 header, extension; + int src_queue = 0; + int dst_queue = 0; + int ret; + + dev_dbg(sdev->dev, "%s: bind %s -> %s\n", __func__, + src_widget->widget->name, sink_widget->widget->name); + + header = src_fw_module->man4_module_entry.id; + header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); + header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_BIND); + header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + + extension = sink_fw_module->man4_module_entry.id; + extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); + extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(dst_queue); + extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(src_queue); + + msg.primary = header; + msg.extension = extension; + + ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0); + if (ret < 0) + dev_err(sdev->dev, "%s: failed to bind modules %s -> %s\n", + __func__, src_widget->widget->name, sink_widget->widget->name); + + return ret; +} + +static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *sroute) +{ + struct snd_sof_widget *src_widget = sroute->src_widget; + struct snd_sof_widget *sink_widget = sroute->sink_widget; + struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; + struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; + struct sof_ipc4_msg msg = {{ 0 }}; + u32 header, extension; + int src_queue = 0; + int dst_queue = 0; + int ret; + + dev_dbg(sdev->dev, "%s: unbind modules %s -> %s\n", __func__, + src_widget->widget->name, sink_widget->widget->name); + + header = src_fw_module->man4_module_entry.id; + header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); + header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_UNBIND); + header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); + header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); + + extension = sink_fw_module->man4_module_entry.id; + extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); + extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(dst_queue); + extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(src_queue); + + msg.primary = header; + msg.extension = extension; + + ret = sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0); + if (ret < 0) + dev_err(sdev->dev, "failed to unbind modules %s -> %s\n", + src_widget->widget->name, sink_widget->widget->name); + + return ret; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1281,4 +1355,6 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .control = &tplg_ipc4_control_ops, .widget_setup = sof_ipc4_widget_setup, .widget_free = sof_ipc4_widget_free, + .route_setup = sof_ipc4_route_setup, + .route_free = sof_ipc4_route_free, }; -- GitLab From acf48a1f76b887f6a63f3c91eedac80b38341c05 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:34 -0700 Subject: [PATCH 457/942] ASoC: SOF: ipc4-topology: Add the dai_config op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define and set the dai_config op for IPC4. Co-developed-by: Rander Wang Signed-off-by: Rander Wang Co-developed-by: Bard Liao Signed-off-by: Bard Liao Signed-off-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220609032643.916882-15-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 45 +++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index f5067d630f2db..9615034f8c705 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1273,6 +1273,50 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s return ret; } +static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, + unsigned int flags, struct snd_sof_dai_config_data *data) +{ + struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + struct snd_sof_dai *dai = swidget->private; + struct sof_ipc4_gtw_attributes *gtw_attr; + struct sof_ipc4_copier_data *copier_data; + struct sof_ipc4_copier *ipc4_copier; + + if (!dai || !dai->private) { + dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", + swidget->widget->name); + return -EINVAL; + } + + ipc4_copier = (struct sof_ipc4_copier *)dai->private; + copier_data = &ipc4_copier->data; + + if (!data) + return 0; + + switch (ipc4_copier->dai_type) { + case SOF_DAI_INTEL_HDA: + gtw_attr = ipc4_copier->gtw_attr; + gtw_attr->lp_buffer_alloc = pipeline->lp_mode; + fallthrough; + case SOF_DAI_INTEL_ALH: + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; + copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); + break; + case SOF_DAI_INTEL_DMIC: + case SOF_DAI_INTEL_SSP: + /* nothing to do for SSP/DMIC */ + break; + default: + dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, + ipc4_copier->dai_type); + return -EINVAL; + } + + return 0; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1357,4 +1401,5 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .widget_free = sof_ipc4_widget_free, .route_setup = sof_ipc4_route_setup, .route_free = sof_ipc4_route_free, + .dai_config = sof_ipc4_dai_config, }; diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index eebf46b244307..0cadf04efa6a4 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -26,7 +26,7 @@ #define SOF_IPC4_FW_MAX_PAGE_COUNT 20 #define SOF_IPC4_FW_MAX_QUEUE_COUNT 8 -/* Node index and mask applicable for host copier */ +/* Node index and mask applicable for host copier and ALH/HDA type DAI copiers */ #define SOF_IPC4_NODE_INDEX_MASK 0xFF #define SOF_IPC4_NODE_INDEX(x) ((x) & SOF_IPC4_NODE_INDEX_MASK) #define SOF_IPC4_NODE_TYPE(x) ((x) << 8) -- GitLab From d0c0d5bf944b13b4e293746eb655f1c2caf67231 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:35 -0700 Subject: [PATCH 458/942] ASoC: SOF: ipc4-pcm: Expose sof_ipc4_set_pipeline_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose the sof_ipc4_set_pipeline_state() function as it will be used in the IPC4-specific BE DAI driver ops. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-16-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-pcm.c | 3 ++- sound/soc/sof/ipc4-priv.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 7a56fba8f1d98..6a702f9dc065b 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -13,7 +13,7 @@ #include "ipc4-priv.h" #include "ipc4-topology.h" -static int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state) +int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state) { struct sof_ipc4_msg msg = {{ 0 }}; u32 primary; @@ -30,6 +30,7 @@ static int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 sta return sof_ipc_tx_message(sdev->ipc, &msg, 0, NULL, 0); } +EXPORT_SYMBOL(sof_ipc4_set_pipeline_state); static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, struct snd_pcm_substream *substream, int state) diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index e4381a74516c8..8dddceaf5eb36 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -44,4 +44,6 @@ extern const struct sof_ipc_tplg_ops ipc4_tplg_ops; extern const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops; extern const struct sof_ipc_pcm_ops ipc4_pcm_ops; +int sof_ipc4_set_pipeline_state(struct snd_sof_dev *sdev, u32 id, u32 state); + #endif -- GitLab From 4c30004a7c6920c66a08c1aa16481c28202eefd0 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:36 -0700 Subject: [PATCH 459/942] ASoC: SOF: IPC4: set the BE DAI ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add BE DAI drv ops for IPC4 for DMIC, SSP and HDA type DAI's. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-17-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 173 +++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 9823230d2ef4a..5423667002e5a 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -10,6 +10,10 @@ #include #include +#include +#include +#include "../ipc4-priv.h" +#include "../ipc4-topology.h" #include "../sof-priv.h" #include "../sof-audio.h" #include "hda.h" @@ -369,8 +373,7 @@ static int hda_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w) return ret; } -static int ipc3_hda_dai_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static int hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(dai, substream); @@ -438,6 +441,91 @@ static int ipc3_hda_dai_trigger(struct snd_pcm_substream *substream, return 0; } +/* + * In contrast to IPC3, the dai trigger in IPC4 mixes pipeline state changes + * (over IPC channel) and DMA state change (direct host register changes). + */ +static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(dai, substream); + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + struct snd_soc_pcm_runtime *rtd; + struct snd_sof_widget *swidget; + struct snd_soc_dapm_widget *w; + struct snd_soc_dai *codec_dai; + struct hdac_stream *hstream; + struct snd_soc_dai *cpu_dai; + int ret; + + dev_dbg(dai->dev, "%s: cmd=%d dai %s direction %d\n", __func__, cmd, + dai->name, substream->stream); + + hstream = substream->runtime->private_data; + rtd = asoc_substream_to_rtd(substream); + cpu_dai = asoc_rtd_to_cpu(rtd, 0); + codec_dai = asoc_rtd_to_codec(rtd, 0); + + w = snd_soc_dai_get_widget(dai, substream->stream); + swidget = w->dobj.private; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + snd_hdac_ext_link_stream_start(hext_stream); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + { + struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) + return ret; + + pipeline->state = SOF_IPC4_PIPE_PAUSED; + + snd_hdac_ext_link_stream_clear(hext_stream); + + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_RESET); + if (ret < 0) + return ret; + + pipeline->state = SOF_IPC4_PIPE_RESET; + + ret = hda_link_dma_cleanup(substream, hstream, cpu_dai, codec_dai, false); + if (ret < 0) { + dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); + return ret; + } + break; + } + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + { + struct snd_sof_widget *pipe_widget = swidget->pipe_widget; + struct sof_ipc4_pipeline *pipeline = pipe_widget->private; + + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) + return ret; + + pipeline->state = SOF_IPC4_PIPE_PAUSED; + + snd_hdac_ext_link_stream_clear(hext_stream); + break; + } + default: + dev_err(sdev->dev, "%s: unknown trigger command %d\n", __func__, cmd); + return -EINVAL; + } + + return 0; +} + static int hda_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -454,7 +542,7 @@ static const struct snd_soc_dai_ops ipc3_hda_dai_ops = { .hw_params = hda_dai_hw_params, .hw_free = hda_dai_hw_free, .trigger = ipc3_hda_dai_trigger, - .prepare = ipc3_hda_dai_prepare, + .prepare = hda_dai_prepare, }; static int hda_dai_suspend(struct hdac_bus *bus) @@ -497,6 +585,14 @@ static int hda_dai_suspend(struct hdac_bus *bus) return 0; } + +static const struct snd_soc_dai_ops ipc4_hda_dai_ops = { + .hw_params = hda_dai_hw_params, + .hw_free = hda_dai_hw_free, + .trigger = ipc4_hda_dai_trigger, + .prepare = hda_dai_prepare, +}; + #endif /* only one flag used so far to harden hw_params/hw_free/trigger/prepare */ @@ -608,6 +704,59 @@ static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { .shutdown = ssp_dai_shutdown, }; +static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_sof_widget *pipe_widget; + struct sof_ipc4_pipeline *pipeline; + struct snd_sof_widget *swidget; + struct snd_soc_dapm_widget *w; + struct snd_sof_dev *sdev; + int ret; + + w = snd_soc_dai_get_widget(dai, substream->stream); + swidget = w->dobj.private; + pipe_widget = swidget->pipe_widget; + pipeline = pipe_widget->private; + sdev = snd_soc_component_get_drvdata(swidget->scomp); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) + return ret; + pipeline->state = SOF_IPC4_PIPE_PAUSED; + + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_RESET); + if (ret < 0) + return ret; + pipeline->state = SOF_IPC4_PIPE_RESET; + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, + SOF_IPC4_PIPE_PAUSED); + if (ret < 0) + return ret; + pipeline->state = SOF_IPC4_PIPE_PAUSED; + break; + default: + break; + } + + return 0; +} + +static const struct snd_soc_dai_ops ipc4_dmic_dai_ops = { + .trigger = ipc4_be_dai_trigger, +}; + +static const struct snd_soc_dai_ops ipc4_ssp_dai_ops = { + .trigger = ipc4_be_dai_trigger, +}; + void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) { int i; @@ -624,6 +773,24 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) strstr(ops->drv[i].name, "Analog") || strstr(ops->drv[i].name, "Digital")) ops->drv[i].ops = &ipc3_hda_dai_ops; +#endif + } + break; + case SOF_INTEL_IPC4: + for (i = 0; i < ops->num_drv; i++) { + if (strstr(ops->drv[i].name, "DMIC")) { + ops->drv[i].ops = &ipc4_dmic_dai_ops; + continue; + } + if (strstr(ops->drv[i].name, "SSP")) { + ops->drv[i].ops = &ipc4_ssp_dai_ops; + continue; + } +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + if (strstr(ops->drv[i].name, "iDisp") || + strstr(ops->drv[i].name, "Analog") || + strstr(ops->drv[i].name, "Digital")) + ops->drv[i].ops = &ipc4_hda_dai_ops; #endif } break; -- GitLab From bc433fd76faefb8484f5bc653d846043822a2d35 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:37 -0700 Subject: [PATCH 460/942] ASoC: SOF: Add ops_free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the ops_free callback in struct sof_dev_desc. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-18-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof.h | 1 + sound/soc/sof/core.c | 7 ++++++- sound/soc/sof/ops.h | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/sound/sof.h b/include/sound/sof.h index 1a82a0db5e7f0..367dccfea7ade 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -138,6 +138,7 @@ struct sof_dev_desc { struct snd_sof_dsp_ops *ops; int (*ops_init)(struct snd_sof_dev *sdev); + void (*ops_free)(struct snd_sof_dev *sdev); }; int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd); diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 53719c04658ff..c99b5e6c026c1 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -189,7 +189,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) ret = snd_sof_probe(sdev); if (ret < 0) { dev_err(sdev->dev, "error: failed to probe DSP %d\n", ret); - return ret; + goto probe_err; } sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE); @@ -317,6 +317,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) snd_sof_free_debug(sdev); dsp_err: snd_sof_remove(sdev); +probe_err: + sof_ops_free(sdev); /* all resources freed, update state to match */ sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); @@ -374,6 +376,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) !sof_ops(sdev)->block_read || !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg || !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data) { + sof_ops_free(sdev); dev_err(dev, "error: missing mandatory ops\n"); return -EINVAL; } @@ -457,6 +460,8 @@ int snd_sof_device_remove(struct device *dev) snd_sof_remove(sdev); } + sof_ops_free(sdev); + /* release firmware */ snd_sof_fw_unload(sdev); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index b79ae4f66ebaa..55d43adb6a295 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -29,6 +29,12 @@ static inline int sof_ops_init(struct snd_sof_dev *sdev) return 0; } +static inline void sof_ops_free(struct snd_sof_dev *sdev) +{ + if (sdev->pdata->desc->ops_free) + sdev->pdata->desc->ops_free(sdev); +} + /* Mandatory operations are verified during probing */ /* init */ -- GitLab From 1da51943725f29000ae4d2be3b3b4bf8309d99a2 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:38 -0700 Subject: [PATCH 461/942] ASoC: SOF: Intel: hda: init NHLT for IPC4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Init and save the BIOS NHLT as part of the IPC4 FW data. Add a kernel module param to override the BIOS NHLT with the NHLT from the topology. Also, add the ops_free callback for all HDA platforms to free the NHLT. Co-developed-by: Jaska Uimonen Signed-off-by: Jaska Uimonen Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-19-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 28 ++++++++++++++++++++++++++++ sound/soc/sof/intel/hda.h | 1 + sound/soc/sof/intel/pci-apl.c | 1 + sound/soc/sof/intel/pci-cnl.c | 1 + sound/soc/sof/intel/pci-icl.c | 1 + sound/soc/sof/intel/pci-tgl.c | 1 + sound/soc/sof/ipc4-priv.h | 2 ++ 7 files changed, 35 insertions(+) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 5423667002e5a..228079a52c3d2 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include "../ipc4-priv.h" @@ -18,6 +19,14 @@ #include "../sof-audio.h" #include "hda.h" +/* + * The default method is to fetch NHLT from BIOS. With this parameter set + * it is possible to override that with NHLT in the SOF topology manifest. + */ +static bool hda_use_tplg_nhlt; +module_param_named(sof_use_tplg_nhlt, hda_use_tplg_nhlt, bool, 0444); +MODULE_PARM_DESC(sof_use_tplg_nhlt, "SOF topology nhlt override"); + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) struct hda_pipe_params { @@ -777,6 +786,9 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) } break; case SOF_INTEL_IPC4: + { + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + for (i = 0; i < ops->num_drv; i++) { if (strstr(ops->drv[i].name, "DMIC")) { ops->drv[i].ops = &ipc4_dmic_dai_ops; @@ -793,12 +805,28 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) ops->drv[i].ops = &ipc4_hda_dai_ops; #endif } + + if (!hda_use_tplg_nhlt) + ipc4_data->nhlt = intel_nhlt_init(sdev->dev); + break; + } default: break; } } +void hda_ops_free(struct snd_sof_dev *sdev) +{ + if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) { + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + + if (!hda_use_tplg_nhlt) + intel_nhlt_free(ipc4_data->nhlt); + } +} +EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON); + /* * common dai driver for skl+ platforms. * some products who use this DAI array only physically have a subset of diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 3e0f7b0c586a2..59181468e05e1 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -763,6 +763,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f extern int sof_hda_position_quirk; void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops); +void hda_ops_free(struct snd_sof_dev *sdev); /* IPC4 */ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context); diff --git a/sound/soc/sof/intel/pci-apl.c b/sound/soc/sof/intel/pci-apl.c index 2de3658eb8178..998e219011f01 100644 --- a/sound/soc/sof/intel/pci-apl.c +++ b/sound/soc/sof/intel/pci-apl.c @@ -44,6 +44,7 @@ static const struct sof_dev_desc bxt_desc = { .nocodec_tplg_filename = "sof-apl-nocodec.tplg", .ops = &sof_apl_ops, .ops_init = sof_apl_ops_init, + .ops_free = hda_ops_free, }; static const struct sof_dev_desc glk_desc = { diff --git a/sound/soc/sof/intel/pci-cnl.c b/sound/soc/sof/intel/pci-cnl.c index 87e587aef9c9d..c797356f7028b 100644 --- a/sound/soc/sof/intel/pci-cnl.c +++ b/sound/soc/sof/intel/pci-cnl.c @@ -73,6 +73,7 @@ static const struct sof_dev_desc cfl_desc = { .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", .ops = &sof_cnl_ops, .ops_init = sof_cnl_ops_init, + .ops_free = hda_ops_free, }; static const struct sof_dev_desc cml_desc = { diff --git a/sound/soc/sof/intel/pci-icl.c b/sound/soc/sof/intel/pci-icl.c index 1c7f16ce531e0..48f24f8ace261 100644 --- a/sound/soc/sof/intel/pci-icl.c +++ b/sound/soc/sof/intel/pci-icl.c @@ -45,6 +45,7 @@ static const struct sof_dev_desc icl_desc = { .nocodec_tplg_filename = "sof-icl-nocodec.tplg", .ops = &sof_icl_ops, .ops_init = sof_icl_ops_init, + .ops_free = hda_ops_free, }; static const struct sof_dev_desc jsl_desc = { diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c index 58a9bd92a2376..ccc44ba3ad94d 100644 --- a/sound/soc/sof/intel/pci-tgl.c +++ b/sound/soc/sof/intel/pci-tgl.c @@ -73,6 +73,7 @@ static const struct sof_dev_desc tglh_desc = { .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", .ops = &sof_tgl_ops, .ops_init = sof_tgl_ops_init, + .ops_free = hda_ops_free, }; static const struct sof_dev_desc ehl_desc = { diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index 8dddceaf5eb36..9492fe1796c2f 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -18,11 +18,13 @@ * @manifest_fw_hdr_offset: FW header offset in the manifest * @num_fw_modules : Number of modules in base FW * @fw_modules: Array of base FW modules + * @nhlt: NHLT table either from the BIOS or the topology manifest */ struct sof_ipc4_fw_data { u32 manifest_fw_hdr_offset; int num_fw_modules; void *fw_modules; + void *nhlt; }; /** -- GitLab From 4453d24d10fdd9e40c84673e3eda7701055081ea Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:39 -0700 Subject: [PATCH 462/942] ASoC: SOF: Add two new structures for topology manifest data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a couple of structures for parsing and saving the topology manifest data. Co-developed-by: Jaska Uimonen Signed-off-by: Jaska Uimonen Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-20-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- include/uapi/sound/sof/abi.h | 2 ++ include/uapi/sound/sof/header.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/uapi/sound/sof/abi.h b/include/uapi/sound/sof/abi.h index 0e7dccdc25fdd..c88f467374aec 100644 --- a/include/uapi/sound/sof/abi.h +++ b/include/uapi/sound/sof/abi.h @@ -24,6 +24,8 @@ #ifndef __INCLUDE_UAPI_SOUND_SOF_ABI_H__ #define __INCLUDE_UAPI_SOUND_SOF_ABI_H__ +#include + /* SOF ABI version major, minor and patch numbers */ #define SOF_ABI_MAJOR 3 #define SOF_ABI_MINOR 21 diff --git a/include/uapi/sound/sof/header.h b/include/uapi/sound/sof/header.h index 5f4518e7a9723..f125f7772ee7b 100644 --- a/include/uapi/sound/sof/header.h +++ b/include/uapi/sound/sof/header.h @@ -26,4 +26,34 @@ struct sof_abi_hdr { __u32 data[0]; /**< Component data - opaque to core */ } __packed; +#define SOF_MANIFEST_DATA_TYPE_NHLT 1 + +/** + * struct sof_manifest_tlv - SOF manifest TLV data + * @type: type of data + * @size: data size (not including the size of this struct) + * @data: payload data + */ +struct sof_manifest_tlv { + __le32 type; + __le32 size; + __u8 data[]; +}; + +/** + * struct sof_manifest - SOF topology manifest + * @abi_major: Major ABI version + * @abi_minor: Minor ABI version + * @abi_patch: ABI patch + * @count: count of tlv items + * @items: consecutive variable size tlv items + */ +struct sof_manifest { + __le16 abi_major; + __le16 abi_minor; + __le16 abi_patch; + __le16 count; + struct sof_manifest_tlv items[]; +}; + #endif -- GitLab From 323aa1f093e6113f78a8ae808c6c097663d8cb4c Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:40 -0700 Subject: [PATCH 463/942] ASoC: SOF: Add a new IPC op for parsing topology manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new topology IPC op, parse_manifest. Define and set the op for IPC4 and IPC4. Co-developed-by: Jaska Uimonen Signed-off-by: Jaska Uimonen Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-21-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 48 ++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.c | 63 +++++++++++++++++++++++++++++++++++ sound/soc/sof/sof-audio.h | 3 ++ sound/soc/sof/topology.c | 45 +++---------------------- 4 files changed, 118 insertions(+), 41 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 043554d7cb4a6..a91d7df3f07e2 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -17,6 +17,9 @@ /* Full volume for default values */ #define VOL_ZERO_DB BIT(VOLUME_FWL) +/* size of tplg ABI in bytes */ +#define SOF_IPC3_TPLG_ABI_SIZE 3 + struct sof_widget_data { int ctrl_type; int ipc_cmd; @@ -2303,6 +2306,50 @@ static int sof_ipc3_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *da return -EINVAL; } +static int sof_ipc3_parse_manifest(struct snd_soc_component *scomp, int index, + struct snd_soc_tplg_manifest *man) +{ + u32 size = le32_to_cpu(man->priv.size); + u32 abi_version; + + /* backward compatible with tplg without ABI info */ + if (!size) { + dev_dbg(scomp->dev, "No topology ABI info\n"); + return 0; + } + + if (size != SOF_IPC3_TPLG_ABI_SIZE) { + dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", + __func__, size); + return -EINVAL; + } + + dev_info(scomp->dev, + "Topology: ABI %d:%d:%d Kernel ABI %hhu:%hhu:%hhu\n", + man->priv.data[0], man->priv.data[1], man->priv.data[2], + SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH); + + abi_version = SOF_ABI_VER(man->priv.data[0], man->priv.data[1], man->priv.data[2]); + + if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { + dev_err(scomp->dev, "%s: Incompatible topology ABI version\n", __func__); + return -EINVAL; + } + + if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { + if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { + dev_warn(scomp->dev, "%s: Topology ABI is more recent than kernel\n", + __func__); + } else { + dev_err(scomp->dev, "%s: Topology ABI is more recent than kernel\n", + __func__); + return -EINVAL; + } + } + + return 0; +} + /* token list for each topology object */ static enum sof_tokens host_token_list[] = { SOF_CORE_TOKENS, @@ -2413,4 +2460,5 @@ const struct sof_ipc_tplg_ops ipc3_tplg_ops = { .dai_get_clk = sof_ipc3_dai_get_clk, .set_up_all_pipelines = sof_ipc3_set_up_all_pipelines, .tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines, + .parse_manifest = sof_ipc3_parse_manifest, }; diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 9615034f8c705..27ad48990383a 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -16,6 +16,7 @@ #include "ops.h" #define SOF_IPC4_GAIN_PARAM_ID 0 +#define SOF_IPC4_TPLG_ABI_SIZE 6 static const struct sof_topology_token ipc4_sched_tokens[] = { {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, @@ -1317,6 +1318,67 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * return 0; } +static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index, + struct snd_soc_tplg_manifest *man) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + struct sof_manifest_tlv *manifest_tlv; + struct sof_manifest *manifest; + u32 size = le32_to_cpu(man->priv.size); + u8 *man_ptr = man->priv.data; + u32 len_check; + int i; + + if (!size || size < SOF_IPC4_TPLG_ABI_SIZE) { + dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", + __func__, size); + return -EINVAL; + } + + manifest = (struct sof_manifest *)man_ptr; + + dev_info(scomp->dev, + "Topology: ABI %d:%d:%d Kernel ABI %u:%u:%u\n", + le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), + le16_to_cpu(manifest->abi_patch), + SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH); + + /* TODO: Add ABI compatibility check */ + + /* no more data after the ABI version */ + if (size <= SOF_IPC4_TPLG_ABI_SIZE) + return 0; + + manifest_tlv = manifest->items; + len_check = sizeof(struct sof_manifest); + for (i = 0; i < le16_to_cpu(manifest->count); i++) { + len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); + if (len_check > size) + return -EINVAL; + + switch (le32_to_cpu(manifest_tlv->type)) { + case SOF_MANIFEST_DATA_TYPE_NHLT: + /* no NHLT in BIOS, so use the one from topology manifest */ + if (ipc4_data->nhlt) + break; + ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, + le32_to_cpu(manifest_tlv->size), GFP_KERNEL); + if (!ipc4_data->nhlt) + return -ENOMEM; + break; + default: + dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", + manifest_tlv->type); + break; + } + man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); + manifest_tlv = (struct sof_manifest_tlv *)man_ptr; + } + + return 0; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1402,4 +1464,5 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .route_setup = sof_ipc4_route_setup, .route_free = sof_ipc4_route_free, .dai_config = sof_ipc4_dai_config, + .parse_manifest = sof_ipc4_parse_manifest, }; diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index d896da1192c5e..79486266081f4 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -168,6 +168,7 @@ struct sof_ipc_tplg_widget_ops { * @dai_get_clk: Function pointer for getting the DAI clock setting * @set_up_all_pipelines: Function pointer for setting up all topology pipelines * @tear_down_all_pipelines: Function pointer for tearing down all topology pipelines + * @parse_manifest: Optional function pointer for ipc4 specific parsing of topology manifest */ struct sof_ipc_tplg_ops { const struct sof_ipc_tplg_widget_ops *widget; @@ -185,6 +186,8 @@ struct sof_ipc_tplg_ops { int (*dai_get_clk)(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type); int (*set_up_all_pipelines)(struct snd_sof_dev *sdev, bool verify); int (*tear_down_all_pipelines)(struct snd_sof_dev *sdev, bool verify); + int (*parse_manifest)(struct snd_soc_component *scomp, int index, + struct snd_soc_tplg_manifest *man); }; /** struct snd_sof_tuple - Tuple info diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 606dbca942460..1893c590f2f01 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -36,9 +36,6 @@ #define TLV_STEP 1 #define TLV_MUTE 2 -/* size of tplg abi in byte */ -#define SOF_TPLG_ABI_SIZE 3 - /** * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the * token ID. @@ -2020,45 +2017,11 @@ static int sof_complete(struct snd_soc_component *scomp) static int sof_manifest(struct snd_soc_component *scomp, int index, struct snd_soc_tplg_manifest *man) { - u32 size; - u32 abi_version; - - size = le32_to_cpu(man->priv.size); - - /* backward compatible with tplg without ABI info */ - if (!size) { - dev_dbg(scomp->dev, "No topology ABI info\n"); - return 0; - } - - if (size != SOF_TPLG_ABI_SIZE) { - dev_err(scomp->dev, "error: invalid topology ABI size\n"); - return -EINVAL; - } - - dev_info(scomp->dev, - "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n", - man->priv.data[0], man->priv.data[1], - man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR, - SOF_ABI_PATCH); - - abi_version = SOF_ABI_VER(man->priv.data[0], - man->priv.data[1], - man->priv.data[2]); - - if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) { - dev_err(scomp->dev, "error: incompatible topology ABI version\n"); - return -EINVAL; - } + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + const struct sof_ipc_tplg_ops *ipc_tplg_ops = sdev->ipc->ops->tplg; - if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { - dev_warn(scomp->dev, "warn: topology ABI is more recent than kernel\n"); - } else { - dev_err(scomp->dev, "error: topology ABI is more recent than kernel\n"); - return -EINVAL; - } - } + if (ipc_tplg_ops->parse_manifest) + return ipc_tplg_ops->parse_manifest(scomp, index, man); return 0; } -- GitLab From aa84ffb721587d134702a1932f2c8793e8709df4 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:41 -0700 Subject: [PATCH 464/942] ASoC: SOF: ipc4-topology: Add support for SSP/DMIC DAI's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The copier config for SSP and DMIC type DAI copiers needs to be parsed and matched with the runtime hw_config from the NHLT table. Along with this, also add the change to set the node_id for these copier types. Co-developed-by: Jaska Uimonen Signed-off-by: Jaska Uimonen Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-22-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 148 ++++++++++++++++++++++++++++++++-- sound/soc/sof/ipc4-topology.h | 6 ++ 2 files changed, 146 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 27ad48990383a..9f055c187b728 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "sof-priv.h" #include "sof-audio.h" #include "ipc4-priv.h" @@ -473,14 +474,30 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); - ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); - if (!ipc4_copier->gtw_attr) { - ret = -ENOMEM; - goto err; - } - ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; - ipc4_copier->data.gtw_cfg.config_length = sizeof(struct sof_ipc4_gtw_attributes) >> 2; + switch (ipc4_copier->dai_type) { + case SOF_DAI_INTEL_SSP: + /* set SSP DAI index as the node_id */ + ipc4_copier->data.gtw_cfg.node_id |= + SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); + break; + case SOF_DAI_INTEL_DMIC: + /* set DMIC DAI index as the node_id */ + ipc4_copier->data.gtw_cfg.node_id |= + SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); + break; + default: + ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); + if (!ipc4_copier->gtw_attr) { + ret = -ENOMEM; + goto err; + } + + ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; + ipc4_copier->data.gtw_cfg.config_length = + sizeof(struct sof_ipc4_gtw_attributes) >> 2; + break; + } dai->scomp = scomp; dai->private = ipc4_copier; @@ -516,7 +533,9 @@ static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget) kfree(available_fmt->dma_buffer_size); kfree(available_fmt->base_config); kfree(available_fmt->out_audio_fmt); - kfree(ipc4_copier->copier_config); + if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && + ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) + kfree(ipc4_copier->copier_config); kfree(dai->private); kfree(dai); swidget->private = NULL; @@ -822,6 +841,112 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) ida_free(&fw_module->m_ida, swidget->instance_id); } +#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT) +static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, + int *sample_rate, int *channel_count, int *bit_depth) +{ + struct snd_soc_tplg_hw_config *hw_config; + struct snd_sof_dai_link *slink; + bool dai_link_found = false; + bool hw_cfg_found = false; + int i; + + /* get current hw_config from link */ + list_for_each_entry(slink, &sdev->dai_link_list, list) { + if (!strcmp(slink->link->name, dai->name)) { + dai_link_found = true; + break; + } + } + + if (!dai_link_found) { + dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); + return -EINVAL; + } + + for (i = 0; i < slink->num_hw_configs; i++) { + hw_config = &slink->hw_configs[i]; + if (dai->current_config == le32_to_cpu(hw_config->id)) { + hw_cfg_found = true; + break; + } + } + + if (!hw_cfg_found) { + dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, + dai->name); + return -EINVAL; + } + + *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); + *channel_count = le32_to_cpu(hw_config->tdm_slots); + *sample_rate = le32_to_cpu(hw_config->fsync_rate); + + dev_dbg(sdev->dev, "%s: sample rate: %d sample width: %d channels: %d\n", + __func__, *sample_rate, *bit_depth, *channel_count); + + return 0; +} + +static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, + struct snd_pcm_hw_params *params, u32 dai_index, + u32 linktype, u8 dir, u32 **dst, u32 *len) +{ + struct sof_ipc4_fw_data *ipc4_data = sdev->private; + struct nhlt_specific_cfg *cfg; + int sample_rate, channel_count; + int bit_depth, ret; + u32 nhlt_type; + + /* convert to NHLT type */ + switch (linktype) { + case SOF_DAI_INTEL_DMIC: + nhlt_type = NHLT_LINK_DMIC; + bit_depth = params_width(params); + channel_count = params_channels(params); + sample_rate = params_rate(params); + break; + case SOF_DAI_INTEL_SSP: + nhlt_type = NHLT_LINK_SSP; + ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count, + &bit_depth); + if (ret < 0) + return ret; + break; + default: + return 0; + } + + dev_dbg(sdev->dev, "%s: dai index %d nhlt type %d direction %d\n", + __func__, dai_index, nhlt_type, dir); + + /* find NHLT blob with matching params */ + cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, + bit_depth, bit_depth, channel_count, sample_rate, + dir, 0); + + if (!cfg) { + dev_err(sdev->dev, + "no matching blob for sample rate: %d sample width: %d channels: %d\n", + sample_rate, bit_depth, channel_count); + return -EINVAL; + } + + /* config length should be in dwords */ + *len = cfg->size >> 2; + *dst = (u32 *)cfg->caps; + + return 0; +} +#else +static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, + struct snd_pcm_hw_params *params, u32 dai_index, + u32 linktype, u8 dir, u32 **dst, u32 *len) +{ + return 0; +} +#endif + static int sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct snd_pcm_hw_params *fe_params, @@ -906,6 +1031,13 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ref_params = pipeline_params; + ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, fe_params, ipc4_copier->dai_index, + ipc4_copier->dai_type, dir, + &ipc4_copier->copier_config, + &copier_data->gtw_cfg.config_length); + if (ret < 0) + return ret; + break; } default: diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 0cadf04efa6a4..64d836f05bad8 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -31,6 +31,12 @@ #define SOF_IPC4_NODE_INDEX(x) ((x) & SOF_IPC4_NODE_INDEX_MASK) #define SOF_IPC4_NODE_TYPE(x) ((x) << 8) +/* Node ID for SSP type DAI copiers */ +#define SOF_IPC4_NODE_INDEX_INTEL_SSP(x) (((x) & 0xf) << 4) + +/* Node ID for DMIC type DAI copiers */ +#define SOF_IPC4_NODE_INDEX_INTEL_DMIC(x) (((x) & 0x7) << 5) + #define SOF_IPC4_GAIN_ALL_CHANNELS_MASK 0xffffffff #define SOF_IPC4_VOL_ZERO_DB 0x7fffffff -- GitLab From 9e2b5d33fec938ea2518735f2b66313cab89bb61 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 8 Jun 2022 20:26:42 -0700 Subject: [PATCH 465/942] AsoC: SOF: ipc4-topology: Add dai_get_clk op MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define and set the dai_get_clk_op for IPC4. Signed-off-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220609032643.916882-23-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 9f055c187b728..d5cb08ec1af13 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -1511,6 +1511,63 @@ static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index, return 0; } +static int sof_ipc4_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type) +{ + struct sof_ipc4_copier *ipc4_copier = dai->private; + struct snd_soc_tplg_hw_config *hw_config; + struct snd_sof_dai_link *slink; + bool dai_link_found = false; + bool hw_cfg_found = false; + int i; + + if (!ipc4_copier) + return 0; + + list_for_each_entry(slink, &sdev->dai_link_list, list) { + if (!strcmp(slink->link->name, dai->name)) { + dai_link_found = true; + break; + } + } + + if (!dai_link_found) { + dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); + return -EINVAL; + } + + for (i = 0; i < slink->num_hw_configs; i++) { + hw_config = &slink->hw_configs[i]; + if (dai->current_config == le32_to_cpu(hw_config->id)) { + hw_cfg_found = true; + break; + } + } + + if (!hw_cfg_found) { + dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); + return -EINVAL; + } + + switch (ipc4_copier->dai_type) { + case SOF_DAI_INTEL_SSP: + switch (clk_type) { + case SOF_DAI_CLK_INTEL_SSP_MCLK: + return le32_to_cpu(hw_config->mclk_rate); + case SOF_DAI_CLK_INTEL_SSP_BCLK: + return le32_to_cpu(hw_config->bclk_rate); + default: + dev_err(sdev->dev, "Invalid clk type for SSP %d\n", clk_type); + break; + } + break; + default: + dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); + break; + } + + return -EINVAL; +} + static enum sof_tokens host_token_list[] = { SOF_COMP_TOKENS, SOF_AUDIO_FMT_NUM_TOKENS, @@ -1597,4 +1654,5 @@ const struct sof_ipc_tplg_ops ipc4_tplg_ops = { .route_free = sof_ipc4_route_free, .dai_config = sof_ipc4_dai_config, .parse_manifest = sof_ipc4_parse_manifest, + .dai_get_clk = sof_ipc4_dai_get_clk, }; -- GitLab From a45a4d4390b7a562f8edc3518ba6cd2ad17be5bc Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 8 Jun 2022 20:26:43 -0700 Subject: [PATCH 466/942] ASoC: SOF: IPC4: add sdw blob Add IPC4 SoundWire blob. It includes a common IPC4 gateway and a multiple ALH configuration struct which is used for storing the aggregated SoundWire stream information. Signed-off-by: Bard Liao Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Signed-off-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609032643.916882-24-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 44 +++++++++++++++++++++++++++++++++++ sound/soc/sof/ipc4-topology.h | 25 ++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index d5cb08ec1af13..cb0f0823b8ebc 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -476,6 +476,20 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); switch (ipc4_copier->dai_type) { + case SOF_DAI_INTEL_ALH: + { + struct sof_ipc4_alh_configuration_blob *blob; + + blob = kzalloc(sizeof(*blob), GFP_KERNEL); + if (!blob) { + ret = -ENOMEM; + goto err; + } + + ipc4_copier->copier_config = (uint32_t *)blob; + ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; + break; + } case SOF_DAI_INTEL_SSP: /* set SSP DAI index as the node_id */ ipc4_copier->data.gtw_cfg.node_id |= @@ -1053,6 +1067,36 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, if (ret < 0) return ret; + switch (swidget->id) { + case snd_soc_dapm_dai_in: + case snd_soc_dapm_dai_out: + { + /* + * Only SOF_DAI_INTEL_ALH needs copier_data to set blob. + * That's why only ALH dai's blob is set after sof_ipc4_init_audio_fmt + */ + if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { + struct sof_ipc4_alh_configuration_blob *blob; + u32 ch_map; + int i; + + blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; + /* TODO: add aggregation mode support */ + blob->alh_cfg.count = 1; + blob->alh_cfg.mapping[0].alh_id = copier_data->gtw_cfg.node_id; + blob->gw_attr.lp_buffer_alloc = 0; + + /* Get channel_mask from ch_map */ + ch_map = copier_data->base_config.audio_fmt.ch_map; + for (i = 0; ch_map; i++) { + if ((ch_map & 0xf) != 0xf) + blob->alh_cfg.mapping[0].channel_mask |= BIT(i); + ch_map >>= 4; + } + } + } + } + /* modify the input params for the next widget */ fmt = hw_param_mask(pipeline_params, SNDRV_PCM_HW_PARAM_FORMAT); out_sample_valid_bits = diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 64d836f05bad8..1a9c0627bae9d 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -40,6 +40,8 @@ #define SOF_IPC4_GAIN_ALL_CHANNELS_MASK 0xffffffff #define SOF_IPC4_VOL_ZERO_DB 0x7fffffff +#define ALH_MAX_NUMBER_OF_GTW 16 + /** * struct sof_ipc4_pipeline - pipeline config data * @priority: Priority of this pipeline @@ -112,6 +114,29 @@ struct sof_ipc4_gtw_attributes { uint32_t rsvd : 30; }; +/** struct sof_ipc4_alh_multi_gtw_cfg: ALH gateway cfg data + * @count: Number of streams (valid items in mapping array) + * @alh_id: ALH stream id of a single ALH stream aggregated + * @channel_mask: Channel mask + * @mapping: ALH streams + */ +struct sof_ipc4_alh_multi_gtw_cfg { + uint32_t count; + struct { + uint32_t alh_id; + uint32_t channel_mask; + } mapping[ALH_MAX_NUMBER_OF_GTW]; +} __packed; + +/** struct sof_ipc4_alh_configuration_blob: ALH blob + * @gw_attr: Gateway attributes + * @alh_cfg: ALH configuration data + */ +struct sof_ipc4_alh_configuration_blob { + struct sof_ipc4_gtw_attributes gw_attr; + struct sof_ipc4_alh_multi_gtw_cfg alh_cfg; +}; + /** * struct sof_ipc4_copier - copier config data * @data: IPC copier data -- GitLab From 5babb012c847beb6c8c7108fd78f650b7a2c6054 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 9 Jun 2022 12:19:00 +0100 Subject: [PATCH 467/942] ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV move all the digital gains form using SX_TLV to S8_TLV, these gains are actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB rest of the Qualcomm wcd codecs uses these properly. Fixes: ef8a4757a6db ("ASoC: msm8916-wcd-digital: Add sidetone support") Fixes: 150db8c5afa1 ("ASoC: codecs: Add msm8916-wcd digital codec") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220609111901.318047-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-digital.c | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 20a07c92b2fc2..098a58990f07d 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -328,8 +328,8 @@ static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM( static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM( "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); -/* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ -static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); +/* Digital Gain control -84 dB to +40 dB in 1 dB steps */ +static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); /* Cutoff Freq for High Pass Filter at -3dB */ static const char * const hpf_cutoff_text[] = { @@ -510,15 +510,15 @@ static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN, - -128, 127, digital_gain), + -84, 40, digital_gain), SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum), SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum), SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0), @@ -553,22 +553,22 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3), WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4), WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5), - SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL, + -84, 40, digital_gain), }; -- GitLab From 2fbe0953732e06b471cdedbf6f615b84235580d8 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 9 Jun 2022 12:19:01 +0100 Subject: [PATCH 468/942] ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV move all the digital gains form using SX_TLV to S8_TLV, these gains are actually 8 bit gains with 7th signed bit and ranges from -84dB to +40dB rest of the Qualcomm wcd codecs uses these properly. Fixes: 8c4f021d806a ("ASoC: wcd9335: add basic controls") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220609111901.318047-3-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 81 +++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index e1b6930480842..4a982770dbab0 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -2253,51 +2253,42 @@ static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, static const struct snd_kcontrol_new wcd9335_snd_controls[] = { /* -84dB min - 40dB max */ - SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", - WCD9335_CDC_RX0_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", - WCD9335_CDC_RX1_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", - WCD9335_CDC_RX2_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", - WCD9335_CDC_RX3_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", - WCD9335_CDC_RX4_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", - WCD9335_CDC_RX5_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", - WCD9335_CDC_RX6_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", - WCD9335_CDC_RX7_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), - SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", - WCD9335_CDC_RX8_RX_VOL_MIX_CTL, - 0, -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, + -84, 40, digital_gain), + SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, + -84, 40, digital_gain), SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), -- GitLab From a43b4394bb35391b74486a788be6634ed91e221a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 9 Jun 2022 15:35:31 +0200 Subject: [PATCH 469/942] ASoC: codecs: rt274: Always init jack_detect_work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improves readability by making sure the work is always initialized. Signed-off-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220609133541.3984886-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt274.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index ab093bdb55523..a5615e94ec7d0 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -980,14 +980,11 @@ static int rt274_probe(struct snd_soc_component *component) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); rt274->component = component; + INIT_DELAYED_WORK(&rt274->jack_detect_work, rt274_jack_detect_work); - if (rt274->i2c->irq) { - INIT_DELAYED_WORK(&rt274->jack_detect_work, - rt274_jack_detect_work); + if (rt274->i2c->irq) schedule_delayed_work(&rt274->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } -- GitLab From 3082afe097cc5d794c28a629f3492a0133ee4891 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 9 Jun 2022 15:35:32 +0200 Subject: [PATCH 470/942] ASoC: codecs: rt286: Reorganize jack detect handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up in order to use and expose .set_jack callback. Signed-off-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220609133541.3984886-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 17 ++++++----------- sound/soc/codecs/rt286.h | 2 -- sound/soc/intel/boards/broadwell.c | 6 +++--- sound/soc/intel/boards/skl_rt286.c | 2 +- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index ad8ea1fa7c232..0534a073ee695 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -311,7 +311,8 @@ static void rt286_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt286_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); @@ -335,7 +336,6 @@ int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *j return 0; } -EXPORT_SYMBOL_GPL(rt286_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -947,17 +947,11 @@ static int rt286_probe(struct snd_soc_component *component) struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); rt286->component = component; + INIT_DELAYED_WORK(&rt286->jack_detect_work, rt286_jack_detect_work); - if (rt286->i2c->irq) { - regmap_update_bits(rt286->regmap, - RT286_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt286->jack_detect_work, - rt286_jack_detect_work); + if (rt286->i2c->irq) schedule_delayed_work(&rt286->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(50)); return 0; } @@ -1055,6 +1049,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt286 = { .suspend = rt286_suspend, .resume = rt286_resume, .set_bias_level = rt286_set_bias_level, + .set_jack = rt286_mic_detect, .controls = rt286_snd_controls, .num_controls = ARRAY_SIZE(rt286_snd_controls), .dapm_widgets = rt286_dapm_widgets, diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index f27a4e71d5b6f..4b7a3bd6043d7 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h @@ -196,7 +196,5 @@ enum { RT286_AIFS, }; -int rt286_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT286_H__ */ diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c index b29d77dfb2813..48bf3241b3e63 100644 --- a/sound/soc/intel/boards/broadwell.c +++ b/sound/soc/intel/boards/broadwell.c @@ -75,7 +75,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt286_mic_detect(component, &broadwell_headset); + snd_soc_component_set_jack(component, &broadwell_headset, NULL); return 0; } @@ -235,7 +235,7 @@ static void broadwell_disable_jack(struct snd_soc_card *card) if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); - rt286_mic_detect(component, NULL); + snd_soc_component_set_jack(component, NULL, NULL); break; } } @@ -255,7 +255,7 @@ static int broadwell_resume(struct snd_soc_card *card){ if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "enabling jack detect for resume.\n"); - rt286_mic_detect(component, &broadwell_headset); + snd_soc_component_set_jack(component, &broadwell_headset, NULL); break; } } diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index e9f9520dcea43..4f3d655e2bfa8 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -133,7 +133,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt286_mic_detect(component, &skylake_headset); + snd_soc_component_set_jack(component, &skylake_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); -- GitLab From 1eb73102da280b28bc3899f694e673bf3e4d0afd Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 9 Jun 2022 15:35:33 +0200 Subject: [PATCH 471/942] ASoC: codecs: rt298: Reorganize jack detect handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up in order to use and expose .set_jack callback. Signed-off-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220609133541.3984886-4-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 17 ++++++----------- sound/soc/codecs/rt298.h | 2 -- sound/soc/intel/boards/bxt_rt298.c | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index c291786dc82de..1a27e5e63289c 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -326,7 +326,8 @@ static void rt298_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt298_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); struct snd_soc_dapm_context *dapm; @@ -358,7 +359,6 @@ int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *j return 0; } -EXPORT_SYMBOL_GPL(rt298_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -1011,17 +1011,11 @@ static int rt298_probe(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); rt298->component = component; + INIT_DELAYED_WORK(&rt298->jack_detect_work, rt298_jack_detect_work); - if (rt298->i2c->irq) { - regmap_update_bits(rt298->regmap, - RT298_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt298->jack_detect_work, - rt298_jack_detect_work); + if (rt298->i2c->irq) schedule_delayed_work(&rt298->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } @@ -1120,6 +1114,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .suspend = rt298_suspend, .resume = rt298_resume, .set_bias_level = rt298_set_bias_level, + .set_jack = rt298_mic_detect, .controls = rt298_snd_controls, .num_controls = ARRAY_SIZE(rt298_snd_controls), .dapm_widgets = rt298_dapm_widgets, diff --git a/sound/soc/codecs/rt298.h b/sound/soc/codecs/rt298.h index ed2b8fd87f4c6..f1be9c1354012 100644 --- a/sound/soc/codecs/rt298.h +++ b/sound/soc/codecs/rt298.h @@ -207,7 +207,5 @@ enum { RT298_AIFS, }; -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack); - #endif /* __RT298_H__ */ diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 75995d17597d9..4bd93c3ba3777 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -176,7 +176,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - rt298_mic_detect(component, &broxton_headset); + snd_soc_component_set_jack(component, &broxton_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); -- GitLab From df4d27b19b892f464685ea45fa6132dd1a2b6864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 6 Jun 2022 21:19:09 +0200 Subject: [PATCH 472/942] ASoC: Introduce 'fixup_controls' card method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new method is called just before the card is registered, providing an opportune time for machine-level drivers to do some final controls amending: deactivating individual controls or obtaining control references for later use. Some controls can be created by DAPM after 'late_probe' has been called, hence the need for this new method. Signed-off-by: Martin Povišer Link: https://lore.kernel.org/r/20220606191910.16580-5-povik+lin@cutebit.org Signed-off-by: Mark Brown --- include/sound/soc-card.h | 1 + include/sound/soc.h | 1 + sound/soc/soc-card.c | 6 ++++++ sound/soc/soc-core.c | 1 + 4 files changed, 9 insertions(+) diff --git a/include/sound/soc-card.h b/include/sound/soc-card.h index df08573bd80cd..9d31a5c0db33c 100644 --- a/include/sound/soc-card.h +++ b/include/sound/soc-card.h @@ -29,6 +29,7 @@ int snd_soc_card_resume_post(struct snd_soc_card *card); int snd_soc_card_probe(struct snd_soc_card *card); int snd_soc_card_late_probe(struct snd_soc_card *card); +void snd_soc_card_fixup_controls(struct snd_soc_card *card); int snd_soc_card_remove(struct snd_soc_card *card); int snd_soc_card_set_bias_level(struct snd_soc_card *card, diff --git a/include/sound/soc.h b/include/sound/soc.h index f20f5f890794a..faef85e37e320 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -916,6 +916,7 @@ struct snd_soc_card { int (*probe)(struct snd_soc_card *card); int (*late_probe)(struct snd_soc_card *card); + void (*fixup_controls)(struct snd_soc_card *card); int (*remove)(struct snd_soc_card *card); /* the pre and post PM functions are used to do any PM work before and diff --git a/sound/soc/soc-card.c b/sound/soc/soc-card.c index 4158f5aacfd37..285ab4c9c7168 100644 --- a/sound/soc/soc-card.c +++ b/sound/soc/soc-card.c @@ -197,6 +197,12 @@ int snd_soc_card_late_probe(struct snd_soc_card *card) return 0; } +void snd_soc_card_fixup_controls(struct snd_soc_card *card) +{ + if (card->fixup_controls) + card->fixup_controls(card); +} + int snd_soc_card_remove(struct snd_soc_card *card) { int ret = 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 227540851dedf..57f7105c12b76 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2066,6 +2066,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card) goto probe_end; snd_soc_dapm_new_widgets(card); + snd_soc_card_fixup_controls(card); ret = snd_card_register(card->snd_card); if (ret < 0) { -- GitLab From 145cb4e7a9ee12326f99948d8980ad258462b6c4 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:04:21 +0300 Subject: [PATCH 473/942] ASoC: SOF: debug: Clarify the IPC timeout handling path The dmesg log message of "Firmware exception" causes lots of confusion as the snd_sof_handle_fw_exception() is only called in case of an IPC tx timeout, where such a message does not make much sense. To not limit the snd_sof_handle_fw_exception() handler to just one error case, add a parameter to allow the caller to specify a meaningful message to be printed. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Yaochun Hung Link: https://lore.kernel.org/r/20220610080421.31453-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/debug.c | 5 ++--- sound/soc/sof/ipc3.c | 2 +- sound/soc/sof/sof-priv.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index cf1271eb29b23..c5d797e97c027 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -428,7 +428,7 @@ static void snd_sof_ipc_dump(struct snd_sof_dev *sdev) } } -void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev) +void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg) { if (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT) || sof_debug_check_flag(SOF_DBG_RETAIN_CTX)) { @@ -441,8 +441,7 @@ void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev) /* dump vital information to the logs */ snd_sof_ipc_dump(sdev); - snd_sof_dsp_dbg_dump(sdev, "Firmware exception", - SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); + snd_sof_dsp_dbg_dump(sdev, msg, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); sof_fw_trace_fw_crashed(sdev); } EXPORT_SYMBOL(snd_sof_handle_fw_exception); diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index dff5feaad3703..ef8019e009b7e 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -290,7 +290,7 @@ static int ipc3_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data) dev_err(sdev->dev, "ipc tx timed out for %#x (msg/reply size: %d/%zu)\n", hdr->cmd, hdr->size, msg->reply_size); - snd_sof_handle_fw_exception(ipc->sdev); + snd_sof_handle_fw_exception(ipc->sdev, "IPC timeout"); ret = -ETIMEDOUT; } else { ret = msg->reply_error; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 9d7f53ff9c70e..32c152528f1d3 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -655,7 +655,7 @@ void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level, u32 panic_code, u32 tracep_code, void *oops, struct sof_ipc_panic_info *panic_info, void *stack, size_t stack_words); -void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev); +void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg); int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev); int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size, -- GitLab From c7b6c95c3ef37d7a0b28e62391bccfefdabd7a18 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 10 Jun 2022 10:12:45 +0300 Subject: [PATCH 474/942] ASoC: SOF: ipc3-dtrace: use pm_runtime_resume_and_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use pm_runtime_resume_and_get() to replace the pm_runtime_get_sync() and pm_runtime_put_noidle() pattern. No functional changes. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220610071245.26576-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index b4e1343f9138f..45bf9c5dc412d 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -157,9 +157,8 @@ static int ipc3_trace_update_filter(struct snd_sof_dev *sdev, int num_elems, msg->elem_cnt = num_elems; memcpy(&msg->elems[0], elems, num_elems * sizeof(*elems)); - ret = pm_runtime_get_sync(sdev->dev); + ret = pm_runtime_resume_and_get(sdev->dev); if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(sdev->dev); dev_err(sdev->dev, "enabling device failed: %d\n", ret); goto error; } -- GitLab From ce253b8573ce3de1278513395f07118650a49e39 Mon Sep 17 00:00:00 2001 From: Alejandro Tafalla Date: Thu, 9 Jun 2022 22:42:18 +0200 Subject: [PATCH 475/942] arm64/sysreg: Fix typo in Enum element regex In the awk script, there was a typo with the comparison operator when checking if the matched pattern is inside an Enum block. This prevented the generation of the whole sysreg-defs.h header. Fixes: 66847e0618d7 ("arm64: Add sysreg header generation scripting") Signed-off-by: Alejandro Tafalla Reviewed-by: Mark Brown Link: https://lore.kernel.org/r/20220609204220.12112-1-atafalla@dnyon.com Signed-off-by: Catalin Marinas --- arch/arm64/tools/gen-sysreg.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/tools/gen-sysreg.awk b/arch/arm64/tools/gen-sysreg.awk index 89bfb74e28de5..5c55509eb43f5 100755 --- a/arch/arm64/tools/gen-sysreg.awk +++ b/arch/arm64/tools/gen-sysreg.awk @@ -253,7 +253,7 @@ END { next } -/0b[01]+/ && block = "Enum" { +/0b[01]+/ && block == "Enum" { expect_fields(2) val = $1 name = $2 -- GitLab From bb314511b6dc0f863d6fb31ebae912ee96af7805 Mon Sep 17 00:00:00 2001 From: Xiang wangx Date: Fri, 10 Jun 2022 15:05:43 +0800 Subject: [PATCH 476/942] arm64/fpsimd: Fix typo in comment Delete the redundant word 'in'. Signed-off-by: Xiang wangx Link: https://lore.kernel.org/r/20220610070543.59338-1-wangxiang@cdjrlc.com Signed-off-by: Catalin Marinas --- arch/arm64/kernel/fpsimd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 819979398127e..f1d476fa50a9e 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -331,7 +331,7 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type, * trapping to the kernel. * * When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the - * corresponding Zn), P0-P15 and FFR are encoded in in + * corresponding Zn), P0-P15 and FFR are encoded in * task->thread.sve_state, formatted appropriately for vector * length task->thread.sve_vl or, if SVCR.SM is set, * task->thread.sme_vl. -- GitLab From 2e990e63220bb01e2755b55b93878ce7c8cbe747 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 14:41:32 +0200 Subject: [PATCH 477/942] arm64/sme: Fix EFI save/restore The EFI save/restore code is confused. When saving the check for saving FFR is inverted due to confusion with the streaming mode check, and when restoring we check if we need to restore FFR by checking the percpu efi_sm_state without the required wrapper rather than based on the combination of FA64 support and streaming mode. Fixes: e0838f6373e5 ("arm64/sme: Save and restore streaming mode over EFI runtime calls") Reported-by: kernel test robot Reviewed-by: Catalin Marinas Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602124132.3528951-1-broonie@kernel.org Signed-off-by: Catalin Marinas --- arch/arm64/kernel/fpsimd.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index f1d476fa50a9e..aecf3071efddd 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1916,10 +1916,15 @@ void __efi_fpsimd_begin(void) if (system_supports_sme()) { svcr = read_sysreg_s(SYS_SVCR); - if (!system_supports_fa64()) - ffr = svcr & SVCR_SM_MASK; + __this_cpu_write(efi_sm_state, + svcr & SVCR_SM_MASK); - __this_cpu_write(efi_sm_state, ffr); + /* + * Unless we have FA64 FFR does not + * exist in streaming mode. + */ + if (!system_supports_fa64()) + ffr = !(svcr & SVCR_SM_MASK); } sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()), @@ -1964,8 +1969,13 @@ void __efi_fpsimd_end(void) sysreg_clear_set_s(SYS_SVCR, 0, SVCR_SM_MASK); + + /* + * Unless we have FA64 FFR does not + * exist in streaming mode. + */ if (!system_supports_fa64()) - ffr = efi_sm_state; + ffr = false; } } -- GitLab From 46c80e72c16adff20f61240f887c4842e80cb6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Fri, 10 Jun 2022 14:42:57 +0200 Subject: [PATCH 478/942] ASoC: Intel: avs: Fix parsing UUIDs in topology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use correct type for parsing UUIDs, this eliminates warning present, when compiling with W=1. Fixes: 34ae2cd53673 ("ASoC: Intel: avs: Add topology parsing infrastructure") Reported-by: Pierre-Louis Bossart Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220610124257.4160658-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 0d11cc8aab0bd..6a06fe387d13b 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -128,10 +128,10 @@ struct avs_tplg_token_parser { static int avs_parse_uuid_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset) { - struct snd_soc_tplg_vendor_value_elem *tuple = elem; + struct snd_soc_tplg_vendor_uuid_elem *tuple = elem; guid_t *val = (guid_t *)((u8 *)object + offset); - guid_copy((guid_t *)val, (const guid_t *)&tuple->value); + guid_copy((guid_t *)val, (const guid_t *)&tuple->uuid); return 0; } -- GitLab From 81eef68f3bb78f5b3dc29032ffd804a4a2d7aaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Fri, 10 Jun 2022 14:44:20 +0200 Subject: [PATCH 479/942] ASoC: Remove unused hw_write_t type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 81da8a0b7975 ("ASoC: remove codec hw_write/control_data") removed use of hw_write_t in struct snd_soc_codec, but it left type definition. Fully clean it up. Fixes: 81da8a0b7975 ("ASoC: remove codec hw_write/control_data") Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220610124420.4160986-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- include/sound/soc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index f20f5f890794a..b276dcb5d4e8b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -408,8 +408,6 @@ struct snd_soc_jack_pin; struct snd_soc_jack_gpio; -typedef int (*hw_write_t)(void *,const char* ,int); - enum snd_soc_pcm_subclass { SND_SOC_PCM_CLASS_PCM = 0, SND_SOC_PCM_CLASS_BE = 1, -- GitLab From 6548c884a595391fab172faeae39e2b329b848f3 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 10 Jun 2022 15:48:18 +0100 Subject: [PATCH 480/942] ASoC: qdsp6: q6apm-dai: unprepare stream if its already prepared prepare callback can be called multiple times, so unprepare the stream if its already prepared. Without this DSP is not happy to setting the params on a already prepared graph. Fixes: 9b4fe0f1cd79 ("ASoC: qdsp6: audioreach: add q6apm-dai support") Reported-by: Srinivasa Rao Mandadapu Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220610144818.511797-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6apm-dai.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index 19c4a90ec1ea9..ee59ef36b85a6 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -147,6 +147,12 @@ static int q6apm_dai_prepare(struct snd_soc_component *component, cfg.num_channels = runtime->channels; cfg.bit_width = prtd->bits_per_sample; + if (prtd->state) { + /* clear the previous setup if any */ + q6apm_graph_stop(prtd->graph); + q6apm_unmap_memory_regions(prtd->graph, substream->stream); + } + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); prtd->pos = 0; /* rate and channels are sent to audio driver */ -- GitLab From 78cdaf3f4257ab10a6cec308ed774e7c7f7e5f72 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 10 Jun 2022 18:01:31 +0100 Subject: [PATCH 481/942] arm64: Add kasan_hw_tags_enable() prototype to silence sparse This function is only called from assembly, no need for a prototype declaration in a header file. In addition, add #ifdef around the function since it is only used when CONFIG_KASAN_HW_TAGS. Signed-off-by: Catalin Marinas Reported-by: kernel test robot --- arch/arm64/kernel/mte.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 57b30bcf9f21d..f6b00743c3994 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -244,6 +244,11 @@ static void mte_update_gcr_excl(struct task_struct *task) SYS_GCR_EL1); } +#ifdef CONFIG_KASAN_HW_TAGS +/* Only called from assembly, silence sparse */ +void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr, + __le32 *updptr, int nr_inst); + void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr, __le32 *updptr, int nr_inst) { @@ -252,6 +257,7 @@ void __init kasan_hw_tags_enable(struct alt_instr *alt, __le32 *origptr, if (kasan_hw_tags_enabled()) *updptr = cpu_to_le32(aarch64_insn_gen_nop()); } +#endif void mte_thread_init_user(void) { -- GitLab From 01aa6cbf3dafadd955d6e55eaa001861e8d356ab Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 6 Jun 2022 16:22:39 -0500 Subject: [PATCH 482/942] dt-bindings: pinctrl: ralink: Fix 'enum' lists with duplicate entries There's no reason to list the same value twice in an 'enum'. This was fixed treewide in commit c3b006819426 ("dt-bindings: Fix 'enum' lists with duplicate entries"), but this one got added in the merge window. A meta-schema change will catch future cases. Signed-off-by: Rob Herring Acked-by: Sergio Paracuellos Link: https://lore.kernel.org/r/20220606212239.1360877-1-robh@kernel.org --- .../pinctrl/ralink,mt7620-pinctrl.yaml | 26 +++++++++++------- .../pinctrl/ralink,rt305x-pinctrl.yaml | 27 +++++++++---------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/ralink,mt7620-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ralink,mt7620-pinctrl.yaml index 4d820df24b89f..6f17f39916400 100644 --- a/Documentation/devicetree/bindings/pinctrl/ralink,mt7620-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ralink,mt7620-pinctrl.yaml @@ -32,31 +32,37 @@ patternProperties: groups: description: The pin group to select. enum: [ + # common + i2c, spi, wdt, + # For MT7620 SoC - ephy, i2c, mdio, nd_sd, pa, pcie, rgmii1, rgmii2, spi, spi refclk, - uartf, uartlite, wdt, wled, + ephy, mdio, nd_sd, pa, pcie, rgmii1, rgmii2, spi refclk, + uartf, uartlite, wled, # For MT7628 and MT7688 SoCs - gpio, i2c, i2s, p0led_an, p0led_kn, p1led_an, p1led_kn, p2led_an, + gpio, i2s, p0led_an, p0led_kn, p1led_an, p1led_kn, p2led_an, p2led_kn, p3led_an, p3led_kn, p4led_an, p4led_kn, perst, pwm0, - pwm1, refclk, sdmode, spi, spi cs1, spis, uart0, uart1, uart2, - wdt, wled_an, wled_kn, + pwm1, refclk, sdmode, spi cs1, spis, uart0, uart1, uart2, + wled_an, wled_kn, ] function: description: The mux function to select. enum: [ + # common + gpio, i2c, refclk, spi, + # For MT7620 SoC - ephy, gpio, gpio i2s, gpio uartf, i2c, i2s uartf, mdio, nand, pa, - pcie refclk, pcie rst, pcm gpio, pcm i2s, pcm uartf, refclk, - rgmii1, rgmii2, sd, spi, spi refclk, uartf, uartlite, wdt refclk, + ephy, gpio i2s, gpio uartf, i2s uartf, mdio, nand, pa, + pcie refclk, pcie rst, pcm gpio, pcm i2s, pcm uartf, + rgmii1, rgmii2, sd, spi refclk, uartf, uartlite, wdt refclk, wdt rst, wled, # For MT7628 and MT7688 SoCs - antenna, debug, gpio, i2c, i2s, jtag, p0led_an, p0led_kn, + antenna, debug, i2s, jtag, p0led_an, p0led_kn, p1led_an, p1led_kn, p2led_an, p2led_kn, p3led_an, p3led_kn, p4led_an, p4led_kn, pcie, pcm, perst, pwm, pwm0, pwm1, pwm_uart2, - refclk, rsvd, sdxc, sdxc d5 d4, sdxc d6, sdxc d7, spi, spi cs1, + rsvd, sdxc, sdxc d5 d4, sdxc d6, sdxc d7, spi cs1, spis, sw_r, uart0, uart1, uart2, utif, wdt, wled_an, wled_kn, -, ] diff --git a/Documentation/devicetree/bindings/pinctrl/ralink,rt305x-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ralink,rt305x-pinctrl.yaml index 425401c542696..f602a5d6e13a6 100644 --- a/Documentation/devicetree/bindings/pinctrl/ralink,rt305x-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ralink,rt305x-pinctrl.yaml @@ -33,32 +33,29 @@ patternProperties: groups: description: The pin group to select. enum: [ + # common + i2c, jtag, led, mdio, rgmii, spi, spi_cs1, uartf, uartlite, + # For RT3050, RT3052 and RT3350 SoCs - i2c, jtag, mdio, rgmii, sdram, spi, uartf, uartlite, + sdram, # For RT3352 SoC - i2c, jtag, led, lna, mdio, pa, rgmii, spi, spi_cs1, uartf, - uartlite, - - # For RT5350 SoC - i2c, jtag, led, spi, spi_cs1, uartf, uartlite, + lna, pa ] function: description: The mux function to select. enum: [ + # common + gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, mdio, + pcm gpio, pcm i2s, pcm uartf, rgmii, spi, spi_cs1, uartf, + uartlite, wdg_cs1, + # For RT3050, RT3052 and RT3350 SoCs - gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, mdio, pcm gpio, - pcm i2s, pcm uartf, rgmii, sdram, spi, uartf, uartlite, + sdram, # For RT3352 SoC - gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, lna, mdio, - pa, pcm gpio, pcm i2s, pcm uartf, rgmii, spi, spi_cs1, uartf, - uartlite, wdg_cs1, - - # For RT5350 SoC - gpio, gpio i2s, gpio uartf, i2c, i2s uartf, jtag, led, pcm gpio, - pcm i2s, pcm uartf, spi, spi_cs1, uartf, uartlite, wdg_cs1, + lna, pa ] required: -- GitLab From 0b9431c8221cfe73d06f6b9cd37b813fa52be8ce Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 9 Jun 2022 17:27:29 +0100 Subject: [PATCH 483/942] dt-bindings: display: arm,malidp: remove bogus RQOS property As Liviu pointed out, the arm,malidp-arqos-high-level property mentioned in the original .txt binding was a mistake, and arm,malidp-arqos-value needs to take its place. The binding commit ce6eb0253cba ("dt/bindings: display: Add optional property node define for Mali DP500") mentions the right name in the commit message, but has the wrong name in the diff. Commit d298e6a27a81 ("drm/arm/mali-dp: Add display QoS interface configuration for Mali DP500") uses the property in the driver, but uses the shorter name. Remove the wrong property from the binding, and use the proper name in the example. The actual property was already documented properly. Fixes: 2c8b082a3ab1 ("dt-bindings: display: convert Arm Mali-DP to DT schema") Link: https://lore.kernel.org/linux-arm-kernel/YnumGEilUblhBx8E@e110455-lin.cambridge.arm.com/ Signed-off-by: Andre Przywara Reported-by: Liviu Dudau Reviewed-by: Liviu Dudau Signed-off-by: Rob Herring Link: https://lore.kernel.org/r/20220609162729.1441760-1-andre.przywara@arm.com --- Documentation/devicetree/bindings/display/arm,malidp.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/display/arm,malidp.yaml b/Documentation/devicetree/bindings/display/arm,malidp.yaml index 795a08ac9f128..2a17ec6fc97c0 100644 --- a/Documentation/devicetree/bindings/display/arm,malidp.yaml +++ b/Documentation/devicetree/bindings/display/arm,malidp.yaml @@ -71,11 +71,6 @@ properties: - description: number of output lines for the green channel (G) - description: number of output lines for the blue channel (B) - arm,malidp-arqos-high-level: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - integer describing the ARQoS levels of DP500's QoS signaling - arm,malidp-arqos-value: $ref: /schemas/types.yaml#/definitions/uint32 description: @@ -113,7 +108,7 @@ examples: clocks = <&oscclk2>, <&fpgaosc0>, <&fpgaosc1>, <&fpgaosc1>; clock-names = "pxlclk", "mclk", "aclk", "pclk"; arm,malidp-output-port-lines = /bits/ 8 <8 8 8>; - arm,malidp-arqos-high-level = <0xd000d000>; + arm,malidp-arqos-value = <0xd000d000>; port { dp0_output: endpoint { -- GitLab From d56fd98612aef73f85ec0c44e86fe04a9d3325ee Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 10 Jun 2022 19:35:55 +0100 Subject: [PATCH 484/942] certs: Convert spaces in certs/Makefile to a tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a rule in certs/Makefile for which the command begins with eight spaces. This results in: ../certs/Makefile:21: FORCE prerequisite is missing ../certs/Makefile:21: *** missing separator. Stop. Fix this by turning the spaces into a tab. Fixes: addf466389d9 ("certs: Check that builtin blacklist hashes are valid") Signed-off-by: David Howells Reviewed-by: Jarkko Sakkinen Reviewed-by: Mickaël Salaün cc: keyrings@vger.kernel.org Link: https://lore.kernel.org/r/486b1b80-9932-aab6-138d-434c541c934a@digikod.net/ # v1 Signed-off-by: Linus Torvalds --- certs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certs/Makefile b/certs/Makefile index bb904f90f1394..cb1a9da3fc581 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -18,7 +18,7 @@ CFLAGS_blacklist_hashes.o += -I$(srctree) targets += blacklist_hashes_checked $(obj)/blacklist_hashes_checked: $(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(SYSTEM_BLACKLIST_HASH_LIST_FILENAME) scripts/check-blacklist-hashes.awk FORCE - $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST)) + $(call if_changed,check_blacklist_hashes,$(SYSTEM_BLACKLIST_HASH_LIST_SRCPREFIX)$(CONFIG_SYSTEM_BLACKLIST_HASH_LIST)) obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o else obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o -- GitLab From a4c934d74e408cb5ea5209b5fdf6184e3e250b1b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 24 May 2022 09:15:44 +0200 Subject: [PATCH 485/942] platform/mellanox: Spelling s/platfom/platform/ Fix a misspelling of the word "platform". Signed-off-by: Geert Uytterhoeven Acked-by: Michael Shych Link: https://lore.kernel.org/r/9c8edde31e271311b7832d7677fe84aba917da8d.1653376503.git.geert@linux-m68k.org Signed-off-by: Hans de Goede --- drivers/platform/mellanox/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig index 72df4b8f4dd8b..09c7829e95c4b 100644 --- a/drivers/platform/mellanox/Kconfig +++ b/drivers/platform/mellanox/Kconfig @@ -85,7 +85,7 @@ config NVSW_SN2201 depends on I2C depends on REGMAP_I2C help - This driver provides support for the Nvidia SN2201 platfom. + This driver provides support for the Nvidia SN2201 platform. The SN2201 is a highly integrated for one rack unit system with L3 management switches. It has 48 x 1Gbps RJ45 + 4 x 100G QSFP28 ports in a compact 1RU form factor. The system also including a -- GitLab From dddf30564054796696bcd4c462b232a5beacf72c Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Fri, 10 Jun 2022 15:07:48 -0400 Subject: [PATCH 486/942] dm: fix zoned locking imbalance due to needless check in clone_endio After the commit ca522482e3ea ("dm: pass NULL bdev to bio_alloc_clone"), clone_endio() only calls dm_zone_endio() when DM targets remap the clone bio's bdev to something other than the md->disk->part0 default. However, if a DM target (e.g. dm-crypt) stacked ontop of a dm-zoned does not remap the clone bio using bio_set_dev() then dm_zone_endio() is not called at completion of the bios and zone locks are not properly unlocked. This triggers a hang, in dm_zone_map_bio(), when blktests block/004 is run for dm-crypt on zoned block devices. To avoid the hang, simply remove the clone_endio() check that verifies the target remapped the clone bio to a device other than the default. Fixes: ca522482e3ea ("dm: pass NULL bdev to bio_alloc_clone") Reported-by: Shin'ichiro Kawasaki Signed-off-by: Mike Snitzer --- drivers/md/dm.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 8b21155d3c4f5..d8f16183bf27c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1016,23 +1016,19 @@ static void clone_endio(struct bio *bio) struct dm_io *io = tio->io; struct mapped_device *md = io->md; - if (likely(bio->bi_bdev != md->disk->part0)) { - struct request_queue *q = bdev_get_queue(bio->bi_bdev); - - if (unlikely(error == BLK_STS_TARGET)) { - if (bio_op(bio) == REQ_OP_DISCARD && - !bdev_max_discard_sectors(bio->bi_bdev)) - disable_discard(md); - else if (bio_op(bio) == REQ_OP_WRITE_ZEROES && - !q->limits.max_write_zeroes_sectors) - disable_write_zeroes(md); - } - - if (static_branch_unlikely(&zoned_enabled) && - unlikely(blk_queue_is_zoned(q))) - dm_zone_endio(io, bio); + if (unlikely(error == BLK_STS_TARGET)) { + if (bio_op(bio) == REQ_OP_DISCARD && + !bdev_max_discard_sectors(bio->bi_bdev)) + disable_discard(md); + else if (bio_op(bio) == REQ_OP_WRITE_ZEROES && + !bdev_write_zeroes_sectors(bio->bi_bdev)) + disable_write_zeroes(md); } + if (static_branch_unlikely(&zoned_enabled) && + unlikely(blk_queue_is_zoned(bdev_get_queue(bio->bi_bdev)))) + dm_zone_endio(io, bio); + if (endio) { int r = endio(ti, bio, &error); switch (r) { -- GitLab From 102d841055be8e6e4e24d58917ffc04958262c4d Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 19 May 2022 08:40:12 +0100 Subject: [PATCH 487/942] afs: Fix some checker issues Remove an unused global variable and make another static as reported by make C=1. Signed-off-by: David Howells cc: linux-afs@lists.infradead.org --- fs/afs/volume.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/afs/volume.c b/fs/afs/volume.c index 94a3d247924bc..cc665cef0abe4 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -9,8 +9,7 @@ #include #include "internal.h" -unsigned __read_mostly afs_volume_gc_delay = 10; -unsigned __read_mostly afs_volume_record_life = 60 * 60; +static unsigned __read_mostly afs_volume_record_life = 60 * 60; /* * Insert a volume into a cell. If there's an existing volume record, that is -- GitLab From e81fb4198e27925b151aad1450e0fd607d6733f8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 9 Jun 2022 15:04:01 -0700 Subject: [PATCH 488/942] netfs: Further cleanups after struct netfs_inode wrapper introduced Change the signature of netfs helper functions to take a struct netfs_inode pointer rather than a struct inode pointer where appropriate, thereby relieving the need for the network filesystem to convert its internal inode format down to the VFS inode only for netfslib to bounce it back up. For type safety, it's better not to do that (and it's less typing too). Give netfs_write_begin() an extra argument to pass in a pointer to the netfs_inode struct rather than deriving it internally from the file pointer. Note that the ->write_begin() and ->write_end() ops are intended to be replaced in the future by netfslib code that manages this without the need to call in twice for each page. netfs_readpage() and similar are intended to be pointed at directly by the address_space_operations table, so must stick to the signature dictated by the function pointers there. Changes ======= - Updated the kerneldoc comments and documentation [DH]. Signed-off-by: David Howells cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/CAHk-=wgkwKyNmNdKpQkqZ6DnmUL-x9hp0YBnUGjaPFEAdxDTbw@mail.gmail.com/ --- Documentation/filesystems/netfs_library.rst | 9 +++++---- fs/9p/v9fs.h | 2 +- fs/9p/vfs_addr.c | 2 +- fs/9p/vfs_inode.c | 3 ++- fs/afs/dynroot.c | 2 +- fs/afs/inode.c | 2 +- fs/afs/internal.h | 2 +- fs/afs/write.c | 2 +- fs/ceph/addr.c | 3 ++- fs/ceph/cache.h | 2 +- fs/ceph/inode.c | 2 +- fs/cifs/fscache.h | 2 +- fs/netfs/buffered_read.c | 5 +++-- include/linux/netfs.h | 22 +++++++++------------ 14 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst index 3276c3d551426..9332f66373eee 100644 --- a/Documentation/filesystems/netfs_library.rst +++ b/Documentation/filesystems/netfs_library.rst @@ -79,7 +79,7 @@ To help deal with the per-inode context, a number helper functions are provided. Firstly, a function to perform basic initialisation on a context and set the operations table pointer:: - void netfs_inode_init(struct inode *inode, + void netfs_inode_init(struct netfs_inode *ctx, const struct netfs_request_ops *ops); then a function to cast from the VFS inode structure to the netfs context:: @@ -89,7 +89,7 @@ then a function to cast from the VFS inode structure to the netfs context:: and finally, a function to get the cache cookie pointer from the context attached to an inode (or NULL if fscache is disabled):: - struct fscache_cookie *netfs_i_cookie(struct inode *inode); + struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx); Buffered Read Helpers @@ -136,8 +136,9 @@ Three read helpers are provided:: void netfs_readahead(struct readahead_control *ractl); int netfs_read_folio(struct file *file, - struct folio *folio); - int netfs_write_begin(struct file *file, + struct folio *folio); + int netfs_write_begin(struct netfs_inode *ctx, + struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 1b219c21d15eb..6acabc2e7dc9d 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h @@ -124,7 +124,7 @@ static inline struct v9fs_inode *V9FS_I(const struct inode *inode) static inline struct fscache_cookie *v9fs_inode_cookie(struct v9fs_inode *v9inode) { #ifdef CONFIG_9P_FSCACHE - return netfs_i_cookie(&v9inode->netfs.inode); + return netfs_i_cookie(&v9inode->netfs); #else return NULL; #endif diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 90c6c1ba03ab7..c004b9a73a924 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -274,7 +274,7 @@ static int v9fs_write_begin(struct file *filp, struct address_space *mapping, * file. We need to do this before we get a lock on the page in case * there's more than one writer competing for the same cache block. */ - retval = netfs_write_begin(filp, mapping, pos, len, &folio, fsdata); + retval = netfs_write_begin(&v9inode->netfs, filp, mapping, pos, len, &folio, fsdata); if (retval < 0) return retval; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index e660c6348b9da..419d2f3cf2c26 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -252,7 +252,8 @@ void v9fs_free_inode(struct inode *inode) */ static void v9fs_set_netfs_context(struct inode *inode) { - netfs_inode_init(inode, &v9fs_req_ops); + struct v9fs_inode *v9inode = V9FS_I(inode); + netfs_inode_init(&v9inode->netfs, &v9fs_req_ops); } int v9fs_init_inode(struct v9fs_session_info *v9ses, diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c index 3a5bbffdf0534..d7d9402ff7182 100644 --- a/fs/afs/dynroot.c +++ b/fs/afs/dynroot.c @@ -76,7 +76,7 @@ struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root) /* there shouldn't be an existing inode */ BUG_ON(!(inode->i_state & I_NEW)); - netfs_inode_init(inode, NULL); + netfs_inode_init(&vnode->netfs, NULL); inode->i_size = 0; inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; if (root) { diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 22811e9eacf58..89630acbc2cc5 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c @@ -58,7 +58,7 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren */ static void afs_set_netfs_context(struct afs_vnode *vnode) { - netfs_inode_init(&vnode->netfs.inode, &afs_req_ops); + netfs_inode_init(&vnode->netfs, &afs_req_ops); } /* diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 984b113a91075..a6f25d9e75b52 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -670,7 +670,7 @@ struct afs_vnode { static inline struct fscache_cookie *afs_vnode_cache(struct afs_vnode *vnode) { #ifdef CONFIG_AFS_FSCACHE - return netfs_i_cookie(&vnode->netfs.inode); + return netfs_i_cookie(&vnode->netfs); #else return NULL; #endif diff --git a/fs/afs/write.c b/fs/afs/write.c index f80a6096d91c7..2c885b22de34f 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -60,7 +60,7 @@ int afs_write_begin(struct file *file, struct address_space *mapping, * file. We need to do this before we get a lock on the page in case * there's more than one writer competing for the same cache block. */ - ret = netfs_write_begin(file, mapping, pos, len, &folio, fsdata); + ret = netfs_write_begin(&vnode->netfs, file, mapping, pos, len, &folio, fsdata); if (ret < 0) return ret; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index f5f116ed1b9e9..9763e7ea8148e 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -1322,10 +1322,11 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) { struct inode *inode = file_inode(file); + struct ceph_inode_info *ci = ceph_inode(inode); struct folio *folio = NULL; int r; - r = netfs_write_begin(file, inode->i_mapping, pos, len, &folio, NULL); + r = netfs_write_begin(&ci->netfs, file, inode->i_mapping, pos, len, &folio, NULL); if (r == 0) folio_wait_fscache(folio); if (r < 0) { diff --git a/fs/ceph/cache.h b/fs/ceph/cache.h index 26c6ae06e2f41..dc502daac49ab 100644 --- a/fs/ceph/cache.h +++ b/fs/ceph/cache.h @@ -28,7 +28,7 @@ void ceph_fscache_invalidate(struct inode *inode, bool dio_write); static inline struct fscache_cookie *ceph_fscache_cookie(struct ceph_inode_info *ci) { - return netfs_i_cookie(&ci->netfs.inode); + return netfs_i_cookie(&ci->netfs); } static inline void ceph_fscache_resize(struct inode *inode, loff_t to) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 650746b3ba999..56c53ab3618e8 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -460,7 +460,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb) dout("alloc_inode %p\n", &ci->netfs.inode); /* Set parameters for the netfs library */ - netfs_inode_init(&ci->netfs.inode, &ceph_netfs_ops); + netfs_inode_init(&ci->netfs, &ceph_netfs_ops); spin_lock_init(&ci->i_ceph_lock); diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h index ab9a51d0125cd..aa3b941a55557 100644 --- a/fs/cifs/fscache.h +++ b/fs/cifs/fscache.h @@ -61,7 +61,7 @@ void cifs_fscache_fill_coherency(struct inode *inode, static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { - return netfs_i_cookie(inode); + return netfs_i_cookie(&CIFS_I(inode)->netfs); } static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c index d37e012386f34..42f892c5712ea 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -297,6 +297,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len, /** * netfs_write_begin - Helper to prepare for writing + * @ctx: The netfs context * @file: The file to read from * @mapping: The mapping to read from * @pos: File position at which the write will begin @@ -326,12 +327,12 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len, * * This is usable whether or not caching is enabled. */ -int netfs_write_begin(struct file *file, struct address_space *mapping, +int netfs_write_begin(struct netfs_inode *ctx, + struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, struct folio **_folio, void **_fsdata) { struct netfs_io_request *rreq; - struct netfs_inode *ctx = netfs_inode(file_inode(file )); struct folio *folio; unsigned int fgp_flags = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE; pgoff_t index = pos >> PAGE_SHIFT; diff --git a/include/linux/netfs.h b/include/linux/netfs.h index 6dbb4c9ce50d7..a62739f3726b3 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -277,7 +277,8 @@ struct netfs_cache_ops { struct readahead_control; extern void netfs_readahead(struct readahead_control *); int netfs_read_folio(struct file *, struct folio *); -extern int netfs_write_begin(struct file *, struct address_space *, +extern int netfs_write_begin(struct netfs_inode *, + struct file *, struct address_space *, loff_t, unsigned int, struct folio **, void **); @@ -302,19 +303,17 @@ static inline struct netfs_inode *netfs_inode(struct inode *inode) /** * netfs_inode_init - Initialise a netfslib inode context - * @inode: The inode with which the context is associated + * @inode: The netfs inode to initialise * @ops: The netfs's operations list * * Initialise the netfs library context struct. This is expected to follow on * directly from the VFS inode struct. */ -static inline void netfs_inode_init(struct inode *inode, +static inline void netfs_inode_init(struct netfs_inode *ctx, const struct netfs_request_ops *ops) { - struct netfs_inode *ctx = netfs_inode(inode); - ctx->ops = ops; - ctx->remote_i_size = i_size_read(inode); + ctx->remote_i_size = i_size_read(&ctx->inode); #if IS_ENABLED(CONFIG_FSCACHE) ctx->cache = NULL; #endif @@ -322,28 +321,25 @@ static inline void netfs_inode_init(struct inode *inode, /** * netfs_resize_file - Note that a file got resized - * @inode: The inode being resized + * @ctx: The netfs inode being resized * @new_i_size: The new file size * * Inform the netfs lib that a file got resized so that it can adjust its state. */ -static inline void netfs_resize_file(struct inode *inode, loff_t new_i_size) +static inline void netfs_resize_file(struct netfs_inode *ctx, loff_t new_i_size) { - struct netfs_inode *ctx = netfs_inode(inode); - ctx->remote_i_size = new_i_size; } /** * netfs_i_cookie - Get the cache cookie from the inode - * @inode: The inode to query + * @ctx: The netfs inode to query * * Get the caching cookie (if enabled) from the network filesystem's inode. */ -static inline struct fscache_cookie *netfs_i_cookie(struct inode *inode) +static inline struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx) { #if IS_ENABLED(CONFIG_FSCACHE) - struct netfs_inode *ctx = netfs_inode(inode); return ctx->cache; #else return NULL; -- GitLab From 40a81101202300df7db273f77dda9fbe6271b1d2 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 25 Feb 2022 11:19:14 +0000 Subject: [PATCH 489/942] netfs: Rename the netfs_io_request cleanup op and give it an op pointer The netfs_io_request cleanup op is now always in a position to be given a pointer to a netfs_io_request struct, so this can be passed in instead of the mapping and private data arguments (both of which are included in the struct). So rename the ->cleanup op to ->free_request (to match ->init_request) and pass in the I/O pointer. Signed-off-by: David Howells Reviewed-by: Jeff Layton cc: linux-cachefs@redhat.com --- Documentation/filesystems/netfs_library.rst | 24 ++++++++++----------- fs/9p/vfs_addr.c | 11 +++++----- fs/afs/file.c | 6 +++--- fs/ceph/addr.c | 9 ++++---- fs/netfs/objects.c | 6 +++--- include/linux/netfs.h | 3 ++- 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/Documentation/filesystems/netfs_library.rst b/Documentation/filesystems/netfs_library.rst index 9332f66373eee..4d19b19bcc086 100644 --- a/Documentation/filesystems/netfs_library.rst +++ b/Documentation/filesystems/netfs_library.rst @@ -158,9 +158,10 @@ The helpers manage the read request, calling back into the network filesystem through the suppplied table of operations. Waits will be performed as necessary before returning for helpers that are meant to be synchronous. -If an error occurs and netfs_priv is non-NULL, ops->cleanup() will be called to -deal with it. If some parts of the request are in progress when an error -occurs, the request will get partially completed if sufficient data is read. +If an error occurs, the ->free_request() will be called to clean up the +netfs_io_request struct allocated. If some parts of the request are in +progress when an error occurs, the request will get partially completed if +sufficient data is read. Additionally, there is:: @@ -208,8 +209,7 @@ The above fields are the ones the netfs can use. They are: * ``netfs_priv`` The network filesystem's private data. The value for this can be passed in - to the helper functions or set during the request. The ->cleanup() op will - be called if this is non-NULL at the end. + to the helper functions or set during the request. * ``start`` * ``len`` @@ -294,6 +294,7 @@ through which it can issue requests and negotiate:: struct netfs_request_ops { void (*init_request)(struct netfs_io_request *rreq, struct file *file); + void (*free_request)(struct netfs_io_request *rreq); int (*begin_cache_operation)(struct netfs_io_request *rreq); void (*expand_readahead)(struct netfs_io_request *rreq); bool (*clamp_length)(struct netfs_io_subrequest *subreq); @@ -302,7 +303,6 @@ through which it can issue requests and negotiate:: int (*check_write_begin)(struct file *file, loff_t pos, unsigned len, struct folio *folio, void **_fsdata); void (*done)(struct netfs_io_request *rreq); - void (*cleanup)(struct address_space *mapping, void *netfs_priv); }; The operations are as follows: @@ -310,7 +310,12 @@ The operations are as follows: * ``init_request()`` [Optional] This is called to initialise the request structure. It is given - the file for reference and can modify the ->netfs_priv value. + the file for reference. + + * ``free_request()`` + + [Optional] This is called as the request is being deallocated so that the + filesystem can clean up any state it has attached there. * ``begin_cache_operation()`` @@ -384,11 +389,6 @@ The operations are as follows: [Optional] This is called after the folios in the request have all been unlocked (and marked uptodate if applicable). - * ``cleanup`` - - [Optional] This is called as the request is being deallocated so that the - filesystem can clean up ->netfs_priv. - Read Helper Procedure diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index c004b9a73a924..a8f512b44a851 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -66,13 +66,12 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file) } /** - * v9fs_req_cleanup - Cleanup request initialized by v9fs_init_request - * @mapping: unused mapping of request to cleanup - * @priv: private data to cleanup, a fid, guaranted non-null. + * v9fs_free_request - Cleanup request initialized by v9fs_init_rreq + * @rreq: The I/O request to clean up */ -static void v9fs_req_cleanup(struct address_space *mapping, void *priv) +static void v9fs_free_request(struct netfs_io_request *rreq) { - struct p9_fid *fid = priv; + struct p9_fid *fid = rreq->netfs_priv; p9_client_clunk(fid); } @@ -94,9 +93,9 @@ static int v9fs_begin_cache_operation(struct netfs_io_request *rreq) const struct netfs_request_ops v9fs_req_ops = { .init_request = v9fs_init_request, + .free_request = v9fs_free_request, .begin_cache_operation = v9fs_begin_cache_operation, .issue_read = v9fs_issue_read, - .cleanup = v9fs_req_cleanup, }; /** diff --git a/fs/afs/file.c b/fs/afs/file.c index 4de7af7c2f09e..42118a4f33833 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -382,17 +382,17 @@ static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len, return test_bit(AFS_VNODE_DELETED, &vnode->flags) ? -ESTALE : 0; } -static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv) +static void afs_free_request(struct netfs_io_request *rreq) { - key_put(netfs_priv); + key_put(rreq->netfs_priv); } const struct netfs_request_ops afs_req_ops = { .init_request = afs_init_request, + .free_request = afs_free_request, .begin_cache_operation = afs_begin_cache_operation, .check_write_begin = afs_check_write_begin, .issue_read = afs_issue_read, - .cleanup = afs_priv_cleanup, }; int afs_write_inode(struct inode *inode, struct writeback_control *wbc) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 9763e7ea8148e..6dee88815491c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -394,11 +394,10 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file) return 0; } -static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) +static void ceph_netfs_free_request(struct netfs_io_request *rreq) { - struct inode *inode = mapping->host; - struct ceph_inode_info *ci = ceph_inode(inode); - int got = (uintptr_t)priv; + struct ceph_inode_info *ci = ceph_inode(rreq->inode); + int got = (uintptr_t)rreq->netfs_priv; if (got) ceph_put_cap_refs(ci, got); @@ -406,12 +405,12 @@ static void ceph_readahead_cleanup(struct address_space *mapping, void *priv) const struct netfs_request_ops ceph_netfs_ops = { .init_request = ceph_init_request, + .free_request = ceph_netfs_free_request, .begin_cache_operation = ceph_begin_cache_operation, .issue_read = ceph_netfs_issue_read, .expand_readahead = ceph_netfs_expand_readahead, .clamp_length = ceph_netfs_clamp_length, .check_write_begin = ceph_netfs_check_write_begin, - .cleanup = ceph_readahead_cleanup, }; #ifdef CONFIG_CEPH_FSCACHE diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c index c6afa605b63b8..e17cdf53f6a78 100644 --- a/fs/netfs/objects.c +++ b/fs/netfs/objects.c @@ -75,10 +75,10 @@ static void netfs_free_request(struct work_struct *work) struct netfs_io_request *rreq = container_of(work, struct netfs_io_request, work); - netfs_clear_subrequests(rreq, false); - if (rreq->netfs_priv) - rreq->netfs_ops->cleanup(rreq->mapping, rreq->netfs_priv); trace_netfs_rreq(rreq, netfs_rreq_trace_free); + netfs_clear_subrequests(rreq, false); + if (rreq->netfs_ops->free_request) + rreq->netfs_ops->free_request(rreq); if (rreq->cache_resources.ops) rreq->cache_resources.ops->end_operation(&rreq->cache_resources); kfree(rreq); diff --git a/include/linux/netfs.h b/include/linux/netfs.h index a62739f3726b3..097cdd6446652 100644 --- a/include/linux/netfs.h +++ b/include/linux/netfs.h @@ -206,7 +206,9 @@ struct netfs_io_request { */ struct netfs_request_ops { int (*init_request)(struct netfs_io_request *rreq, struct file *file); + void (*free_request)(struct netfs_io_request *rreq); int (*begin_cache_operation)(struct netfs_io_request *rreq); + void (*expand_readahead)(struct netfs_io_request *rreq); bool (*clamp_length)(struct netfs_io_subrequest *subreq); void (*issue_read)(struct netfs_io_subrequest *subreq); @@ -214,7 +216,6 @@ struct netfs_request_ops { int (*check_write_begin)(struct file *file, loff_t pos, unsigned len, struct folio *folio, void **_fsdata); void (*done)(struct netfs_io_request *rreq); - void (*cleanup)(struct address_space *mapping, void *netfs_priv); }; /* -- GitLab From 6c77676645ad42993e0a8bdb8dafa517851a352a Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 9 Jun 2022 09:07:01 +0100 Subject: [PATCH 490/942] iov_iter: Fix iter_xarray_get_pages{,_alloc}() The maths at the end of iter_xarray_get_pages() to calculate the actual size doesn't work under some circumstances, such as when it's been asked to extract a partial single page. Various terms of the equation cancel out and you end up with actual == offset. The same issue exists in iter_xarray_get_pages_alloc(). Fix these to just use min() to select the lesser amount from between the amount of page content transcribed into the buffer, minus the offset, and the size limit specified. This doesn't appear to have caused a problem yet upstream because network filesystems aren't getting the pages from an xarray iterator, but rather passing it directly to the socket, which just iterates over it. Cachefiles *does* do DIO from one to/from ext4/xfs/btrfs/etc. but it always asks for whole pages to be written or read. Fixes: 7ff5062079ef ("iov_iter: Add ITER_XARRAY") Reported-by: Jeff Layton Signed-off-by: David Howells cc: Alexander Viro cc: Dominique Martinet cc: Mike Marshall cc: Gao Xiang cc: linux-afs@lists.infradead.org cc: v9fs-developer@lists.sourceforge.net cc: devel@lists.orangefs.org cc: linux-erofs@lists.ozlabs.org cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org Signed-off-by: Al Viro --- lib/iov_iter.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 6dd5330f7a995..dda6d5f481c1c 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1434,7 +1434,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i, { unsigned nr, offset; pgoff_t index, count; - size_t size = maxsize, actual; + size_t size = maxsize; loff_t pos; if (!size || !maxpages) @@ -1461,13 +1461,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i, if (nr == 0) return 0; - actual = PAGE_SIZE * nr; - actual -= offset; - if (nr == count && size > 0) { - unsigned last_offset = (nr > 1) ? 0 : offset; - actual -= PAGE_SIZE - (last_offset + size); - } - return actual; + return min(nr * PAGE_SIZE - offset, maxsize); } /* must be done on non-empty ITER_IOVEC one */ @@ -1602,7 +1596,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i, struct page **p; unsigned nr, offset; pgoff_t index, count; - size_t size = maxsize, actual; + size_t size = maxsize; loff_t pos; if (!size) @@ -1631,13 +1625,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i, if (nr == 0) return 0; - actual = PAGE_SIZE * nr; - actual -= offset; - if (nr == count && size > 0) { - unsigned last_offset = (nr > 1) ? 0 : offset; - actual -= PAGE_SIZE - (last_offset + size); - } - return actual; + return min(nr * PAGE_SIZE - offset, maxsize); } ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, -- GitLab From b9c29f391f4195a778620f3d2efd0d9746a414fe Mon Sep 17 00:00:00 2001 From: Michael Shych Date: Thu, 2 Jun 2022 17:51:03 +0300 Subject: [PATCH 491/942] platform/mellanox: Add static in struct declaration. Fix problem of missing static in struct declaration. Fixes: 662f24826f954 ("platform/mellanox: Add support for new SN2201 system") Reported-by: kernel test robot Signed-off-by: Michael Shych Link: https://lore.kernel.org/r/20220602145103.11859-1-michaelsh@nvidia.com Signed-off-by: Hans de Goede --- drivers/platform/mellanox/nvsw-sn2201.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/mellanox/nvsw-sn2201.c b/drivers/platform/mellanox/nvsw-sn2201.c index 0bcdc7c75007d..2923daf63b75d 100644 --- a/drivers/platform/mellanox/nvsw-sn2201.c +++ b/drivers/platform/mellanox/nvsw-sn2201.c @@ -326,7 +326,7 @@ static struct resource nvsw_sn2201_lpc_res[] = { }; /* SN2201 I2C platform data. */ -struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = { +static struct mlxreg_core_hotplug_platform_data nvsw_sn2201_i2c_data = { .irq = NVSW_SN2201_CPLD_SYSIRQ, }; -- GitLab From 66cb3a2d7ad0d0e9af4d3430a4f2a32ffb9ac098 Mon Sep 17 00:00:00 2001 From: David Arcari Date: Thu, 26 May 2022 16:31:40 -0400 Subject: [PATCH 492/942] platform/x86/intel: Fix pmt_crashlog array reference The probe function pmt_crashlog_probe() may incorrectly reference the 'priv->entry array' as it uses 'i' to reference the array instead of 'priv->num_entries' as it should. This is similar to the problem that was addressed in pmt_telemetry_probe via commit 2cdfa0c20d58 ("platform/x86/intel: Fix 'rmmod pmt_telemetry' panic"). Cc: "David E. Box" Cc: Hans de Goede Cc: Mark Gross Cc: linux-kernel@vger.kernel.org Signed-off-by: David Arcari Reviewed-by: David E. Box Link: https://lore.kernel.org/r/20220526203140.339120-1-darcari@redhat.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/pmt/crashlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c index 34daf9df168b1..ace1239bc0a0b 100644 --- a/drivers/platform/x86/intel/pmt/crashlog.c +++ b/drivers/platform/x86/intel/pmt/crashlog.c @@ -282,7 +282,7 @@ static int pmt_crashlog_probe(struct auxiliary_device *auxdev, auxiliary_set_drvdata(auxdev, priv); for (i = 0; i < intel_vsec_dev->num_resources; i++) { - struct intel_pmt_entry *entry = &priv->entry[i].entry; + struct intel_pmt_entry *entry = &priv->entry[priv->num_entries].entry; ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, intel_vsec_dev, i); if (ret < 0) -- GitLab From 552f3b801de6eb062b225a76e140995483a0609c Mon Sep 17 00:00:00 2001 From: George D Sworo Date: Wed, 1 Jun 2022 18:26:17 -0700 Subject: [PATCH 493/942] platform/x86/intel: pmc: Support Intel Raptorlake P Add Raptorlake P to the list of the platforms that intel_pmc_core driver supports for pmc_core device. Raptorlake P PCH is based on Alderlake P PCH. Signed-off-by: George D Sworo Reviewed-by: David E. Box Link: https://lore.kernel.org/r/20220602012617.20100-1-george.d.sworo@intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/pmc/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index edaf22e5ae98c..40183bda7894a 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1912,6 +1912,7 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map), {} }; -- GitLab From 011881b80ebe773914b59905bce0f5e0ef93e7ba Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Thu, 26 May 2022 17:03:45 +0800 Subject: [PATCH 494/942] platform/x86: barco-p50-gpio: Add check for platform_driver_register As platform_driver_register() could fail, it should be better to deal with the return value in order to maintain the code consisitency. Fixes: 86af1d02d458 ("platform/x86: Support for EC-connected GPIOs for identify LED/button on Barco P50 board") Signed-off-by: Jiasheng Jiang Acked-by: Peter Korsgaard Link: https://lore.kernel.org/r/20220526090345.1444172-1-jiasheng@iscas.ac.cn Signed-off-by: Hans de Goede --- drivers/platform/x86/barco-p50-gpio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/barco-p50-gpio.c b/drivers/platform/x86/barco-p50-gpio.c index 05534287bc26b..8dd6723394858 100644 --- a/drivers/platform/x86/barco-p50-gpio.c +++ b/drivers/platform/x86/barco-p50-gpio.c @@ -405,11 +405,14 @@ MODULE_DEVICE_TABLE(dmi, dmi_ids); static int __init p50_module_init(void) { struct resource res = DEFINE_RES_IO(P50_GPIO_IO_PORT_BASE, P50_PORT_CMD + 1); + int ret; if (!dmi_first_match(dmi_ids)) return -ENODEV; - platform_driver_register(&p50_gpio_driver); + ret = platform_driver_register(&p50_gpio_driver); + if (ret) + return ret; gpio_pdev = platform_device_register_simple(DRIVER_NAME, PLATFORM_DEVID_NONE, &res, 1); if (IS_ERR(gpio_pdev)) { -- GitLab From 8a041afe3e774bedd3e0a9b96f65e48a1299a595 Mon Sep 17 00:00:00 2001 From: Piotr Chmura Date: Mon, 6 Jun 2022 19:15:13 +0200 Subject: [PATCH 495/942] platform/x86: gigabyte-wmi: Add Z690M AORUS ELITE AX DDR4 support Add dmi_system_id of Gigabyte Z690M AORUS ELITE AX DDR4 board. Tested on my PC. Signed-off-by: Piotr Chmura Link: https://lore.kernel.org/r/bd83567e-ebf5-0b31-074b-5f6dc7f7c147@gmail.com Signed-off-by: Hans de Goede --- drivers/platform/x86/gigabyte-wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/gigabyte-wmi.c b/drivers/platform/x86/gigabyte-wmi.c index 1ef606e3ef80d..f52f9a52557b5 100644 --- a/drivers/platform/x86/gigabyte-wmi.c +++ b/drivers/platform/x86/gigabyte-wmi.c @@ -156,6 +156,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 I AORUS PRO WIFI"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 UD"), + DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z690M AORUS ELITE AX DDR4"), { } }; -- GitLab From c6bc7e8ee90845556a90faf8b043cbefd77b8903 Mon Sep 17 00:00:00 2001 From: August Wikerfors Date: Wed, 8 Jun 2022 23:20:28 +0200 Subject: [PATCH 496/942] platform/x86: gigabyte-wmi: Add support for B450M DS3H-CF Tested and works on my system. Signed-off-by: August Wikerfors Link: https://lore.kernel.org/r/20220608212028.28307-1-git@augustwikerfors.se Signed-off-by: Hans de Goede --- drivers/platform/x86/gigabyte-wmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/gigabyte-wmi.c b/drivers/platform/x86/gigabyte-wmi.c index f52f9a52557b5..497ad2f64a51c 100644 --- a/drivers/platform/x86/gigabyte-wmi.c +++ b/drivers/platform/x86/gigabyte-wmi.c @@ -140,6 +140,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev) }} static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { + DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M DS3H-CF"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"), DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"), -- GitLab From 4c14d7043fede258957d7b01da0cad2d9fe3a205 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Mon, 6 Jun 2022 09:52:46 +0000 Subject: [PATCH 497/942] cifs: populate empty hostnames for extra channels Currently, the secondary channels of a multichannel session also get hostname populated based on the info in primary channel. However, this will end up with a wrong resolution of hostname to IP address during reconnect. This change fixes this by not populating hostname info for all secondary channels. Fixes: 5112d80c162f ("cifs: populate server_hostname for extra channels") Cc: stable@vger.kernel.org Signed-off-by: Shyam Prasad N Signed-off-by: Steve French --- fs/cifs/connect.c | 4 ++++ fs/cifs/sess.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d46702f5a6630..1849e34114878 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -97,6 +97,10 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server) if (!server->hostname) return -EINVAL; + /* if server hostname isn't populated, there's nothing to do here */ + if (server->hostname[0] == '\0') + return 0; + len = strlen(server->hostname) + 3; unc = kmalloc(len, GFP_KERNEL); diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 3b7915af1f62e..0bece97547d4b 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -301,7 +301,10 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, /* Auth */ ctx.domainauto = ses->domainAuto; ctx.domainname = ses->domainName; - ctx.server_hostname = ses->server->hostname; + + /* no hostname for extra channels */ + ctx.server_hostname = ""; + ctx.username = ses->user_name; ctx.password = ses->password; ctx.sectype = ses->sectype; -- GitLab From eacea844594ff338db06437806707313210d4865 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Fri, 10 Jun 2022 17:12:03 +0200 Subject: [PATCH 498/942] um: virt-pci: set device ready in probe() Call virtio_device_ready() to make this driver work after commit b4ec69d7e09 ("virtio: harden vring IRQ"), since the driver uses the virtqueues in the probe function. (The virtio core sets the device ready when probe returns.) Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Vincent Whitchurch Message-Id: <20220610151203.3492541-1-vincent.whitchurch@axis.com> Signed-off-by: Michael S. Tsirkin Tested-by: Johannes Berg --- arch/um/drivers/virt-pci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index 5c092a9153eae..0278470231841 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -544,6 +544,8 @@ static int um_pci_init_vqs(struct um_pci_device *dev) dev->cmd_vq = vqs[0]; dev->irq_vq = vqs[1]; + virtio_device_ready(dev->vdev); + for (i = 0; i < NUM_IRQ_MSGS; i++) { void *msg = kzalloc(MAX_IRQ_MSG_SIZE, GFP_KERNEL); @@ -587,7 +589,7 @@ static int um_pci_virtio_probe(struct virtio_device *vdev) dev->irq = irq_alloc_desc(numa_node_id()); if (dev->irq < 0) { err = dev->irq; - goto error; + goto err_reset; } um_pci_devices[free].dev = dev; vdev->priv = dev; @@ -604,6 +606,9 @@ static int um_pci_virtio_probe(struct virtio_device *vdev) um_pci_rescan(); return 0; +err_reset: + virtio_reset_device(vdev); + vdev->config->del_vqs(vdev); error: mutex_unlock(&um_pci_mtx); kfree(dev); -- GitLab From 1f7a6cf6b07c74a17343c2559cd5f5018a245961 Mon Sep 17 00:00:00 2001 From: Kuan-Ying Lee Date: Fri, 10 Jun 2022 15:14:57 +0800 Subject: [PATCH 499/942] scripts/gdb: change kernel config dumping method MAGIC_START("IKCFG_ST") and MAGIC_END("IKCFG_ED") are moved out from the kernel_config_data variable. Thus, we parse kernel_config_data directly instead of considering offset of MAGIC_START and MAGIC_END. Fixes: 13610aa908dc ("kernel/configs: use .incbin directive to embed config_data.gz") Signed-off-by: Kuan-Ying Lee Signed-off-by: Masahiro Yamada --- scripts/gdb/linux/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/gdb/linux/config.py b/scripts/gdb/linux/config.py index 90e1565b19671..8843ab3cbaddc 100644 --- a/scripts/gdb/linux/config.py +++ b/scripts/gdb/linux/config.py @@ -24,9 +24,9 @@ class LxConfigDump(gdb.Command): filename = arg try: - py_config_ptr = gdb.parse_and_eval("kernel_config_data + 8") - py_config_size = gdb.parse_and_eval( - "sizeof(kernel_config_data) - 1 - 8 * 2") + py_config_ptr = gdb.parse_and_eval("&kernel_config_data") + py_config_ptr_end = gdb.parse_and_eval("&kernel_config_data_end") + py_config_size = py_config_ptr_end - py_config_ptr except gdb.error as e: raise gdb.GdbError("Can't find config, enable CONFIG_IKCONFIG?") -- GitLab From 17b0128a136d43e5f8f268631f48bc267373ebff Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 10 Jun 2022 16:32:02 +0200 Subject: [PATCH 500/942] wireguard: selftests: use maximum cpu features and allow rng seeding By forcing the maximum CPU that QEMU has available, we expose additional capabilities, such as the RNDR instruction, which increases test coverage. This then allows the CI to skip the fake seeding step in some cases. Also enable STRICT_KERNEL_RWX to catch issues related to early jump labels when the RNG is initialized at boot. Signed-off-by: Jason A. Donenfeld --- .../testing/selftests/wireguard/qemu/Makefile | 28 +++++++++---------- tools/testing/selftests/wireguard/qemu/init.c | 3 ++ .../selftests/wireguard/qemu/kernel.config | 3 ++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/wireguard/qemu/Makefile b/tools/testing/selftests/wireguard/qemu/Makefile index bca07b93eeb07..7d1b80988d8af 100644 --- a/tools/testing/selftests/wireguard/qemu/Makefile +++ b/tools/testing/selftests/wireguard/qemu/Makefile @@ -64,8 +64,8 @@ QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm else -QEMU_MACHINE := -cpu cortex-a53 -machine virt -CFLAGS += -march=armv8-a -mtune=cortex-a53 +QEMU_MACHINE := -cpu max -machine virt +CFLAGS += -march=armv8-a endif else ifeq ($(ARCH),aarch64_be) CHOST := aarch64_be-linux-musl @@ -76,8 +76,8 @@ QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm else -QEMU_MACHINE := -cpu cortex-a53 -machine virt -CFLAGS += -march=armv8-a -mtune=cortex-a53 +QEMU_MACHINE := -cpu max -machine virt +CFLAGS += -march=armv8-a endif else ifeq ($(ARCH),arm) CHOST := arm-linux-musleabi @@ -88,8 +88,8 @@ QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm else -QEMU_MACHINE := -cpu cortex-a15 -machine virt -CFLAGS += -march=armv7-a -mtune=cortex-a15 -mabi=aapcs-linux +QEMU_MACHINE := -cpu max -machine virt +CFLAGS += -march=armv7-a -mabi=aapcs-linux endif else ifeq ($(ARCH),armeb) CHOST := armeb-linux-musleabi @@ -100,8 +100,8 @@ QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host -machine virt,gic_version=host,accel=kvm else -QEMU_MACHINE := -cpu cortex-a15 -machine virt -CFLAGS += -march=armv7-a -mabi=aapcs-linux # We don't pass -mtune=cortex-a15 due to a compiler bug on big endian. +QEMU_MACHINE := -cpu max -machine virt +CFLAGS += -march=armv7-a -mabi=aapcs-linux LDFLAGS += -Wl,--be8 endif else ifeq ($(ARCH),x86_64) @@ -112,8 +112,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host -machine q35,accel=kvm else -QEMU_MACHINE := -cpu Skylake-Server -machine q35 -CFLAGS += -march=skylake-avx512 +QEMU_MACHINE := -cpu max -machine q35 endif else ifeq ($(ARCH),i686) CHOST := i686-linux-musl @@ -123,8 +122,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH)) QEMU_MACHINE := -cpu host -machine q35,accel=kvm else -QEMU_MACHINE := -cpu coreduo -machine q35 -CFLAGS += -march=prescott +QEMU_MACHINE := -cpu max -machine q35 endif else ifeq ($(ARCH),mips64) CHOST := mips64-linux-musl @@ -182,7 +180,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host,accel=kvm -machine pseries else -QEMU_MACHINE := -machine pseries +QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng endif else ifeq ($(ARCH),powerpc64le) CHOST := powerpc64le-linux-musl @@ -192,7 +190,7 @@ KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host,accel=kvm -machine pseries else -QEMU_MACHINE := -machine pseries +QEMU_MACHINE := -machine pseries -device spapr-rng,rng=rng -object rng-random,id=rng endif else ifeq ($(ARCH),powerpc) CHOST := powerpc-linux-musl @@ -247,7 +245,7 @@ QEMU_VPORT_RESULT := virtio-serial-ccw ifeq ($(HOST_ARCH),$(ARCH)) QEMU_MACHINE := -cpu host,accel=kvm -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) else -QEMU_MACHINE := -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) +QEMU_MACHINE := -cpu max -machine s390-ccw-virtio -append $(KERNEL_CMDLINE) endif else $(error I only build: x86_64, i686, arm, armeb, aarch64, aarch64_be, mips, mipsel, mips64, mips64el, powerpc64, powerpc64le, powerpc, m68k, riscv64, riscv32, s390x) diff --git a/tools/testing/selftests/wireguard/qemu/init.c b/tools/testing/selftests/wireguard/qemu/init.c index 2a0f48fac925a..c9e128436546f 100644 --- a/tools/testing/selftests/wireguard/qemu/init.c +++ b/tools/testing/selftests/wireguard/qemu/init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,8 @@ static void seed_rng(void) { int bits = 256, fd; + if (!getrandom(NULL, 0, GRND_NONBLOCK)) + return; pretty_message("[+] Fake seeding RNG..."); fd = open("/dev/random", O_WRONLY); if (fd < 0) diff --git a/tools/testing/selftests/wireguard/qemu/kernel.config b/tools/testing/selftests/wireguard/qemu/kernel.config index a9b5a520a1d22..bad88f4b0a033 100644 --- a/tools/testing/selftests/wireguard/qemu/kernel.config +++ b/tools/testing/selftests/wireguard/qemu/kernel.config @@ -31,6 +31,7 @@ CONFIG_TTY=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_SCRIPT=y CONFIG_VDSO=y +CONFIG_STRICT_KERNEL_RWX=y CONFIG_VIRTUALIZATION=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y @@ -65,6 +66,8 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +CONFIG_RANDOM_TRUST_CPU=y +CONFIG_RANDOM_TRUST_BOOTLOADER=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 CONFIG_LOG_BUF_SHIFT=18 CONFIG_PRINTK_TIME=y -- GitLab From 1c27f1fc1549f0e470429f5497a76ad28a37f21a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 11 Jun 2022 10:30:20 -0700 Subject: [PATCH 501/942] iov_iter: fix build issue due to possible type mis-match Commit 6c77676645ad ("iov_iter: Fix iter_xarray_get_pages{,_alloc}()") introduced a problem on some 32-bit architectures (at least arm, xtensa, csky,sparc and mips), that have a 'size_t' that is 'unsigned int'. The reason is that we now do min(nr * PAGE_SIZE - offset, maxsize); where 'nr' and 'offset' and both 'unsigned int', and PAGE_SIZE is 'unsigned long'. As a result, the normal C type rules means that the first argument to 'min()' ends up being 'unsigned long'. In contrast, 'maxsize' is of type 'size_t'. Now, 'size_t' and 'unsigned long' are always the same physical type in the kernel, so you'd think this doesn't matter, and from an actual arithmetic standpoint it doesn't. But on 32-bit architectures 'size_t' is commonly 'unsigned int', even if it could also be 'unsigned long'. In that situation, both are unsigned 32-bit types, but they are not the *same* type. And as a result 'min()' will complain about the distinct types (ignore the "pointer types" part of the error message: that's an artifact of the way we have made 'min()' check types for being the same): lib/iov_iter.c: In function 'iter_xarray_get_pages': include/linux/minmax.h:20:35: error: comparison of distinct pointer types lacks a cast [-Werror] 20 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) | ^~ lib/iov_iter.c:1464:16: note: in expansion of macro 'min' 1464 | return min(nr * PAGE_SIZE - offset, maxsize); | ^~~ This was not visible on 64-bit architectures (where we always define 'size_t' to be 'unsigned long'). Force these cases to use 'min_t(size_t, x, y)' to make the type explicit and avoid the issue. [ Nit-picky note: technically 'size_t' doesn't have to match 'unsigned long' arithmetically. We've certainly historically seen environments with 16-bit address spaces and 32-bit 'unsigned long'. Similarly, even in 64-bit modern environments, 'size_t' could be its own type distinct from 'unsigned long', even if it were arithmetically identical. So the above type commentary is only really descriptive of the kernel environment, not some kind of universal truth for the kinds of wild and crazy situations that are allowed by the C standard ] Reported-by: Sudip Mukherjee Link: https://lore.kernel.org/all/YqRyL2sIqQNDfky2@debian/ Cc: Jeff Layton Cc: David Howells Cc: Al Viro Signed-off-by: Linus Torvalds --- lib/iov_iter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index dda6d5f481c1c..0b64695ab632f 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1461,7 +1461,7 @@ static ssize_t iter_xarray_get_pages(struct iov_iter *i, if (nr == 0) return 0; - return min(nr * PAGE_SIZE - offset, maxsize); + return min_t(size_t, nr * PAGE_SIZE - offset, maxsize); } /* must be done on non-empty ITER_IOVEC one */ @@ -1625,7 +1625,7 @@ static ssize_t iter_xarray_get_pages_alloc(struct iov_iter *i, if (nr == 0) return 0; - return min(nr * PAGE_SIZE - offset, maxsize); + return min_t(size_t, nr * PAGE_SIZE - offset, maxsize); } ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, -- GitLab From 8bee9dd953b69c634d1c9a3241a8b357469ad4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 10 Jun 2022 01:41:10 +0200 Subject: [PATCH 502/942] workqueue: Switch to new kerneldoc syntax for named variable macro argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The syntax without dots is available since commit 43756e347f21 ("scripts/kernel-doc: Add support for named variable macro arguments"). The same HTML output is produced with and without this patch. Signed-off-by: Jonathan Neuschäfer Acked-by: Tejun Heo Signed-off-by: Tejun Heo --- include/linux/workqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index e1f1c8b1121bd..62e75dd40d9a6 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -406,7 +406,7 @@ alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...); * alloc_ordered_workqueue - allocate an ordered workqueue * @fmt: printf format for the name of the workqueue * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful) - * @args...: args for @fmt + * @args: args for @fmt * * Allocate an ordered workqueue. An ordered workqueue executes at * most one work item at any given time in the queued order. They are -- GitLab From dc6a6ab58379f25bf991d8e4a13b001ed806e881 Mon Sep 17 00:00:00 2001 From: Jorge Lopez Date: Wed, 8 Jun 2022 16:29:23 -0500 Subject: [PATCH 503/942] platform/x86: hp-wmi: Resolve WMI query failures on some devices WMI queries fail on some devices where the ACPI method HWMC unconditionally attempts to create Fields beyond the buffer if the buffer is too small, this breaks essential features such as power profiles: CreateByteField (Arg1, 0x10, D008) CreateByteField (Arg1, 0x11, D009) CreateByteField (Arg1, 0x12, D010) CreateDWordField (Arg1, 0x10, D032) CreateField (Arg1, 0x80, 0x0400, D128) In cases where args->data had zero length, ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Field [D008] at bit offset/length 128/8 exceeds size of target Buffer (128 bits) (20211217/dsopcode-198) was obtained. ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Field [D009] at bit offset/length 136/8 exceeds size of target Buffer (136bits) (20211217/dsopcode-198) The original code created a buffer size of 128 bytes regardless if the WMI call required a smaller buffer or not. This particular behavior occurs in older BIOS and reproduced in OMEN laptops. Newer BIOS handles buffer sizes properly and meets the latest specification requirements. This is the reason why testing with a dynamically allocated buffer did not uncover any failures with the test systems at hand. This patch was tested on several OMEN, Elite, and Zbooks. It was confirmed the patch resolves HPWMI_FAN GET/SET calls in an OMEN Laptop 15-ek0xxx. No problems were reported when testing on several Elite and Zbooks notebooks. Fixes: 4b4967cbd268 ("platform/x86: hp-wmi: Changing bios_args.data to be dynamically allocated") Signed-off-by: Jorge Lopez Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220608212923.8585-2-jorge.lopez2@hp.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/hp-wmi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 667f94bba905b..e4a53c3d70289 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -290,14 +290,16 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command, struct bios_return *bios_return; union acpi_object *obj = NULL; struct bios_args *args = NULL; - int mid, actual_outsize, ret; + int mid, actual_insize, actual_outsize; size_t bios_args_size; + int ret; mid = encode_outsize_for_pvsz(outsize); if (WARN_ON(mid < 0)) return mid; - bios_args_size = struct_size(args, data, insize); + actual_insize = max(insize, 128); + bios_args_size = struct_size(args, data, actual_insize); args = kmalloc(bios_args_size, GFP_KERNEL); if (!args) return -ENOMEM; -- GitLab From 65f936f3535950d2643eac5bf34a735a0e428cdd Mon Sep 17 00:00:00 2001 From: Bedant Patnaik Date: Thu, 9 Jun 2022 00:58:43 +0530 Subject: [PATCH 504/942] platform/x86: hp-wmi: Use zero insize parameter only when supported commit be9d73e64957 ("platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls") and commit 12b19f14a21a ("platform/x86: hp-wmi: Fix hp_wmi_read_int() reporting error (0x05)") cause ACPI BIOS Error (bug): Attempt to CreateField of length zero (20211217/dsopcode-133) because of the ACPI method HWMC, which unconditionally creates a Field of size (insize*8) bits: CreateField (Arg1, 0x80, (Local5 * 0x08), DAIN) In cases where args->insize = 0, the Field size is 0, resulting in an error. Fix this by using zero insize only if 0x5 error code is returned Tested on Omen 15 AMD (2020) board ID: 8786. Fixes: be9d73e64957 ("platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls") Signed-off-by: Bedant Patnaik Tested-by: Jorge Lopez Link: https://lore.kernel.org/r/41be46743d21c78741232a47bbb5f1cdbcc3d21e.camel@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/hp-wmi.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index e4a53c3d70289..0d8cb22e30df9 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -38,6 +38,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" #define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95 +#define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required /* DMI board names of devices that should use the omen specific path for * thermal profiles. @@ -220,6 +221,7 @@ static struct input_dev *hp_wmi_input_dev; static struct platform_device *hp_wmi_platform_dev; static struct platform_profile_handler platform_profile_handler; static bool platform_profile_support; +static bool zero_insize_support; static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; @@ -376,7 +378,7 @@ static int hp_wmi_read_int(int query) int val = 0, ret; ret = hp_wmi_perform_query(query, HPWMI_READ, &val, - 0, sizeof(val)); + zero_if_sup(val), sizeof(val)); if (ret) return ret < 0 ? ret : -EINVAL; @@ -412,7 +414,8 @@ static int hp_wmi_get_tablet_mode(void) return -ENODEV; ret = hp_wmi_perform_query(HPWMI_SYSTEM_DEVICE_MODE, HPWMI_READ, - system_device_mode, 0, sizeof(system_device_mode)); + system_device_mode, zero_if_sup(system_device_mode), + sizeof(system_device_mode)); if (ret < 0) return ret; @@ -499,7 +502,7 @@ static int hp_wmi_fan_speed_max_get(void) int val = 0, ret; ret = hp_wmi_perform_query(HPWMI_FAN_SPEED_MAX_GET_QUERY, HPWMI_GM, - &val, 0, sizeof(val)); + &val, zero_if_sup(val), sizeof(val)); if (ret) return ret < 0 ? ret : -EINVAL; @@ -511,7 +514,7 @@ static int __init hp_wmi_bios_2008_later(void) { int state = 0; int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + zero_if_sup(state), sizeof(state)); if (!ret) return 1; @@ -522,7 +525,7 @@ static int __init hp_wmi_bios_2009_later(void) { u8 state[128]; int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + zero_if_sup(state), sizeof(state)); if (!ret) return 1; @@ -600,7 +603,7 @@ static int hp_wmi_rfkill2_refresh(void) int err, i; err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + zero_if_sup(state), sizeof(state)); if (err) return err; @@ -1009,7 +1012,7 @@ static int __init hp_wmi_rfkill2_setup(struct platform_device *device) int err, i; err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + zero_if_sup(state), sizeof(state)); if (err) return err < 0 ? err : -EINVAL; @@ -1485,11 +1488,15 @@ static int __init hp_wmi_init(void) { int event_capable = wmi_has_guid(HPWMI_EVENT_GUID); int bios_capable = wmi_has_guid(HPWMI_BIOS_GUID); - int err; + int err, tmp = 0; if (!bios_capable && !event_capable) return -ENODEV; + if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp, + sizeof(tmp), sizeof(tmp)) == HPWMI_RET_INVALID_PARAMETERS) + zero_insize_support = true; + if (event_capable) { err = hp_wmi_input_setup(); if (err) -- GitLab From d4fe9cc4ff8656704b58cfd9363d7c3c9d65e519 Mon Sep 17 00:00:00 2001 From: Duke Lee Date: Tue, 7 Jun 2022 14:36:54 -0700 Subject: [PATCH 505/942] platform/x86/intel: hid: Add Surface Go to VGBS allow list The Surface Go reports Chassis Type 9 (Laptop,) so the device needs to be added to dmi_vgbs_allow_list to enable tablet mode when an attached Type Cover is folded back. BugLink: https://github.com/linux-surface/linux-surface/issues/837 Signed-off-by: Duke Lee Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220607213654.5567-1-krnhotwings@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/hid.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 216d31e3403dd..79cff1fc675c2 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -122,6 +122,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible 15-df0xxx"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), + }, + }, { } }; -- GitLab From b13baccc3850ca8b8cccbf8ed9912dbaa0fdf7f3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 12 Jun 2022 16:11:37 -0700 Subject: [PATCH 506/942] Linux 5.19-rc2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b2e93c1a80218..1a6678d817bd1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Superb Owl # *DOCUMENTATION* -- GitLab From 7263fc6c71c3a88c17a1ce3565b7b6f378d13878 Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Mon, 6 Jun 2022 19:22:26 +0400 Subject: [PATCH 507/942] ASoC: wcd9335: Remove RX channel from old list before adding it to a new one Currently in slim_rx_mux_put, an RX channel gets added to a new list even if it is already in one. This can mess up links and make either it, the new list head, or both, get linked to the wrong entries. This can cause an entry to link to itself which in turn ends up making list_for_each_entry in other functions loop infinitely. To avoid issues, always remove the RX channel from any list it's in before adding it to a new list. Signed-off-by: Yassine Oudjana Link: https://lore.kernel.org/r/20220606152226.149164-1-y.oudjana@protonmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 617a36a89dfed..597420679505b 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1289,9 +1289,12 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc, wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + /* Remove channel from any list it's in before adding it to a new one */ + list_del_init(&wcd->rx_chs[port_id].list); + switch (wcd->rx_port_value[port_id]) { case 0: - list_del_init(&wcd->rx_chs[port_id].list); + /* Channel already removed from lists. Nothing to do here */ break; case 1: list_add_tail(&wcd->rx_chs[port_id].list, -- GitLab From 6bda28a2f7113b1c49eb05155ace02b75bccae7b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 14:46:09 +0200 Subject: [PATCH 508/942] ASoC: wcd9335: Fix spurious event generation The slimbus mux put operation unconditionally reports a change in value which means that spurious events are generated. Fix this by exiting early in that case. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220603124609.4024666-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 597420679505b..d9f1352006881 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1287,6 +1287,9 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc, struct snd_soc_dapm_update *update = NULL; u32 port_id = w->shift; + if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) + return 0; + wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; /* Remove channel from any list it's in before adding it to a new one */ -- GitLab From 9f1c8677724a0e6a6ac7a74d2b0192a584df859d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Jun 2022 12:30:29 +0200 Subject: [PATCH 509/942] ASoC: hdmi-codec: Update to modern DAI terminology As part of retiring the old defines used to specify DAI formats update the hdmi_codec driver to use the modern names, including the variables in the struct hdmi_codec_daifmt exported to the DRM drivers. In updating this I did note that the only use of this information in DRM drivers is to reject clock provider settings, thinking about what this hardware is doing I rather suspect that there might not be any hardware out there which needs the configuration so it may be worth considering just having hdmi-codec support only clock consumer. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220602103029.3498791-1-broonie@kernel.org Signed-off-by: Mark Brown --- drivers/gpu/drm/bridge/sii902x.c | 5 +++-- .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 2 +- drivers/gpu/drm/exynos/exynos_hdmi.c | 8 ++++---- drivers/gpu/drm/i2c/tda998x_drv.c | 6 +++--- drivers/gpu/drm/sti/sti_hdmi.c | 8 ++++---- include/sound/hdmi-codec.h | 4 ++-- sound/soc/codecs/hdmi-codec.c | 18 +++++++++--------- 7 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index 65549fbfdc870..be9736f67542c 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -549,8 +549,9 @@ static int sii902x_audio_hw_params(struct device *dev, void *data, unsigned long mclk_rate; int i, ret; - if (daifmt->bit_clk_master || daifmt->frame_clk_master) { - dev_dbg(dev, "%s: I2S master mode not supported\n", __func__); + if (daifmt->bit_clk_provider || daifmt->frame_clk_provider) { + dev_dbg(dev, "%s: I2S clock provider mode not supported\n", + __func__); return -EINVAL; } diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index f50b47ac11a82..a2f0860b20bb9 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -45,7 +45,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data, u8 inputclkfs = 0; /* it cares I2S only */ - if (fmt->bit_clk_master | fmt->frame_clk_master) { + if (fmt->bit_clk_provider | fmt->frame_clk_provider) { dev_err(dev, "unsupported clock settings\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 7655142a4651c..10b0036f8a2e2 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1594,12 +1594,12 @@ static int hdmi_audio_hw_params(struct device *dev, void *data, struct hdmi_context *hdata = dev_get_drvdata(dev); if (daifmt->fmt != HDMI_I2S || daifmt->bit_clk_inv || - daifmt->frame_clk_inv || daifmt->bit_clk_master || - daifmt->frame_clk_master) { + daifmt->frame_clk_inv || daifmt->bit_clk_provider || + daifmt->frame_clk_provider) { dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, daifmt->bit_clk_inv, daifmt->frame_clk_inv, - daifmt->bit_clk_master, - daifmt->frame_clk_master); + daifmt->bit_clk_provider, + daifmt->frame_clk_provider); return -EINVAL; } diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index b7ec6c374fbda..c4fadaecbb2d6 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1095,11 +1095,11 @@ static int tda998x_audio_hw_params(struct device *dev, void *data, if (!spdif && (daifmt->bit_clk_inv || daifmt->frame_clk_inv || - daifmt->bit_clk_master || daifmt->frame_clk_master)) { + daifmt->bit_clk_provider || daifmt->frame_clk_provider)) { dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, daifmt->bit_clk_inv, daifmt->frame_clk_inv, - daifmt->bit_clk_master, - daifmt->frame_clk_master); + daifmt->bit_clk_provider, + daifmt->frame_clk_provider); return -EINVAL; } diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index b3fbee7eac114..65c76077e866a 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -1175,12 +1175,12 @@ static int hdmi_audio_hw_params(struct device *dev, DRM_DEBUG_DRIVER("\n"); if ((daifmt->fmt != HDMI_I2S) || daifmt->bit_clk_inv || - daifmt->frame_clk_inv || daifmt->bit_clk_master || - daifmt->frame_clk_master) { + daifmt->frame_clk_inv || daifmt->bit_clk_provider || + daifmt->frame_clk_provider) { dev_err(dev, "%s: Bad flags %d %d %d %d\n", __func__, daifmt->bit_clk_inv, daifmt->frame_clk_inv, - daifmt->bit_clk_master, - daifmt->frame_clk_master); + daifmt->bit_clk_provider, + daifmt->frame_clk_provider); return -EINVAL; } diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index 4fc733c8c570e..48ad33aba393b 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -32,8 +32,8 @@ struct hdmi_codec_daifmt { } fmt; unsigned int bit_clk_inv:1; unsigned int frame_clk_inv:1; - unsigned int bit_clk_master:1; - unsigned int frame_clk_master:1; + unsigned int bit_clk_provider:1; + unsigned int frame_clk_provider:1; /* bit_fmt could be standard PCM format or * IEC958 encoded format. ALSA IEC958 plugin will pass * IEC958_SUBFRAME format to the underneath driver. diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index b773466619b23..7d1e351f863a4 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -606,18 +606,18 @@ static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai, /* Reset daifmt */ memset(cf, 0, sizeof(*cf)); - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - cf->bit_clk_master = 1; - cf->frame_clk_master = 1; + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + cf->bit_clk_provider = 1; + cf->frame_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBS_CFM: - cf->frame_clk_master = 1; + case SND_SOC_DAIFMT_CBC_CFP: + cf->frame_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBM_CFS: - cf->bit_clk_master = 1; + case SND_SOC_DAIFMT_CBP_CFC: + cf->bit_clk_provider = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: break; default: return -EINVAL; -- GitLab From 65c1c99d96f160e3fead8c6ec67b669cbe62320f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 14:25:26 +0200 Subject: [PATCH 510/942] ASoC: wcd938x: Fix event generation for some controls Currently wcd938x_*_put() unconditionally report that the value of the control changed, resulting in spurious events being generated. Return 0 in that case instead as we should. There is still an issue in the compander control which is a bit more complex. Signed-off-by: Mark Brown Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220603122526.3914942-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index c1b61b997f696..781ae569be290 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2519,6 +2519,9 @@ static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; + if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0]) + return 0; + wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0]; return 1; @@ -2541,6 +2544,9 @@ static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0]) + return 0; + wcd938x->hph_mode = ucontrol->value.enumerated.item[0]; return 1; @@ -2632,6 +2638,9 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->ldoh == ucontrol->value.integer.value[0]) + return 0; + wcd938x->ldoh = ucontrol->value.integer.value[0]; return 1; @@ -2654,6 +2663,9 @@ static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->bcs_dis == ucontrol->value.integer.value[0]) + return 0; + wcd938x->bcs_dis = ucontrol->value.integer.value[0]; return 1; -- GitLab From 3729928137c74fe9079f51d8f0348ab588a247ae Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 10 Jun 2022 16:43:13 -0500 Subject: [PATCH 511/942] MAINTAINERS: update ASoC/Intel/SOF maintainers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keyon Jie was a key contributor to the Intel ASoC and SOF Intel drivers, but he's moved on to a different role within Intel. We wish him all the best in his new endeavors. Bard Liao, Kai Vehmanen, Ranjani Sridharan and Peter Ujfalusi have been involved in the Intel multi-maintainer team, it's time to update the MAINTAINERS entry to reflect their contributions and clarify their role. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220610214313.42903-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- MAINTAINERS | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d0..440f3d7c93b9e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9803,7 +9803,10 @@ INTEL ASoC DRIVERS M: Cezary Rojewski M: Pierre-Louis Bossart M: Liam Girdwood -M: Jie Yang +M: Peter Ujfalusi +M: Bard Liao +M: Ranjani Sridharan +M: Kai Vehmanen L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported F: sound/soc/intel/ @@ -18670,8 +18673,10 @@ F: sound/soc/ SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS M: Pierre-Louis Bossart M: Liam Girdwood +M: Peter Ujfalusi +M: Bard Liao M: Ranjani Sridharan -M: Kai Vehmanen +R: Kai Vehmanen M: Daniel Baluta L: sound-open-firmware@alsa-project.org (moderated for non-subscribers) S: Supported -- GitLab From da440af07fc3dd2b5a5138671eba51991dd1fac8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Jun 2022 17:56:52 +0200 Subject: [PATCH 512/942] ASoC: Intel: bytcr_wm5102: Fix GPIO related probe-ordering problem The "wlf,spkvdd-ena" GPIO needed by the bytcr_wm5102 driver is made available through a gpio-lookup table. This gpio-lookup table is registered by drivers/mfd/arizona-spi.c, which may get probed after the bytcr_wm5102 driver. If the gpio-lookup table has not registered yet then the gpiod_get() will return -ENOENT. Treat -ENOENT as -EPROBE_DEFER to still keep things working in this case. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220612155652.107310-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_wm5102.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 00384c6fbcaa5..330c0ace16387 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -421,8 +421,17 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) priv->spkvdd_en_gpio = gpiod_get(codec_dev, "wlf,spkvdd-ena", GPIOD_OUT_LOW); put_device(codec_dev); - if (IS_ERR(priv->spkvdd_en_gpio)) - return dev_err_probe(dev, PTR_ERR(priv->spkvdd_en_gpio), "getting spkvdd-GPIO\n"); + if (IS_ERR(priv->spkvdd_en_gpio)) { + ret = PTR_ERR(priv->spkvdd_en_gpio); + /* + * The spkvdd gpio-lookup is registered by: drivers/mfd/arizona-spi.c, + * so -ENOENT means that arizona-spi hasn't probed yet. + */ + if (ret == -ENOENT) + ret = -EPROBE_DEFER; + + return dev_err_probe(dev, ret, "getting spkvdd-GPIO\n"); + } /* override platform name, if required */ byt_wm5102_card.dev = dev; -- GitLab From 18489174e4fb98ad07fd387973a39e755ac01dee Mon Sep 17 00:00:00 2001 From: Yong Zhi Date: Fri, 10 Jun 2022 16:44:15 -0500 Subject: [PATCH 513/942] ASoC: intel: sof_sdw: add RT711 SDCA card for MTL platform Enable on-board rt711 based sound card for MTL RVP. Reviewed-by: Bard Liao Signed-off-by: Yong Zhi Signed-off-by: Uday M Bhat Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220610214415.42942-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 8 +++++ .../intel/common/soc-acpi-intel-mtl-match.c | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index f871daa5cb33d..aae89afd4d38d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -315,6 +315,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { RT711_JD2 | SOF_SDW_FOUR_SPK), }, + /* MeteorLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), + }, + .driver_data = (void *)(RT711_JD1 | SOF_SDW_TGL_HDMI), + }, {} }; diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index cc594b27e03be..74d3b82f8d35c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -15,6 +15,31 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines); +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, +}; + +static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_link_adr mtl_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { /* mockup tests need to be first */ @@ -36,6 +61,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg", }, + { + .link_mask = BIT(0), + .links = mtl_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt711.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); -- GitLab From beb89d1d49e9ae1188356d6e37581e5f0b5f62b4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 13 Jun 2022 17:15:51 +0100 Subject: [PATCH 514/942] ASoC: sun8i-codec: Partial revert to fix clock specifiers Recent updates accidentally updated the clock producer/consumer specifiers on this device as part of refactoring the CPU side of the DAI links. However, this device sits on the CODEC side and shouldn't have been updated. Partially revert the changes keeping the switch to the new clock terminology but going back to the CODEC defines. Fixes: 7cc3965fde74 ("ASoC: sunxi: Update to use set_fmt_new callback") Reported-by: Samuel Holland Signed-off-by: Charles Keepax Reviewed-by: Samuel Holland Tested-by: Samuel Holland Link: https://lore.kernel.org/r/20220613161552.481337-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun8i-codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 90d74a2d53f38..f797c535f2983 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -287,10 +287,10 @@ static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) /* clock masters */ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BP_FP: /* Codec slave, DAI master */ + case SND_SOC_DAIFMT_CBC_CFC: /* Codec slave, DAI master */ value = 0x1; break; - case SND_SOC_DAIFMT_BC_FC: /* Codec Master, DAI slave */ + case SND_SOC_DAIFMT_CBP_CFP: /* Codec Master, DAI slave */ value = 0x0; break; default: -- GitLab From 845a215558647acd4290dd773b9c0de62c123335 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 13 Jun 2022 17:15:52 +0100 Subject: [PATCH 515/942] ASoC: mediatek: mt8186: Use new direct clock defines Update this driver to the new direct clock producer/consumer defines. It appears this driver was added with the inversion taken account of but still uses the CODEC defines so no inversion of the producer/consumer is necessary. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220613161552.481337-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c index dfff209b60da4..c6ead7c252f01 100644 --- a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c @@ -585,10 +585,10 @@ static int mtk_dai_tdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_CBP_CFP: + case SND_SOC_DAIFMT_BP_FP: tdm_priv->slave_mode = false; break; - case SND_SOC_DAIFMT_CBC_CFC: + case SND_SOC_DAIFMT_BC_FC: tdm_priv->slave_mode = true; break; default: -- GitLab From 519d1130b66e000ce363ad82c0d61ae36a5392dc Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 10 Jun 2022 16:45:04 -0500 Subject: [PATCH 516/942] ASoC: SOF: Intel: hda-dai: enhance debug messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same message was added twice for dai and link_dma, remove the latter one and add dai name and direction to better understand problematic sequences. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220610214504.42974-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 228079a52c3d2..70721defca467 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -270,7 +270,6 @@ static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd) struct hdac_ext_stream *hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); int ret; - dev_dbg(cpu_dai->dev, "%s: cmd=%d\n", __func__, cmd); if (!hext_stream) return 0; @@ -420,13 +419,15 @@ static int ipc3_hda_dai_trigger(struct snd_pcm_substream *substream, struct snd_soc_dapm_widget *w; int ret; + dev_dbg(dai->dev, "%s: cmd=%d dai %s direction %d\n", __func__, cmd, + dai->name, substream->stream); + ret = hda_link_dma_trigger(substream, cmd); if (ret < 0) return ret; w = snd_soc_dai_get_widget(dai, substream->stream); - dev_dbg(dai->dev, "%s: cmd=%d\n", __func__, cmd); switch (cmd) { case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: -- GitLab From 81ae0635df7de58496def18b0b9333992630b9af Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 10 Jun 2022 13:47:21 +0800 Subject: [PATCH 517/942] ASoC: dt-bindings: fsl,mqs: Add compatible string for i.MX93 platform Add compatible string "fsl,imx93-mqs" for i.MX93 platform Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1654840042-7069-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,mqs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/fsl,mqs.txt b/Documentation/devicetree/bindings/sound/fsl,mqs.txt index 40353fc30255b..d66284b8bef29 100644 --- a/Documentation/devicetree/bindings/sound/fsl,mqs.txt +++ b/Documentation/devicetree/bindings/sound/fsl,mqs.txt @@ -2,7 +2,7 @@ fsl,mqs audio CODEC Required properties: - compatible : Must contain one of "fsl,imx6sx-mqs", "fsl,codec-mqs" - "fsl,imx8qm-mqs", "fsl,imx8qxp-mqs". + "fsl,imx8qm-mqs", "fsl,imx8qxp-mqs", "fsl,imx93-mqs". - clocks : A list of phandles + clock-specifiers, one for each entry in clock-names - clock-names : "mclk" - must required. -- GitLab From 047c69a3a9b19f29e021c77a7e9ce79230a342ed Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 10 Jun 2022 13:47:22 +0800 Subject: [PATCH 518/942] ASoC: fsl_mqs: Add support for i.MX93 platform Add i.MX93 compatible string and specific soc data Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1654840042-7069-2-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_mqs.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index c9c11914a78ea..bb25c58e335fb 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -338,9 +338,23 @@ static const struct fsl_mqs_soc_data fsl_mqs_imx6sx_data = { .div_shift = IMX6SX_GPR2_MQS_CLK_DIV_SHIFT, }; +static const struct fsl_mqs_soc_data fsl_mqs_imx93_data = { + .use_gpr = true, + .ctrl_off = 0x20, + .en_mask = BIT(1), + .en_shift = 1, + .rst_mask = BIT(2), + .rst_shift = 2, + .osr_mask = BIT(3), + .osr_shift = 3, + .div_mask = GENMASK(15, 8), + .div_shift = 8, +}; + static const struct of_device_id fsl_mqs_dt_ids[] = { { .compatible = "fsl,imx8qm-mqs", .data = &fsl_mqs_imx8qm_data }, { .compatible = "fsl,imx6sx-mqs", .data = &fsl_mqs_imx6sx_data }, + { .compatible = "fsl,imx93-mqs", .data = &fsl_mqs_imx93_data }, {} }; MODULE_DEVICE_TABLE(of, fsl_mqs_dt_ids); -- GitLab From f7309dbe628d5c8653d5f3649ef05a65c9b88daf Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 10 Jun 2022 16:46:01 -0500 Subject: [PATCH 519/942] ASoC: SOF: reduce default verbosity of IPC logs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently log the initiation of an IPC as well at its success. [ 3906.106987] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx: 0x80010000: GLB_DAI_MSG: CONFIG [ 3906.107189] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc tx succeeded: 0x80010000: GLB_DAI_MSG: CONFIG This is overkill in most cases, we already have a message thrown in case of errors and have tracepoints enabled to check for IPC duration. The only case where this might be useful is to check if there is an interleaved IPC RX. Add a flag and only print those logs if enabled. In addition, the DMA_POSITION_UPDATE for traces brings limited information in most cases and pollutes the logs for no good reason. [ 3906.322256] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3906.322308] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx done: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3906.822261] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3906.822319] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx done: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3907.822261] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3907.822319] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx done: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3908.822251] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx: 0x90020000: GLB_TRACE_MSG: DMA_POSITION [ 3908.822309] kernel: sof-audio-pci-intel-tgl 0000:00:1f.3: ipc rx done: 0x90020000: GLB_TRACE_MSG: DMA_POSITION This information is only helpful when debugging the trace support, not when using the trace. Add a flag to only print DMA position update logs if enabled. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220610214601.43005-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3.c | 5 ++++- sound/soc/sof/sof-priv.h | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index 0df57e7e83acf..1fb132b477bf2 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -147,6 +147,8 @@ static void ipc3_log_header(struct device *dev, u8 *text, u32 cmd) case SOF_IPC_TRACE_DMA_PARAMS: str2 = "DMA_PARAMS"; break; case SOF_IPC_TRACE_DMA_POSITION: + if (!sof_debug_check_flag(SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS)) + return; str2 = "DMA_POSITION"; break; case SOF_IPC_TRACE_DMA_PARAMS_EXT: str2 = "DMA_PARAMS_EXT"; break; @@ -299,7 +301,8 @@ static int ipc3_wait_tx_done(struct snd_sof_ipc *ipc, void *reply_data) "ipc tx error for %#x (msg/reply size: %d/%zu): %d\n", hdr->cmd, hdr->size, msg->reply_size, ret); } else { - ipc3_log_header(sdev->dev, "ipc tx succeeded", hdr->cmd); + if (sof_debug_check_flag(SOF_DBG_PRINT_IPC_SUCCESS_LOGS)) + ipc3_log_header(sdev->dev, "ipc tx succeeded", hdr->cmd); if (msg->reply_size) /* copy the data returned from DSP */ memcpy(reply_data, msg->reply_data, diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index bd637153c08fe..52396f38dcec2 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -37,6 +37,12 @@ #define SOF_DBG_IGNORE_D3_PERSISTENT BIT(7) /* ignore the DSP D3 persistent capability * and always download firmware upon D3 exit */ +#define SOF_DBG_PRINT_DMA_POSITION_UPDATE_LOGS BIT(8) /* print DMA position updates + * in dmesg logs + */ +#define SOF_DBG_PRINT_IPC_SUCCESS_LOGS BIT(9) /* print IPC success + * in dmesg logs + */ /* Flag definitions used for controlling the DSP dump behavior */ #define SOF_DBG_DUMP_REGS BIT(0) -- GitLab From 689614ce48b0310b50d8d6c9a64f8a98cfc6f195 Mon Sep 17 00:00:00 2001 From: Ajit Kumar Pandey Date: Tue, 14 Jun 2022 10:52:51 +0300 Subject: [PATCH 520/942] ASoC: SOF: topology: add code to parse config params for ACPDMIC dai MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add sof_ipc_dai_acpdmic_params and tokens to parse dmic channels and rate params from topology file Signed-off-by: Ajit Kumar Pandey Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220614075251.21499-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- include/sound/sof/dai-amd.h | 7 +++++++ include/sound/sof/dai.h | 2 +- include/uapi/sound/sof/tokens.h | 4 ++++ sound/soc/sof/ipc3-pcm.c | 8 ++++---- sound/soc/sof/ipc3-topology.c | 25 +++++++++++++++++++------ sound/soc/sof/sof-audio.h | 1 + sound/soc/sof/topology.c | 4 ++++ 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/sound/sof/dai-amd.h b/include/sound/sof/dai-amd.h index 90d09dbdd709b..92f45c180b7cc 100644 --- a/include/sound/sof/dai-amd.h +++ b/include/sound/sof/dai-amd.h @@ -18,4 +18,11 @@ struct sof_ipc_dai_acp_params { uint32_t fsync_rate; /* FSYNC frequency in Hz */ uint32_t tdm_slots; } __packed; + +/* ACPDMIC Configuration Request - SOF_IPC_DAI_AMD_CONFIG */ +struct sof_ipc_dai_acpdmic_params { + uint32_t pdm_rate; + uint32_t pdm_ch; +} __packed; + #endif diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index a818a0f0a2267..21d98f31a9cab 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -111,7 +111,7 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_sai_params sai; struct sof_ipc_dai_acp_params acpbt; struct sof_ipc_dai_acp_params acpsp; - struct sof_ipc_dai_acp_params acpdmic; + struct sof_ipc_dai_acpdmic_params acpdmic; struct sof_ipc_dai_mtk_afe_params afe; }; } __packed; diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index f7b2019065ad1..5caf75cadaf8c 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -157,6 +157,10 @@ /* MIXER */ #define SOF_TKN_MIXER_TYPE 1700 +/* ACPDMIC */ +#define SOF_TKN_AMD_ACPDMIC_RATE 1800 +#define SOF_TKN_AMD_ACPDMIC_CH 1801 + /* CAVS AUDIO FORMAT */ #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901 diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index c8774a891d6fa..b97e63d3724aa 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -344,10 +344,10 @@ static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, channels->min, channels->max); break; case SOF_DAI_AMD_DMIC: - rate->min = private->dai_config->acpdmic.fsync_rate; - rate->max = private->dai_config->acpdmic.fsync_rate; - channels->min = private->dai_config->acpdmic.tdm_slots; - channels->max = private->dai_config->acpdmic.tdm_slots; + rate->min = private->dai_config->acpdmic.pdm_rate; + rate->max = private->dai_config->acpdmic.pdm_rate; + channels->min = private->dai_config->acpdmic.pdm_ch; + channels->max = private->dai_config->acpdmic.pdm_ch; dev_dbg(component->dev, "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max); diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index a91d7df3f07e2..5ee1537f9c2d7 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -266,6 +266,16 @@ static const struct sof_topology_token afe_tokens[] = { offsetof(struct sof_ipc_dai_mtk_afe_params, format)}, }; +/* ACPDMIC */ +static const struct sof_topology_token acpdmic_tokens[] = { + {SOF_TKN_AMD_ACPDMIC_RATE, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_acpdmic_params, pdm_rate)}, + {SOF_TKN_AMD_ACPDMIC_CH, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_acpdmic_params, pdm_ch)}, +}; + /* Core tokens */ static const struct sof_topology_token core_tokens[] = { {SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, @@ -300,6 +310,7 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = { [SOF_ESAI_TOKENS] = {"ESAI tokens", esai_tokens, ARRAY_SIZE(esai_tokens)}, [SOF_SAI_TOKENS] = {"SAI tokens", sai_tokens, ARRAY_SIZE(sai_tokens)}, [SOF_AFE_TOKENS] = {"AFE tokens", afe_tokens, ARRAY_SIZE(afe_tokens)}, + [SOF_ACPDMIC_TOKENS] = {"ACPDMIC tokens", acpdmic_tokens, ARRAY_SIZE(acpdmic_tokens)}, }; /** @@ -1120,20 +1131,22 @@ static int sof_link_acp_dmic_load(struct snd_soc_component *scomp, struct snd_so struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs; struct sof_dai_private_data *private = dai->private; u32 size = sizeof(*config); + int ret; /* handle master/slave and inverted clocks */ sof_dai_set_format(hw_config, config); - /* init IPC */ - memset(&config->acpdmic, 0, sizeof(config->acpdmic)); config->hdr.size = size; - config->acpdmic.fsync_rate = le32_to_cpu(hw_config->fsync_rate); - config->acpdmic.tdm_slots = le32_to_cpu(hw_config->tdm_slots); + /* parse the required set of ACPDMIC tokens based on num_hw_cfgs */ + ret = sof_update_ipc_object(scomp, &config->acpdmic, SOF_ACPDMIC_TOKENS, slink->tuples, + slink->num_tuples, size, slink->num_hw_configs); + if (ret < 0) + return ret; dev_info(scomp->dev, "ACP_DMIC config ACP%d channel %d rate %d\n", - config->dai_index, config->acpdmic.tdm_slots, - config->acpdmic.fsync_rate); + config->dai_index, config->acpdmic.pdm_ch, + config->acpdmic.pdm_rate); dai->number_configs = 1; dai->current_config = 0; diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index 79486266081f4..4284ea2f3a1ff 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -236,6 +236,7 @@ enum sof_tokens { SOF_AUDIO_FMT_NUM_TOKENS, SOF_COPIER_FORMAT_TOKENS, SOF_GAIN_TOKENS, + SOF_ACPDMIC_TOKENS, /* this should be the last */ SOF_TOKEN_COUNT, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 1893c590f2f01..7e54eb1bf77b3 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1739,6 +1739,10 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ token_id = SOF_AFE_TOKENS; num_tuples += token_list[SOF_AFE_TOKENS].count; break; + case SOF_DAI_AMD_DMIC: + token_id = SOF_ACPDMIC_TOKENS; + num_tuples += token_list[SOF_ACPDMIC_TOKENS].count; + break; default: break; } -- GitLab From 7ed1f83bb4f05fe460984ae49e98d1c1be38fb5f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 14 Jun 2022 10:56:17 +0300 Subject: [PATCH 521/942] ASoC: SOF: Compile and runtime IPC version selection The new IPC4 version is only supported by Intel platforms, iMX, AMD and MediaTek only uses the standard SOF IPC. There is no need for these platforms to build kernel support for IPC4 as it is just dead code for them. SND_SOC_SOF_IPC3 and SND_SOC_SOF_INTEL_IPC4 is introduced to allow compile time selection and exclusion of IPC implementations. To avoid randconfig failures add also support for runtime selection of the IPC ops in ipc.c based on sdev->pdata->ipc_type Signed-off-by: Peter Ujfalusi Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220614075618.28605-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/Kconfig | 7 +++++++ sound/soc/sof/Makefile | 16 ++++++++++++---- sound/soc/sof/amd/Kconfig | 1 + sound/soc/sof/imx/Kconfig | 1 + sound/soc/sof/intel/Kconfig | 11 +++++++++++ sound/soc/sof/ipc.c | 24 ++++++++++++++++++------ sound/soc/sof/mediatek/Kconfig | 1 + 7 files changed, 51 insertions(+), 10 deletions(-) diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 4542868cd730f..e90f173d067c9 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -252,6 +252,13 @@ config SND_SOC_SOF_PROBE_WORK_QUEUE When selected, the probe is handled in two steps, for example to avoid lockdeps if request_module is used in the probe. +# Supported IPC versions +config SND_SOC_SOF_IPC3 + bool + +config SND_SOC_SOF_INTEL_IPC4 + bool + source "sound/soc/sof/amd/Kconfig" source "sound/soc/sof/imx/Kconfig" source "sound/soc/sof/intel/Kconfig" diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 2fa8088707a8a..9a74ed116ed92 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -1,10 +1,18 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ - control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\ - ipc3-topology.o ipc3-control.o ipc3.o ipc3-pcm.o ipc3-loader.o\ - ipc3-dtrace.o\ - ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o + control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o + +# IPC implementations +ifneq ($(CONFIG_SND_SOC_SOF_IPC3),) +snd-sof-objs += ipc3.o ipc3-loader.o ipc3-topology.o ipc3-control.o ipc3-pcm.o\ + ipc3-dtrace.o +endif +ifneq ($(CONFIG_SND_SOC_SOF_INTEL_IPC4),) +snd-sof-objs += ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o +endif + +# SOF client support ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),) snd-sof-objs += sof-client.o endif diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig index 085232e04582e..190c85d57047b 100644 --- a/sound/soc/sof/amd/Kconfig +++ b/sound/soc/sof/amd/Kconfig @@ -17,6 +17,7 @@ if SND_SOC_SOF_AMD_TOPLEVEL config SND_SOC_SOF_AMD_COMMON tristate select SND_SOC_SOF + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_PCI_DEV select SND_AMD_ACP_CONFIG select SND_SOC_ACPI if ACPI diff --git a/sound/soc/sof/imx/Kconfig b/sound/soc/sof/imx/Kconfig index 9b8d5bb1e4491..cc6e695f913a1 100644 --- a/sound/soc/sof/imx/Kconfig +++ b/sound/soc/sof/imx/Kconfig @@ -15,6 +15,7 @@ config SND_SOC_SOF_IMX_COMMON tristate select SND_SOC_SOF_OF_DEV select SND_SOC_SOF + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_XTENSA select SND_SOC_SOF_COMPRESS help diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 0def2aa5581da..80cdc3788bbed 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -40,6 +40,7 @@ if SND_SOC_SOF_ACPI config SND_SOC_SOF_BAYTRAIL tristate "SOF support for Baytrail, Braswell and Cherrytrail" default SND_SOC_SOF_ACPI + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_INTEL_COMMON select SND_SOC_SOF_INTEL_ATOM_HIFI_EP select SND_SOC_SOF_ACPI_DEV @@ -60,6 +61,7 @@ config SND_SOC_SOF_BAYTRAIL config SND_SOC_SOF_BROADWELL tristate "SOF support for Broadwell" default SND_SOC_SOF_ACPI + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_INTEL_COMMON select SND_SOC_SOF_INTEL_HIFI_EP_IPC select SND_SOC_SOF_ACPI_DEV @@ -85,6 +87,7 @@ config SND_SOC_SOF_MERRIFIELD tristate "SOF support for Tangier/Merrifield" default SND_SOC_SOF_PCI select SND_SOC_SOF_PCI_DEV + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_INTEL_ATOM_HIFI_EP help This adds support for Sound Open Firmware for Intel(R) platforms @@ -95,6 +98,8 @@ config SND_SOC_SOF_MERRIFIELD config SND_SOC_SOF_INTEL_APL tristate select SND_SOC_SOF_HDA_COMMON + select SND_SOC_SOF_IPC3 + select SND_SOC_SOF_INTEL_IPC4 config SND_SOC_SOF_APOLLOLAKE tristate "SOF support for Apollolake" @@ -120,6 +125,8 @@ config SND_SOC_SOF_INTEL_CNL tristate select SND_SOC_SOF_HDA_COMMON select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE + select SND_SOC_SOF_IPC3 + select SND_SOC_SOF_INTEL_IPC4 config SND_SOC_SOF_CANNONLAKE tristate "SOF support for Cannonlake" @@ -154,6 +161,8 @@ config SND_SOC_SOF_INTEL_ICL tristate select SND_SOC_SOF_HDA_COMMON select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE + select SND_SOC_SOF_IPC3 + select SND_SOC_SOF_INTEL_IPC4 config SND_SOC_SOF_ICELAKE tristate "SOF support for Icelake" @@ -179,6 +188,8 @@ config SND_SOC_SOF_INTEL_TGL tristate select SND_SOC_SOF_HDA_COMMON select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE + select SND_SOC_SOF_IPC3 + select SND_SOC_SOF_INTEL_IPC4 config SND_SOC_SOF_TIGERLAKE tristate "SOF support for Tigerlake" diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index c5aef5fc056b5..6ed3f9b6a0c4e 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -155,12 +155,22 @@ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev) init_waitqueue_head(&msg->waitq); - /* - * Use IPC3 ops as it is the only available version now. With the addition of new IPC - * versions, this will need to be modified to use the selected version at runtime. - */ - ipc->ops = &ipc3_ops; - ops = ipc->ops; + switch (sdev->pdata->ipc_type) { +#if defined(CONFIG_SND_SOC_SOF_IPC3) + case SOF_IPC: + ops = &ipc3_ops; + break; +#endif +#if defined(CONFIG_SND_SOC_SOF_INTEL_IPC4) + case SOF_INTEL_IPC4: + ops = &ipc4_ops; + break; +#endif + default: + dev_err(sdev->dev, "Not supported IPC version: %d\n", + sdev->pdata->ipc_type); + return NULL; + } /* check for mandatory ops */ if (!ops->tx_msg || !ops->rx_msg || !ops->set_get_data || !ops->get_reply) { @@ -190,6 +200,8 @@ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev) return NULL; } + ipc->ops = ops; + return ipc; } EXPORT_SYMBOL(snd_sof_ipc_init); diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig index a149dd1b3f44c..4a2eddf6009a5 100644 --- a/sound/soc/sof/mediatek/Kconfig +++ b/sound/soc/sof/mediatek/Kconfig @@ -15,6 +15,7 @@ config SND_SOC_SOF_MTK_COMMON tristate select SND_SOC_SOF_OF_DEV select SND_SOC_SOF + select SND_SOC_SOF_IPC3 select SND_SOC_SOF_XTENSA select SND_SOC_SOF_COMPRESS help -- GitLab From 30ac49841386f933339817771ec315a34a4c0edd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 13:25:08 +0200 Subject: [PATCH 522/942] ASoC: ops: Don't modify the driver's plaform_max when reading state Currently snd_soc_info_volsw() will set a platform_max based on the limit the control has if one is not already set. This isn't really great, we shouldn't be modifying the passed in driver data especially in a path like this which may not ever be executed or where we may execute other callbacks before this one. Instead make this function leave the data unchanged, and clarify things a bit by referring to max rather than platform_max within the function. platform_max is now applied as a limit after working out the natural maximum value for the control. This means that platform_max is no longer treated as a direct register value for controls were min is non-zero. The put() callbacks already validate on this basis, and there do not appear to be any in tree users that would be affected. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220603112508.3856519-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 184910ed2d7b3..b624ed79ade33 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -176,20 +176,21 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - int platform_max; + int max; - if (!mc->platform_max) - mc->platform_max = mc->max; - platform_max = mc->platform_max; + max = uinfo->value.integer.max = mc->max - mc->min; + if (mc->platform_max && mc->platform_max < max) + max = mc->platform_max; - if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) + if (max == 1 && !strstr(kcontrol->id.name, " Volume")) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; uinfo->value.integer.min = 0; - uinfo->value.integer.max = platform_max - mc->min; + uinfo->value.integer.max = max; + return 0; } EXPORT_SYMBOL_GPL(snd_soc_info_volsw); -- GitLab From a150345aa758492e05d2934f318ce7c2566b1cfe Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 14 Jun 2022 17:26:30 +0800 Subject: [PATCH 523/942] ASoC: SOF: ipc4-topology: add SoundWire/ALH aggregation support Some SoundWire hardware topologies rely on different amplifiers or capture devices connected on different links. These devices need to be 'aggregated', remain synchronized and be handled as a single logical device. In the IPC3 solution, the aggregation for amplifiers was handled by a firmware 'demux' component. In the IPC4 solution, the demux component is not needed, the gateway component can handle multiple ALH/DMA transfers at the same time. This change makes the topology slightly more complicated in that only one ALH DAI will be connected in the topology with the gateway. The other DAIs that are part of the 'aggregated' dailink are not shown in the DAPM graph as connected to the gateway, but they will however be activated thanks to a feature in soc-dapm.c where events are forwarded to all DAIs in the dailink (see soc_dapm_stream_event). The topology also sets the same stream name for all widgets, dais and dailinks, so a search for the stream name helps identify cases where SoundWire/ALH aggregation is needed. Signed-off-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220614092630.20144-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 68 ++++++++++++++++++++++++++++++++--- sound/soc/sof/ipc4-topology.h | 11 ++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index cb0f0823b8ebc..3c949298e007f 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -19,6 +19,8 @@ #define SOF_IPC4_GAIN_PARAM_ID 0 #define SOF_IPC4_TPLG_ABI_SIZE 6 +static DEFINE_IDA(alh_group_ida); + static const struct sof_topology_token ipc4_sched_tokens[] = { {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, offsetof(struct sof_ipc4_pipeline, lp_mode)} @@ -478,7 +480,9 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) switch (ipc4_copier->dai_type) { case SOF_DAI_INTEL_ALH: { + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct sof_ipc4_alh_configuration_blob *blob; + struct snd_sof_widget *w; blob = kzalloc(sizeof(*blob), GFP_KERNEL); if (!blob) { @@ -486,6 +490,14 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) goto err; } + list_for_each_entry(w, &sdev->widget_list, list) { + if (w->widget->sname && + strcmp(w->widget->sname, swidget->widget->sname)) + continue; + + blob->alh_cfg.count++; + } + ipc4_copier->copier_config = (uint32_t *)blob; ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; break; @@ -844,6 +856,17 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) struct snd_sof_dai *dai = swidget->private; ipc4_copier = dai->private; + if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { + struct sof_ipc4_alh_configuration_blob *blob; + unsigned int group_id; + + blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; + if (blob->alh_cfg.count > 1) { + group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - + ALH_MULTI_GTW_BASE; + ida_free(&alh_group_ida, group_id); + } + } } if (ipc4_copier) { @@ -973,6 +996,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, struct sof_ipc4_copier_data *copier_data; struct snd_pcm_hw_params *ref_params; struct sof_ipc4_copier *ipc4_copier; + struct snd_sof_dai *dai; struct snd_mask *fmt; int out_sample_valid_bits; size_t ref_audio_fmt_size; @@ -1022,7 +1046,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, case snd_soc_dapm_dai_in: case snd_soc_dapm_dai_out: { - struct snd_sof_dai *dai = swidget->private; + dai = swidget->private; ipc4_copier = (struct sof_ipc4_copier *)dai->private; copier_data = &ipc4_copier->data; @@ -1077,22 +1101,56 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, */ if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { struct sof_ipc4_alh_configuration_blob *blob; + struct sof_ipc4_copier_data *alh_data; + struct sof_ipc4_copier *alh_copier; + struct snd_sof_widget *w; + u32 ch_mask = 0; u32 ch_map; int i; blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; - /* TODO: add aggregation mode support */ - blob->alh_cfg.count = 1; - blob->alh_cfg.mapping[0].alh_id = copier_data->gtw_cfg.node_id; + blob->gw_attr.lp_buffer_alloc = 0; /* Get channel_mask from ch_map */ ch_map = copier_data->base_config.audio_fmt.ch_map; for (i = 0; ch_map; i++) { if ((ch_map & 0xf) != 0xf) - blob->alh_cfg.mapping[0].channel_mask |= BIT(i); + ch_mask |= BIT(i); ch_map >>= 4; } + + /* + * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] + * for all widgets with the same stream name + */ + i = 0; + list_for_each_entry(w, &sdev->widget_list, list) { + if (w->widget->sname && + strcmp(w->widget->sname, swidget->widget->sname)) + continue; + + dai = w->private; + alh_copier = (struct sof_ipc4_copier *)dai->private; + alh_data = &alh_copier->data; + blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id; + blob->alh_cfg.mapping[i].channel_mask = ch_mask; + i++; + } + if (blob->alh_cfg.count > 1) { + int group_id; + + group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT, + GFP_KERNEL); + + if (group_id < 0) + return group_id; + + /* add multi-gateway base */ + group_id += ALH_MULTI_GTW_BASE; + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; + copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); + } } } } diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h index 1a9c0627bae9d..3bc2fe38c7333 100644 --- a/sound/soc/sof/ipc4-topology.h +++ b/sound/soc/sof/ipc4-topology.h @@ -42,6 +42,17 @@ #define ALH_MAX_NUMBER_OF_GTW 16 +/* + * The base of multi-gateways. Multi-gateways addressing starts from + * ALH_MULTI_GTW_BASE and there are ALH_MULTI_GTW_COUNT multi-sources + * and ALH_MULTI_GTW_COUNT multi-sinks available. + * Addressing is continuous from ALH_MULTI_GTW_BASE to + * ALH_MULTI_GTW_BASE + ALH_MULTI_GTW_COUNT - 1. + */ +#define ALH_MULTI_GTW_BASE 0x50 +/* A magic number from FW */ +#define ALH_MULTI_GTW_COUNT 8 + /** * struct sof_ipc4_pipeline - pipeline config data * @priority: Priority of this pipeline -- GitLab From aa2a4b897132169fbc6d32932644b95875cf9c7f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 4 Jun 2022 11:54:07 +0100 Subject: [PATCH 524/942] ASoC: ops: Fix boolean/integer detection for simple controls The standard snd_soc_info_volsw() detects if a control is a volume control and needs to be reported as an integer even if it only has two values by looking for the string " Volume" in the control name. This results in false positives if the control has a name like "HP Volume Ramp Switch" since any " Volume" is matched, not just a trailing one. Fix this by making sure that we only match at the end of the control name. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220604105407.4055294-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index b624ed79ade33..c22d87581f6f2 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -176,13 +176,21 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; + const char *vol_string = NULL; int max; max = uinfo->value.integer.max = mc->max - mc->min; if (mc->platform_max && mc->platform_max < max) max = mc->platform_max; - if (max == 1 && !strstr(kcontrol->id.name, " Volume")) + /* Even two value controls ending in Volume should always be integer */ + if (max == 1) { + vol_string = strstr(kcontrol->id.name, " Volume"); + if (vol_string && strcmp(vol_string, " Volume")) + vol_string = NULL; + } + + if (!vol_string) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -- GitLab From d919630fe77904931277e663c902582ea6f4e4cf Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 14 Jun 2022 14:10:22 +0100 Subject: [PATCH 525/942] ASoC: cs35l45: Add endianness flag in snd_soc_component_driver The endianness flag is used on the CODEC side to specify an ambivalence to endian, typically because it is lost over the hardware link. This device receives audio over an I2S DAI and as such should have endianness applied. Fixes: 0d463d016000 ("ASoC: cs35l45: Add driver for Cirrus Logic CS35L45 Smart Amp") Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220614131022.778057-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l45.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index c94edfce4b720..d15b3b77c7eb0 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -500,6 +500,8 @@ static const struct snd_soc_component_driver cs35l45_component = { .num_controls = ARRAY_SIZE(cs35l45_controls), .name = "cs35l45", + + .endianness = 1, }; static int __maybe_unused cs35l45_runtime_suspend(struct device *dev) -- GitLab From c27e1efb61c545f36c450ef60862df9251d239a4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Jun 2022 08:45:37 +0200 Subject: [PATCH 526/942] ALSA: control: Use xarray for faster lookups The control elements are managed in a single linked list and we traverse the whole list for matching each numid or ctl id per every inquiry of a control element. This is OK-ish for a small number of elements but obviously it doesn't scale. Especially the matching with the ctl id takes time because it checks each field of the snd_ctl_id element, e.g. the name string is matched with strcmp(). This patch adds the hash tables with Xarray for improving the lookup speed of a control element. There are two xarray tables added to the card; one for numid and another for ctl id. For the numid, we use the numid as the index, while for the ctl id, we calculate a hash key. The lookup is done via a single xa_load() execution. As long as the given control element is found on the Xarray table, that's fine, we can give back a quick lookup result. The problem is when no entry hits on the table, and for this case, we have a slight optimization. Namely, the driver checks whether we had a collision on Xarray table, and do a fallback search (linear lookup of the full entries) only if a hash key collision happened beforehand. So, in theory, the inquiry for a non-existing element might take still time even with this patch in a worst case, but this must be pretty rare. The feature is enabled via CONFIG_SND_CTL_FAST_LOOKUP, which is turned on as default. For simplicity, the option can be turned off only when CONFIG_EXPERT is set ("You are expert? Then you manage 1000 knobs"). Link: https://lore.kernel.org/r/20211028130027.18764-1-tiwai@suse.de Link: https://lore.kernel.org/r/20220609180504.775-1-tiwai@suse.de Link: https://lore.kernel.org/all/cover.1653813866.git.quic_rbankapu@quicinc.com/ Link: https://lore.kernel.org/r/20220610064537.18660-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/core.h | 6 ++ sound/core/Kconfig | 10 +++ sound/core/control.c | 180 +++++++++++++++++++++++++++++++++++-------- sound/core/init.c | 4 + 4 files changed, 168 insertions(+), 32 deletions(-) diff --git a/include/sound/core.h b/include/sound/core.h index 6d4cc49584c63..dd28de2343b80 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -14,6 +14,7 @@ #include /* pm_message_t */ #include #include +#include /* number of supported soundcards */ #ifdef CONFIG_SND_DYNAMIC_MINORS @@ -103,6 +104,11 @@ struct snd_card { size_t user_ctl_alloc_size; // current memory allocation by user controls. struct list_head controls; /* all controls for this card */ struct list_head ctl_files; /* active control files */ +#ifdef CONFIG_SND_CTL_FAST_LOOKUP + struct xarray ctl_numids; /* hash table for numids */ + struct xarray ctl_hash; /* hash table for ctl id matching */ + bool ctl_hash_collision; /* ctl_hash collision seen? */ +#endif struct snd_info_entry *proc_root; /* root for soundcard specific files */ struct proc_dir_entry *proc_root_link; /* number link to real id */ diff --git a/sound/core/Kconfig b/sound/core/Kconfig index dd7b407347230..25b2434e45567 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -154,6 +154,16 @@ config SND_VERBOSE_PRINTK You don't need this unless you're debugging ALSA. +config SND_CTL_FAST_LOOKUP + bool "Fast lookup of control elements" if EXPERT + default y + select XARRAY_MULTI + help + This option enables the faster lookup of control elements. + It will consume more memory because of the additional Xarray. + If you want to choose the memory footprint over the performance + inevitably, turn this off. + config SND_DEBUG bool "Debug" help diff --git a/sound/core/control.c b/sound/core/control.c index a25c0d64d104f..6a8fd9933f062 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -364,6 +364,93 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) return 0; } +/* check whether the given id is contained in the given kctl */ +static bool elem_id_matches(const struct snd_kcontrol *kctl, + const struct snd_ctl_elem_id *id) +{ + return kctl->id.iface == id->iface && + kctl->id.device == id->device && + kctl->id.subdevice == id->subdevice && + !strncmp(kctl->id.name, id->name, sizeof(kctl->id.name)) && + kctl->id.index <= id->index && + kctl->id.index + kctl->count > id->index; +} + +#ifdef CONFIG_SND_CTL_FAST_LOOKUP +/* Compute a hash key for the corresponding ctl id + * It's for the name lookup, hence the numid is excluded. + * The hash key is bound in LONG_MAX to be used for Xarray key. + */ +#define MULTIPLIER 37 +static unsigned long get_ctl_id_hash(const struct snd_ctl_elem_id *id) +{ + unsigned long h; + const unsigned char *p; + + h = id->iface; + h = MULTIPLIER * h + id->device; + h = MULTIPLIER * h + id->subdevice; + for (p = id->name; *p; p++) + h = MULTIPLIER * h + *p; + h = MULTIPLIER * h + id->index; + h &= LONG_MAX; + return h; +} + +/* add hash entries to numid and ctl xarray tables */ +static void add_hash_entries(struct snd_card *card, + struct snd_kcontrol *kcontrol) +{ + struct snd_ctl_elem_id id = kcontrol->id; + int i; + + xa_store_range(&card->ctl_numids, kcontrol->id.numid, + kcontrol->id.numid + kcontrol->count - 1, + kcontrol, GFP_KERNEL); + + for (i = 0; i < kcontrol->count; i++) { + id.index = kcontrol->id.index + i; + if (xa_insert(&card->ctl_hash, get_ctl_id_hash(&id), + kcontrol, GFP_KERNEL)) { + /* skip hash for this entry, noting we had collision */ + card->ctl_hash_collision = true; + dev_dbg(card->dev, "ctl_hash collision %d:%s:%d\n", + id.iface, id.name, id.index); + } + } +} + +/* remove hash entries that have been added */ +static void remove_hash_entries(struct snd_card *card, + struct snd_kcontrol *kcontrol) +{ + struct snd_ctl_elem_id id = kcontrol->id; + struct snd_kcontrol *matched; + unsigned long h; + int i; + + for (i = 0; i < kcontrol->count; i++) { + xa_erase(&card->ctl_numids, id.numid); + h = get_ctl_id_hash(&id); + matched = xa_load(&card->ctl_hash, h); + if (matched && (matched == kcontrol || + elem_id_matches(matched, &id))) + xa_erase(&card->ctl_hash, h); + id.index++; + id.numid++; + } +} +#else /* CONFIG_SND_CTL_FAST_LOOKUP */ +static inline void add_hash_entries(struct snd_card *card, + struct snd_kcontrol *kcontrol) +{ +} +static inline void remove_hash_entries(struct snd_card *card, + struct snd_kcontrol *kcontrol) +{ +} +#endif /* CONFIG_SND_CTL_FAST_LOOKUP */ + enum snd_ctl_add_mode { CTL_ADD_EXCLUSIVE, CTL_REPLACE, CTL_ADD_ON_REPLACE, }; @@ -408,6 +495,8 @@ static int __snd_ctl_add_replace(struct snd_card *card, kcontrol->id.numid = card->last_numid + 1; card->last_numid += kcontrol->count; + add_hash_entries(card, kcontrol); + for (idx = 0; idx < kcontrol->count; idx++) snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_ADD, kcontrol, idx); @@ -479,6 +568,26 @@ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, } EXPORT_SYMBOL(snd_ctl_replace); +static int __snd_ctl_remove(struct snd_card *card, + struct snd_kcontrol *kcontrol, + bool remove_hash) +{ + unsigned int idx; + + if (snd_BUG_ON(!card || !kcontrol)) + return -EINVAL; + list_del(&kcontrol->list); + + if (remove_hash) + remove_hash_entries(card, kcontrol); + + card->controls_count -= kcontrol->count; + for (idx = 0; idx < kcontrol->count; idx++) + snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_REMOVE, kcontrol, idx); + snd_ctl_free_one(kcontrol); + return 0; +} + /** * snd_ctl_remove - remove the control from the card and release it * @card: the card instance @@ -492,16 +601,7 @@ EXPORT_SYMBOL(snd_ctl_replace); */ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) { - unsigned int idx; - - if (snd_BUG_ON(!card || !kcontrol)) - return -EINVAL; - list_del(&kcontrol->list); - card->controls_count -= kcontrol->count; - for (idx = 0; idx < kcontrol->count; idx++) - snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_REMOVE, kcontrol, idx); - snd_ctl_free_one(kcontrol); - return 0; + return __snd_ctl_remove(card, kcontrol, true); } EXPORT_SYMBOL(snd_ctl_remove); @@ -642,14 +742,30 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, up_write(&card->controls_rwsem); return -ENOENT; } + remove_hash_entries(card, kctl); kctl->id = *dst_id; kctl->id.numid = card->last_numid + 1; card->last_numid += kctl->count; + add_hash_entries(card, kctl); up_write(&card->controls_rwsem); return 0; } EXPORT_SYMBOL(snd_ctl_rename_id); +#ifndef CONFIG_SND_CTL_FAST_LOOKUP +static struct snd_kcontrol * +snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) +{ + struct snd_kcontrol *kctl; + + list_for_each_entry(kctl, &card->controls, list) { + if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) + return kctl; + } + return NULL; +} +#endif /* !CONFIG_SND_CTL_FAST_LOOKUP */ + /** * snd_ctl_find_numid - find the control instance with the given number-id * @card: the card instance @@ -665,15 +781,13 @@ EXPORT_SYMBOL(snd_ctl_rename_id); */ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid) { - struct snd_kcontrol *kctl; - if (snd_BUG_ON(!card || !numid)) return NULL; - list_for_each_entry(kctl, &card->controls, list) { - if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) - return kctl; - } - return NULL; +#ifdef CONFIG_SND_CTL_FAST_LOOKUP + return xa_load(&card->ctl_numids, numid); +#else + return snd_ctl_find_numid_slow(card, numid); +#endif } EXPORT_SYMBOL(snd_ctl_find_numid); @@ -699,21 +813,18 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, return NULL; if (id->numid != 0) return snd_ctl_find_numid(card, id->numid); - list_for_each_entry(kctl, &card->controls, list) { - if (kctl->id.iface != id->iface) - continue; - if (kctl->id.device != id->device) - continue; - if (kctl->id.subdevice != id->subdevice) - continue; - if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name))) - continue; - if (kctl->id.index > id->index) - continue; - if (kctl->id.index + kctl->count <= id->index) - continue; +#ifdef CONFIG_SND_CTL_FAST_LOOKUP + kctl = xa_load(&card->ctl_hash, get_ctl_id_hash(id)); + if (kctl && elem_id_matches(kctl, id)) return kctl; - } + if (!card->ctl_hash_collision) + return NULL; /* we can rely on only hash table */ +#endif + /* no matching in hash table - try all as the last resort */ + list_for_each_entry(kctl, &card->controls, list) + if (elem_id_matches(kctl, id)) + return kctl; + return NULL; } EXPORT_SYMBOL(snd_ctl_find_id); @@ -2195,8 +2306,13 @@ static int snd_ctl_dev_free(struct snd_device *device) down_write(&card->controls_rwsem); while (!list_empty(&card->controls)) { control = snd_kcontrol(card->controls.next); - snd_ctl_remove(card, control); + __snd_ctl_remove(card, control, false); } + +#ifdef CONFIG_SND_CTL_FAST_LOOKUP + xa_destroy(&card->ctl_numids); + xa_destroy(&card->ctl_hash); +#endif up_write(&card->controls_rwsem); put_device(&card->ctl_dev); return 0; diff --git a/sound/core/init.c b/sound/core/init.c index 726a8353201f8..1870aee7b64f6 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -310,6 +310,10 @@ static int snd_card_init(struct snd_card *card, struct device *parent, rwlock_init(&card->ctl_files_rwlock); INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); +#ifdef CONFIG_SND_CTL_FAST_LOOKUP + xa_init(&card->ctl_numids); + xa_init(&card->ctl_hash); +#endif spin_lock_init(&card->files_lock); INIT_LIST_HEAD(&card->files_list); mutex_init(&card->memory_mutex); -- GitLab From 2c7463d070c4e49ff850322d4f0321e97b0b6740 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 9 Jun 2022 14:02:16 +0200 Subject: [PATCH 527/942] ASoC: topology: Drop superfluous check of CONFIG_SND_CTL_VALIDATION The compiler must be clever enough to optimize out for the no-op when CONFIG_SND_CTL_VALIDATION is disabled. Let's drop the superfluous check. Link: https://lore.kernel.org/r/20220609120219.3937-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/soc/soc-topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 3f9d314fba168..b101db85446ff 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -535,7 +535,7 @@ static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr, * return an -EINVAL error and prevent the card from * being configured. */ - if (IS_ENABLED(CONFIG_SND_CTL_VALIDATION) && sbe->max > 512) + if (sbe->max > 512) k->access |= SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK; ext_ops = tplg->bytes_ext_ops; -- GitLab From 1b7ec5143c34f167266fa21245d99bacb4db4aa6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 9 Jun 2022 14:02:17 +0200 Subject: [PATCH 528/942] ALSA: control: Rename CONFIG_SND_CTL_VALIDATION to CONFIG_SND_CTL_DEBUG The purpose of CONFIG_SND_CTL_VALIDATION is rather to enable the debugging feature for the control API. The validation is only a part of it. Let's rename it to be more explicit and intuitive. While we're at it, let's advertise, give more comment to recommend this feature for development in the kconfig help text. Link: https://lore.kernel.org/r/20220609120219.3937-3-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/control.h | 2 +- sound/core/Kconfig | 17 +++++++++++------ sound/core/control.c | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/include/sound/control.h b/include/sound/control.h index 985c51a8fb748..fcd3cce673ec3 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -23,7 +23,7 @@ typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol, unsigned int __user *tlv); /* internal flag for skipping validations */ -#ifdef CONFIG_SND_CTL_VALIDATION +#ifdef CONFIG_SND_CTL_DEBUG #define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK (1 << 24) #define snd_ctl_skip_validation(info) \ ((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK) diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 25b2434e45567..5289bb29131ba 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -188,14 +188,19 @@ config SND_PCM_XRUN_DEBUG sound clicking when system is loaded, it may help to determine the process or driver which causes the scheduling gaps. -config SND_CTL_VALIDATION - bool "Perform sanity-checks for each control element access" +config SND_CTL_DEBUG + bool "Enable debugging feature for control API" depends on SND_DEBUG help - Say Y to enable the additional validation of each control element - access, including sanity-checks like whether the values returned - from the driver are in the proper ranges or the check of the invalid - access at out-of-array areas. + Say Y to enable the debugging feature for ALSA control API. + It performs the additional sanity-checks for each control element + read access, such as whether the values returned from the driver + are in the proper ranges or the check of the invalid access at + out-of-array areas. The error is printed when the driver gives + such unexpected values. + When you develop a driver that deals with control elements, it's + strongly recommended to try this one once and verify whether you see + any relevant errors or not. config SND_JACK_INJECTION_DEBUG bool "Sound jack injection interface via debugfs" diff --git a/sound/core/control.c b/sound/core/control.c index 6a8fd9933f062..1401522ce552d 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -966,7 +966,7 @@ static const unsigned int value_sizes[] = { [SNDRV_CTL_ELEM_TYPE_INTEGER64] = sizeof(long long), }; -#ifdef CONFIG_SND_CTL_VALIDATION +#ifdef CONFIG_SND_CTL_DEBUG /* fill the remaining snd_ctl_elem_value data with the given pattern */ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control, struct snd_ctl_elem_info *info, @@ -1188,7 +1188,7 @@ static int snd_ctl_elem_read(struct snd_card *card, snd_ctl_build_ioff(&control->id, kctl, index_offset); -#ifdef CONFIG_SND_CTL_VALIDATION +#ifdef CONFIG_SND_CTL_DEBUG /* info is needed only for validation */ memset(&info, 0, sizeof(info)); info.id = control->id; -- GitLab From 4e54316ad2485dedf8570fc2afa6fa6ce32db207 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 9 Jun 2022 14:02:18 +0200 Subject: [PATCH 529/942] ALSA: control: Drop superfluous ifdef CONFIG_SND_CTL_DEBUG Compilers should be smart enough to optimize out the dead functions, so we don't need to define ugly dummy functions with ifdef. Link: https://lore.kernel.org/r/20220609120219.3937-4-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/control.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index 1401522ce552d..559398891eb97 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -966,7 +966,6 @@ static const unsigned int value_sizes[] = { [SNDRV_CTL_ELEM_TYPE_INTEGER64] = sizeof(long long), }; -#ifdef CONFIG_SND_CTL_DEBUG /* fill the remaining snd_ctl_elem_value data with the given pattern */ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control, struct snd_ctl_elem_info *info, @@ -1078,21 +1077,6 @@ static int sanity_check_elem_value(struct snd_card *card, return ret; } -#else -static inline void fill_remaining_elem_value(struct snd_ctl_elem_value *control, - struct snd_ctl_elem_info *info, - u32 pattern) -{ -} - -static inline int sanity_check_elem_value(struct snd_card *card, - struct snd_ctl_elem_value *control, - struct snd_ctl_elem_info *info, - u32 pattern) -{ - return 0; -} -#endif static int __snd_ctl_elem_info(struct snd_card *card, struct snd_kcontrol *kctl, -- GitLab From f5e829f92a494a0b66d309497bab4e9d10d4ce3e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 9 Jun 2022 14:02:19 +0200 Subject: [PATCH 530/942] ALSA: control: Add input validation This patch adds a new feature to enable the validation of input data to control elements in the ALSA core side. When CONFIG_SND_CTL_INPUT_VALIDATION is set, ALSA core verifies whether the each input value via control API is in the defined ranges, also checks whether it's aligned to the defined steps. If an invalid value is detected, ALSA core returns -EINVAL error immediately without passing further to the driver's callback. So this is a kind of hardening for (badly written) drivers that have no proper error checks, at the cost of a slight performance overhead. Technically seen, this reuses a part of the existing validation code for CONFIG_SND_CTL_DEBUG case with a slight modification to suppress error prints for the input validation. Link: https://lore.kernel.org/r/20220609120219.3937-5-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/Kconfig | 10 +++++++ sound/core/control.c | 69 +++++++++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 5289bb29131ba..12990d9a4dffe 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -188,6 +188,16 @@ config SND_PCM_XRUN_DEBUG sound clicking when system is loaded, it may help to determine the process or driver which causes the scheduling gaps. +config SND_CTL_INPUT_VALIDATION + bool "Validate input data to control API" + help + Say Y to enable the additional validation for the input data to + each control element, including the value range checks. + An error is returned from ALSA core for invalid inputs without + passing to the driver. This is a kind of hardening for drivers + that have no proper error checks, at the cost of a slight + performance overhead. + config SND_CTL_DEBUG bool "Enable debugging feature for control API" depends on SND_DEBUG diff --git a/sound/core/control.c b/sound/core/control.c index 559398891eb97..fa04a92331554 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -982,7 +982,7 @@ static void fill_remaining_elem_value(struct snd_ctl_elem_value *control, static int sanity_check_int_value(struct snd_card *card, const struct snd_ctl_elem_value *control, const struct snd_ctl_elem_info *info, - int i) + int i, bool print_error) { long long lval, lmin, lmax, lstep; u64 rem; @@ -1016,21 +1016,23 @@ static int sanity_check_int_value(struct snd_card *card, } if (lval < lmin || lval > lmax) { - dev_err(card->dev, - "control %i:%i:%i:%s:%i: value out of range %lld (%lld/%lld) at count %i\n", - control->id.iface, control->id.device, - control->id.subdevice, control->id.name, - control->id.index, lval, lmin, lmax, i); + if (print_error) + dev_err(card->dev, + "control %i:%i:%i:%s:%i: value out of range %lld (%lld/%lld) at count %i\n", + control->id.iface, control->id.device, + control->id.subdevice, control->id.name, + control->id.index, lval, lmin, lmax, i); return -EINVAL; } if (lstep) { div64_u64_rem(lval, lstep, &rem); if (rem) { - dev_err(card->dev, - "control %i:%i:%i:%s:%i: unaligned value %lld (step %lld) at count %i\n", - control->id.iface, control->id.device, - control->id.subdevice, control->id.name, - control->id.index, lval, lstep, i); + if (print_error) + dev_err(card->dev, + "control %i:%i:%i:%s:%i: unaligned value %lld (step %lld) at count %i\n", + control->id.iface, control->id.device, + control->id.subdevice, control->id.name, + control->id.index, lval, lstep, i); return -EINVAL; } } @@ -1038,15 +1040,13 @@ static int sanity_check_int_value(struct snd_card *card, return 0; } -/* perform sanity checks to the given snd_ctl_elem_value object */ -static int sanity_check_elem_value(struct snd_card *card, - const struct snd_ctl_elem_value *control, - const struct snd_ctl_elem_info *info, - u32 pattern) +/* check whether the all input values are valid for the given elem value */ +static int sanity_check_input_values(struct snd_card *card, + const struct snd_ctl_elem_value *control, + const struct snd_ctl_elem_info *info, + bool print_error) { - size_t offset; - int i, ret = 0; - u32 *p; + int i, ret; switch (info->type) { case SNDRV_CTL_ELEM_TYPE_BOOLEAN: @@ -1054,7 +1054,8 @@ static int sanity_check_elem_value(struct snd_card *card, case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_ENUMERATED: for (i = 0; i < info->count; i++) { - ret = sanity_check_int_value(card, control, info, i); + ret = sanity_check_int_value(card, control, info, i, + print_error); if (ret < 0) return ret; } @@ -1063,6 +1064,23 @@ static int sanity_check_elem_value(struct snd_card *card, break; } + return 0; +} + +/* perform sanity checks to the given snd_ctl_elem_value object */ +static int sanity_check_elem_value(struct snd_card *card, + const struct snd_ctl_elem_value *control, + const struct snd_ctl_elem_info *info, + u32 pattern) +{ + size_t offset; + int ret; + u32 *p; + + ret = sanity_check_input_values(card, control, info, true); + if (ret < 0) + return ret; + /* check whether the remaining area kept untouched */ offset = value_sizes[info->type] * info->count; offset = DIV_ROUND_UP(offset, sizeof(u32)); @@ -1249,6 +1267,17 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, snd_ctl_build_ioff(&control->id, kctl, index_offset); result = snd_power_ref_and_wait(card); + /* validate input values */ + if (IS_ENABLED(CONFIG_SND_CTL_INPUT_VALIDATION) && !result) { + struct snd_ctl_elem_info info; + + memset(&info, 0, sizeof(info)); + info.id = control->id; + result = __snd_ctl_elem_info(card, kctl, &info, NULL); + if (!result) + result = sanity_check_input_values(card, control, &info, + false); + } if (!result) result = kctl->put(kctl, control); snd_power_unref(card); -- GitLab From 5983a8a4a4dc13b5f192212a5e744eb303cd65c2 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Wed, 15 Jun 2022 13:34:37 +0530 Subject: [PATCH 531/942] ASoC: tegra: Fix clock DAI format on Tegra210 I2S reset failures are seen on Tegra210 and later platforms. This indicates absence of I2S bit clock, which is required to perform the reset operation. Following failures are seen with I2S based tests on Tegra210 and later: tegra210-i2s 2901100.i2s: timeout: failed to reset I2S for playback tegra210-i2s 2901100.i2s: ASoC: PRE_PMU: I2S2 RX event failed: -110 tegra210-i2s 2901100.i2s: timeout: failed to reset I2S for capture tegra210-i2s 2901100.i2s: ASoC: PRE_PMU: I2S2 TX event failed: -110 The commit d92ad6633fa7 ("ASoC: tegra: Update to use set_fmt_new callback") regressed I2S functionality on Tegra platforms. Basically it flipped clock provider and consumer DAI formats. This configures Tegra I2S in consumer mode by default now and there is none to provide bit clock during loopback tests. The external codec based tests also fail because both Tegra I2S and codec I2S get configured in consumer mode. ASoC core flips the DAI format before calling set_fmt() for CPU DAIs. This is negated in above commit. Fix this by swapping SND_SOC_DAIFMT_BC_FC and SND_SOC_DAIFMT_BP_FP switch cases. Fixes: d92ad6633fa7 ("ASoC: tegra: Update to use set_fmt_new callback") Signed-off-by: Sameer Pujar Cc: Charles Keepax Link: https://lore.kernel.org/r/1655280277-4701-1-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index a28945895466b..01c76ba36e1ac 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -215,10 +215,10 @@ static int tegra210_i2s_set_fmt(struct snd_soc_dai *dai, mask = I2S_CTRL_MASTER_EN_MASK; switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BP_FP: + case SND_SOC_DAIFMT_BC_FC: val = 0; break; - case SND_SOC_DAIFMT_BC_FC: + case SND_SOC_DAIFMT_BP_FP: val = I2S_CTRL_MASTER_EN; break; default: -- GitLab From 4edf738d4c7989c315e37d4d61e34c94557b6ed2 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Wed, 15 Jun 2022 10:08:34 +0530 Subject: [PATCH 532/942] ASoC: tegra: Fix MBDRC bypass mode check MBDRC supports different modes of operation. There is no configuration required for bypass mode. The hw_params() call does not filter bypass mode correctly and it leads to following Smatch static checker warning: sound/soc/tegra/tegra210_mbdrc.c:778 tegra210_mbdrc_hw_params() warn: bitwise AND condition is false here Fix this condition by using proper mode mask and just return for bypass mode. Reported-by: Dan Carpenter Fixes: 7358a803c778 ("ASoC: tegra: Add Tegra210 based OPE driver") Signed-off-by: Sameer Pujar Link: https://lore.kernel.org/r/1655267914-24702-1-git-send-email-spujar@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_mbdrc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra210_mbdrc.c b/sound/soc/tegra/tegra210_mbdrc.c index 7d9da33a99512..d786daa6aba62 100644 --- a/sound/soc/tegra/tegra210_mbdrc.c +++ b/sound/soc/tegra/tegra210_mbdrc.c @@ -775,7 +775,9 @@ int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt) regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val); - if (val & TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS) + val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK; + + if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS) return 0; for (i = 0; i < MBDRC_NUM_BAND; i++) { -- GitLab From ab222a4aaecfafece1516c775143e1cb9eb31612 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 15 Jun 2022 16:43:47 +0800 Subject: [PATCH 533/942] ASoC: SOC: Intel: introduce cl_init callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code loader init sequences are different between versions of Intel platforms. Have a cl_init callback allows us to reuse the common code. No function changed. Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220615084348.3489-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/cnl.c | 2 ++ sound/soc/sof/intel/hda-loader.c | 15 ++++++++++++--- sound/soc/sof/intel/hda.h | 1 + sound/soc/sof/intel/icl.c | 1 + sound/soc/sof/intel/shim.h | 1 + sound/soc/sof/intel/tgl.c | 4 ++++ 7 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 0cea280a6d2d3..084c245a95228 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -101,6 +101,7 @@ const struct sof_intel_dsp_desc apl_chip_info = { .ssp_base_offset = APL_SSP_BASE_OFFSET, .quirks = SOF_INTEL_PROCEN_FMT_QUIRK, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_1_5_PLUS, }; EXPORT_SYMBOL_NS(apl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index cd6e5f8a5eb4d..ccf46fcd6c9ab 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -401,6 +401,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_1_8, }; EXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); @@ -430,6 +431,7 @@ const struct sof_intel_dsp_desc jsl_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_0, }; EXPORT_SYMBOL_NS(jsl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index d3ec5996a9a3d..9e99f376f2b33 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -99,7 +99,7 @@ struct hdac_ext_stream *hda_cl_stream_prepare(struct snd_sof_dev *sdev, unsigned * power on all host managed cores and only unstall/run the boot core to boot the * DSP then turn off all non boot cores (if any) is powered on. */ -static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) +int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; @@ -369,9 +369,15 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev) static int hda_dsp_boot_imr(struct snd_sof_dev *sdev) { + const struct sof_intel_dsp_desc *chip_info; int ret; - ret = cl_dsp_init(sdev, 0, true); + chip_info = get_chip_info(sdev->pdata); + if (chip_info->cl_init) + ret = chip_info->cl_init(sdev, 0, true); + else + ret = -EINVAL; + if (!ret) hda_sdw_process_wakeen(sdev); @@ -430,7 +436,10 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) "Attempting iteration %d of Core En/ROM load...\n", i); hda->boot_iteration = i + 1; - ret = cl_dsp_init(sdev, hext_stream->hstream.stream_tag, false); + if (chip_info->cl_init) + ret = chip_info->cl_init(sdev, hext_stream->hstream.stream_tag, false); + else + ret = -EINVAL; /* don't retry anymore if successful */ if (!ret) diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index f4e4cd7d74067..8b7f3c07d4785 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -602,6 +602,7 @@ struct hdac_ext_stream *hda_cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int direction); int hda_cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, struct hdac_ext_stream *hext_stream); +int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot); #define HDA_CL_STREAM_FORMAT 0x40 /* pre and post fw run ops */ diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index f19517dffd624..4e37b7fe06274 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -152,6 +152,7 @@ const struct sof_intel_dsp_desc icl_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_0, }; EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h index 1fd7b485d8212..371991fa474f0 100644 --- a/sound/soc/sof/intel/shim.h +++ b/sound/soc/sof/intel/shim.h @@ -185,6 +185,7 @@ struct sof_intel_dsp_desc { enum sof_intel_hw_ip_version hw_ip_version; bool (*check_sdw_irq)(struct snd_sof_dev *sdev); bool (*check_ipc_irq)(struct snd_sof_dev *sdev); + int (*cl_init)(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot); }; extern struct snd_sof_dsp_ops sof_tng_ops; diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index dcad7c382de69..6dfb4786c7824 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -127,6 +127,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_5, }; EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); @@ -149,6 +150,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_5, }; EXPORT_SYMBOL_NS(tglh_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); @@ -171,6 +173,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_5, }; EXPORT_SYMBOL_NS(ehl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); @@ -193,6 +196,7 @@ const struct sof_intel_dsp_desc adls_chip_info = { .sdw_alh_base = SDW_ALH_BASE, .check_sdw_irq = hda_common_check_sdw_irq, .check_ipc_irq = hda_dsp_check_ipc_irq, + .cl_init = cl_dsp_init, .hw_ip_version = SOF_INTEL_CAVS_2_5, }; EXPORT_SYMBOL_NS(adls_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); -- GitLab From 064520e8aeaa2569f6504a50a37ac801b73656bc Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 15 Jun 2022 16:43:48 +0800 Subject: [PATCH 534/942] ASoC: SOF: Intel: Add support for MeteorLake (MTL) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add platform abstraction for the Meteor Lake platform. This platform has significant differences compared to the TGL/ADL generation: it relies on new hardware using the code name 'ACE' and only supports the INTEL_IPC4 protocol and firmware architecture based on the Zephyr RTOS Co-developed-by: Ranjani Sridharan Signed-off-by: Ranjani Sridharan Signed-off-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20220615084348.3489-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- include/linux/soundwire/sdw_intel.h | 2 + sound/soc/sof/intel/Kconfig | 16 + sound/soc/sof/intel/Makefile | 4 +- sound/soc/sof/intel/hda.h | 3 + sound/soc/sof/intel/mtl.c | 800 ++++++++++++++++++++++++++++ sound/soc/sof/intel/mtl.h | 76 +++ sound/soc/sof/intel/pci-mtl.c | 71 +++ sound/soc/sof/intel/shim.h | 1 + 8 files changed, 972 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/intel/mtl.c create mode 100644 sound/soc/sof/intel/mtl.h create mode 100644 sound/soc/sof/intel/pci-mtl.c diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index 67e0d3e750b5c..b5b489ea1aefe 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -9,6 +9,8 @@ #define SDW_SHIM_BASE 0x2C000 #define SDW_ALH_BASE 0x2C800 +#define SDW_SHIM_BASE_ACE 0x38000 +#define SDW_ALH_BASE_ACE 0x24000 #define SDW_LINK_BASE 0x30000 #define SDW_LINK_SIZE 0x10000 diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 80cdc3788bbed..3f54678e810ba 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -221,6 +221,22 @@ config SND_SOC_SOF_ALDERLAKE Say Y if you have such a device. If unsure select "N". +config SND_SOC_SOF_INTEL_MTL + tristate + select SND_SOC_SOF_HDA_COMMON + select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE + select SND_SOC_SOF_INTEL_IPC4 + +config SND_SOC_SOF_METEORLAKE + tristate "SOF support for Meteorlake" + default SND_SOC_SOF_PCI + select SND_SOC_SOF_INTEL_MTL + help + This adds support for Sound Open Firmware for Intel(R) platforms + using the Meteorlake processors. + Say Y if you have such a device. + If unsure select "N". + config SND_SOC_SOF_HDA_COMMON tristate select SND_SOC_SOF_INTEL_COMMON diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index b9d51dc39ffa6..a079159bb2f02 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -6,7 +6,7 @@ snd-sof-acpi-intel-bdw-objs := bdw.o snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ hda-dai.o hda-bus.o \ - apl.o cnl.o tgl.o icl.o hda-common-ops.o + apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-probes.o snd-sof-intel-hda-objs := hda-codec.o @@ -24,9 +24,11 @@ snd-sof-pci-intel-apl-objs := pci-apl.o snd-sof-pci-intel-cnl-objs := pci-cnl.o snd-sof-pci-intel-icl-objs := pci-icl.o snd-sof-pci-intel-tgl-objs := pci-tgl.o +snd-sof-pci-intel-mtl-objs := pci-mtl.o obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o obj-$(CONFIG_SND_SOC_SOF_INTEL_APL) += snd-sof-pci-intel-apl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_CNL) += snd-sof-pci-intel-cnl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_ICL) += snd-sof-pci-intel-icl.o obj-$(CONFIG_SND_SOC_SOF_INTEL_TGL) += snd-sof-pci-intel-tgl.o +obj-$(CONFIG_SND_SOC_SOF_INTEL_MTL) += snd-sof-pci-intel-mtl.o diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 8b7f3c07d4785..a3118499e34fc 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -714,6 +714,8 @@ extern struct snd_sof_dsp_ops sof_tgl_ops; int sof_tgl_ops_init(struct snd_sof_dev *sdev); extern struct snd_sof_dsp_ops sof_icl_ops; int sof_icl_ops_init(struct snd_sof_dev *sdev); +extern struct snd_sof_dsp_ops sof_mtl_ops; +int sof_mtl_ops_init(struct snd_sof_dev *sdev); extern const struct sof_intel_dsp_desc apl_chip_info; extern const struct sof_intel_dsp_desc cnl_chip_info; @@ -723,6 +725,7 @@ extern const struct sof_intel_dsp_desc tglh_chip_info; extern const struct sof_intel_dsp_desc ehl_chip_info; extern const struct sof_intel_dsp_desc jsl_chip_info; extern const struct sof_intel_dsp_desc adls_chip_info; +extern const struct sof_intel_dsp_desc mtl_chip_info; /* Probes support */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c new file mode 100644 index 0000000000000..37be77beb415f --- /dev/null +++ b/sound/soc/sof/intel/mtl.c @@ -0,0 +1,800 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Authors: Ranjani Sridharan +// + +/* + * Hardware interface for audio DSP on Meteorlake. + */ + +#include +#include +#include "../ipc4-priv.h" +#include "../ops.h" +#include "hda.h" +#include "hda-ipc.h" +#include "../sof-audio.h" +#include "mtl.h" + +static const struct snd_sof_debugfs_map mtl_dsp_debugfs[] = { + {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, + {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS}, + {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS}, +}; + +static void mtl_ipc_host_done(struct snd_sof_dev *sdev) +{ + /* + * clear busy interrupt to tell dsp controller this interrupt has been accepted, + * not trigger it again + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR, + MTL_DSP_REG_HFIPCXTDR_BUSY, MTL_DSP_REG_HFIPCXTDR_BUSY); + /* + * clear busy bit to ack dsp the msg has been processed and send reply msg to dsp + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDA, + MTL_DSP_REG_HFIPCXTDA_BUSY, 0); +} + +static void mtl_ipc_dsp_done(struct snd_sof_dev *sdev) +{ + /* + * set DONE bit - tell DSP we have received the reply msg from DSP, and processed it, + * don't send more reply to host + */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA, + MTL_DSP_REG_HFIPCXIDA_DONE, MTL_DSP_REG_HFIPCXIDA_DONE); + + /* unmask Done interrupt */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL, + MTL_DSP_REG_HFIPCXCTL_DONE, MTL_DSP_REG_HFIPCXCTL_DONE); +} + +/* Check if an IPC IRQ occurred */ +static bool mtl_dsp_check_ipc_irq(struct snd_sof_dev *sdev) +{ + u32 irq_status; + u32 hfintipptr; + + /* read Interrupt IP Pointer */ + hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; + irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS); + + dev_vdbg(sdev->dev, "irq handler: irq_status:0x%x\n", irq_status); + + if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_IPC)) + return true; + + return false; +} + +/* Check if an SDW IRQ occurred */ +static bool mtl_dsp_check_sdw_irq(struct snd_sof_dev *sdev) +{ + u32 irq_status; + u32 hfintipptr; + + /* read Interrupt IP Pointer */ + hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; + irq_status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr + MTL_DSP_IRQSTS); + + if (irq_status != U32_MAX && (irq_status & MTL_DSP_IRQSTS_SDW)) + return true; + + return false; +} + +static int mtl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) +{ + struct sof_ipc4_msg *msg_data = msg->msg_data; + + /* send the message via mailbox */ + if (msg_data->data_size) + sof_mailbox_write(sdev, sdev->host_box.offset, msg_data->data_ptr, + msg_data->data_size); + + snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDDY, + msg_data->extension); + snd_sof_dsp_write(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDR, + msg_data->primary | MTL_DSP_REG_HFIPCXIDR_BUSY); + + return 0; +} + +static void mtl_enable_ipc_interrupts(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + + /* enable IPC DONE and BUSY interrupts */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, + MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, + MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE); +} + +static void mtl_disable_ipc_interrupts(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + + /* disable IPC DONE and BUSY interrupts */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl, + MTL_DSP_REG_HFIPCXCTL_BUSY | MTL_DSP_REG_HFIPCXCTL_DONE, 0); +} + +static int mtl_enable_interrupts(struct snd_sof_dev *sdev) +{ + u32 hfintipptr; + u32 irqinten; + u32 host_ipc; + u32 hipcie; + int ret; + + /* read Interrupt IP Pointer */ + hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; + + /* Enable Host IPC and SOUNDWIRE */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr, + MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK, + MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK); + + /* check if operation was successful */ + host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK; + irqinten = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten, + (irqinten & host_ipc) == host_ipc, + HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) { + dev_err(sdev->dev, "failed to enable Host IPC and/or SOUNDWIRE\n"); + return ret; + } + + /* Set Host IPC interrupt enable */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, + MTL_DSP_REG_HfHIPCIE_IE_MASK, MTL_DSP_REG_HfHIPCIE_IE_MASK); + + /* check if operation was successful */ + host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK; + hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie, + (hipcie & host_ipc) == host_ipc, + HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) { + dev_err(sdev->dev, "failed to set Host IPC interrupt enable\n"); + return ret; + } + + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, + MTL_DSP_REG_HfSNDWIE_IE_MASK, MTL_DSP_REG_HfSNDWIE_IE_MASK); + host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK; + hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie, + (hipcie & host_ipc) == host_ipc, + HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) + dev_err(sdev->dev, "failed to set SoundWire IPC interrupt enable\n"); + + return ret; +} + +static int mtl_disable_interrupts(struct snd_sof_dev *sdev) +{ + u32 hfintipptr; + u32 irqinten; + u32 host_ipc; + u32 hipcie; + int ret1; + int ret; + + /* read Interrupt IP Pointer */ + hfintipptr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFINTIPPTR) & MTL_HFINTIPPTR_PTR_MASK; + + /* Disable Host IPC and SOUNDWIRE */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, hfintipptr, + MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK, 0); + + /* check if operation was successful */ + host_ipc = MTL_IRQ_INTEN_L_HOST_IPC_MASK | MTL_IRQ_INTEN_L_SOUNDWIRE_MASK; + irqinten = snd_sof_dsp_read(sdev, HDA_DSP_BAR, hfintipptr); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, hfintipptr, irqinten, + (irqinten & host_ipc) == 0, + HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_RESET_TIMEOUT_US); + /* Continue to disable other interrupts when error happens */ + if (ret < 0) + dev_err(sdev->dev, "failed to disable Host IPC and SoundWire\n"); + + /* Set Host IPC interrupt disable */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, + MTL_DSP_REG_HfHIPCIE_IE_MASK, 0); + + /* check if operation was successful */ + host_ipc = MTL_DSP_REG_HfHIPCIE_IE_MASK; + hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE); + ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfHIPCIE, hipcie, + (hipcie & host_ipc) == 0, + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret1 < 0) { + dev_err(sdev->dev, "failed to set Host IPC interrupt disable\n"); + if (!ret) + ret = ret1; + } + + /* Set SoundWire IPC interrupt disable */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, + MTL_DSP_REG_HfSNDWIE_IE_MASK, 0); + host_ipc = MTL_DSP_REG_HfSNDWIE_IE_MASK; + hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE); + ret1 = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP_REG_HfSNDWIE, hipcie, + (hipcie & host_ipc) == 0, + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret1 < 0) { + dev_err(sdev->dev, "failed to set SoundWire IPC interrupt disable\n"); + if (!ret) + ret = ret1; + } + + return ret; +} + +/* pre fw run operations */ +static int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev) +{ + u32 dsphfpwrsts; + u32 dsphfdsscs; + u32 cpa; + u32 pgs; + int ret; + + /* Set the DSP subsystem power on */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS, + MTL_HFDSSCS_SPA_MASK, MTL_HFDSSCS_SPA_MASK); + + /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ + usleep_range(1000, 1010); + + /* poll with timeout to check if operation successful */ + cpa = MTL_HFDSSCS_CPA_MASK; + dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs, + (dsphfdsscs & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) { + dev_err(sdev->dev, "failed to enable DSP subsystem\n"); + return ret; + } + + /* Power up gated-DSP-0 domain in order to access the DSP shim register block. */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL, + MTL_HFPWRCTL_WPDSPHPXPG, MTL_HFPWRCTL_WPDSPHPXPG); + + usleep_range(1000, 1010); + + /* poll with timeout to check if operation successful */ + pgs = MTL_HFPWRSTS_DSPHPXPGS_MASK; + dsphfpwrsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFPWRSTS); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFPWRSTS, dsphfpwrsts, + (dsphfpwrsts & pgs) == pgs, + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) + dev_err(sdev->dev, "failed to power up gated DSP domain\n"); + + /* make sure SoundWire is not power-gated */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, MTL_HFPWRCTL, + MTL_HfPWRCTL_WPIOXPG(1), MTL_HfPWRCTL_WPIOXPG(1)); + return ret; +} + +static int mtl_dsp_post_fw_run(struct snd_sof_dev *sdev) +{ + int ret; + + if (sdev->first_boot) { + struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; + + ret = hda_sdw_startup(sdev); + if (ret < 0) { + dev_err(sdev->dev, "could not startup SoundWire links\n"); + return ret; + } + + /* Check if IMR boot is usable */ + if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) + hdev->imrboot_supported = true; + } + + hda_sdw_int_enable(sdev, true); + return 0; +} + +static void mtl_dsp_dump(struct snd_sof_dev *sdev, u32 flags) +{ + char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR; + u32 romdbgsts; + u32 romdbgerr; + u32 fwsts; + u32 fwlec; + + fwsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_STS); + fwlec = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_ROM_ERROR); + romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY); + romdbgerr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY_ERROR); + + dev_err(sdev->dev, "ROM status: %#x, ROM error: %#x\n", fwsts, fwlec); + dev_err(sdev->dev, "ROM debug status: %#x, ROM debug error: %#x\n", romdbgsts, + romdbgerr); + romdbgsts = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFFLGPXQWY + 0x8 * 3); + dev_printk(level, sdev->dev, "ROM feature bit%s enabled\n", + romdbgsts & BIT(24) ? "" : " not"); +} + +static bool mtl_dsp_primary_core_is_enabled(struct snd_sof_dev *sdev) +{ + int val; + + val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE); + if (val != U32_MAX && val & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) + return true; + + return false; +} + +static int mtl_dsp_core_power_up(struct snd_sof_dev *sdev, int core) +{ + unsigned int cpa; + u32 dspcxctl; + int ret; + + /* Only the primary core can be powered up by the host */ + if (core != SOF_DSP_PRIMARY_CORE || mtl_dsp_primary_core_is_enabled(sdev)) + return 0; + + /* Program the owner of the IP & shim registers (10: Host CPU) */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, + MTL_DSP2CXCTL_PRIMARY_CORE_OSEL, + 0x2 << MTL_DSP2CXCTL_PRIMARY_CORE_OSEL_SHIFT); + + /* enable SPA bit */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, + MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK, + MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK); + + /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ + usleep_range(1000, 1010); + + /* poll with timeout to check if operation successful */ + cpa = MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK; + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl, + (dspcxctl & cpa) == cpa, HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) { + dev_err(sdev->dev, "%s: timeout on MTL_DSP2CXCTL_PRIMARY_CORE read\n", + __func__); + return ret; + } + + /* did core power up ? */ + dspcxctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE); + if ((dspcxctl & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) + != MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK) { + dev_err(sdev->dev, "power up core failed core %d adspcs %#x\n", + core, dspcxctl); + ret = -EIO; + } + + return ret; +} + +static int mtl_dsp_core_power_down(struct snd_sof_dev *sdev, int core) +{ + u32 dspcxctl; + int ret; + + /* Only the primary core can be powered down by the host */ + if (core != SOF_DSP_PRIMARY_CORE || !mtl_dsp_primary_core_is_enabled(sdev)) + return 0; + + /* disable SPA bit */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, + MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK, 0); + + /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ + usleep_range(1000, 1010); + + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_DSP2CXCTL_PRIMARY_CORE, dspcxctl, + !(dspcxctl & MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK), + HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC); + if (ret < 0) + dev_err(sdev->dev, "failed to power down primary core\n"); + + return ret; +} + +static int mtl_dsp_cl_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + unsigned int status; + u32 ipc_hdr; + int ret; + + /* step 1: purge FW request */ + ipc_hdr = chip->ipc_req_mask | HDA_DSP_ROM_IPC_CONTROL; + if (!imr_boot) + ipc_hdr |= HDA_DSP_ROM_IPC_PURGE_FW | ((stream_tag - 1) << 9); + + snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, ipc_hdr); + + /* step 2: power up primary core */ + ret = mtl_dsp_core_power_up(sdev, SOF_DSP_PRIMARY_CORE); + if (ret < 0) { + if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) + dev_err(sdev->dev, "dsp core 0/1 power up failed\n"); + goto err; + } + + dev_dbg(sdev->dev, "Primary core power up successful\n"); + + /* step 3: wait for IPC DONE bit from ROM */ + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, chip->ipc_ack, status, + ((status & chip->ipc_ack_mask) == chip->ipc_ack_mask), + HDA_DSP_REG_POLL_INTERVAL_US, MTL_DSP_PURGE_TIMEOUT_US); + if (ret < 0) { + if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) + dev_err(sdev->dev, "timeout waiting for purge IPC done\n"); + goto err; + } + + /* set DONE bit to clear the reply IPC message */ + snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, chip->ipc_ack, chip->ipc_ack_mask, + chip->ipc_ack_mask); + + /* step 4: enable interrupts */ + ret = mtl_enable_interrupts(sdev); + if (ret < 0) { + if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) + dev_err(sdev->dev, "%s: failed to enable interrupts\n", __func__); + goto err; + } + + mtl_enable_ipc_interrupts(sdev); + + /* + * ACE workaround: don't wait for ROM INIT. + * The platform cannot catch ROM_INIT_DONE because of a very short + * timing window. Follow the recommendations and skip this part. + */ + + return 0; + +err: + snd_sof_dsp_dbg_dump(sdev, "MTL DSP init fail", 0); + mtl_dsp_core_power_down(sdev, SOF_DSP_PRIMARY_CORE); + return ret; +} + +static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) +{ + struct sof_ipc4_msg notification_data = {{ 0 }}; + struct snd_sof_dev *sdev = context; + bool ipc_irq = false; + u32 hipcida; + u32 hipctdr; + + hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA); + + /* reply message from DSP */ + if (hipcida & MTL_DSP_REG_HFIPCXIDA_DONE) { + /* DSP received the message */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL, + MTL_DSP_REG_HFIPCXCTL_DONE, 0); + + mtl_ipc_dsp_done(sdev); + + ipc_irq = true; + } + + hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR); + if (hipctdr & MTL_DSP_REG_HFIPCXTDR_BUSY) { + /* Message from DSP (reply or notification) */ + u32 extension = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDDY); + u32 primary = hipctdr & MTL_DSP_REG_HFIPCXTDR_MSG_MASK; + + /* + * ACE fw sends a new fw ipc message to host to + * notify the status of the last host ipc message + */ + if (primary & SOF_IPC4_MSG_DIR_MASK) { + /* Reply received */ + struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; + + data->primary = primary; + data->extension = extension; + + spin_lock_irq(&sdev->ipc_lock); + + snd_sof_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, data->primary); + + spin_unlock_irq(&sdev->ipc_lock); + } else { + /* Notification received */ + notification_data.primary = primary; + notification_data.extension = extension; + + sdev->ipc->msg.rx_data = ¬ification_data; + snd_sof_ipc_msgs_rx(sdev); + sdev->ipc->msg.rx_data = NULL; + } + + mtl_ipc_host_done(sdev); + + ipc_irq = true; + } + + if (!ipc_irq) { + /* This interrupt is not shared so no need to return IRQ_NONE. */ + dev_dbg_ratelimited(sdev->dev, "%s nothing to do in IPC IRQ thread\n", + __func__); + } + + return IRQ_HANDLED; +} + +static int mtl_dsp_ipc_get_mailbox_offset(struct snd_sof_dev *sdev) +{ + return MTL_DSP_MBOX_UPLINK_OFFSET; +} + +static int mtl_dsp_ipc_get_window_offset(struct snd_sof_dev *sdev, u32 id) +{ + return MTL_SRAM_WINDOW_OFFSET(id); +} + +static int mtl_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + struct hdac_bus *bus = sof_to_bus(sdev); +#endif + u32 dsphfdsscs; + u32 cpa; + int ret; + int i; + + mtl_disable_ipc_interrupts(sdev); + ret = mtl_disable_interrupts(sdev); + if (ret) + return ret; + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + hda_codec_jack_wake_enable(sdev, runtime_suspend); + /* power down all hda link */ + snd_hdac_ext_bus_link_power_down_all(bus); +#endif + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL, + MTL_HFPWRCTL_WPDSPHPXPG, 0); + + /* Set the DSP subsystem power down */ + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS, + MTL_HFDSSCS_SPA_MASK, 0); + + /* Wait for unstable CPA read (1 then 0 then 1) just after setting SPA bit */ + usleep_range(1000, 1010); + + /* poll with timeout to check if operation successful */ + cpa = MTL_HFDSSCS_CPA_MASK; + dsphfdsscs = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_HFDSSCS); + ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFDSSCS, dsphfdsscs, + (dsphfdsscs & cpa) == 0, HDA_DSP_REG_POLL_INTERVAL_US, + HDA_DSP_RESET_TIMEOUT_US); + if (ret < 0) + dev_err(sdev->dev, "failed to disable DSP subsystem\n"); + + /* reset ref counts for all cores */ + for (i = 0; i < chip->cores_num; i++) + sdev->dsp_core_ref_count[i] = 0; + + /* TODO: need to reset controller? */ + + /* display codec can be powered off after link reset */ + hda_codec_i915_display_power(sdev, false); + + return 0; +} + +static int mtl_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) +{ + const struct sof_dsp_power_state target_dsp_state = { + .state = target_state, + .substate = target_state == SOF_DSP_PM_D0 ? + SOF_HDA_DSP_PM_D0I3 : 0, + }; + int ret; + + ret = mtl_suspend(sdev, false); + if (ret < 0) + return ret; + + return snd_sof_dsp_set_power_state(sdev, &target_dsp_state); +} + +static int mtl_dsp_runtime_suspend(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D3, + }; + int ret; + + ret = mtl_suspend(sdev, true); + if (ret < 0) + return ret; + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static int mtl_resume(struct snd_sof_dev *sdev, bool runtime_resume) +{ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + struct hdac_bus *bus = sof_to_bus(sdev); + struct hdac_ext_link *hlink = NULL; +#endif + + /* display codec must be powered before link reset */ + hda_codec_i915_display_power(sdev, true); + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + /* check jack status */ + if (runtime_resume) { + hda_codec_jack_wake_enable(sdev, false); + if (sdev->system_suspend_target == SOF_SUSPEND_NONE) + hda_codec_jack_check(sdev); + } + + /* turn off the links that were off before suspend */ + list_for_each_entry(hlink, &bus->hlink_list, list) { + if (!hlink->ref_count) + snd_hdac_ext_bus_link_power_down(hlink); + } + + /* check dma status and clean up CORB/RIRB buffers */ + if (!bus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(bus); +#endif + + return 0; +} + +static int mtl_dsp_resume(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + .substate = SOF_HDA_DSP_PM_D0I0, + }; + int ret; + + ret = mtl_resume(sdev, false); + if (ret < 0) + return ret; + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static int mtl_dsp_runtime_resume(struct snd_sof_dev *sdev) +{ + const struct sof_dsp_power_state target_state = { + .state = SOF_DSP_PM_D0, + }; + int ret; + + ret = mtl_resume(sdev, true); + if (ret < 0) + return ret; + + return snd_sof_dsp_set_power_state(sdev, &target_state); +} + +static void mtl_ipc_dump(struct snd_sof_dev *sdev) +{ + u32 hipcctl; + u32 hipcida; + u32 hipctdr; + + /* read IPC status */ + hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXIDA); + hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXCTL); + hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, MTL_DSP_REG_HFIPCXTDR); + + /* dump the IPC regs */ + /* TODO: parse the raw msg */ + dev_err(sdev->dev, + "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", + hipcida, hipctdr, hipcctl); +} + +/* Meteorlake ops */ +struct snd_sof_dsp_ops sof_mtl_ops; +EXPORT_SYMBOL_NS(sof_mtl_ops, SND_SOC_SOF_INTEL_HDA_COMMON); + +int sof_mtl_ops_init(struct snd_sof_dev *sdev) +{ + struct sof_ipc4_fw_data *ipc4_data; + + /* common defaults */ + memcpy(&sof_mtl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops)); + + /* shutdown */ + sof_mtl_ops.shutdown = hda_dsp_shutdown; + + /* doorbell */ + sof_mtl_ops.irq_thread = mtl_ipc_irq_thread; + + /* ipc */ + sof_mtl_ops.send_msg = mtl_ipc_send_msg; + sof_mtl_ops.get_mailbox_offset = mtl_dsp_ipc_get_mailbox_offset; + sof_mtl_ops.get_window_offset = mtl_dsp_ipc_get_window_offset; + + /* debug */ + sof_mtl_ops.debug_map = mtl_dsp_debugfs; + sof_mtl_ops.debug_map_count = ARRAY_SIZE(mtl_dsp_debugfs); + sof_mtl_ops.dbg_dump = mtl_dsp_dump; + sof_mtl_ops.ipc_dump = mtl_ipc_dump; + + /* pre/post fw run */ + sof_mtl_ops.pre_fw_run = mtl_dsp_pre_fw_run; + sof_mtl_ops.post_fw_run = mtl_dsp_post_fw_run; + + /* parse platform specific extended manifest */ + sof_mtl_ops.parse_platform_ext_manifest = NULL; + + /* dsp core get/put */ + /* TODO: add core_get and core_put */ + + /* PM */ + sof_mtl_ops.suspend = mtl_dsp_suspend; + sof_mtl_ops.resume = mtl_dsp_resume; + sof_mtl_ops.runtime_suspend = mtl_dsp_runtime_suspend; + sof_mtl_ops.runtime_resume = mtl_dsp_runtime_resume; + + sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); + if (!sdev->private) + return -ENOMEM; + + ipc4_data = sdev->private; + ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET; + + /* set DAI ops */ + hda_set_dai_drv_ops(sdev, &sof_mtl_ops); + + return 0; +}; +EXPORT_SYMBOL_NS(sof_mtl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON); + +const struct sof_intel_dsp_desc mtl_chip_info = { + .cores_num = 3, + .init_core_mask = BIT(0), + .host_managed_cores_mask = BIT(0), + .ipc_req = MTL_DSP_REG_HFIPCXIDR, + .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY, + .ipc_ack = MTL_DSP_REG_HFIPCXIDA, + .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE, + .ipc_ctl = MTL_DSP_REG_HFIPCXCTL, + .rom_status_reg = MTL_DSP_ROM_STS, + .rom_init_timeout = 300, + .ssp_count = ICL_SSP_COUNT, + .ssp_base_offset = CNL_SSP_BASE_OFFSET, + .sdw_shim_base = SDW_SHIM_BASE_ACE, + .sdw_alh_base = SDW_ALH_BASE_ACE, + .check_sdw_irq = mtl_dsp_check_sdw_irq, + .check_ipc_irq = mtl_dsp_check_ipc_irq, + .cl_init = mtl_dsp_cl_init, + .hw_ip_version = SOF_INTEL_ACE_1_0, +}; +EXPORT_SYMBOL_NS(mtl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h new file mode 100644 index 0000000000000..788bf0e3ea879 --- /dev/null +++ b/sound/soc/sof/intel/mtl.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2020-2022 Intel Corporation. All rights reserved. + */ + +/* DSP Registers */ +#define MTL_HFDSSCS 0x1000 +#define MTL_HFDSSCS_SPA_MASK BIT(16) +#define MTL_HFDSSCS_CPA_MASK BIT(24) +#define MTL_HFSNDWIE 0x114C +#define MTL_HFPWRCTL 0x1D18 +#define MTL_HfPWRCTL_WPIOXPG(x) BIT((x) + 8) +#define MTL_HFPWRCTL_WPDSPHPXPG BIT(0) +#define MTL_HFPWRSTS 0x1D1C +#define MTL_HFPWRSTS_DSPHPXPGS_MASK BIT(0) +#define MTL_HFINTIPPTR 0x1108 +#define MTL_IRQ_INTEN_L_HOST_IPC_MASK BIT(0) +#define MTL_IRQ_INTEN_L_SOUNDWIRE_MASK BIT(6) +#define MTL_HFINTIPPTR_PTR_MASK GENMASK(20, 0) + +#define MTL_DSP2CXCAP_PRIMARY_CORE 0x178D00 +#define MTL_DSP2CXCTL_PRIMARY_CORE 0x178D04 +#define MTL_DSP2CXCTL_PRIMARY_CORE_SPA_MASK BIT(0) +#define MTL_DSP2CXCTL_PRIMARY_CORE_CPA_MASK BIT(8) +#define MTL_DSP2CXCTL_PRIMARY_CORE_OSEL GENMASK(25, 24) +#define MTL_DSP2CXCTL_PRIMARY_CORE_OSEL_SHIFT 24 + +/* IPC Registers */ +#define MTL_DSP_REG_HFIPCXTDR 0x73200 +#define MTL_DSP_REG_HFIPCXTDR_BUSY BIT(31) +#define MTL_DSP_REG_HFIPCXTDR_MSG_MASK GENMASK(30, 0) +#define MTL_DSP_REG_HFIPCXTDA 0x73204 +#define MTL_DSP_REG_HFIPCXTDA_BUSY BIT(31) +#define MTL_DSP_REG_HFIPCXIDR 0x73210 +#define MTL_DSP_REG_HFIPCXIDR_BUSY BIT(31) +#define MTL_DSP_REG_HFIPCXIDR_MSG_MASK GENMASK(30, 0) +#define MTL_DSP_REG_HFIPCXIDA 0x73214 +#define MTL_DSP_REG_HFIPCXIDA_DONE BIT(31) +#define MTL_DSP_REG_HFIPCXIDA_MSG_MASK GENMASK(30, 0) +#define MTL_DSP_REG_HFIPCXCTL 0x73228 +#define MTL_DSP_REG_HFIPCXCTL_BUSY BIT(0) +#define MTL_DSP_REG_HFIPCXCTL_DONE BIT(1) +#define MTL_DSP_REG_HFIPCXTDDY 0x73300 +#define MTL_DSP_REG_HFIPCXIDDY 0x73380 +#define MTL_DSP_REG_HfHIPCIE 0x1140 +#define MTL_DSP_REG_HfHIPCIE_IE_MASK BIT(0) +#define MTL_DSP_REG_HfSNDWIE 0x114C +#define MTL_DSP_REG_HfSNDWIE_IE_MASK GENMASK(3, 0) + +#define MTL_DSP_IRQSTS 0x20 +#define MTL_DSP_IRQSTS_IPC BIT(0) +#define MTL_DSP_IRQSTS_SDW BIT(6) + +#define MTL_DSP_PURGE_TIMEOUT_US 20000000 /* 20s */ +#define MTL_DSP_REG_POLL_INTERVAL_US 10 /* 10 us */ + +/* Memory windows */ +#define MTL_SRAM_WINDOW_OFFSET(x) (0x180000 + 0x8000 * (x)) + +#define MTL_DSP_MBOX_UPLINK_OFFSET (MTL_SRAM_WINDOW_OFFSET(0) + 0x1000) +#define MTL_DSP_MBOX_UPLINK_SIZE 0x1000 +#define MTL_DSP_MBOX_DOWNLINK_OFFSET MTL_SRAM_WINDOW_OFFSET(1) +#define MTL_DSP_MBOX_DOWNLINK_SIZE 0x1000 + +/* FW registers */ +#define MTL_DSP_ROM_STS MTL_SRAM_WINDOW_OFFSET(0) /* ROM status */ +#define MTL_DSP_ROM_ERROR (MTL_SRAM_WINDOW_OFFSET(0) + 0x4) /* ROM error code */ + +#define MTL_DSP_REG_HFFLGPXQWY 0x163200 /* ROM debug status */ +#define MTL_DSP_REG_HFFLGPXQWY_ERROR 0x163204 /* ROM debug error code */ +#define MTL_DSP_REG_HfIMRIS1 0x162088 +#define MTL_DSP_REG_HfIMRIS1_IU_MASK BIT(0) + diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c new file mode 100644 index 0000000000000..899b00d53d64f --- /dev/null +++ b/sound/soc/sof/intel/pci-mtl.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2018-2022 Intel Corporation. All rights reserved. +// +// Author: Ranjani Sridharan +// + +#include +#include +#include +#include +#include +#include "../ops.h" +#include "../sof-pci-dev.h" + +/* platform specific devices */ +#include "hda.h" +#include "mtl.h" + +static const struct sof_dev_desc mtl_desc = { + .use_acpi_target_states = true, + .machines = snd_soc_acpi_intel_mtl_machines, + .alt_machines = snd_soc_acpi_intel_mtl_sdw_machines, + .resindex_lpe_base = 0, + .resindex_pcicfg_base = -1, + .resindex_imr_base = -1, + .irqindex_host_ipc = -1, + .chip_info = &mtl_chip_info, + .ipc_supported_mask = BIT(SOF_INTEL_IPC4), + .ipc_default = SOF_INTEL_IPC4, + .default_fw_path = { + [SOF_INTEL_IPC4] = "intel/sof-ipc4/mtl", + }, + .default_tplg_path = { + [SOF_INTEL_IPC4] = "intel/sof-ace-tplg", + }, + .default_fw_filename = { + [SOF_INTEL_IPC4] = "dsp_basefw.bin", + }, + .nocodec_tplg_filename = "sof-mtl-nocodec.tplg", + .ops = &sof_mtl_ops, + .ops_init = sof_mtl_ops_init, +}; + +/* PCI IDs */ +static const struct pci_device_id sof_pci_ids[] = { + { PCI_DEVICE(0x8086, 0x7E28), /* MTL */ + .driver_data = (unsigned long)&mtl_desc}, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, sof_pci_ids); + +/* pci_driver definition */ +static struct pci_driver snd_sof_pci_intel_mtl_driver = { + .name = "sof-audio-pci-intel-mtl", + .id_table = sof_pci_ids, + .probe = hda_pci_intel_probe, + .remove = sof_pci_remove, + .shutdown = sof_pci_shutdown, + .driver = { + .pm = &sof_pci_pm, + }, +}; +module_pci_driver(snd_sof_pci_intel_mtl_driver); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); +MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV); diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h index 371991fa474f0..638159bee8645 100644 --- a/sound/soc/sof/intel/shim.h +++ b/sound/soc/sof/intel/shim.h @@ -20,6 +20,7 @@ enum sof_intel_hw_ip_version { SOF_INTEL_CAVS_1_8, /* CannonLake, CometLake, CoffeeLake */ SOF_INTEL_CAVS_2_0, /* IceLake, JasperLake */ SOF_INTEL_CAVS_2_5, /* TigerLake, AlderLake */ + SOF_INTEL_ACE_1_0, /* MeteorLake */ }; /* -- GitLab From f67be8b7ee90c292948c3ec6395673963cccaee6 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 22 May 2022 20:26:58 -0700 Subject: [PATCH 535/942] regmap: provide regmap_field helpers for simple bit operations We have set/clear/test operations for regmap, but not for regmap_field yet. So let's introduce regmap_field helpers too. In many instances regmap_field_update_bits() is used for simple bit setting and clearing. In these cases the last argument is redundant and we can hide it with a static inline function. This adds three new helpers for simple bit operations: set_bits, clear_bits and test_bits (the last one defined as a regular function). Signed-off-by: Li Chen Link: https://lore.kernel.org/r/180eef422c3.deae9cd960729.8518395646822099769@zohomail.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 22 +++++++++++++++++++++ include/linux/regmap.h | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2221d98638317..cb0be5e7b100e 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2220,6 +2220,28 @@ int regmap_field_update_bits_base(struct regmap_field *field, } EXPORT_SYMBOL_GPL(regmap_field_update_bits_base); +/** + * regmap_field_test_bits() - Check if all specified bits are set in a + * register field. + * + * @field: Register field to operate on + * @bits: Bits to test + * + * Returns -1 if the underlying regmap_field_read() fails, 0 if at least one of the + * tested bits is not set and 1 if all tested bits are set. + */ +int regmap_field_test_bits(struct regmap_field *field, unsigned int bits) +{ + unsigned int val, ret; + + ret = regmap_field_read(field, &val); + if (ret) + return ret; + + return (val & bits) == bits; +} +EXPORT_SYMBOL_GPL(regmap_field_test_bits); + /** * regmap_fields_update_bits_base() - Perform a read/modify/write cycle a * register field with port ID diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 8952fa3d0d593..d5b08f4f0dc0b 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1336,6 +1336,22 @@ static inline int regmap_field_update_bits(struct regmap_field *field, NULL, false, false); } +static inline int regmap_field_set_bits(struct regmap_field *field, + unsigned int bits) +{ + return regmap_field_update_bits_base(field, bits, bits, NULL, false, + false); +} + +static inline int regmap_field_clear_bits(struct regmap_field *field, + unsigned int bits) +{ + return regmap_field_update_bits_base(field, bits, 0, NULL, false, + false); +} + +int regmap_field_test_bits(struct regmap_field *field, unsigned int bits); + static inline int regmap_field_force_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val) @@ -1769,6 +1785,27 @@ regmap_field_force_update_bits(struct regmap_field *field, return -EINVAL; } +static inline int regmap_field_set_bits(struct regmap_field *field, + unsigned int bits) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + +static inline int regmap_field_clear_bits(struct regmap_field *field, + unsigned int bits) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + +static inline int regmap_field_test_bits(struct regmap_field *field, + unsigned int bits) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + static inline int regmap_fields_write(struct regmap_field *field, unsigned int id, unsigned int val) { -- GitLab From b23662406b1b225847b964e4549a5718c45f20d6 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 22 May 2022 20:27:59 -0700 Subject: [PATCH 536/942] ASoC: sunxi: Use {regmap/regmap_field}_{set/clear}_bits helpers Appropriately change calls to {regmap/regmap_field}_update_bits() with {regmap/regmap_field}_set_bits() and {regmap/regmap_field}_clear_bits() for improved readability. Signed-off-by: Li Chen Link: https://lore.kernel.org/r/180eef50e96.cb7c34db60740.8898768158778553647@zohomail.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 78 ++++++++++++++--------------------- 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 60712f24ade59..53e3f43816cc2 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -250,37 +250,33 @@ struct sun4i_codec { static void sun4i_codec_start_playback(struct sun4i_codec *scodec) { /* Flush TX FIFO */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), - BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); /* Enable DAC DRQ */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), - BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); } static void sun4i_codec_stop_playback(struct sun4i_codec *scodec) { /* Disable DAC DRQ */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN), - 0); + regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN)); } static void sun4i_codec_start_capture(struct sun4i_codec *scodec) { /* Enable ADC DRQ */ - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), - BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN)); + regmap_field_set_bits(scodec->reg_adc_fifoc, + BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN)); } static void sun4i_codec_stop_capture(struct sun4i_codec *scodec) { /* Disable ADC DRQ */ - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0); + regmap_field_clear_bits(scodec->reg_adc_fifoc, + BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN)); } static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, @@ -323,8 +319,7 @@ static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream, /* Flush RX FIFO */ - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH), + regmap_field_set_bits(scodec->reg_adc_fifoc, BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH)); @@ -365,8 +360,7 @@ static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, u32 val; /* Flush the TX FIFO */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH), + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH)); /* Set TX FIFO Empty Trigger Level */ @@ -386,9 +380,8 @@ static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, val); /* Send zeros when we have an underrun */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT), - 0); + regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT)); return 0; }; @@ -485,33 +478,27 @@ static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec, /* Set the number of channels we want to use */ if (params_channels(params) == 1) - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), + regmap_field_set_bits(scodec->reg_adc_fifoc, BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN)); else - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN), - 0); + regmap_field_clear_bits(scodec->reg_adc_fifoc, + BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN)); /* Set the number of sample bits to either 16 or 24 bits */ if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS), + regmap_field_set_bits(scodec->reg_adc_fifoc, BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS)); - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE), - 0); + regmap_field_clear_bits(scodec->reg_adc_fifoc, + BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE)); scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; } else { - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS), - 0); + regmap_field_clear_bits(scodec->reg_adc_fifoc, + BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS)); /* Fill most significant bits with valid data MSB */ - regmap_field_update_bits(scodec->reg_adc_fifoc, - BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE), + regmap_field_set_bits(scodec->reg_adc_fifoc, BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE)); scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; @@ -543,24 +530,20 @@ static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec, /* Set the number of sample bits to either 16 or 24 bits */ if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) { - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS), + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); /* Set TX FIFO mode to padding the LSBs with 0 */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE), - 0); + regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; } else { - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS), - 0); + regmap_clear_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, + BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS)); /* Set TX FIFO mode to repeat the MSB */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE), + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE)); scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; @@ -624,8 +607,7 @@ static int sun4i_codec_startup(struct snd_pcm_substream *substream, * Stop issuing DRQ when we have room for less than 16 samples * in our TX FIFO */ - regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, - 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT, + regmap_set_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC, 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT); return clk_prepare_enable(scodec->clk_module); -- GitLab From 62257638170eee07926c9df5a4c9059ec69a3734 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Jun 2022 11:19:44 +0300 Subject: [PATCH 537/942] ASoC: SOF: mediatek: Fix error code in probe This should return PTR_ERR() instead of IS_ERR(). Fixes: e0100bfd383c ("ASoC: SOF: mediatek: Add mt8186 ipc support") Signed-off-by: Dan Carpenter Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/YqmWIK8sTj578OJP@kili Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8186/mt8186.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 3333a0634e29d..e006532caf2f0 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -392,7 +392,7 @@ static int mt8186_dsp_probe(struct snd_sof_dev *sdev) PLATFORM_DEVID_NONE, pdev, sizeof(*pdev)); if (IS_ERR(priv->ipc_dev)) { - ret = IS_ERR(priv->ipc_dev); + ret = PTR_ERR(priv->ipc_dev); dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n"); goto err_adsp_off; } -- GitLab From 7acf970a6fbb3c10bb5979d0dc3ed42b161daf15 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 16 Jun 2022 07:31:09 +0300 Subject: [PATCH 538/942] ASoC: SOF: ipc4-topology: Fix error code in sof_ipc4_volume_put() The sof_ipc4_volume_put() function returns type bool so returning -ENOENT means returning true. Return false instead. Fixes: 955e84fc0b6d ("ASoC: SOF: ipc4-topology: Add control IO ops") Signed-off-by: Dan Carpenter Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/YqqyDU5BhOzpRjco@kili Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4-control.c b/sound/soc/sof/ipc4-control.c index 95ee121dd3cf0..0d5a578c34962 100644 --- a/sound/soc/sof/ipc4-control.c +++ b/sound/soc/sof/ipc4-control.c @@ -142,7 +142,7 @@ static bool sof_ipc4_volume_put(struct snd_sof_control *scontrol, if (!widget_found) { dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); - return -ENOENT; + return false; } ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol); -- GitLab From 1ec0c91f6d6b21703c17d5e89f32d52feac5887e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 14 Jun 2022 19:38:09 +0100 Subject: [PATCH 539/942] ASoC: Intel: Skylake: remove redundant re-assignments to pointer array There are two occurrences where the pointer array is being assigned a value that is never read, the pointer gets updated in the next iteration of a loop. These assignments are redundant and can be removed. Cleans up clang scan-build warnings: sound/soc/intel/skylake/skl-topology.c:2953:3: warning: Value stored to 'array' is never read [deadcode.DeadStores] sound/soc/intel/skylake/skl-topology.c:3602:3: warning: Value stored to 'array' is never read [deadcode.DeadStores] Signed-off-by: Colin Ian King Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220614183809.163531-1-colin.i.king@gmail.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 9bdf020a2b643..e06eac592da12 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -2950,9 +2950,6 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, block_size = ret; off += array->size; - array = (struct snd_soc_tplg_vendor_array *) - (tplg_w->priv.data + off); - data = (tplg_w->priv.data + off); if (block_type == SKL_TYPE_TUPLE) { @@ -3599,9 +3596,6 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, block_size = ret; off += array->size; - array = (struct snd_soc_tplg_vendor_array *) - (manifest->priv.data + off); - data = (manifest->priv.data + off); if (block_type == SKL_TYPE_TUPLE) { -- GitLab From 2964e31cdda03fdff3b7c2f4f043e788e607987f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 16 Jun 2022 08:49:10 +0300 Subject: [PATCH 540/942] ASoC: SOF: Intel: IPC4: enable IMR boot IPC4 based firmwares have unconditional support for IMR boot. Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220616054910.16690-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 9e99f376f2b33..bca9dc5917f42 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -538,7 +538,8 @@ int hda_dsp_post_fw_run(struct snd_sof_dev *sdev) /* Check if IMR boot is usable */ if (!sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT) && - sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) + (sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT || + sdev->pdata->ipc_type == SOF_INTEL_IPC4)) hdev->imrboot_supported = true; } -- GitLab From 6639990dbb25257eeb3df4d03e38e7d26c2484ab Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:16 -0500 Subject: [PATCH 541/942] ASoC: SOF: pm: add explicit behavior for ACPI S1 and S2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing code only deals with S0 and S3, let's start adding S1 and S2. No functional change. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 18eb327a57f03..239f39a5166a4 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -335,8 +335,18 @@ int snd_sof_prepare(struct device *dev) return 0; #if defined(CONFIG_ACPI) - if (acpi_target_system_state() == ACPI_STATE_S0) + switch (acpi_target_system_state()) { + case ACPI_STATE_S0: sdev->system_suspend_target = SOF_SUSPEND_S0IX; + break; + case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + sdev->system_suspend_target = SOF_SUSPEND_S3; + break; + default: + break; + } #endif return 0; -- GitLab From 7a5974e035a6d496797547e4b469bc88938343c2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:17 -0500 Subject: [PATCH 542/942] ASoC: SOF: pm: add definitions for S4 and S5 states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently don't have a means to differentiate between S3, S4 and S5. Add definitions so that we have select different code paths depending on the target state in follow-up patches. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pm.c | 9 +++++++++ sound/soc/sof/sof-priv.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 239f39a5166a4..df740be645e84 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -23,6 +23,9 @@ static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev) u32 target_dsp_state; switch (sdev->system_suspend_target) { + case SOF_SUSPEND_S5: + case SOF_SUSPEND_S4: + /* DSP should be in D3 if the system is suspending to S3+ */ case SOF_SUSPEND_S3: /* DSP should be in D3 if the system is suspending to S3 */ target_dsp_state = SOF_DSP_PM_D3; @@ -344,6 +347,12 @@ int snd_sof_prepare(struct device *dev) case ACPI_STATE_S3: sdev->system_suspend_target = SOF_SUSPEND_S3; break; + case ACPI_STATE_S4: + sdev->system_suspend_target = SOF_SUSPEND_S4; + break; + case ACPI_STATE_S5: + sdev->system_suspend_target = SOF_SUSPEND_S5; + break; default: break; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 9d7f53ff9c70e..f0f3d72c0da73 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -85,6 +85,8 @@ enum sof_system_suspend_state { SOF_SUSPEND_NONE = 0, SOF_SUSPEND_S0IX, SOF_SUSPEND_S3, + SOF_SUSPEND_S4, + SOF_SUSPEND_S5, }; enum sof_dfsentry_type { -- GitLab From 58ecb11eab44dd5d64e35664ac4d62fecb6328f4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:18 -0500 Subject: [PATCH 543/942] ASoC: SOF: Intel: disable IMR boot when resuming from ACPI S4 and S5 states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IMR was assumed to be preserved when suspending to S4 and S5 states, but community reports invalidate that assumption, the hardware seems to be powered off and the IMR memory content cleared. Make sure regular boot with firmware download is used for S4 and S5. BugLink: https://github.com/thesofproject/sof/issues/5892 Fixes: 5fb5f51185126 ("ASoC: SOF: Intel: hda-loader: add IMR restore support") Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index d3ec5996a9a3d..145d483bd129f 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -389,7 +389,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) struct snd_dma_buffer dmab; int ret, ret1, i; - if (hda->imrboot_supported && !sdev->first_boot) { + if (sdev->system_suspend_target < SOF_SUSPEND_S4 && + hda->imrboot_supported && !sdev->first_boot) { dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n"); hda->boot_iteration = 0; ret = hda_dsp_boot_imr(sdev); -- GitLab From a37a9224d0500f0cf5bf13cb225163c21b29e0f6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 16 Jun 2022 15:19:53 -0500 Subject: [PATCH 544/942] ASoC: SOF: Intel: hda: Fix compressed stream position tracking Commit 288fad2f71fa ("ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information") modified the PCM path only, but left the compressed data patch using an obsolete option. Move the functionality in a helper that can be called for both PCM and compressed data. Reviewed-by: Ranjani Sridharan Fixes: 288fad2f71fa ("ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information") Signed-off-by: Peter Ujfalusi Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220616201953.130876-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-pcm.c | 74 +------------------------ sound/soc/sof/intel/hda-stream.c | 94 ++++++++++++++++++++++++++++++-- sound/soc/sof/intel/hda.h | 3 + 3 files changed, 94 insertions(+), 77 deletions(-) diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index dc1f743730c0d..6888e0a4665d2 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -192,79 +192,7 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, goto found; } - switch (sof_hda_position_quirk) { - case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY: - /* - * This legacy code, inherited from the Skylake driver, - * mixes DPIB registers and DPIB DDR updates and - * does not seem to follow any known hardware recommendations. - * It's not clear e.g. why there is a different flow - * for capture and playback, the only information that matters is - * what traffic class is used, and on all SOF-enabled platforms - * only VC0 is supported so the work-around was likely not necessary - * and quite possibly wrong. - */ - - /* DPIB/posbuf position mode: - * For Playback, Use DPIB register from HDA space which - * reflects the actual data transferred. - * For Capture, Use the position buffer for pointer, as DPIB - * is not accurate enough, its update may be completed - * earlier than the data written to DDR. - */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - } else { - /* - * For capture stream, we need more workaround to fix the - * position incorrect issue: - * - * 1. Wait at least 20us before reading position buffer after - * the interrupt generated(IOC), to make sure position update - * happens on frame boundary i.e. 20.833uSec for 48KHz. - * 2. Perform a dummy Read to DPIB register to flush DMA - * position value. - * 3. Read the DMA Position from posbuf. Now the readback - * value should be >= period boundary. - */ - usleep_range(20, 21); - snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - pos = snd_hdac_stream_get_pos_posbuf(hstream); - } - break; - case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS: - /* - * In case VC1 traffic is disabled this is the recommended option - */ - pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - break; - case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE: - /* - * This is the recommended option when VC1 is enabled. - * While this isn't needed for SOF platforms it's added for - * consistency and debug. - */ - pos = snd_hdac_stream_get_pos_posbuf(hstream); - break; - default: - dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", - sof_hda_position_quirk); - pos = 0; - break; - } - - if (pos >= hstream->bufsize) - pos = 0; - + pos = hda_dsp_stream_get_position(hstream, substream->stream, true); found: pos = bytes_to_frames(substream->runtime, pos); diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index daeb64c495e40..d95ae17e81cc4 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -707,12 +707,13 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev) } static void -hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size) +hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction) { + u64 buffer_size = hstream->bufsize; u64 prev_pos, pos, num_bytes; div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); - pos = snd_hdac_stream_get_pos_posbuf(hstream); + pos = hda_dsp_stream_get_position(hstream, direction, false); if (pos < prev_pos) num_bytes = (buffer_size - prev_pos) + pos; @@ -748,8 +749,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) if (s->substream && sof_hda->no_ipc_position) { snd_sof_pcm_period_elapsed(s->substream); } else if (s->cstream) { - hda_dsp_set_bytes_transferred(s, - s->cstream->runtime->buffer_size); + hda_dsp_compr_bytes_transferred(s, s->cstream->direction); snd_compr_fragment_elapsed(s->cstream); } } @@ -1009,3 +1009,89 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) devm_kfree(sdev->dev, hda_stream); } } + +snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, + int direction, bool can_sleep) +{ + struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream); + struct sof_intel_hda_stream *hda_stream = hstream_to_sof_hda_stream(hext_stream); + struct snd_sof_dev *sdev = hda_stream->sdev; + snd_pcm_uframes_t pos; + + switch (sof_hda_position_quirk) { + case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY: + /* + * This legacy code, inherited from the Skylake driver, + * mixes DPIB registers and DPIB DDR updates and + * does not seem to follow any known hardware recommendations. + * It's not clear e.g. why there is a different flow + * for capture and playback, the only information that matters is + * what traffic class is used, and on all SOF-enabled platforms + * only VC0 is supported so the work-around was likely not necessary + * and quite possibly wrong. + */ + + /* DPIB/posbuf position mode: + * For Playback, Use DPIB register from HDA space which + * reflects the actual data transferred. + * For Capture, Use the position buffer for pointer, as DPIB + * is not accurate enough, its update may be completed + * earlier than the data written to DDR. + */ + if (direction == SNDRV_PCM_STREAM_PLAYBACK) { + pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + } else { + /* + * For capture stream, we need more workaround to fix the + * position incorrect issue: + * + * 1. Wait at least 20us before reading position buffer after + * the interrupt generated(IOC), to make sure position update + * happens on frame boundary i.e. 20.833uSec for 48KHz. + * 2. Perform a dummy Read to DPIB register to flush DMA + * position value. + * 3. Read the DMA Position from posbuf. Now the readback + * value should be >= period boundary. + */ + if (can_sleep) + usleep_range(20, 21); + + snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + pos = snd_hdac_stream_get_pos_posbuf(hstream); + } + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS: + /* + * In case VC1 traffic is disabled this is the recommended option + */ + pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE: + /* + * This is the recommended option when VC1 is enabled. + * While this isn't needed for SOF platforms it's added for + * consistency and debug. + */ + pos = snd_hdac_stream_get_pos_posbuf(hstream); + break; + default: + dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", + sof_hda_position_quirk); + pos = 0; + break; + } + + if (pos >= hstream->bufsize) + pos = 0; + + return pos; +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 0f57ef5d9b8e9..06476ffe96d73 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -565,6 +565,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev, bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev); bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev); +snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, + int direction, bool can_sleep); + struct hdac_ext_stream * hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags); int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag); -- GitLab From e1ab67be68e900a6585277ca442ca7f67dffb3bd Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:08:01 -0500 Subject: [PATCH 545/942] ASoC: cs4270: update kernel-doc Remove warning sound/soc/codecs/cs4270.c:672: warning: Excess function parameter 'id' description in 'cs4270_i2c_probe' Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220616220802.136282-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs4270.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 531f63b015547..97d26b9e8f7fe 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -663,7 +663,6 @@ static int cs4270_i2c_remove(struct i2c_client *i2c_client) /** * cs4270_i2c_probe - initialize the I2C interface of the CS4270 * @i2c_client: the I2C client object - * @id: the I2C device ID (ignored) * * This function is called whenever the I2C subsystem finds a device that * matches the device ID given via a prior call to i2c_add_driver(). -- GitLab From 7c619b306285588725573d975fd44607d13438cf Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:08:02 -0500 Subject: [PATCH 546/942] ASoC: sunxi: sun4i-i2s: update kernel-doc Remove warnings sound/soc/sunxi/sun4i-i2s.c:205: warning: Function parameter or member 'num_din_pins' not described in 'sun4i_i2s_quirks' sound/soc/sunxi/sun4i-i2s.c:205: warning: Function parameter or member 'num_dout_pins' not described in 'sun4i_i2s_quirks' Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220616220802.136282-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-i2s.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index f58aa6406a874..5be33d07361bd 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -161,6 +161,8 @@ struct sun4i_i2s; * @field_clkdiv_mclk_en: regmap field to enable mclk output. * @field_fmt_wss: regmap field to set word select size. * @field_fmt_sr: regmap field to set sample resolution. + * @num_din_pins: input pins + * @num_dout_pins: output pins (currently set but unused) * @bclk_dividers: bit clock dividers array * @num_bclk_dividers: number of bit clock dividers * @mclk_dividers: mclk dividers array -- GitLab From e33ea0685a219543f3e23d88186bc6c3259b3ff4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:43 -0500 Subject: [PATCH 547/942] ASoC: Intel: skl_nau88l25_max98357a: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- .../soc/intel/boards/skl_nau88l25_max98357a.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index 8e2d03e360792..8dceb0b025812 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -97,6 +97,17 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = { SND_SOC_DAPM_POST_PMD), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route skylake_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -163,9 +174,11 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset); + ret = snd_soc_card_jack_new_pins(&skylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; -- GitLab From 4864ef4a67edfbf802ba36c921c5e9f66e1530bf Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:44 -0500 Subject: [PATCH 548/942] ASoC: Intel: skl_nau88l25_ssm4567: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/skl_nau88l25_ssm4567.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 501f0bbfc4045..62c0d46d00862 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -101,6 +101,17 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = { SND_SOC_DAPM_POST_PMD), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route skylake_map[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HPOL"}, @@ -182,9 +193,11 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) * 4 buttons here map to the google Reference headset * The use of these buttons can be decided by the user space. */ - ret = snd_soc_card_jack_new(&skylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset); + ret = snd_soc_card_jack_new_pins(&skylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, &skylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; -- GitLab From decdbf3dd7ec3e3522548f50e22d81558d151118 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:45 -0500 Subject: [PATCH 549/942] ASoC: Intel: kbl_rt5663_max98927: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/kbl_rt5663_max98927.c | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 8d37b2676a81a..2d4224c5b1520 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -206,6 +206,17 @@ static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { SND_SOC_DAPM_POST_PMD), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route kabylake_5663_map[] = { { "Headphone Jack", NULL, "Platform Clock" }, { "Headphone Jack", NULL, "HPOL" }, @@ -271,10 +282,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->kabylake_headset); + ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + &ctx->kabylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; -- GitLab From c2065d43ae8546668f8f187138eda8a18f7625fd Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:46 -0500 Subject: [PATCH 550/942] ASoC: Intel: kbl_da7219_max98357a: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/kbl_da7219_max98357a.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index ceabed85e9daa..329457e3e3a22 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -99,6 +99,17 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_POST_PMD), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route kabylake_map[] = { { "Headphone Jack", NULL, "HPL" }, { "Headphone Jack", NULL, "HPR" }, @@ -179,10 +190,12 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->kabylake_headset); + ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &ctx->kabylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From b9f53b9fc14e26ef3b3c33160afb094ad7ae192b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:47 -0500 Subject: [PATCH 551/942] ASoC: Intel: kbl_da7219_max98927: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/kbl_da7219_max98927.c | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index 703ccff634b01..362579f25835e 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -119,6 +119,17 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_POST_PMD), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route kabylake_map[] = { /* speaker */ { "Left Spk", NULL, "Left BE_OUT" }, @@ -354,10 +365,12 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->kabylake_headset); + ret = snd_soc_card_jack_new_pins(kabylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &ctx->kabylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From c0703be996c343b4d1036b6ba258133d88b7932b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:48 -0500 Subject: [PATCH 552/942] ASoC: Intel: kbl_rt5663_rt5514_max98927: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- .../intel/boards/kbl_rt5663_rt5514_max98927.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 564c70a0fbc83..2c79fca57b19e 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -145,6 +145,17 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route kabylake_map[] = { /* Headphones */ { "Headphone Jack", NULL, "Platform Clock" }, @@ -228,10 +239,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(&kabylake_audio_card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->kabylake_headset); + ret = snd_soc_card_jack_new_pins(&kabylake_audio_card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + &ctx->kabylake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; -- GitLab From bbdd4ea2190b4712c0cd9989a5e402c7f99fc122 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:49 -0500 Subject: [PATCH 553/942] ASoC: Intel: bxt_da7219_max98357a: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bxt_da7219_max98357a.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index d98376da425a6..7c6c95e99ade2 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -186,6 +186,17 @@ static const struct snd_soc_dapm_route gemini_map[] = { {"ssp2 Rx", NULL, "Capture"}, }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -231,10 +242,12 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &broxton_headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &broxton_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 4c3a68e9026ad7d3aa61278ce5702407d91d5dd9 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:50 -0500 Subject: [PATCH 554/942] ASoC: Intel: glk_rt5682_max98357a: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/glk_rt5682_max98357a.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c index 170164baae7da..cf0f89db3e204 100644 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c @@ -78,6 +78,17 @@ static const struct snd_soc_dapm_widget geminilake_widgets[] = { SND_SOC_DAPM_SPK("HDMI3", NULL), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route geminilake_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -173,10 +184,12 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->geminilake_headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &ctx->geminilake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 77a036e8b074a679c0177f61c9d3b8e942673141 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:51 -0500 Subject: [PATCH 555/942] ASoC: Intel: cml_rt1011_rt5682: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/cml_rt1011_rt5682.c | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index a99f74a15b5fd..20da83d9eeced 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -121,6 +121,17 @@ static const struct snd_soc_dapm_route cml_rt1011_tt_map[] = { {"TR Ext Spk", NULL, "TR SPO" }, }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); @@ -137,11 +148,13 @@ static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + &ctx->headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 7459c8940a506280908f8b5e9e4227784a0b6569 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:52 -0500 Subject: [PATCH 556/942] ASoC: Intel: sof_cs42l42: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cs42l42.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index 6a979c333bc59..a1a14d6d7c238 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -52,6 +52,17 @@ enum { LINK_HDMI = 4, }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + /* Default: SSP2 */ static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2); @@ -98,11 +109,13 @@ static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - jack); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 2913bb1f6830251416659dbb04c392bbc9592f14 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:53 -0500 Subject: [PATCH 557/942] ASoC: Intel: sof_da7219_max98373: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_da7219_max98373.c | 23 +++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219_max98373.c index a83f30b687cf3..34cf849a8344e 100644 --- a/sound/soc/intel/boards/sof_da7219_max98373.c +++ b/sound/soc/intel/boards/sof_da7219_max98373.c @@ -135,6 +135,17 @@ static const struct snd_soc_dapm_route max98360a_map[] = { {"DMic", NULL, "SoC DMIC"}, }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static struct snd_soc_jack headset; static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) @@ -156,11 +167,13 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 2a172d2f06c155ea7c9b34f47febdfe9b9bbe1c2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:54 -0500 Subject: [PATCH 558/942] ASoC: Intel: sof_nau8825: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-13-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_nau8825.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 97dcd204a2466..f49700eb721b4 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -81,6 +81,17 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); @@ -93,11 +104,13 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sof_headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + &ctx->sof_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From c3ce12b27e562bf3a255bc9f3096dacea2194dd8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:40:55 -0500 Subject: [PATCH 559/942] ASoC: Intel: sof_rt5682: remap jack pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The card did not map jack pins to controls, which prevents PulseAudio/PipeWire from dealing with jack detection. It's likely that jack detection was only tested with the CRAS server and extensions of UCM. Suggested-by: Jaroslav Kysela Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616214055.134943-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index f28dae64587e1..a24fb71d5ff3a 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -248,6 +248,17 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); @@ -295,11 +306,13 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2 | - SND_JACK_BTN_3, - &ctx->sof_headset); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + &ctx->sof_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; -- GitLab From 6d5e37b0f343af70a7e824641f264fb140bbead5 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:39 -0500 Subject: [PATCH 560/942] ASoC: SOF: Intel: hda-dsp: report error on power-up/down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev_dbg() is not good-enough since the flow returns an error. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 263ad455e283a..2afaee91b982a 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -743,7 +743,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev) if (hlink->ref_count) { ret = snd_hdac_ext_bus_link_power_up(hlink); if (ret < 0) { - dev_dbg(sdev->dev, + dev_err(sdev->dev, "error %d in %s: failed to power up links", ret, __func__); return ret; @@ -871,7 +871,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) /* no link can be powered in s0ix state */ ret = snd_hdac_ext_bus_link_power_down_all(bus); if (ret < 0) { - dev_dbg(sdev->dev, + dev_err(sdev->dev, "error %d in %s: failed to power down links", ret, __func__); return ret; -- GitLab From 3abc88730a0e45247296a561a12e811b5d2d2236 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:40 -0500 Subject: [PATCH 561/942] ASoC: SOF: Intel: hda-stream: report error on stream not opened MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We report -ENODEV but only use dev_dbg, this is inconsistent. dev_err() makes sense here. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index daeb64c495e40..d3403b7a2b2ea 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -271,7 +271,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); if (!found) { - dev_dbg(sdev->dev, "%s: stream_tag %d not opened!\n", + dev_err(sdev->dev, "%s: stream_tag %d not opened!\n", __func__, stream_tag); return -ENODEV; } -- GitLab From 18701bb1370cb6b34a8f3ad820045930138083dc Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:41 -0500 Subject: [PATCH 562/942] ASoC: SOF: Intel: hda-dai: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 70721defca467..ed74a1f264e86 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -393,7 +393,7 @@ static int hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_d if (hext_stream && hext_stream->link_prepared) return 0; - dev_dbg(sdev->dev, "%s: prepare stream dir %d\n", __func__, substream->stream); + dev_dbg(sdev->dev, "prepare stream dir %d\n", substream->stream); ret = hda_link_dma_prepare(substream); if (ret < 0) @@ -419,7 +419,7 @@ static int ipc3_hda_dai_trigger(struct snd_pcm_substream *substream, struct snd_soc_dapm_widget *w; int ret; - dev_dbg(dai->dev, "%s: cmd=%d dai %s direction %d\n", __func__, cmd, + dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd, dai->name, substream->stream); ret = hda_link_dma_trigger(substream, cmd); @@ -468,7 +468,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai; int ret; - dev_dbg(dai->dev, "%s: cmd=%d dai %s direction %d\n", __func__, cmd, + dev_dbg(dai->dev, "cmd=%d dai %s direction %d\n", cmd, dai->name, substream->stream); hstream = substream->runtime->private_data; -- GitLab From 8bf064f8e439d9b92a023a54adc657f920f4e1a8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:42 -0500 Subject: [PATCH 563/942] ASoC: SOF: Intel: hda-stream: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index d3403b7a2b2ea..a4d51f855e56c 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -116,13 +116,13 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev, int remain, ioc; period_bytes = hstream->period_bytes; - dev_dbg(sdev->dev, "%s: period_bytes:0x%x\n", __func__, period_bytes); + dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes); if (!period_bytes) period_bytes = hstream->bufsize; periods = hstream->bufsize / period_bytes; - dev_dbg(sdev->dev, "%s: periods:%d\n", __func__, periods); + dev_dbg(sdev->dev, "periods:%d\n", periods); remain = hstream->bufsize % period_bytes; if (remain) -- GitLab From b837870fe17f21cf80b15d143c9ea0bc6b342741 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:43 -0500 Subject: [PATCH 564/942] ASoC: SOF: Intel: mtl: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/mtl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 37be77beb415f..3a043589c12bb 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -540,8 +540,7 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) if (!ipc_irq) { /* This interrupt is not shared so no need to return IRQ_NONE. */ - dev_dbg_ratelimited(sdev->dev, "%s nothing to do in IPC IRQ thread\n", - __func__); + dev_dbg_ratelimited(sdev->dev, "nothing to do in IPC IRQ thread\n"); } return IRQ_HANDLED; -- GitLab From 9fd8fcd03451ea3f04af9a419748248d3fa8fb59 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:44 -0500 Subject: [PATCH 565/942] ASoC: SOF: ipc3-dtrace: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-dtrace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index ecca6dceaad29..b815b0244d9e4 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -470,7 +470,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev) dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret); return ret; } - dev_dbg(sdev->dev, "%s: stream_tag: %d\n", __func__, params.stream_tag); + dev_dbg(sdev->dev, "stream_tag: %d\n", params.stream_tag); /* send IPC to the DSP */ priv->dtrace_state = SOF_DTRACE_INITIALIZING; @@ -544,8 +544,7 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev) goto table_err; priv->dma_trace_pages = ret; - dev_dbg(sdev->dev, "%s: dma_trace_pages: %d\n", __func__, - priv->dma_trace_pages); + dev_dbg(sdev->dev, "dma_trace_pages: %d\n", priv->dma_trace_pages); if (sdev->first_boot) { ret = debugfs_create_dtrace(sdev); -- GitLab From e16809a74f09b2c2e066b3d7cf1d87be2a75911e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:45 -0500 Subject: [PATCH 566/942] ASoC: SOF: ipc3-loader: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-loader.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/sof/ipc3-loader.c b/sound/soc/sof/ipc3-loader.c index f3c741b495198..c573e7593808a 100644 --- a/sound/soc/sof/ipc3-loader.c +++ b/sound/soc/sof/ipc3-loader.c @@ -75,13 +75,12 @@ static int ipc3_fw_ext_man_get_config_data(struct snd_sof_dev *sdev, elems_size = config->hdr.size - sizeof(struct sof_ext_man_elem_header); elems_counter = elems_size / sizeof(struct sof_config_elem); - dev_dbg(sdev->dev, "%s can hold up to %d config elements\n", - __func__, elems_counter); + dev_dbg(sdev->dev, "manifest can hold up to %d config elements\n", elems_counter); for (i = 0; i < elems_counter; ++i) { elem = &config->elems[i]; - dev_dbg(sdev->dev, "%s get index %d token %d val %d\n", - __func__, i, elem->token, elem->value); + dev_dbg(sdev->dev, "get index %d token %d val %d\n", + i, elem->token, elem->value); switch (elem->token) { case SOF_EXT_MAN_CONFIG_EMPTY: /* unused memory space is zero filled - mapped to EMPTY elements */ @@ -323,10 +322,10 @@ static int sof_ipc3_load_fw_to_dsp(struct snd_sof_dev *sdev) header = (struct snd_sof_fw_header *)(fw->data + plat_data->fw_offset); load_module = sof_ops(sdev)->load_module; if (!load_module) { - dev_dbg(sdev->dev, "%s: Using generic module loading\n", __func__); + dev_dbg(sdev->dev, "Using generic module loading\n"); load_module = sof_ipc3_parse_module_memcpy; } else { - dev_dbg(sdev->dev, "%s: Using custom module loading\n", __func__); + dev_dbg(sdev->dev, "Using custom module loading\n"); } /* parse each module */ -- GitLab From f132dc020270976fe83c86f8c826890873023980 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:46 -0500 Subject: [PATCH 567/942] ASoC: SOF: ipc3-topology: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 28d3c14145728..99b62fe7a95cd 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1452,8 +1452,8 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) if (ret < 0) goto free; - dev_dbg(scomp->dev, "%s dai %s: type %d index %d\n", - __func__, swidget->widget->name, comp_dai->type, comp_dai->dai_index); + dev_dbg(scomp->dev, "dai %s: type %d index %d\n", + swidget->widget->name, comp_dai->type, comp_dai->dai_index); sof_dbg_comp_config(scomp, &comp_dai->config); /* now update DAI config */ -- GitLab From 3809264b53906b8b666b93831ecc23a00e119b68 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:47 -0500 Subject: [PATCH 568/942] ASoC: SOF: ipc4-topology remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 3c949298e007f..34f805431f2eb 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -804,8 +804,8 @@ static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev, valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); if (params_rate(params) == rate && params_channels(params) == channels && sample_valid_bits == valid_bits) { - dev_dbg(sdev->dev, "%s: matching audio format index for %uHz, %ubit, %u channels: %d\n", - __func__, rate, valid_bits, channels, i); + dev_dbg(sdev->dev, "matching audio format index for %uHz, %ubit, %u channels: %d\n", + rate, valid_bits, channels, i); /* copy ibs/obs and input format */ memcpy(base_config, &available_fmt->base_config[i], @@ -919,8 +919,8 @@ static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof *channel_count = le32_to_cpu(hw_config->tdm_slots); *sample_rate = le32_to_cpu(hw_config->fsync_rate); - dev_dbg(sdev->dev, "%s: sample rate: %d sample width: %d channels: %d\n", - __func__, *sample_rate, *bit_depth, *channel_count); + dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", + *sample_rate, *bit_depth, *channel_count); return 0; } @@ -954,8 +954,8 @@ static int snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_s return 0; } - dev_dbg(sdev->dev, "%s: dai index %d nhlt type %d direction %d\n", - __func__, dai_index, nhlt_type, dir); + dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d\n", + dai_index, nhlt_type, dir); /* find NHLT blob with matching params */ cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, @@ -1005,7 +1005,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, u32 **data; int ipc_size, ret; - dev_dbg(sdev->dev, "%s: copier %s, type %d", __func__, swidget->widget->name, swidget->id); + dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); switch (swidget->id) { case snd_soc_dapm_aif_in: @@ -1446,7 +1446,7 @@ static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route * int dst_queue = 0; int ret; - dev_dbg(sdev->dev, "%s: bind %s -> %s\n", __func__, + dev_dbg(sdev->dev, "bind %s -> %s\n", src_widget->widget->name, sink_widget->widget->name); header = src_fw_module->man4_module_entry.id; @@ -1483,7 +1483,7 @@ static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *s int dst_queue = 0; int ret; - dev_dbg(sdev->dev, "%s: unbind modules %s -> %s\n", __func__, + dev_dbg(sdev->dev, "unbind modules %s -> %s\n", src_widget->widget->name, sink_widget->widget->name); header = src_fw_module->man4_module_entry.id; -- GitLab From 298e3aba1b56d19dcb70e10ffe93057d1ddd18f6 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:48 -0500 Subject: [PATCH 569/942] ASoC: SOF: sof-client: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 16cca666bb852..125aa21371954 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -383,8 +383,8 @@ void sof_client_ipc_rx_dispatcher(struct snd_sof_dev *sdev, void *msg_buf) msg_type = SOF_IPC4_NOTIFICATION_TYPE_GET(msg->primary); } else { - dev_dbg_once(sdev->dev, "%s: Not supported IPC version: %d\n", - __func__, sdev->pdata->ipc_type); + dev_dbg_once(sdev->dev, "Not supported IPC version: %d\n", + sdev->pdata->ipc_type); return; } -- GitLab From b3ec3eb2baaad057631ab7e09c38ab3ad5c7a42b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:49 -0500 Subject: [PATCH 570/942] ASoC: SOF: ipc4: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index a8dea5abf2655..432b812bdf9c6 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -574,7 +574,7 @@ static void sof_ipc4_rx_msg(struct snd_sof_dev *sdev) data_size = sizeof(struct sof_ipc4_notify_resource_data); break; default: - dev_dbg(sdev->dev, "%s: Unhandled DSP message: %#x|%#x\n", __func__, + dev_dbg(sdev->dev, "Unhandled DSP message: %#x|%#x\n", ipc4_msg->primary, ipc4_msg->extension); break; } -- GitLab From 46bc6bc3a6a3af5306e8e3320a083cf3c32350d4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:50 -0500 Subject: [PATCH 571/942] ASoC: Intel: boards: hda: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-13-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hda_dsp_common.c | 4 ++-- sound/soc/intel/boards/skl_hda_dsp_generic.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/hda_dsp_common.c b/sound/soc/intel/boards/hda_dsp_common.c index 5c31ddc0884ab..83c7dfbccd9d4 100644 --- a/sound/soc/intel/boards/hda_dsp_common.c +++ b/sound/soc/intel/boards/hda_dsp_common.c @@ -62,8 +62,8 @@ int hda_dsp_hdmi_build_controls(struct snd_soc_card *card, hpcm->pcm = spcm; hpcm->device = spcm->device; dev_dbg(card->dev, - "%s: mapping HDMI converter %d to PCM %d (%p)\n", - __func__, i, hpcm->device, spcm); + "mapping HDMI converter %d to PCM %d (%p)\n", + i, hpcm->device, spcm); } else { hpcm->pcm = NULL; hpcm->device = SNDRV_PCM_INVALID_DEVICE; diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index f4b4eeca3e03c..81144efb4b44e 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -75,7 +75,7 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link) struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card); int ret = 0; - dev_dbg(card->dev, "%s: dai link name - %s\n", __func__, link->name); + dev_dbg(card->dev, "dai link name - %s\n", link->name); link->platforms->name = ctx->platform_name; link->nonatomic = 1; @@ -203,7 +203,7 @@ static int skl_hda_audio_probe(struct platform_device *pdev) struct skl_hda_private *ctx; int ret; - dev_dbg(&pdev->dev, "%s: entry\n", __func__); + dev_dbg(&pdev->dev, "entry\n"); ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) -- GitLab From d2d19cb6ed13eb54dd6c958f3808a23820c3ebba Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:53:51 -0500 Subject: [PATCH 572/942] ASoC: Intel: boards: sof_sdw: remove use of __func__ in dev_dbg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The module and function information can be added with 'modprobe foo dyndbg=+pmf' Suggested-by: Greg KH Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220616215351.135643-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index d23846572543b..0c47d76a79e26 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1447,7 +1447,7 @@ static int mc_probe(struct platform_device *pdev) int amp_num = 0, i; int ret; - dev_dbg(&pdev->dev, "Entry %s\n", __func__); + dev_dbg(&pdev->dev, "Entry\n"); ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) -- GitLab From 7adadfb06b9839fa7d9de0cde7ad57a3be3665f0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 16 Jun 2022 18:35:21 +0300 Subject: [PATCH 573/942] ASoC: twl4030: Drop legacy, non DT boot support Legacy or non DT boot is no longer possible on systems where the tw4030/5030 is used. Drop the support for handling legacy pdata and replace it with a local board_params struct to allow further cleanups on the mfd side. Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220616153521.29701-1-peter.ujfalusi@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 101 ++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 0ba3546ef8708..87b58017094b2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -34,6 +34,14 @@ #define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) +struct twl4030_board_params { + unsigned int digimic_delay; /* in ms */ + unsigned int ramp_delay_value; + unsigned int offset_cncl_path; + unsigned int hs_extmute:1; + int hs_extmute_gpio; +}; + /* codec private data */ struct twl4030_priv { unsigned int codec_powered; @@ -58,7 +66,7 @@ struct twl4030_priv { u8 carkitl_enabled, carkitr_enabled; u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1]; - struct twl4030_codec_data *pdata; + struct twl4030_board_params *board_params; }; static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030) @@ -193,73 +201,71 @@ static void twl4030_codec_enable(struct snd_soc_component *component, int enable udelay(10); } -static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, - struct device_node *node) +static void +twl4030_get_board_param_values(struct twl4030_board_params *board_params, + struct device_node *node) { int value; - of_property_read_u32(node, "ti,digimic_delay", - &pdata->digimic_delay); - of_property_read_u32(node, "ti,ramp_delay_value", - &pdata->ramp_delay_value); - of_property_read_u32(node, "ti,offset_cncl_path", - &pdata->offset_cncl_path); + of_property_read_u32(node, "ti,digimic_delay", &board_params->digimic_delay); + of_property_read_u32(node, "ti,ramp_delay_value", &board_params->ramp_delay_value); + of_property_read_u32(node, "ti,offset_cncl_path", &board_params->offset_cncl_path); if (!of_property_read_u32(node, "ti,hs_extmute", &value)) - pdata->hs_extmute = value; + board_params->hs_extmute = value; - pdata->hs_extmute_gpio = of_get_named_gpio(node, - "ti,hs_extmute_gpio", 0); - if (gpio_is_valid(pdata->hs_extmute_gpio)) - pdata->hs_extmute = 1; + board_params->hs_extmute_gpio = of_get_named_gpio(node, "ti,hs_extmute_gpio", 0); + if (gpio_is_valid(board_params->hs_extmute_gpio)) + board_params->hs_extmute = 1; } -static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_component *component) +static struct twl4030_board_params* +twl4030_get_board_params(struct snd_soc_component *component) { - struct twl4030_codec_data *pdata = dev_get_platdata(component->dev); + struct twl4030_board_params *board_params = NULL; struct device_node *twl4030_codec_node = NULL; twl4030_codec_node = of_get_child_by_name(component->dev->parent->of_node, "codec"); - if (!pdata && twl4030_codec_node) { - pdata = devm_kzalloc(component->dev, - sizeof(struct twl4030_codec_data), - GFP_KERNEL); - if (!pdata) { + if (twl4030_codec_node) { + board_params = devm_kzalloc(component->dev, + sizeof(struct twl4030_board_params), + GFP_KERNEL); + if (!board_params) { of_node_put(twl4030_codec_node); return NULL; } - twl4030_setup_pdata_of(pdata, twl4030_codec_node); + twl4030_get_board_param_values(board_params, twl4030_codec_node); of_node_put(twl4030_codec_node); } - return pdata; + return board_params; } static void twl4030_init_chip(struct snd_soc_component *component) { - struct twl4030_codec_data *pdata; + struct twl4030_board_params *board_params; struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); u8 reg, byte; int i = 0; - pdata = twl4030_get_pdata(component); + board_params = twl4030_get_board_params(component); - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { int ret; - if (!pdata->hs_extmute_gpio) + if (!board_params->hs_extmute_gpio) dev_warn(component->dev, "Extmute GPIO is 0 is this correct?\n"); - ret = gpio_request_one(pdata->hs_extmute_gpio, + ret = gpio_request_one(board_params->hs_extmute_gpio, GPIOF_OUT_INIT_LOW, "hs_extmute"); if (ret) { dev_err(component->dev, "Failed to get hs_extmute GPIO\n"); - pdata->hs_extmute_gpio = -1; + board_params->hs_extmute_gpio = -1; } } else { u8 pin_mux; @@ -290,14 +296,14 @@ static void twl4030_init_chip(struct snd_soc_component *component) twl4030_write(component, TWL4030_REG_ARXR2_APGA_CTL, 0x32); /* Machine dependent setup */ - if (!pdata) + if (!board_params) return; - twl4030->pdata = pdata; + twl4030->board_params = board_params; reg = twl4030_read(component, TWL4030_REG_HS_POPN_SET); reg &= ~TWL4030_RAMP_DELAY; - reg |= (pdata->ramp_delay_value << 2); + reg |= (board_params->ramp_delay_value << 2); twl4030_write(component, TWL4030_REG_HS_POPN_SET, reg); /* initiate offset cancellation */ @@ -305,7 +311,7 @@ static void twl4030_init_chip(struct snd_soc_component *component) reg = twl4030_read(component, TWL4030_REG_ANAMICL); reg &= ~TWL4030_OFFSET_CNCL_SEL; - reg |= pdata->offset_cncl_path; + reg |= board_params->offset_cncl_path; twl4030_write(component, TWL4030_REG_ANAMICL, reg | TWL4030_CNCL_OFFSET_START); @@ -692,7 +698,7 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) { unsigned char hs_gain, hs_pop; struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; /* Base values for ramp delay calculation: 2^19 - 2^26 */ unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864}; @@ -705,9 +711,9 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) /* Enable external mute control, this dramatically reduces * the pop-noise */ - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { - gpio_set_value(pdata->hs_extmute_gpio, 1); + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { + gpio_set_value(board_params->hs_extmute_gpio, 1); } else { hs_pop |= TWL4030_EXTMUTE; twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -741,9 +747,9 @@ static void headset_ramp(struct snd_soc_component *component, int ramp) } /* Disable external mute */ - if (pdata && pdata->hs_extmute) { - if (gpio_is_valid(pdata->hs_extmute_gpio)) { - gpio_set_value(pdata->hs_extmute_gpio, 0); + if (board_params && board_params->hs_extmute) { + if (gpio_is_valid(board_params->hs_extmute_gpio)) { + gpio_set_value(board_params->hs_extmute_gpio, 0); } else { hs_pop &= ~TWL4030_EXTMUTE; twl4030_write(component, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -806,10 +812,10 @@ static int digimic_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; - if (pdata && pdata->digimic_delay) - twl4030_wait_ms(pdata->digimic_delay); + if (board_params && board_params->digimic_delay) + twl4030_wait_ms(board_params->digimic_delay); return 0; } @@ -2168,10 +2174,11 @@ static int twl4030_soc_probe(struct snd_soc_component *component) static void twl4030_soc_remove(struct snd_soc_component *component) { struct twl4030_priv *twl4030 = snd_soc_component_get_drvdata(component); - struct twl4030_codec_data *pdata = twl4030->pdata; + struct twl4030_board_params *board_params = twl4030->board_params; - if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) - gpio_free(pdata->hs_extmute_gpio); + if (board_params && board_params->hs_extmute && + gpio_is_valid(board_params->hs_extmute_gpio)) + gpio_free(board_params->hs_extmute_gpio); } static const struct snd_soc_component_driver soc_component_dev_twl4030 = { -- GitLab From 442302003bd2b151e12d52b0af9a7dac131bf931 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Fri, 17 Jun 2022 16:36:06 +0100 Subject: [PATCH 574/942] ASoC: ops: Fix integer detection for when max possible values > 1 The standard snd_soc_info_volsw() allows a two value control to be defined as an integer control only if the control name ends in "Volume". It achieves this by creating a substring if it contains " Volume", and ensuring this exists at the end of the name. The volume substring is then used to decide whether the type is a SNDRV_CTL_ELEM_TYPE_INTEGER or SNDRV_CTL_ELEM_TYPE_BOOLEAN. However this volume substring is only computed for a two value control. This means for controls where there are more than two possible values, the substring is never created, so in this case the substring remains NULL, and the condition yields SNDRV_CTL_ELEM_TYPE_BOOLEAN, even though there are more than 2 possible values. If there are more than 2 possible values for the control, then it should always be an integer control. Fixes: aa2a4b897132 ("ASoC: ops: Fix boolean/integer detection for simple controls") Signed-off-by: Stefan Binding Reviewed-by: Charles Keepax Link: https://lore.kernel.org/r/20220617153606.2619457-1-sbinding@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index c22d87581f6f2..bd88de0563583 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -183,17 +183,16 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, if (mc->platform_max && mc->platform_max < max) max = mc->platform_max; - /* Even two value controls ending in Volume should always be integer */ if (max == 1) { + /* Even two value controls ending in Volume should always be integer */ vol_string = strstr(kcontrol->id.name, " Volume"); - if (vol_string && strcmp(vol_string, " Volume")) - vol_string = NULL; - } - - if (!vol_string) - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - else + if (vol_string && !strcmp(vol_string, " Volume")) + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + else + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + } else { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + } uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; uinfo->value.integer.min = 0; -- GitLab From 6c9e9046e1ff356bda66661213735d33c6cfea53 Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Fri, 17 Jun 2022 19:10:04 +0800 Subject: [PATCH 575/942] ASoC: mediatek: mt8186: Fix mutex double unlock in GPIO request The lockdep mechanism revealed an unbalanced unlocking on MT8186: [ 2.993966] WARNING: bad unlock balance detected! [ 2.993978] ------------------------------------- [ 2.993983] kworker/u16:1/10 is trying to release lock (gpio_request_mutex) at: [ 2.993994] [] mt8186_afe_gpio_request+0xf8/0x210 [ 2.994012] but there are no more locks to release! The cause is that the mutex will be double unlocked if dai is unknown during GPIO selection, and this patch fixes it. Fixes: cfa9a966f12a ("ASoC: mediatek: mt8186: support gpio control in platform driver") Signed-off-by: Fei Shao Link: https://lore.kernel.org/r/20220617111003.2014395-1-fshao@chromium.org Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-afe-gpio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c index 255ffba637d31..274c0c8ec2f29 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c @@ -230,7 +230,6 @@ int mt8186_afe_gpio_request(struct device *dev, bool enable, sel = enable ? MT8186_AFE_GPIO_PCM_ON : MT8186_AFE_GPIO_PCM_OFF; break; default: - mutex_unlock(&gpio_request_mutex); dev_err(dev, "%s(), invalid dai %d\n", __func__, dai); goto unlock; } -- GitLab From 4ea3bfd13a2484b5f1c19f60b1dc7494f261f0a4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:08:24 -0500 Subject: [PATCH 576/942] ASoC: SOF: pcm: use pm_resume_and_get() on component probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before initiating IPC and/or bus transactions when loading the topology during a component probe, which happens on card registration/creation, make sure the device for the SOF driver is pm_runtime active. The SOF probe is not necessarily followed by the component probe, such a timing assumption can be broken in driver bind/unbind tests. This can be artifially shown if the module for the machine driver is 'blacklisted' and the SOF device becomes pm_runtime_suspended before manually calling modprobe to register the card. In an initial experiment, pm_resume_and_get() was called from soc-component.c, since the current ASoC component model is arguably missing dependencies between component status and device status. However this approach proved too invasive and breaks all existing HDMI playback solutions on Intel platforms. While this will result in duplication of code, generating pm_runtime transitions only if strictly required for a given component makes more sense overall. This patch adds the pm_runtime resume transition for SOF only. BugLink: https://github.com/thesofproject/linux/issues/3651 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616210825.132093-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index a76d0b5b2ad95..27504abc5385f 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -604,6 +604,14 @@ static int sof_pcm_probe(struct snd_soc_component *component) const char *tplg_filename; int ret; + /* + * make sure the device is pm_runtime_active before loading the + * topology and initiating IPC or bus transactions + */ + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + /* load the default topology */ sdev->component = component; @@ -621,6 +629,9 @@ static int sof_pcm_probe(struct snd_soc_component *component) return ret; } + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return ret; } -- GitLab From 011e397f5c9c96e533d4a244af84e74c9caefb83 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 16:08:25 -0500 Subject: [PATCH 577/942] ASoC: codecs: soundwire: call pm_runtime_resume() in component probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the bus and codecs are pm_runtime active when the card is registered/created. This avoid timeouts when accessing registers. BugLink: https://github.com/thesofproject/linux/issues/3651 BugLink: https://github.com/thesofproject/linux/issues/3650 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616210825.132093-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373.c | 14 +++++++++++++- sound/soc/codecs/rt1308-sdw.c | 12 ++++++++++++ sound/soc/codecs/rt1316-sdw.c | 12 ++++++++++++ sound/soc/codecs/rt700.c | 5 +++++ sound/soc/codecs/rt711-sdca.c | 5 +++++ sound/soc/codecs/rt711.c | 5 +++++ sound/soc/codecs/rt715-sdca.c | 12 ++++++++++++ sound/soc/codecs/rt715.c | 12 ++++++++++++ 8 files changed, 76 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index e14fe98349a5e..1517c47afbf14 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -440,8 +441,19 @@ const struct snd_soc_component_driver soc_codec_dev_max98373 = { }; EXPORT_SYMBOL_GPL(soc_codec_dev_max98373); +static int max98373_sdw_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = { - .probe = NULL, + .probe = max98373_sdw_probe, .controls = max98373_snd_controls, .num_controls = ARRAY_SIZE(max98373_snd_controls), .dapm_widgets = max98373_dapm_widgets, diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 72f673f278eec..0be6e72ff5a9a 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -608,7 +608,19 @@ static const struct sdw_slave_ops rt1308_slave_ops = { .bus_config = rt1308_bus_config, }; +static int rt1308_sdw_component_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_component_sdw_rt1308 = { + .probe = rt1308_sdw_component_probe, .controls = rt1308_snd_controls, .num_controls = ARRAY_SIZE(rt1308_snd_controls), .dapm_widgets = rt1308_dapm_widgets, diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 2d6b5f9d4d770..e53396606a1c6 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -590,7 +590,19 @@ static struct sdw_slave_ops rt1316_slave_ops = { .update_status = rt1316_update_status, }; +static int rt1316_sdw_component_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_component_sdw_rt1316 = { + .probe = rt1316_sdw_component_probe, .controls = rt1316_snd_controls, .num_controls = ARRAY_SIZE(rt1316_snd_controls), .dapm_widgets = rt1316_dapm_widgets, diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 9bceeeb830b15..055c3ae974d80 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -818,9 +818,14 @@ static const struct snd_soc_dapm_route rt700_audio_map[] = { static int rt700_probe(struct snd_soc_component *component) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index dfe3c9299ebde..9d226b1cb7e92 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1194,10 +1194,15 @@ static int rt711_sdca_parse_dt(struct rt711_sdca_priv *rt711, struct device *dev static int rt711_sdca_probe(struct snd_soc_component *component) { struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711_sdca_parse_dt(rt711, &rt711->slave->dev); rt711->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 9df800abfc2d8..1bf6180891942 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -935,10 +935,15 @@ static int rt711_parse_dt(struct rt711_priv *rt711, struct device *dev) static int rt711_probe(struct snd_soc_component *component) { struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711_parse_dt(rt711, &rt711->slave->dev); rt711->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 5857d08663073..ce8bbc76199a8 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -758,7 +758,19 @@ static const struct snd_soc_dapm_route rt715_sdca_audio_map[] = { {"ADC 25 Mux", "DMIC4", "DMIC4"}, }; +static int rt715_sdca_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = { + .probe = rt715_sdca_probe, .controls = rt715_sdca_snd_controls, .num_controls = ARRAY_SIZE(rt715_sdca_snd_controls), .dapm_widgets = rt715_sdca_dapm_widgets, diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 418e006b19ef5..e93240521c74e 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -737,7 +737,19 @@ static int rt715_set_bias_level(struct snd_soc_component *component, return 0; } +static int rt715_probe(struct snd_soc_component *component) +{ + int ret; + + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + + return 0; +} + static const struct snd_soc_component_driver soc_codec_dev_rt715 = { + .probe = rt715_probe, .set_bias_level = rt715_set_bias_level, .controls = rt715_snd_controls, .num_controls = ARRAY_SIZE(rt715_snd_controls), -- GitLab From cd76175a2b204911a3cddef36b99e56945b6938c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Jun 2022 16:40:47 +0200 Subject: [PATCH 578/942] ALSA: rawmidi: Make internal functions local static __snd_rawmidi_transmit_peek() and __snd_rawmidi_transmit_ack() are never called from the outside. Let's make them local static and unexport them. Link: https://lore.kernel.org/r/20220617144051.18985-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/rawmidi.h | 4 ---- sound/core/rawmidi.c | 13 ++++++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 7a08ed2acd609..9402c25ae9ba1 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -156,10 +156,6 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count); int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, unsigned char *buffer, int count); -int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, - unsigned char *buffer, int count); -int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, - int count); int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream); /* main midi functions */ diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index befa9809ff001..82e8f656bbb2e 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1258,7 +1258,7 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) } EXPORT_SYMBOL(snd_rawmidi_transmit_empty); -/** +/* * __snd_rawmidi_transmit_peek - copy data from the internal buffer * @substream: the rawmidi substream * @buffer: the buffer pointer @@ -1266,8 +1266,8 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_empty); * * This is a variant of snd_rawmidi_transmit_peek() without spinlock. */ -int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, - unsigned char *buffer, int count) +static int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, + unsigned char *buffer, int count) { int result, count1; struct snd_rawmidi_runtime *runtime = substream->runtime; @@ -1304,7 +1304,6 @@ int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, __skip: return result; } -EXPORT_SYMBOL(__snd_rawmidi_transmit_peek); /** * snd_rawmidi_transmit_peek - copy data from the internal buffer @@ -1334,14 +1333,15 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, } EXPORT_SYMBOL(snd_rawmidi_transmit_peek); -/** +/* * __snd_rawmidi_transmit_ack - acknowledge the transmission * @substream: the rawmidi substream * @count: the transferred count * * This is a variant of __snd_rawmidi_transmit_ack() without spinlock. */ -int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) +static int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, + int count) { struct snd_rawmidi_runtime *runtime = substream->runtime; @@ -1361,7 +1361,6 @@ int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int coun } return count; } -EXPORT_SYMBOL(__snd_rawmidi_transmit_ack); /** * snd_rawmidi_transmit_ack - acknowledge the transmission -- GitLab From f1d40433352e5d4babd59c0dd50b5f9414073ddb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Jun 2022 16:40:48 +0200 Subject: [PATCH 579/942] ALSA: rawmidi: Move lock to snd_rawmidi_substream Having a lock in snd_rawmidi_runtime can be a problem especially when a substream is accessed from the outside, as the runtime creation might be racy with the external calls. As a first step for hardening, move the spinlock from snd_rawmidi_runtime to snd_rawmidi_substream. This patch just replaces the lock calls, no real functional change is put yet. Link: https://lore.kernel.org/r/20220617144051.18985-3-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/rawmidi.h | 2 +- sound/core/rawmidi.c | 131 ++++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 68 deletions(-) diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 9402c25ae9ba1..e1f59b2940aff 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h @@ -63,7 +63,6 @@ struct snd_rawmidi_runtime { size_t xruns; /* over/underruns counter */ int buffer_ref; /* buffer reference count */ /* misc */ - spinlock_t lock; wait_queue_head_t sleep; /* event handler (new bytes, input only) */ void (*event)(struct snd_rawmidi_substream *substream); @@ -85,6 +84,7 @@ struct snd_rawmidi_substream { unsigned int clock_type; /* clock source to use for input framing */ int use_count; /* use counter (for output) */ size_t bytes; + spinlock_t lock; struct snd_rawmidi *rmidi; struct snd_rawmidi_str *pstr; char name[32]; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 82e8f656bbb2e..0a00f37d8c429 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -102,13 +102,12 @@ static inline bool __snd_rawmidi_ready(struct snd_rawmidi_runtime *runtime) static bool snd_rawmidi_ready(struct snd_rawmidi_substream *substream) { - struct snd_rawmidi_runtime *runtime = substream->runtime; unsigned long flags; bool ready; - spin_lock_irqsave(&runtime->lock, flags); - ready = __snd_rawmidi_ready(runtime); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); + ready = __snd_rawmidi_ready(substream->runtime); + spin_unlock_irqrestore(&substream->lock, flags); return ready; } @@ -130,7 +129,7 @@ static void snd_rawmidi_input_event_work(struct work_struct *work) runtime->event(runtime->substream); } -/* buffer refcount management: call with runtime->lock held */ +/* buffer refcount management: call with substream->lock held */ static inline void snd_rawmidi_buffer_ref(struct snd_rawmidi_runtime *runtime) { runtime->buffer_ref++; @@ -149,7 +148,6 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) if (!runtime) return -ENOMEM; runtime->substream = substream; - spin_lock_init(&runtime->lock); init_waitqueue_head(&runtime->sleep); INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work); runtime->event = NULL; @@ -203,20 +201,20 @@ static void __reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime, runtime->avail = is_input ? 0 : runtime->buffer_size; } -static void reset_runtime_ptrs(struct snd_rawmidi_runtime *runtime, +static void reset_runtime_ptrs(struct snd_rawmidi_substream *substream, bool is_input) { unsigned long flags; - spin_lock_irqsave(&runtime->lock, flags); - __reset_runtime_ptrs(runtime, is_input); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); + __reset_runtime_ptrs(substream->runtime, is_input); + spin_unlock_irqrestore(&substream->lock, flags); } int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream) { snd_rawmidi_output_trigger(substream, 0); - reset_runtime_ptrs(substream->runtime, false); + reset_runtime_ptrs(substream, false); return 0; } EXPORT_SYMBOL(snd_rawmidi_drop_output); @@ -256,7 +254,7 @@ EXPORT_SYMBOL(snd_rawmidi_drain_output); int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream) { snd_rawmidi_input_trigger(substream, 0); - reset_runtime_ptrs(substream->runtime, true); + reset_runtime_ptrs(substream, true); return 0; } EXPORT_SYMBOL(snd_rawmidi_drain_input); @@ -676,10 +674,11 @@ static int snd_rawmidi_info_select_user(struct snd_card *card, return 0; } -static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, +static int resize_runtime_buffer(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params *params, bool is_input) { + struct snd_rawmidi_runtime *runtime = substream->runtime; char *newbuf, *oldbuf; unsigned int framing = params->mode & SNDRV_RAWMIDI_MODE_FRAMING_MASK; @@ -693,9 +692,9 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, newbuf = kvzalloc(params->buffer_size, GFP_KERNEL); if (!newbuf) return -ENOMEM; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); if (runtime->buffer_ref) { - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); kvfree(newbuf); return -EBUSY; } @@ -703,7 +702,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, runtime->buffer = newbuf; runtime->buffer_size = params->buffer_size; __reset_runtime_ptrs(runtime, is_input); - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); kvfree(oldbuf); } runtime->avail_min = params->avail_min; @@ -717,7 +716,7 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, return -EBUSY; snd_rawmidi_drain_output(substream); substream->active_sensing = !params->no_active_sensing; - return resize_runtime_buffer(substream->runtime, params, false); + return resize_runtime_buffer(substream, params, false); } EXPORT_SYMBOL(snd_rawmidi_output_params); @@ -735,7 +734,7 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) return -EINVAL; snd_rawmidi_drain_input(substream); - err = resize_runtime_buffer(substream->runtime, params, true); + err = resize_runtime_buffer(substream, params, true); if (err < 0) return err; @@ -752,9 +751,9 @@ static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream, memset(status, 0, sizeof(*status)); status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); status->avail = runtime->avail; - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return 0; } @@ -765,11 +764,11 @@ static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream, memset(status, 0, sizeof(*status)); status->stream = SNDRV_RAWMIDI_STREAM_INPUT; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); status->avail = runtime->avail; status->xruns = runtime->xruns; runtime->xruns = 0; - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return 0; } @@ -1074,7 +1073,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, return -EINVAL; } - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) { result = receive_with_tstamp_framing(substream, buffer, count, &ts64); } else if (count == 1) { /* special case, faster code */ @@ -1121,7 +1120,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, else if (__snd_rawmidi_ready(runtime)) wake_up(&runtime->sleep); } - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result; } EXPORT_SYMBOL(snd_rawmidi_receive); @@ -1136,7 +1135,7 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, unsigned long appl_ptr; int err = 0; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); snd_rawmidi_buffer_ref(runtime); while (count > 0 && runtime->avail) { count1 = runtime->buffer_size - runtime->appl_ptr; @@ -1154,11 +1153,11 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, if (kernelbuf) memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1); if (userbuf) { - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); if (copy_to_user(userbuf + result, runtime->buffer + appl_ptr, count1)) err = -EFAULT; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); if (err) goto out; } @@ -1167,7 +1166,7 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream, } out: snd_rawmidi_buffer_unref(runtime); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result > 0 ? result : err; } @@ -1196,31 +1195,31 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun snd_rawmidi_input_trigger(substream, 1); result = 0; while (count > 0) { - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); while (!__snd_rawmidi_ready(runtime)) { wait_queue_entry_t wait; if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return result > 0 ? result : -EAGAIN; } init_waitqueue_entry(&wait, current); add_wait_queue(&runtime->sleep, &wait); set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); schedule(); remove_wait_queue(&runtime->sleep, &wait); if (rfile->rmidi->card->shutdown) return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); if (!runtime->avail) { - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return result > 0 ? result : -EIO; } } - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); count1 = snd_rawmidi_kernel_read1(substream, (unsigned char __user *)buf, NULL/*kernelbuf*/, @@ -1251,9 +1250,9 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) "snd_rawmidi_transmit_empty: output is not active!!!\n"); return 1; } - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); result = runtime->avail >= runtime->buffer_size; - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result; } EXPORT_SYMBOL(snd_rawmidi_transmit_empty); @@ -1322,13 +1321,12 @@ static int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, unsigned char *buffer, int count) { - struct snd_rawmidi_runtime *runtime = substream->runtime; int result; unsigned long flags; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); result = __snd_rawmidi_transmit_peek(substream, buffer, count); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result; } EXPORT_SYMBOL(snd_rawmidi_transmit_peek); @@ -1375,13 +1373,12 @@ static int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, */ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) { - struct snd_rawmidi_runtime *runtime = substream->runtime; int result; unsigned long flags; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); result = __snd_rawmidi_transmit_ack(substream, count); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result; } EXPORT_SYMBOL(snd_rawmidi_transmit_ack); @@ -1399,11 +1396,10 @@ EXPORT_SYMBOL(snd_rawmidi_transmit_ack); int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, unsigned char *buffer, int count) { - struct snd_rawmidi_runtime *runtime = substream->runtime; int result; unsigned long flags; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); if (!substream->opened) result = -EBADFD; else { @@ -1413,7 +1409,7 @@ int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, else result = __snd_rawmidi_transmit_ack(substream, count); } - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return result; } EXPORT_SYMBOL(snd_rawmidi_transmit); @@ -1430,12 +1426,12 @@ int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream) unsigned long flags; int count = 0; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); if (runtime->avail < runtime->buffer_size) { count = runtime->buffer_size - runtime->avail; __snd_rawmidi_transmit_ack(substream, count); } - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return count; } EXPORT_SYMBOL(snd_rawmidi_proceed); @@ -1456,10 +1452,10 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, return -EINVAL; result = 0; - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); if (substream->append) { if ((long)runtime->avail < count) { - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); return -EAGAIN; } } @@ -1481,14 +1477,14 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, memcpy(runtime->buffer + appl_ptr, kernelbuf + result, count1); else if (userbuf) { - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); if (copy_from_user(runtime->buffer + appl_ptr, userbuf + result, count1)) { - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); result = result > 0 ? result : -EFAULT; goto __end; } - spin_lock_irqsave(&runtime->lock, flags); + spin_lock_irqsave(&substream->lock, flags); } result += count1; count -= count1; @@ -1496,7 +1492,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, __end: count1 = runtime->avail < runtime->buffer_size; snd_rawmidi_buffer_unref(runtime); - spin_unlock_irqrestore(&runtime->lock, flags); + spin_unlock_irqrestore(&substream->lock, flags); if (count1) snd_rawmidi_output_trigger(substream, 1); return result; @@ -1526,31 +1522,31 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, return -EIO; result = 0; while (count > 0) { - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); while (!snd_rawmidi_ready_append(substream, count)) { wait_queue_entry_t wait; if (file->f_flags & O_NONBLOCK) { - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return result > 0 ? result : -EAGAIN; } init_waitqueue_entry(&wait, current); add_wait_queue(&runtime->sleep, &wait); set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); timeout = schedule_timeout(30 * HZ); remove_wait_queue(&runtime->sleep, &wait); if (rfile->rmidi->card->shutdown) return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); if (!runtime->avail && !timeout) { - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); return result > 0 ? result : -EIO; } } - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count); if (count1 < 0) return result > 0 ? result : count1; @@ -1561,7 +1557,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, count -= count1; } if (file->f_flags & O_DSYNC) { - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); while (runtime->avail != runtime->buffer_size) { wait_queue_entry_t wait; unsigned int last_avail = runtime->avail; @@ -1569,16 +1565,16 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, init_waitqueue_entry(&wait, current); add_wait_queue(&runtime->sleep, &wait); set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); timeout = schedule_timeout(30 * HZ); remove_wait_queue(&runtime->sleep, &wait); if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; if (runtime->avail == last_avail && !timeout) return result > 0 ? result : -EIO; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); } - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); } return result; } @@ -1649,10 +1645,10 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, " Owner PID : %d\n", pid_vnr(substream->pid)); runtime = substream->runtime; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); buffer_size = runtime->buffer_size; avail = runtime->avail; - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); snd_iprintf(buffer, " Mode : %s\n" " Buffer size : %lu\n" @@ -1676,11 +1672,11 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, " Owner PID : %d\n", pid_vnr(substream->pid)); runtime = substream->runtime; - spin_lock_irq(&runtime->lock); + spin_lock_irq(&substream->lock); buffer_size = runtime->buffer_size; avail = runtime->avail; xruns = runtime->xruns; - spin_unlock_irq(&runtime->lock); + spin_unlock_irq(&substream->lock); snd_iprintf(buffer, " Buffer size : %lu\n" " Avail : %lu\n" @@ -1732,6 +1728,7 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, substream->number = idx; substream->rmidi = rmidi; substream->pstr = stream; + spin_lock_init(&substream->lock); list_add_tail(&substream->list, &stream->substreams); stream->substream_count++; } -- GitLab From 94b98194b62e3fe3f27129d8e4b1f3fd7c5e972b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Jun 2022 16:40:49 +0200 Subject: [PATCH 580/942] ALSA: rawmidi: Take open_mutex around parameter changes The input/output parameter changes are pretty intrusive, possibly involving with the buffer resizing operation. Hence those should be performed exclusively; otherwise some ugly race could happen. This patch puts the existing open_mutex for snd_rawmidi_input_params() and *_output_params() for protecting the concurrent calls. Since those are exported, it's also meant for hardening from the external calls, too. Link: https://lore.kernel.org/r/20220617144051.18985-4-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/rawmidi.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 0a00f37d8c429..7fd6b369d46fd 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -712,11 +712,19 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream, int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, struct snd_rawmidi_params *params) { - if (substream->append && substream->use_count > 1) - return -EBUSY; + int err; + snd_rawmidi_drain_output(substream); - substream->active_sensing = !params->no_active_sensing; - return resize_runtime_buffer(substream, params, false); + mutex_lock(&substream->rmidi->open_mutex); + if (substream->append && substream->use_count > 1) + err = -EBUSY; + else + err = resize_runtime_buffer(substream, params, false); + + if (!err) + substream->active_sensing = !params->no_active_sensing; + mutex_unlock(&substream->rmidi->open_mutex); + return err; } EXPORT_SYMBOL(snd_rawmidi_output_params); @@ -727,19 +735,22 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream, unsigned int clock_type = params->mode & SNDRV_RAWMIDI_MODE_CLOCK_MASK; int err; + snd_rawmidi_drain_input(substream); + mutex_lock(&substream->rmidi->open_mutex); if (framing == SNDRV_RAWMIDI_MODE_FRAMING_NONE && clock_type != SNDRV_RAWMIDI_MODE_CLOCK_NONE) - return -EINVAL; + err = -EINVAL; else if (clock_type > SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW) - return -EINVAL; - if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) - return -EINVAL; - snd_rawmidi_drain_input(substream); - err = resize_runtime_buffer(substream, params, true); - if (err < 0) - return err; + err = -EINVAL; + else if (framing > SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) + err = -EINVAL; + else + err = resize_runtime_buffer(substream, params, true); - substream->framing = framing; - substream->clock_type = clock_type; + if (!err) { + substream->framing = framing; + substream->clock_type = clock_type; + } + mutex_unlock(&substream->rmidi->open_mutex); return 0; } EXPORT_SYMBOL(snd_rawmidi_input_params); -- GitLab From 463a20fd3481de33c2746f050b4e3f2e6db8017f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Jun 2022 16:40:50 +0200 Subject: [PATCH 581/942] ALSA: rawmidi: Check stream state at exported functions The rawmidi interface provides some exported functions to be called from outside, and currently there is no state check for those calls whether the stream is properly opened and running. Although such an invalid call shouldn't happen, but who knows. This patch adds the proper rawmidi stream state checks with spinlocks for avoiding unexpected accesses when such exported functions are called in an invalid state. After this patch, with the substream->opened and substream->runtime are always tied and guaranteed to be set under substream->lock. Link: https://lore.kernel.org/r/20220617144051.18985-5-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/rawmidi.c | 56 ++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 7fd6b369d46fd..889fa4747dad4 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -207,7 +207,8 @@ static void reset_runtime_ptrs(struct snd_rawmidi_substream *substream, unsigned long flags; spin_lock_irqsave(&substream->lock, flags); - __reset_runtime_ptrs(substream->runtime, is_input); + if (substream->opened && substream->runtime) + __reset_runtime_ptrs(substream->runtime, is_input); spin_unlock_irqrestore(&substream->lock, flags); } @@ -309,12 +310,14 @@ static int open_substream(struct snd_rawmidi *rmidi, snd_rawmidi_runtime_free(substream); return err; } + spin_lock_irq(&substream->lock); substream->opened = 1; substream->active_sensing = 0; if (mode & SNDRV_RAWMIDI_LFLG_APPEND) substream->append = 1; substream->pid = get_pid(task_pid(current)); rmidi->streams[substream->stream].substream_opened++; + spin_unlock_irq(&substream->lock); } substream->use_count++; return 0; @@ -520,12 +523,14 @@ static void close_substream(struct snd_rawmidi *rmidi, snd_rawmidi_output_trigger(substream, 0); } } + spin_lock_irq(&substream->lock); + substream->opened = 0; + substream->append = 0; + spin_unlock_irq(&substream->lock); substream->ops->close(substream); if (substream->runtime->private_free) substream->runtime->private_free(substream); snd_rawmidi_runtime_free(substream); - substream->opened = 0; - substream->append = 0; put_pid(substream->pid); substream->pid = NULL; rmidi->streams[substream->stream].substream_opened--; @@ -1074,17 +1079,21 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, unsigned long flags; struct timespec64 ts64 = get_framing_tstamp(substream); int result = 0, count1; - struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_rawmidi_runtime *runtime; - if (!substream->opened) - return -EBADFD; - if (runtime->buffer == NULL) { + spin_lock_irqsave(&substream->lock, flags); + if (!substream->opened) { + result = -EBADFD; + goto unlock; + } + runtime = substream->runtime; + if (!runtime || !runtime->buffer) { rmidi_dbg(substream->rmidi, "snd_rawmidi_receive: input is not active!!!\n"); - return -EINVAL; + result = -EINVAL; + goto unlock; } - spin_lock_irqsave(&substream->lock, flags); if (substream->framing == SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP) { result = receive_with_tstamp_framing(substream, buffer, count, &ts64); } else if (count == 1) { /* special case, faster code */ @@ -1131,6 +1140,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, else if (__snd_rawmidi_ready(runtime)) wake_up(&runtime->sleep); } + unlock: spin_unlock_irqrestore(&substream->lock, flags); return result; } @@ -1252,17 +1262,19 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun */ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream) { - struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_rawmidi_runtime *runtime; int result; unsigned long flags; - if (runtime->buffer == NULL) { + spin_lock_irqsave(&substream->lock, flags); + runtime = substream->runtime; + if (!substream->opened || !runtime || !runtime->buffer) { rmidi_dbg(substream->rmidi, "snd_rawmidi_transmit_empty: output is not active!!!\n"); - return 1; + result = 1; + } else { + result = runtime->avail >= runtime->buffer_size; } - spin_lock_irqsave(&substream->lock, flags); - result = runtime->avail >= runtime->buffer_size; spin_unlock_irqrestore(&substream->lock, flags); return result; } @@ -1336,7 +1348,10 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream, unsigned long flags; spin_lock_irqsave(&substream->lock, flags); - result = __snd_rawmidi_transmit_peek(substream, buffer, count); + if (!substream->opened || !substream->runtime) + result = -EBADFD; + else + result = __snd_rawmidi_transmit_peek(substream, buffer, count); spin_unlock_irqrestore(&substream->lock, flags); return result; } @@ -1388,7 +1403,10 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) unsigned long flags; spin_lock_irqsave(&substream->lock, flags); - result = __snd_rawmidi_transmit_ack(substream, count); + if (!substream->opened || !substream->runtime) + result = -EBADFD; + else + result = __snd_rawmidi_transmit_ack(substream, count); spin_unlock_irqrestore(&substream->lock, flags); return result; } @@ -1433,12 +1451,14 @@ EXPORT_SYMBOL(snd_rawmidi_transmit); */ int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream) { - struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_rawmidi_runtime *runtime; unsigned long flags; int count = 0; spin_lock_irqsave(&substream->lock, flags); - if (runtime->avail < runtime->buffer_size) { + runtime = substream->runtime; + if (substream->opened && runtime && + runtime->avail < runtime->buffer_size) { count = runtime->buffer_size - runtime->avail; __snd_rawmidi_transmit_ack(substream, count); } -- GitLab From 3809db6430bf6a725d234e6eec9a6f6be6b8c1ea Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 17 Jun 2022 16:40:51 +0200 Subject: [PATCH 582/942] ALSA: rawmidi: Take buffer refcount while draining output Although snd_rawmidi_drain_output() may take some long time, it has no protection and intrusive operations like the buffer resize may happen meanwhile. For making the operation a bit more robust, this patch takes the buffer refcount for blocking the buffer resize. Also, as this function is exported, in theory, it might be called asynchronously from the stream open/close state. For avoiding the missing refcount, now the close call checks the buffer refcount, too. Link: https://lore.kernel.org/r/20220617144051.18985-6-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/rawmidi.c | 45 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 889fa4747dad4..6963d5a487b32 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -140,6 +140,23 @@ static inline void snd_rawmidi_buffer_unref(struct snd_rawmidi_runtime *runtime) runtime->buffer_ref--; } +static void snd_rawmidi_buffer_ref_sync(struct snd_rawmidi_substream *substream) +{ + int loop = HZ; + + spin_lock_irq(&substream->lock); + while (substream->runtime->buffer_ref) { + spin_unlock_irq(&substream->lock); + if (!--loop) { + rmidi_err(substream->rmidi, "Buffer ref sync timeout\n"); + return; + } + schedule_timeout_uninterruptible(1); + spin_lock_irq(&substream->lock); + } + spin_unlock_irq(&substream->lock); +} + static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) { struct snd_rawmidi_runtime *runtime; @@ -222,15 +239,27 @@ EXPORT_SYMBOL(snd_rawmidi_drop_output); int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream) { - int err; + int err = 0; long timeout; - struct snd_rawmidi_runtime *runtime = substream->runtime; + struct snd_rawmidi_runtime *runtime; + + spin_lock_irq(&substream->lock); + runtime = substream->runtime; + if (!substream->opened || !runtime || !runtime->buffer) { + err = -EINVAL; + } else { + snd_rawmidi_buffer_ref(runtime); + runtime->drain = 1; + } + spin_unlock_irq(&substream->lock); + if (err < 0) + return err; - err = 0; - runtime->drain = 1; timeout = wait_event_interruptible_timeout(runtime->sleep, (runtime->avail >= runtime->buffer_size), 10*HZ); + + spin_lock_irq(&substream->lock); if (signal_pending(current)) err = -ERESTARTSYS; if (runtime->avail < runtime->buffer_size && !timeout) { @@ -240,6 +269,8 @@ int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream) err = -EIO; } runtime->drain = 0; + spin_unlock_irq(&substream->lock); + if (err != -ERESTARTSYS) { /* we need wait a while to make sure that Tx FIFOs are empty */ if (substream->ops->drain) @@ -248,6 +279,11 @@ int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream) msleep(50); snd_rawmidi_drop_output(substream); } + + spin_lock_irq(&substream->lock); + snd_rawmidi_buffer_unref(runtime); + spin_unlock_irq(&substream->lock); + return err; } EXPORT_SYMBOL(snd_rawmidi_drain_output); @@ -522,6 +558,7 @@ static void close_substream(struct snd_rawmidi *rmidi, if (snd_rawmidi_drain_output(substream) == -ERESTARTSYS) snd_rawmidi_output_trigger(substream, 0); } + snd_rawmidi_buffer_ref_sync(substream); } spin_lock_irq(&substream->lock); substream->opened = 0; -- GitLab From 5ac01e023a1b0492e159ad2f6734e0a350c1b6b6 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:33 +0200 Subject: [PATCH 583/942] regmap: Re-introduce bulk read support check in regmap_bulk_read() Support for drivers to define bulk read/write callbacks in regmap_config was introduced by the commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config"), but this commit wrongly dropped a check in regmap_bulk_read() to determine whether bulk reads can be done or not. Before that commit, it was checked if map->bus was set. Now has to check if a map->read callback has been set. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-2-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2221d98638317..e5bb70374ffc4 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -3017,7 +3017,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, if (val_count == 0) return -EINVAL; - if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { + if (map->read && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { ret = regmap_raw_read(map, reg, val, val_bytes * val_count); if (ret != 0) return ret; -- GitLab From f6e5c3850d1174bf3ca53457d64e6665f48c9041 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:34 +0200 Subject: [PATCH 584/942] regmap: Make regmap_noinc_read() return -ENOTSUPP if map->read isn't set Before adding support to define bulk read/write callbacks in regmap_config by the commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config"), the regmap_noinc_read() function returned an errno early a map->bus->read callback wasn't set. But that commit dropped the check and now a call to _regmap_raw_read() is attempted even when bulk read operations are not supported. That function checks for map->read anyways but there's no point to continue if the read can't succeed. Also is a fragile assumption to make so is better to make it fail earlier. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-3-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e5bb70374ffc4..f37f80a521150 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2904,6 +2904,9 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, size_t read_len; int ret; + if (!map->read) + return -ENOTSUPP; + if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) -- GitLab From 1db43c8ad90ce07311a3ef9af7ace758d79224f9 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:35 +0200 Subject: [PATCH 585/942] regmap: Wire up regmap_config provided bulk write in missed functions There are some functions that were missed by commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") when support to define bulk read/write callbacks in regmap_config was introduced. The regmap_bulk_write() and regmap_noinc_write() functions weren't changed to use the added map->write instead of the map->bus->write handler. Also, the regmap_can_raw_write() was not modified to take map->write into account. So will only return true if a bus with a .write callback is set. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-4-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index f37f80a521150..c3517ccc31591 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1880,8 +1880,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, */ bool regmap_can_raw_write(struct regmap *map) { - return map->bus && map->bus->write && map->format.format_val && - map->format.format_reg; + return map->write && map->format.format_val && map->format.format_reg; } EXPORT_SYMBOL_GPL(regmap_can_raw_write); @@ -2155,10 +2154,9 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, size_t write_len; int ret; - if (!map->bus) - return -EINVAL; - if (!map->bus->write) + if (!map->write) return -ENOTSUPP; + if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) @@ -2278,7 +2276,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, * Some devices don't support bulk write, for them we have a series of * single write operations. */ - if (!map->bus || !map->format.parse_inplace) { + if (!map->write || !map->format.parse_inplace) { map->lock(map->lock_arg); for (i = 0; i < val_count; i++) { unsigned int ival; -- GitLab From 44f362c2cc6dd0c5e3cb499c4fb4ed45b63a6196 Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Wed, 15 Jun 2022 04:56:43 +0000 Subject: [PATCH 586/942] ASoC: rockchip: i2s: switch BCLK to GPIO We discoverd that the state of BCLK on, LRCLK off and SD_MODE on may cause the speaker melting issue. Removing LRCLK while BCLK is present can cause unexpected output behavior including a large DC output voltage as described in the Max98357a datasheet. In order to: 1. prevent BCLK from turning on by other component. 2. keep BCLK and LRCLK being present at the same time This patch switches BCLK to GPIO func before LRCLK output, and configures BCLK func back during LRCLK is output. Without this fix, BCLK is turned on 11 ms earlier than LRCK by the da7219. With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by the rockchip codec. Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20220615045643.3137287-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 160 ++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 31 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 4ce5d25793875..99a128a666fbb 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +55,40 @@ struct rk_i2s_dev { const struct rk_i2s_pins *pins; unsigned int bclk_ratio; spinlock_t lock; /* tx/rx lock */ + struct pinctrl *pinctrl; + struct pinctrl_state *bclk_on; + struct pinctrl_state *bclk_off; }; +static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s) +{ + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on)) + ret = pinctrl_select_state(i2s->pinctrl, + i2s->bclk_on); + + if (ret) + dev_err(i2s->dev, "bclk enable failed %d\n", ret); + + return ret; +} + +static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s) +{ + + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off)) + ret = pinctrl_select_state(i2s->pinctrl, + i2s->bclk_off); + + if (ret) + dev_err(i2s->dev, "bclk disable failed %d\n", ret); + + return ret; +} + static int i2s_runtime_suspend(struct device *dev) { struct rk_i2s_dev *i2s = dev_get_drvdata(dev); @@ -92,38 +125,49 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) return snd_soc_dai_get_drvdata(dai); } -static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); + if (ret < 0) + goto end; - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | I2S_XFER_RXS_START, - I2S_XFER_TXS_START | I2S_XFER_RXS_START); + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->tx_start = true; } else { i2s->tx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->rx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | - I2S_XFER_RXS_START, - I2S_XFER_TXS_STOP | - I2S_XFER_RXS_STOP); + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | + I2S_XFER_RXS_START, + I2S_XFER_TXS_STOP | + I2S_XFER_RXS_STOP); + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, - I2S_CLR_TXC | I2S_CLR_RXC, - I2S_CLR_TXC | I2S_CLR_RXC); + ret = regmap_update_bits(i2s->regmap, I2S_CLR, + I2S_CLR_TXC | I2S_CLR_RXC, + I2S_CLR_TXC | I2S_CLR_RXC); + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); @@ -138,44 +182,57 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } -static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); + if (ret < 0) + goto end; - regmap_update_bits(i2s->regmap, I2S_XFER, + ret = regmap_update_bits(i2s->regmap, I2S_XFER, I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->rx_start = true; } else { i2s->rx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->tx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, + ret = regmap_update_bits(i2s->regmap, I2S_XFER, I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP); - + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, + ret = regmap_update_bits(i2s->regmap, I2S_CLR, I2S_CLR_TXC | I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC); - + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); - /* Should wait for clear operation to finish */ while (val) { regmap_read(i2s->regmap, I2S_CLR, &val); @@ -187,7 +244,12 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, @@ -425,17 +487,26 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 1); + ret = rockchip_snd_rxctrl(i2s, 1); else - rockchip_snd_txctrl(i2s, 1); + ret = rockchip_snd_txctrl(i2s, 1); + /* Do not turn on bclk if lrclk open fails. */ + if (ret < 0) + return ret; + i2s_pinctrl_select_bclk_on(i2s); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 0); - else - rockchip_snd_txctrl(i2s, 0); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (!i2s->tx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_rxctrl(i2s, 0); + } else { + if (!i2s->rx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_txctrl(i2s, 0); + } break; default: ret = -EINVAL; @@ -736,6 +807,33 @@ static int rockchip_i2s_probe(struct platform_device *pdev) } i2s->bclk_ratio = 64; + i2s->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(i2s->pinctrl)) + dev_err(&pdev->dev, "failed to find i2s pinctrl\n"); + + i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, + "bclk_on"); + if (IS_ERR_OR_NULL(i2s->bclk_on)) + dev_err(&pdev->dev, "failed to find i2s default state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk state\n"); + + i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, + "bclk_off"); + if (IS_ERR_OR_NULL(i2s->bclk_off)) + dev_err(&pdev->dev, "failed to find i2s gpio state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk_off state\n"); + + i2s_pinctrl_select_bclk_off(i2s); + + i2s->playback_dma_data.addr = res->start + I2S_TXDR; + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->playback_dma_data.maxburst = 4; + + i2s->capture_dma_data.addr = res->start + I2S_RXDR; + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->capture_dma_data.maxburst = 4; dev_set_drvdata(&pdev->dev, i2s); -- GitLab From ad9894ac6cc1c1f7c36451d508d69f6ba677834a Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 17 Jun 2022 14:02:30 -0700 Subject: [PATCH 587/942] MAINTAINERS: update ASoC Qualcomm maintainer email-id Update Banajit's email address from codeaurora.org to quicinc.com, as codeaurora.org is not in use anymore. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220617210230.7685-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 440f3d7c93b9e..171fa31606960 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16247,7 +16247,7 @@ F: drivers/crypto/qat/ QCOM AUDIO (ASoC) DRIVERS M: Srinivas Kandagatla -M: Banajit Goswami +M: Banajit Goswami L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported F: sound/soc/codecs/lpass-va-macro.c -- GitLab From 289a3ec0b5b9a2de6fc75633aa81f017792ecc99 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 17 Jun 2022 14:01:33 +0200 Subject: [PATCH 588/942] ASoC: fsl_asrc_dma: Use dmaengine_terminate_async() dmaengine_terminate_all() is deprecated and should no longer be used. Use dmaengine_terminate_async() instead. This involves no functional change since both functions do the same. After dmaengine_terminate_async() dmaengine_synchronize() must be called to make sure the channel has really stopped before the underlying memory is freed. This is done implicitly by dma_release_channel() called from the .hw_free hook. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20220617120133.4011846-1-s.hauer@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_asrc_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index aaf7993935b74..33eabb96340eb 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -114,8 +114,8 @@ static int fsl_asrc_dma_trigger(struct snd_soc_component *component, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - dmaengine_terminate_all(pair->dma_chan[OUT]); - dmaengine_terminate_all(pair->dma_chan[IN]); + dmaengine_terminate_async(pair->dma_chan[OUT]); + dmaengine_terminate_async(pair->dma_chan[IN]); break; default: return -EINVAL; -- GitLab From 81d74ddae83fbd85c9006835f36c362114127a7a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:38 +0100 Subject: [PATCH 589/942] ASoC: wm_adsp: Fix event for preloader The preloader controls on ADSP should return a value of 1 if the preloader value was changed, update to correct this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 6d7fd88243aa8..a7784ac15dde6 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -997,7 +997,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_sync(dapm); } - return 0; + return 1; } EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); -- GitLab From 630cc5983740d784a1a6458f9dc2112c43fe0931 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:39 +0100 Subject: [PATCH 590/942] ASoC: wm5110: Fix DRE control The DRE controls on wm5110 should return a value of 1 if the DRE state is actually changed, update to fix this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4973ba1ed7791..4ab7a672f8de8 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -413,6 +413,7 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, unsigned int rnew = (!!ucontrol->value.integer.value[1]) << mc->rshift; unsigned int lold, rold; unsigned int lena, rena; + bool change = false; int ret; snd_soc_dapm_mutex_lock(dapm); @@ -440,8 +441,8 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, goto err; } - ret = regmap_update_bits(arizona->regmap, ARIZONA_DRE_ENABLE, - mask, lnew | rnew); + ret = regmap_update_bits_check(arizona->regmap, ARIZONA_DRE_ENABLE, + mask, lnew | rnew, &change); if (ret) { dev_err(arizona->dev, "Failed to set DRE: %d\n", ret); goto err; @@ -454,6 +455,9 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, if (!rnew && rold) wm5110_clear_pga_volume(arizona, mc->rshift); + if (change) + ret = 1; + err: snd_soc_dapm_mutex_unlock(dapm); -- GitLab From 87912e97a1678d62877aab353ecfd201bc92b372 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:40 +0100 Subject: [PATCH 591/942] ASoC: cs35l41: Correct some control names Various boolean controls on cs35l41 are missing the required "Switch" in the name, add these. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 3e68a07a3c8e0..71ab2a5d1c559 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -333,7 +333,7 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), - SOC_SINGLE("Aux Noise Gate CH1 Enable", + SOC_SINGLE("Aux Noise Gate CH1 Switch", CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), @@ -341,15 +341,15 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), - SOC_SINGLE("Aux Noise Gate CH2 Enable", + SOC_SINGLE("Aux Noise Gate CH2 Switch", CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), SOC_SINGLE("Aux Noise Gate CH2 Threshold", CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), - SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), - SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), - SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, + SOC_SINGLE("SCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("LRCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("Invert Class D Switch", CS35L41_AMP_DIG_VOL_CTRL, CS35L41_AMP_INV_PCM_SHIFT, 1, 0), - SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, + SOC_SINGLE("Amp Gain ZC Switch", CS35L41_AMP_GAIN_CTRL, CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), WM_ADSP_FW_CONTROL("DSP1", 0), -- GitLab From f69a10f84cb5ff0b1c6aef0e19e866bbe53ec7ea Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Tue, 21 Jun 2022 17:07:19 +0800 Subject: [PATCH 592/942] ASoC: rt711-sdca: fix kernel NULL pointer dereference when IO error The initial settings will be written before the codec probe function. But, the rt711->component doesn't be assigned yet. If IO error happened during initial settings operations, it will cause the kernel panic. This patch changed component->dev to slave->dev to fix this issue. Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20220621090719.30558-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index dfe3c9299ebde..5ad53bbc85284 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -34,7 +34,7 @@ static int rt711_sdca_index_write(struct rt711_sdca_priv *rt711, ret = regmap_write(regmap, addr, value); if (ret < 0) - dev_err(rt711->component->dev, + dev_err(&rt711->slave->dev, "Failed to set private value: %06x <= %04x ret=%d\n", addr, value, ret); @@ -50,7 +50,7 @@ static int rt711_sdca_index_read(struct rt711_sdca_priv *rt711, ret = regmap_read(regmap, addr, value); if (ret < 0) - dev_err(rt711->component->dev, + dev_err(&rt711->slave->dev, "Failed to get private value: %06x => %04x ret=%d\n", addr, *value, ret); -- GitLab From 6b183919f7051294dc5fc331bb608d5d7f29f5da Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:41 +0100 Subject: [PATCH 593/942] ASoC: core: Add new SOC_DOUBLE_SX_TLV macro Currently macros only exist for SX style (implicit sign bit 2's compliment) volume controls where the volumes for left and right are in separate registers. Some future Cirrus devices will have both volumes in the same register, as such add a new macro to support this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 8909cc7d311ef..76ee3c2b8b56c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -136,6 +136,18 @@ .put = snd_soc_put_volsw, \ .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ max, invert, 0) } +#define SOC_DOUBLE_SX_TLV(xname, xreg, shift_left, shift_right, xmin, xmax, tlv_array) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_READWRITE, \ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw_sx, \ + .get = snd_soc_get_volsw_sx, \ + .put = snd_soc_put_volsw_sx, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .rreg = xreg, \ + .shift = shift_left, .rshift = shift_right, \ + .max = xmax, .min = xmin} } #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ -- GitLab From 8c77cf26a82e751ce827614664faf40243058d5d Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Sun, 19 Jun 2022 09:53:22 +0000 Subject: [PATCH 594/942] ASoC: rockchip: i2s: switch BCLK to GPIO We discoverd that the state of BCLK on, LRCLK off and SD_MODE on may cause the speaker melting issue. Removing LRCLK while BCLK is present can cause unexpected output behavior including a large DC output voltage as described in the Max98357a datasheet. In order to: 1. prevent BCLK from turning on by other component. 2. keep BCLK and LRCLK being present at the same time This patch switches BCLK to GPIO func before LRCLK output, and configures BCLK func back during LRCLK is output. Without this fix, BCLK is turned on 11 ms earlier than LRCK by the da7219. With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by the rockchip codec. Signed-off-by: Judy Hsiao Reviewed-by: Brian Norris Link: https://lore.kernel.org/r/20220619095324.492678-2-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 169 ++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 46 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 47a3971a9ce14..aa7d9984022a3 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -54,8 +54,38 @@ struct rk_i2s_dev { const struct rk_i2s_pins *pins; unsigned int bclk_ratio; spinlock_t lock; /* tx/rx lock */ + struct pinctrl *pinctrl; + struct pinctrl_state *bclk_on; + struct pinctrl_state *bclk_off; }; +static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s) +{ + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on)) + ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_on); + + if (ret) + dev_err(i2s->dev, "bclk enable failed %d\n", ret); + + return ret; +} + +static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s) +{ + + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off)) + ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_off); + + if (ret) + dev_err(i2s->dev, "bclk disable failed %d\n", ret); + + return ret; +} + static int i2s_runtime_suspend(struct device *dev) { struct rk_i2s_dev *i2s = dev_get_drvdata(dev); @@ -92,39 +122,46 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) return snd_soc_dai_get_drvdata(dai); } -static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); - - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | I2S_XFER_RXS_START, - I2S_XFER_TXS_START | I2S_XFER_RXS_START); - + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, + I2S_DMACR_TDE_ENABLE); + if (ret < 0) + goto end; + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->tx_start = true; } else { i2s->tx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, + I2S_DMACR_TDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->rx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | - I2S_XFER_RXS_START, - I2S_XFER_TXS_STOP | - I2S_XFER_RXS_STOP); - + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP); + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, - I2S_CLR_TXC | I2S_CLR_RXC, - I2S_CLR_TXC | I2S_CLR_RXC); - + ret = regmap_update_bits(i2s->regmap, I2S_CLR, + I2S_CLR_TXC | I2S_CLR_RXC, + I2S_CLR_TXC | I2S_CLR_RXC); + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); /* Should wait for clear operation to finish */ @@ -138,42 +175,55 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } -static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); - - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | I2S_XFER_RXS_START, - I2S_XFER_TXS_START | I2S_XFER_RXS_START); - + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_RDE_ENABLE, + I2S_DMACR_RDE_ENABLE); + if (ret < 0) + goto end; + + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->rx_start = true; } else { i2s->rx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_RDE_ENABLE, + I2S_DMACR_RDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->tx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | - I2S_XFER_RXS_START, - I2S_XFER_TXS_STOP | - I2S_XFER_RXS_STOP); - + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP); + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, - I2S_CLR_TXC | I2S_CLR_RXC, - I2S_CLR_TXC | I2S_CLR_RXC); - + ret = regmap_update_bits(i2s->regmap, I2S_CLR, + I2S_CLR_TXC | I2S_CLR_RXC, + I2S_CLR_TXC | I2S_CLR_RXC); + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); /* Should wait for clear operation to finish */ @@ -187,7 +237,12 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, @@ -425,17 +480,25 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 1); + ret = rockchip_snd_rxctrl(i2s, 1); else - rockchip_snd_txctrl(i2s, 1); + ret = rockchip_snd_txctrl(i2s, 1); + if (ret < 0) + return ret; + i2s_pinctrl_select_bclk_on(i2s); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 0); - else - rockchip_snd_txctrl(i2s, 0); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (!i2s->tx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_rxctrl(i2s, 0); + } else { + if (!i2s->rx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_txctrl(i2s, 0); + } break; default: ret = -EINVAL; @@ -736,6 +799,20 @@ static int rockchip_i2s_probe(struct platform_device *pdev) } i2s->bclk_ratio = 64; + i2s->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(i2s->pinctrl)) + dev_err(&pdev->dev, "failed to find i2s pinctrl\n"); + + i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, "bclk_on"); + if (!IS_ERR_OR_NULL(i2s->bclk_on)) { + i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off"); + if (IS_ERR_OR_NULL(i2s->bclk_off)) { + dev_err(&pdev->dev, "failed to find i2s bclk_off\n"); + goto err_clk; + } + } + + i2s_pinctrl_select_bclk_off(i2s); dev_set_drvdata(&pdev->dev, i2s); -- GitLab From d92c3d13e7650a324edcfb4ed934baaecd287bbf Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Sun, 19 Jun 2022 09:53:24 +0000 Subject: [PATCH 595/942] ASoC: dt-bindings: rockchip: Document pinctrl-names for i2s This patch documents pinctrl-names for i2s. Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20220619095324.492678-4-judyhsiao@chromium.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rockchip-i2s.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml index 5ea16b8ef93f1..7e36e389e9764 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml @@ -61,6 +61,13 @@ properties: - const: tx - const: rx + pinctrl-names: + oneOf: + - const: default + - items: + - const: bclk_on + - const: bclk_off + power-domains: maxItems: 1 -- GitLab From 009b21f392759ca7be91bc4be9d9534f6cee2878 Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Wed, 22 Jun 2022 14:22:42 +0800 Subject: [PATCH 596/942] dt-bindings: dsp: mediatek: Use meaningful names for mbox Rename mbox according to actions instead of 'mbox0' and 'mbox1'. The 8195 dsp node, which uses this binding, has not yet been added to the 8195 devicetree. Signed-off-by: Tinghan Shen Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220622062245.21021-2-tinghan.shen@mediatek.com Signed-off-by: Mark Brown --- .../devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml index b7e68b0dfa13e..ca8d8661f8726 100644 --- a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml +++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml @@ -50,13 +50,13 @@ properties: mboxes: items: - - description: ipc reply between host and audio DSP. - - description: ipc request between host and audio DSP. + - description: mailbox for receiving audio DSP requests. + - description: mailbox for transmitting requests to audio DSP. mbox-names: items: - - const: mbox0 - - const: mbox1 + - const: rx + - const: tx memory-region: items: @@ -100,6 +100,6 @@ examples: memory-region = <&adsp_dma_mem_reserved>, <&adsp_mem_reserved>; power-domains = <&spm 6>; //MT8195_POWER_DOMAIN_ADSP - mbox-names = "mbox0", "mbox1"; + mbox-names = "rx", "tx"; mboxes = <&adsp_mailbox0>, <&adsp_mailbox1>; }; -- GitLab From 74bbdd632637628fef8f651bddc5d17aeb7eb46a Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Wed, 22 Jun 2022 14:22:43 +0800 Subject: [PATCH 597/942] firmware: mediatek: Use meaningful names for mbox Rename mbox according to actions instead of 'mbox0' and 'mbox1' Signed-off-by: Tinghan Shen Link: https://lore.kernel.org/r/20220622062245.21021-3-tinghan.shen@mediatek.com Signed-off-by: Mark Brown --- drivers/firmware/mtk-adsp-ipc.c | 36 +++++++++++---------------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/mtk-adsp-ipc.c b/drivers/firmware/mtk-adsp-ipc.c index cb255a99170c9..3c071f8144555 100644 --- a/drivers/firmware/mtk-adsp-ipc.c +++ b/drivers/firmware/mtk-adsp-ipc.c @@ -12,6 +12,8 @@ #include #include +static const char * const adsp_mbox_ch_names[MTK_ADSP_MBOX_NUM] = { "rx", "tx" }; + /* * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP * @@ -72,7 +74,6 @@ static int mtk_adsp_ipc_probe(struct platform_device *pdev) struct mtk_adsp_ipc *adsp_ipc; struct mtk_adsp_chan *adsp_chan; struct mbox_client *cl; - char *chan_name; int ret; int i, j; @@ -83,12 +84,6 @@ static int mtk_adsp_ipc_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) { - chan_name = kasprintf(GFP_KERNEL, "mbox%d", i); - if (!chan_name) { - ret = -ENOMEM; - goto out; - } - adsp_chan = &adsp_ipc->chans[i]; cl = &adsp_chan->cl; cl->dev = dev->parent; @@ -99,17 +94,20 @@ static int mtk_adsp_ipc_probe(struct platform_device *pdev) adsp_chan->ipc = adsp_ipc; adsp_chan->idx = i; - adsp_chan->ch = mbox_request_channel_byname(cl, chan_name); + adsp_chan->ch = mbox_request_channel_byname(cl, adsp_mbox_ch_names[i]); if (IS_ERR(adsp_chan->ch)) { ret = PTR_ERR(adsp_chan->ch); if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to request mbox chan %d ret %d\n", - i, ret); - goto out_free; - } + dev_err(dev, "Failed to request mbox chan %s ret %d\n", + adsp_mbox_ch_names[i], ret); + + for (j = 0; j < i; j++) { + adsp_chan = &adsp_ipc->chans[j]; + mbox_free_channel(adsp_chan->ch); + } - dev_dbg(dev, "request mbox chan %s\n", chan_name); - kfree(chan_name); + return ret; + } } adsp_ipc->dev = dev; @@ -117,16 +115,6 @@ static int mtk_adsp_ipc_probe(struct platform_device *pdev) dev_dbg(dev, "MTK ADSP IPC initialized\n"); return 0; - -out_free: - kfree(chan_name); -out: - for (j = 0; j < i; j++) { - adsp_chan = &adsp_ipc->chans[j]; - mbox_free_channel(adsp_chan->ch); - } - - return ret; } static int mtk_adsp_ipc_remove(struct platform_device *pdev) -- GitLab From 99370c4ea3d0cee8445f6a1104f25667e3fd47ba Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Wed, 22 Jun 2022 14:22:44 +0800 Subject: [PATCH 598/942] dt-bindings: dsp: mediatek: Add mt8186 dsp document This patch adds mt8186 dsp document. The dsp is used for Sound Open Firmware driver node. It includes registers, clocks, memory regions, and mailbox for dsp. Signed-off-by: Tinghan Shen Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220622062245.21021-4-tinghan.shen@mediatek.com Signed-off-by: Mark Brown --- .../bindings/dsp/mediatek,mt8186-dsp.yaml | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/dsp/mediatek,mt8186-dsp.yaml diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8186-dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8186-dsp.yaml new file mode 100644 index 0000000000000..3e63f79890b43 --- /dev/null +++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8186-dsp.yaml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dsp/mediatek,mt8186-dsp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek mt8186 DSP core + +maintainers: + - Tinghan Shen + +description: | + MediaTek mt8186 SoC contains a DSP core used for + advanced pre- and post- audio processing. + +properties: + compatible: + const: mediatek,mt8186-dsp + + reg: + items: + - description: Address and size of the DSP config registers + - description: Address and size of the DSP SRAM + - description: Address and size of the DSP secure registers + - description: Address and size of the DSP bus registers + + reg-names: + items: + - const: cfg + - const: sram + - const: sec + - const: bus + + clocks: + items: + - description: mux for audio dsp clock + - description: mux for audio dsp local bus + + clock-names: + items: + - const: audiodsp + - const: adsp_bus + + power-domains: + maxItems: 1 + + mboxes: + items: + - description: mailbox for receiving audio DSP requests. + - description: mailbox for transmitting requests to audio DSP. + + mbox-names: + items: + - const: rx + - const: tx + + memory-region: + items: + - description: dma buffer between host and DSP. + - description: DSP system memory. + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - power-domains + - mbox-names + - mboxes + +additionalProperties: false + +examples: + - | + #include + dsp@10680000 { + compatible = "mediatek,mt8186-dsp"; + reg = <0x10680000 0x2000>, + <0x10800000 0x100000>, + <0x1068b000 0x100>, + <0x1068f000 0x1000>; + reg-names = "cfg", "sram", "sec", "bus"; + clocks = <&topckgen CLK_TOP_AUDIODSP>, + <&topckgen CLK_TOP_ADSP_BUS>; + clock-names = "audiodsp", + "adsp_bus"; + power-domains = <&spm 6>; + mbox-names = "rx", "tx"; + mboxes = <&adsp_mailbox0>, <&adsp_mailbox1>; + }; -- GitLab From acaeb8c62fd1b2b57be1523b8d5b1d64a1a9dc38 Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Wed, 22 Jun 2022 14:22:45 +0800 Subject: [PATCH 599/942] ASoC: SOF: mediatek: Align mt8186 clock names with dt-bindings Align clock names in mt8186 dsp driver with dt-bindings. Signed-off-by: Tinghan Shen Link: https://lore.kernel.org/r/20220622062245.21021-5-tinghan.shen@mediatek.com Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8186/mt8186-clk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/mediatek/mt8186/mt8186-clk.c b/sound/soc/sof/mediatek/mt8186/mt8186-clk.c index 22220fd50b626..2df3b7ae1c6f5 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186-clk.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186-clk.c @@ -18,8 +18,8 @@ #include "mt8186-clk.h" static const char *adsp_clks[ADSP_CLK_MAX] = { - [CLK_TOP_AUDIODSP] = "audiodsp_sel", - [CLK_TOP_ADSP_BUS] = "adsp_bus_sel", + [CLK_TOP_AUDIODSP] = "audiodsp", + [CLK_TOP_ADSP_BUS] = "adsp_bus", }; int mt8186_adsp_init_clock(struct snd_sof_dev *sdev) -- GitLab From 1892a991886ace2c3450bec801df2cf4028a803a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 21 Jun 2022 16:58:34 +0200 Subject: [PATCH 600/942] ASoC: core: Make snd_soc_unregister_card() return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function snd_soc_unregister_card() returned 0 unconditionally and most callers don't care to check the return value. Make it return void and adapt the callers that didn't ignore the return value before. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220621145834.198519-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- include/sound/soc.h | 2 +- sound/soc/atmel/mikroe-proto.c | 4 +++- sound/soc/fsl/pcm030-audio-fabric.c | 5 ++--- sound/soc/soc-core.c | 4 +--- sound/soc/soc-topology-test.c | 4 +--- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 76ee3c2b8b56c..aad24a1d32767 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -426,7 +426,7 @@ enum snd_soc_pcm_subclass { }; int snd_soc_register_card(struct snd_soc_card *card); -int snd_soc_unregister_card(struct snd_soc_card *card); +void snd_soc_unregister_card(struct snd_soc_card *card); int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card); #ifdef CONFIG_PM_SLEEP int snd_soc_suspend(struct device *dev); diff --git a/sound/soc/atmel/mikroe-proto.c b/sound/soc/atmel/mikroe-proto.c index ce46d8a0b7e43..954460719aa3d 100644 --- a/sound/soc/atmel/mikroe-proto.c +++ b/sound/soc/atmel/mikroe-proto.c @@ -157,7 +157,9 @@ static int snd_proto_probe(struct platform_device *pdev) static int snd_proto_remove(struct platform_device *pdev) { - return snd_soc_unregister_card(&snd_proto); + snd_soc_unregister_card(&snd_proto); + + return 0; } static const struct of_device_id snd_proto_of_match[] = { diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 83b4a22bf15ac..e4c805acc3497 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -113,12 +113,11 @@ static int pcm030_fabric_probe(struct platform_device *op) static int pcm030_fabric_remove(struct platform_device *op) { struct pcm030_audio_data *pdata = platform_get_drvdata(op); - int ret; - ret = snd_soc_unregister_card(pdata->card); + snd_soc_unregister_card(pdata->card); platform_device_unregister(pdata->codec_device); - return ret; + return 0; } static const struct of_device_id pcm030_audio_match[] = { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 57f7105c12b76..30f0da711ca95 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2319,14 +2319,12 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card); * @card: Card to unregister * */ -int snd_soc_unregister_card(struct snd_soc_card *card) +void snd_soc_unregister_card(struct snd_soc_card *card) { mutex_lock(&client_mutex); snd_soc_unbind_card(card, true); mutex_unlock(&client_mutex); dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); - - return 0; } EXPORT_SYMBOL_GPL(snd_soc_unregister_card); diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index ae3968161509c..225d743559741 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -271,9 +271,7 @@ static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); - + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } -- GitLab From 0deb003933052ac1a44b5f94b927484be6e34f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 22 Jun 2022 08:17:39 +0200 Subject: [PATCH 601/942] ASoC: amd: acp: Fix error handling in .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even in the presence of problems (here: rn_acp_deinit() might fail), it's important to unregister all resources acquired during .probe() because even if .remove() returns an error code, the device is removed. As .remove() is only called after .probe() returned success, platdata must be valid, so the first check in .remove() can just be dropped. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220622061739.225966-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-renoir.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 75c9229ece97a..8375c00ff4c37 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -307,16 +307,10 @@ static int renoir_audio_remove(struct platform_device *pdev) int ret; chip = dev_get_platdata(&pdev->dev); - if (!chip || !chip->base) { - dev_err(&pdev->dev, "ACP chip data is NULL\n"); - return -ENODEV; - } ret = rn_acp_deinit(chip->base); - if (ret) { - dev_err(&pdev->dev, "ACP de-init Failed\n"); - return -EINVAL; - } + if (ret) + dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret)); acp_platform_unregister(dev); return 0; -- GitLab From c3b5fd7fbb698496461f280728b456d9927f22af Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 22 Jun 2022 02:57:47 +0800 Subject: [PATCH 602/942] ASoC: rockchip: i2s: Fix crash on missing pinctrl Commit 44f362c2cc6d ("ASoC: rockchip: i2s: switch BCLK to GPIO") added pinctrl lookups, but did not skip the lookup if there was no pinctrl device tied to the I2S controller. As a result, the lookup was done on an invalid pointer in such cases, causing a kernel panic. Only do the subsequent pinctrl state lookups and switch if a pinctrl device was found. i2s_pinctrl_select_bclk_{on,off} already guard against missing pinctrl device or pinctrl state, so those two functions aren't touched. Fixes: 44f362c2cc6d ("ASoC: rockchip: i2s: switch BCLK to GPIO") Signed-off-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/20220621185747.2782-1-wens@kernel.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index be051e48b97bb..9fa8ffd712ea0 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -808,24 +808,23 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s->bclk_ratio = 64; i2s->pinctrl = devm_pinctrl_get(&pdev->dev); - if (IS_ERR(i2s->pinctrl)) + if (IS_ERR(i2s->pinctrl)) { dev_err(&pdev->dev, "failed to find i2s pinctrl\n"); + } else { + i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, "bclk_on"); + if (IS_ERR_OR_NULL(i2s->bclk_on)) + dev_err(&pdev->dev, "failed to find i2s default state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk state\n"); - i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, - "bclk_on"); - if (IS_ERR_OR_NULL(i2s->bclk_on)) - dev_err(&pdev->dev, "failed to find i2s default state\n"); - else - dev_dbg(&pdev->dev, "find i2s bclk state\n"); - - i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, - "bclk_off"); - if (IS_ERR_OR_NULL(i2s->bclk_off)) - dev_err(&pdev->dev, "failed to find i2s gpio state\n"); - else - dev_dbg(&pdev->dev, "find i2s bclk_off state\n"); + i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off"); + if (IS_ERR_OR_NULL(i2s->bclk_off)) + dev_err(&pdev->dev, "failed to find i2s gpio state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk_off state\n"); - i2s_pinctrl_select_bclk_off(i2s); + i2s_pinctrl_select_bclk_off(i2s); + } i2s->playback_dma_data.addr = res->start + I2S_TXDR; i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -- GitLab From 8b99e24de3fae72ff5ef38832b94b1e41059eeed Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:46 +0200 Subject: [PATCH 603/942] ASoC: Intel: Rename haswell source file to hsw_rt5640 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename source file to drop any ambiguity. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Makefile | 2 +- sound/soc/intel/boards/{haswell.c => hsw_rt5640.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename sound/soc/intel/boards/{haswell.c => hsw_rt5640.c} (100%) diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 40c0c3d1c5007..e479546a3d4b8 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -snd-soc-sst-haswell-objs := haswell.o +snd-soc-sst-haswell-objs := hsw_rt5640.o snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o snd-soc-sst-broadwell-objs := broadwell.o diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/hsw_rt5640.c similarity index 100% rename from sound/soc/intel/boards/haswell.c rename to sound/soc/intel/boards/hsw_rt5640.c -- GitLab From 675002b6ca9132445e340bd106297d584e44fc9a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:47 +0200 Subject: [PATCH 604/942] ASoC: Intel: hsw_rt5640: Reword prefixes of all driver members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace ambiguous 'haswell_rt5640_' prefixes in favour of 'card_', 'link_' and other similar strings to clearly state which object given member implements behavior for. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hsw_rt5640.c | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index aa61e101f793c..b51ce8d0ca22a 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -16,12 +16,12 @@ #include "../../codecs/rt5640.h" /* Haswell ULT platforms have a Headphone and Mic jack */ -static const struct snd_soc_dapm_widget haswell_widgets[] = { +static const struct snd_soc_dapm_widget card_widgets[] = { SND_SOC_DAPM_HP("Headphones", NULL), SND_SOC_DAPM_MIC("Mic", NULL), }; -static const struct snd_soc_dapm_route haswell_rt5640_map[] = { +static const struct snd_soc_dapm_route card_routes[] = { {"Headphones", NULL, "HPOR"}, {"Headphones", NULL, "HPOL"}, @@ -32,7 +32,7 @@ static const struct snd_soc_dapm_route haswell_rt5640_map[] = { {"AIF1 Playback", NULL, "SSP0 CODEC OUT"}, }; -static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, +static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, @@ -49,7 +49,7 @@ static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream, +static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); @@ -70,8 +70,8 @@ static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream, return ret; } -static const struct snd_soc_ops haswell_rt5640_ops = { - .hw_params = haswell_rt5640_hw_params, +static const struct snd_soc_ops codec_link_ops = { + .hw_params = codec_link_hw_params, }; SND_SOC_DAILINK_DEF(dummy, @@ -98,7 +98,7 @@ SND_SOC_DAILINK_DEF(platform, SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); -static struct snd_soc_dai_link haswell_rt5640_dais[] = { +static struct snd_soc_dai_link card_dai_links[] = { /* Front End DAI links */ { .name = "System", @@ -147,8 +147,8 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, - .be_hw_params_fixup = haswell_ssp0_fixup, - .ops = &haswell_rt5640_ops, + .be_hw_params_fixup = codec_link_hw_params_fixup, + .ops = &codec_link_ops, .dpcm_playback = 1, .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp0_port, codec, platform), @@ -156,44 +156,44 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = { }; /* audio machine driver for Haswell Lynxpoint DSP + RT5640 */ -static struct snd_soc_card haswell_rt5640 = { +static struct snd_soc_card hsw_rt5640_card = { .name = "haswell-rt5640", .owner = THIS_MODULE, - .dai_link = haswell_rt5640_dais, - .num_links = ARRAY_SIZE(haswell_rt5640_dais), - .dapm_widgets = haswell_widgets, - .num_dapm_widgets = ARRAY_SIZE(haswell_widgets), - .dapm_routes = haswell_rt5640_map, - .num_dapm_routes = ARRAY_SIZE(haswell_rt5640_map), + .dai_link = card_dai_links, + .num_links = ARRAY_SIZE(card_dai_links), + .dapm_widgets = card_widgets, + .num_dapm_widgets = ARRAY_SIZE(card_widgets), + .dapm_routes = card_routes, + .num_dapm_routes = ARRAY_SIZE(card_routes), .fully_routed = true, }; -static int haswell_audio_probe(struct platform_device *pdev) +static int hsw_rt5640_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach; int ret; - haswell_rt5640.dev = &pdev->dev; + hsw_rt5640_card.dev = &pdev->dev; /* override platform name, if required */ mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(&haswell_rt5640, + ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, mach->mach_params.platform); if (ret) return ret; - return devm_snd_soc_register_card(&pdev->dev, &haswell_rt5640); + return devm_snd_soc_register_card(&pdev->dev, &hsw_rt5640_card); } -static struct platform_driver haswell_audio = { - .probe = haswell_audio_probe, +static struct platform_driver hsw_rt5640_driver = { + .probe = hsw_rt5640_probe, .driver = { .name = "haswell-audio", .pm = &snd_soc_pm_ops, }, }; -module_platform_driver(haswell_audio) +module_platform_driver(hsw_rt5640_driver) /* Module information */ MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); -- GitLab From a69615e81709da0ff1f035886e8b3faf6125cd22 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:48 +0200 Subject: [PATCH 605/942] ASoC: Intel: hsw_rt5640: Reword driver name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with other Intel boards naming convention and let the name explicitly state which components are being connected. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hsw_rt5640.c | 4 ++-- sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index b51ce8d0ca22a..a096453bf1df3 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -188,7 +188,7 @@ static int hsw_rt5640_probe(struct platform_device *pdev) static struct platform_driver hsw_rt5640_driver = { .probe = hsw_rt5640_probe, .driver = { - .name = "haswell-audio", + .name = "hsw_rt5640", .pm = &snd_soc_pm_ops, }, }; @@ -199,4 +199,4 @@ module_platform_driver(hsw_rt5640_driver) MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); MODULE_DESCRIPTION("Intel SST Audio for Haswell Lynxpoint"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:haswell-audio"); +MODULE_ALIAS("platform:hsw_rt5640"); diff --git a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c index 0441df97b2605..4e00f8f6c5211 100644 --- a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c @@ -12,7 +12,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[] = { { .id = "INT33CA", - .drv_name = "haswell-audio", + .drv_name = "hsw_rt5640", .fw_filename = "intel/IntcSST1.bin", .sof_tplg_filename = "sof-hsw.tplg", }, @@ -41,7 +41,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = { }, { .id = "INT33CA", - .drv_name = "haswell-audio", + .drv_name = "hsw_rt5640", .fw_filename = "intel/IntcSST2.bin", .sof_tplg_filename = "sof-bdw-rt5640.tplg", }, -- GitLab From 5b66dde4ada531c1a2417d8daf68004067932a19 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:49 +0200 Subject: [PATCH 606/942] ASoC: Intel: hsw_rt5640: Update code indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make use of 100 character limit and modify indentation so code is easier to read. While at it, sort includes in alphabetical order. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hsw_rt5640.c | 59 +++++++++-------------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index a096453bf1df3..da31b011b4951 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -9,10 +9,9 @@ #include #include #include +#include #include #include -#include - #include "../../codecs/rt5640.h" /* Haswell ULT platforms have a Headphone and Mic jack */ @@ -22,7 +21,6 @@ static const struct snd_soc_dapm_widget card_widgets[] = { }; static const struct snd_soc_dapm_route card_routes[] = { - {"Headphones", NULL, "HPOR"}, {"Headphones", NULL, "HPOL"}, {"IN2P", NULL, "Mic"}, @@ -33,32 +31,28 @@ static const struct snd_soc_dapm_route card_routes[] = { }; static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params) { - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); /* The ADSP will covert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - /* set SSP0 to 16 bit */ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + return 0; } static int codec_link_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int ret; - ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, - SND_SOC_CLOCK_IN); - + ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(rtd->dev, "can't set codec sysclk configuration\n"); return ret; @@ -74,29 +68,15 @@ static const struct snd_soc_ops codec_link_ops = { .hw_params = codec_link_hw_params, }; -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); +SND_SOC_DAILINK_DEF(system, DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); +SND_SOC_DAILINK_DEF(offload0, DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); +SND_SOC_DAILINK_DEF(offload1, DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); +SND_SOC_DAILINK_DEF(loopback, DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin"))); -SND_SOC_DAILINK_DEF(offload0, - DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); - -SND_SOC_DAILINK_DEF(offload1, - DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); - -SND_SOC_DAILINK_DEF(loopback, - DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin"))); - -SND_SOC_DAILINK_DEF(codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT33CA:00", "rt5640-aif1"))); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); - -SND_SOC_DAILINK_DEF(ssp0_port, - DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); +SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); +SND_SOC_DAILINK_DEF(codec, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT33CA:00", "rt5640-aif1"))); +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); +SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); static struct snd_soc_dai_link card_dai_links[] = { /* Front End DAI links */ @@ -137,15 +117,13 @@ static struct snd_soc_dai_link card_dai_links[] = { .dpcm_capture = 1, SND_SOC_DAILINK_REG(loopback, dummy, platform), }, - /* Back End DAI links */ { /* SSP0 - Codec */ .name = "Codec", .id = 0, .no_pcm = 1, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, .ops = &codec_link_ops, @@ -174,11 +152,10 @@ static int hsw_rt5640_probe(struct platform_device *pdev) int ret; hsw_rt5640_card.dev = &pdev->dev; - /* override platform name, if required */ mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, - mach->mach_params.platform); + + ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, mach->mach_params.platform); if (ret) return ret; -- GitLab From 2c53debbbf04eb40854fa33813514828fa455783 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:50 +0200 Subject: [PATCH 607/942] ASoC: Intel: hsw_rt5640: Update file comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop redundant and update valuable comments within the file to increase readability. This patch also revisits module information and kconfig help strings. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 2 +- sound/soc/intel/boards/hsw_rt5640.c | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 4b4c1e1e48087..817b4c04bf6a9 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -41,7 +41,7 @@ config SND_SOC_INTEL_SOF_CIRRUS_COMMON if SND_SOC_INTEL_CATPT config SND_SOC_INTEL_HASWELL_MACH - tristate "Haswell Lynxpoint" + tristate "Haswell with RT5640 I2S codec" depends on I2C depends on I2C_DESIGNWARE_PLATFORM || COMPILE_TEST depends on X86_INTEL_LPSS || COMPILE_TEST diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index da31b011b4951..f843ba5f47184 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Intel Haswell Lynxpoint SST Audio + * Sound card driver for Intel Haswell Lynx Point with Realtek 5640 * * Copyright (C) 2013, Intel Corporation. All rights reserved. */ @@ -14,7 +14,6 @@ #include #include "../../codecs/rt5640.h" -/* Haswell ULT platforms have a Headphone and Mic jack */ static const struct snd_soc_dapm_widget card_widgets[] = { SND_SOC_DAPM_HP("Headphones", NULL), SND_SOC_DAPM_MIC("Mic", NULL), @@ -36,10 +35,10 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo. */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - /* set SSP0 to 16 bit */ + /* Set SSP0 to 16 bit. */ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); return 0; @@ -58,7 +57,7 @@ static int codec_link_hw_params(struct snd_pcm_substream *substream, return ret; } - /* set correct codec filter for DAI format and clock config */ + /* Set correct codec filter for DAI format and clock config. */ snd_soc_component_update_bits(codec_dai->component, 0x83, 0xffff, 0x8000); return ret; @@ -133,7 +132,6 @@ static struct snd_soc_dai_link card_dai_links[] = { }, }; -/* audio machine driver for Haswell Lynxpoint DSP + RT5640 */ static struct snd_soc_card hsw_rt5640_card = { .name = "haswell-rt5640", .owner = THIS_MODULE, @@ -152,7 +150,6 @@ static int hsw_rt5640_probe(struct platform_device *pdev) int ret; hsw_rt5640_card.dev = &pdev->dev; - /* override platform name, if required */ mach = pdev->dev.platform_data; ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, mach->mach_params.platform); @@ -172,8 +169,7 @@ static struct platform_driver hsw_rt5640_driver = { module_platform_driver(hsw_rt5640_driver) -/* Module information */ MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); -MODULE_DESCRIPTION("Intel SST Audio for Haswell Lynxpoint"); -MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Sound card driver for Intel Haswell Lynx Point with Realtek 5640"); +MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:hsw_rt5640"); -- GitLab From 0439f262a9b39734c1440733850969f0342c50c3 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:51 +0200 Subject: [PATCH 608/942] ASoC: Intel: hsw_rt5640: Improve probe() function quality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare local 'dev' and make use of it plus dev_get_platdata() to improve code readability. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hsw_rt5640.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index f843ba5f47184..273c8e274d253 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -147,16 +147,17 @@ static struct snd_soc_card hsw_rt5640_card = { static int hsw_rt5640_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach; + struct device *dev = &pdev->dev; int ret; - hsw_rt5640_card.dev = &pdev->dev; - mach = pdev->dev.platform_data; + hsw_rt5640_card.dev = dev; + mach = dev_get_platdata(dev); ret = snd_soc_fixup_dai_links_platform_name(&hsw_rt5640_card, mach->mach_params.platform); if (ret) return ret; - return devm_snd_soc_register_card(&pdev->dev, &hsw_rt5640_card); + return devm_snd_soc_register_card(dev, &hsw_rt5640_card); } static struct platform_driver hsw_rt5640_driver = { -- GitLab From 6c65908251edc637b53bdeb9e79d918a8d081183 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:52 +0200 Subject: [PATCH 609/942] ASoC: Intel: hsw_rt5640: Improve hw_params() debug-ability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print status if setting sysclk fails. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/hsw_rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index 273c8e274d253..ad747363d1126 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -53,7 +53,7 @@ static int codec_link_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, SND_SOC_CLOCK_IN); if (ret < 0) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); + dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret); return ret; } -- GitLab From 6d8758f6afd91cced9c6c5571337a5fbc6955bb2 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:53 +0200 Subject: [PATCH 610/942] ASoC: Intel: Rename broadwell source file to bdw_rt286 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename source file to drop any ambiguity. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Makefile | 2 +- sound/soc/intel/boards/{broadwell.c => bdw_rt286.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename sound/soc/intel/boards/{broadwell.c => bdw_rt286.c} (100%) diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index e479546a3d4b8..eea1e26acfdaa 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -2,7 +2,7 @@ snd-soc-sst-haswell-objs := hsw_rt5640.o snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o -snd-soc-sst-broadwell-objs := broadwell.o +snd-soc-sst-broadwell-objs := bdw_rt286.o snd-soc-sst-bxt-da7219_max98357a-objs := bxt_da7219_max98357a.o snd-soc-sst-bxt-rt298-objs := bxt_rt298.o snd-soc-sst-sof-pcm512x-objs := sof_pcm512x.o diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/bdw_rt286.c similarity index 100% rename from sound/soc/intel/boards/broadwell.c rename to sound/soc/intel/boards/bdw_rt286.c -- GitLab From 40b5c9030a87e97c00c84403902481deadd2a57b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:54 +0200 Subject: [PATCH 611/942] ASoC: Intel: bdw_rt286: Reword prefixes of all driver members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace ambiguous 'broadwell_rt286_' prefixes in favour of 'card_', 'link_' and other similar strings to clearly state which object given member implements behavior for. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 102 ++++++++++++++--------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 48bf3241b3e63..f28341ec8eb33 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -16,9 +16,9 @@ #include "../../codecs/rt286.h" -static struct snd_soc_jack broadwell_headset; +static struct snd_soc_jack card_headset; /* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin broadwell_headset_pins[] = { +static struct snd_soc_jack_pin card_headset_pins[] = { { .pin = "Mic Jack", .mask = SND_JACK_MICROPHONE, @@ -29,12 +29,12 @@ static struct snd_soc_jack_pin broadwell_headset_pins[] = { }, }; -static const struct snd_kcontrol_new broadwell_controls[] = { +static const struct snd_kcontrol_new card_controls[] = { SOC_DAPM_PIN_SWITCH("Speaker"), SOC_DAPM_PIN_SWITCH("Headphone Jack"), }; -static const struct snd_soc_dapm_widget broadwell_widgets[] = { +static const struct snd_soc_dapm_widget card_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_MIC("Mic Jack", NULL), @@ -43,7 +43,7 @@ static const struct snd_soc_dapm_widget broadwell_widgets[] = { SND_SOC_DAPM_LINE("Line Jack", NULL), }; -static const struct snd_soc_dapm_route broadwell_rt286_map[] = { +static const struct snd_soc_dapm_route card_routes[] = { /* speaker */ {"Speaker", NULL, "SPOR"}, @@ -65,22 +65,22 @@ static const struct snd_soc_dapm_route broadwell_rt286_map[] = { {"AIF1 Playback", NULL, "SSP0 CODEC OUT"}, }; -static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) +static int codec_link_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset, - broadwell_headset_pins, ARRAY_SIZE(broadwell_headset_pins)); + SND_JACK_HEADSET | SND_JACK_BTN_0, &card_headset, + card_headset_pins, ARRAY_SIZE(card_headset_pins)); if (ret) return ret; - snd_soc_component_set_jack(component, &broadwell_headset, NULL); + snd_soc_component_set_jack(component, &card_headset, NULL); return 0; } -static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, +static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, @@ -97,7 +97,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } -static int broadwell_rt286_hw_params(struct snd_pcm_substream *substream, +static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); @@ -115,8 +115,8 @@ static int broadwell_rt286_hw_params(struct snd_pcm_substream *substream, return ret; } -static const struct snd_soc_ops broadwell_rt286_ops = { - .hw_params = broadwell_rt286_hw_params, +static const struct snd_soc_ops codec_link_ops = { + .hw_params = codec_link_hw_params, }; static const unsigned int channels[] = { @@ -129,7 +129,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = { .mask = 0, }; -static int broadwell_fe_startup(struct snd_pcm_substream *substream) +static int bdw_rt286_fe_startup(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -140,8 +140,8 @@ static int broadwell_fe_startup(struct snd_pcm_substream *substream) &constraints_channels); } -static const struct snd_soc_ops broadwell_fe_ops = { - .startup = broadwell_fe_startup, +static const struct snd_soc_ops bdw_rt286_fe_ops = { + .startup = bdw_rt286_fe_startup, }; SND_SOC_DAILINK_DEF(system, @@ -169,7 +169,7 @@ SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); /* broadwell digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link broadwell_rt286_dais[] = { +static struct snd_soc_dai_link card_dai_links[] = { /* Front End DAI links */ { .name = "System PCM", @@ -177,7 +177,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .ops = &broadwell_fe_ops, + .ops = &bdw_rt286_fe_ops, .dpcm_playback = 1, .dpcm_capture = 1, SND_SOC_DAILINK_REG(system, dummy, platform), @@ -215,19 +215,19 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { .name = "Codec", .id = 0, .no_pcm = 1, - .init = broadwell_rt286_codec_init, + .init = codec_link_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, - .be_hw_params_fixup = broadwell_ssp0_fixup, - .ops = &broadwell_rt286_ops, + .be_hw_params_fixup = codec_link_hw_params_fixup, + .ops = &codec_link_ops, .dpcm_playback = 1, .dpcm_capture = 1, SND_SOC_DAILINK_REG(ssp0_port, codec, platform), }, }; -static void broadwell_disable_jack(struct snd_soc_card *card) +static void bdw_rt286_disable_jack(struct snd_soc_card *card) { struct snd_soc_component *component; @@ -241,21 +241,21 @@ static void broadwell_disable_jack(struct snd_soc_card *card) } } -static int broadwell_suspend(struct snd_soc_card *card) +static int bdw_rt286_suspend(struct snd_soc_card *card) { - broadwell_disable_jack(card); + bdw_rt286_disable_jack(card); return 0; } -static int broadwell_resume(struct snd_soc_card *card){ +static int bdw_rt286_resume(struct snd_soc_card *card){ struct snd_soc_component *component; for_each_card_components(card, component) { if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "enabling jack detect for resume.\n"); - snd_soc_component_set_jack(component, &broadwell_headset, NULL); + snd_soc_component_set_jack(component, &card_headset, NULL); break; } } @@ -270,66 +270,66 @@ static int broadwell_resume(struct snd_soc_card *card){ #define DRIVER_NAME NULL /* card name will be used for driver name */ /* broadwell audio machine driver for WPT + RT286S */ -static struct snd_soc_card broadwell_rt286 = { +static struct snd_soc_card bdw_rt286_card = { .owner = THIS_MODULE, - .dai_link = broadwell_rt286_dais, - .num_links = ARRAY_SIZE(broadwell_rt286_dais), - .controls = broadwell_controls, - .num_controls = ARRAY_SIZE(broadwell_controls), - .dapm_widgets = broadwell_widgets, - .num_dapm_widgets = ARRAY_SIZE(broadwell_widgets), - .dapm_routes = broadwell_rt286_map, - .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map), + .dai_link = card_dai_links, + .num_links = ARRAY_SIZE(card_dai_links), + .controls = card_controls, + .num_controls = ARRAY_SIZE(card_controls), + .dapm_widgets = card_widgets, + .num_dapm_widgets = ARRAY_SIZE(card_widgets), + .dapm_routes = card_routes, + .num_dapm_routes = ARRAY_SIZE(card_routes), .fully_routed = true, - .suspend_pre = broadwell_suspend, - .resume_post = broadwell_resume, + .suspend_pre = bdw_rt286_suspend, + .resume_post = bdw_rt286_resume, }; -static int broadwell_audio_probe(struct platform_device *pdev) +static int bdw_rt286_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach; int ret; - broadwell_rt286.dev = &pdev->dev; + bdw_rt286_card.dev = &pdev->dev; /* override platform name, if required */ mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, + ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt286_card, mach->mach_params.platform); if (ret) return ret; /* set card and driver name */ if (snd_soc_acpi_sof_parent(&pdev->dev)) { - broadwell_rt286.name = SOF_CARD_NAME; - broadwell_rt286.driver_name = SOF_DRIVER_NAME; + bdw_rt286_card.name = SOF_CARD_NAME; + bdw_rt286_card.driver_name = SOF_DRIVER_NAME; } else { - broadwell_rt286.name = CARD_NAME; - broadwell_rt286.driver_name = DRIVER_NAME; + bdw_rt286_card.name = CARD_NAME; + bdw_rt286_card.driver_name = DRIVER_NAME; } - return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286); + return devm_snd_soc_register_card(&pdev->dev, &bdw_rt286_card); } -static int broadwell_audio_remove(struct platform_device *pdev) +static int bdw_rt286_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - broadwell_disable_jack(card); + bdw_rt286_disable_jack(card); return 0; } -static struct platform_driver broadwell_audio = { - .probe = broadwell_audio_probe, - .remove = broadwell_audio_remove, +static struct platform_driver bdw_rt286_driver = { + .probe = bdw_rt286_probe, + .remove = bdw_rt286_remove, .driver = { .name = "broadwell-audio", .pm = &snd_soc_pm_ops }, }; -module_platform_driver(broadwell_audio) +module_platform_driver(bdw_rt286_driver) /* Module information */ MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); -- GitLab From 86156bcbca08ee32d04ca56c57ff3fce6fc5fc4b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:55 +0200 Subject: [PATCH 612/942] ASoC: Intel: bdw_rt286: Reword driver name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with other Intel boards naming convention and let the name explicitly state which components are being connected. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 4 ++-- sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index f28341ec8eb33..26ec671a5a52b 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -324,7 +324,7 @@ static struct platform_driver bdw_rt286_driver = { .probe = bdw_rt286_probe, .remove = bdw_rt286_remove, .driver = { - .name = "broadwell-audio", + .name = "bdw_rt286", .pm = &snd_soc_pm_ops }, }; @@ -335,4 +335,4 @@ module_platform_driver(bdw_rt286_driver) MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); MODULE_DESCRIPTION("Intel SST Audio for WPT/Broadwell"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:broadwell-audio"); +MODULE_ALIAS("platform:bdw_rt286"); diff --git a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c index 4e00f8f6c5211..cbcb649604e57 100644 --- a/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-hsw-bdw-match.c @@ -23,7 +23,7 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_haswell_machines); struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[] = { { .id = "INT343A", - .drv_name = "broadwell-audio", + .drv_name = "bdw_rt286", .fw_filename = "intel/IntcSST2.bin", .sof_tplg_filename = "sof-bdw-rt286.tplg", }, -- GitLab From 9de833d2dcd43c953f7869f27bffd41896adb425 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:56 +0200 Subject: [PATCH 613/942] ASoC: Intel: bdw_rt286: Update code indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make use of 100 character limit and modify indentation so code is easier to read. While at it, sort includes in alphabetical order. While at it, rename local variable 'chan' to 'channels' to match hsw_rt5640 board's equivalent. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 79 +++++++++++------------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 26ec671a5a52b..6c0cd53224d54 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -8,12 +8,11 @@ #include #include #include -#include -#include #include +#include #include +#include #include - #include "../../codecs/rt286.h" static struct snd_soc_jack card_headset; @@ -44,7 +43,6 @@ static const struct snd_soc_dapm_widget card_widgets[] = { }; static const struct snd_soc_dapm_route card_routes[] = { - /* speaker */ {"Speaker", NULL, "SPOR"}, {"Speaker", NULL, "SPOL"}, @@ -69,9 +67,10 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; int ret = 0; - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", - SND_JACK_HEADSET | SND_JACK_BTN_0, &card_headset, - card_headset_pins, ARRAY_SIZE(card_headset_pins)); + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, + &card_headset, card_headset_pins, + ARRAY_SIZE(card_headset_pins)); if (ret) return ret; @@ -79,34 +78,29 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) return 0; } - static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params) { - struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *chan = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); /* The ADSP will covert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; - chan->min = chan->max = 2; - + channels->min = channels->max = 2; /* set SSP0 to 16 bit */ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + return 0; } static int codec_link_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int ret; - ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, - SND_SOC_CLOCK_IN); - + ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(rtd->dev, "can't set codec sysclk configuration\n"); return ret; @@ -135,8 +129,7 @@ static int bdw_rt286_fe_startup(struct snd_pcm_substream *substream) /* Board supports stereo configuration only */ runtime->hw.channels_max = 2; - return snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, + return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &constraints_channels); } @@ -144,29 +137,15 @@ static const struct snd_soc_ops bdw_rt286_fe_ops = { .startup = bdw_rt286_fe_startup, }; -SND_SOC_DAILINK_DEF(system, - DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); - -SND_SOC_DAILINK_DEF(offload0, - DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); +SND_SOC_DAILINK_DEF(system, DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); +SND_SOC_DAILINK_DEF(offload0, DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); +SND_SOC_DAILINK_DEF(offload1, DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); +SND_SOC_DAILINK_DEF(loopback, DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin"))); -SND_SOC_DAILINK_DEF(offload1, - DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); - -SND_SOC_DAILINK_DEF(loopback, - DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin"))); - -SND_SOC_DAILINK_DEF(dummy, - DAILINK_COMP_ARRAY(COMP_DUMMY())); - -SND_SOC_DAILINK_DEF(platform, - DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); - -SND_SOC_DAILINK_DEF(codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); - -SND_SOC_DAILINK_DEF(ssp0_port, - DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); +SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); +SND_SOC_DAILINK_DEF(codec, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); +SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); /* broadwell digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link card_dai_links[] = { @@ -216,8 +195,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .id = 0, .no_pcm = 1, .init = codec_link_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, .ops = &codec_link_ops, @@ -233,7 +211,6 @@ static void bdw_rt286_disable_jack(struct snd_soc_card *card) for_each_card_components(card, component) { if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); snd_soc_component_set_jack(component, NULL, NULL); break; @@ -248,17 +225,18 @@ static int bdw_rt286_suspend(struct snd_soc_card *card) return 0; } -static int bdw_rt286_resume(struct snd_soc_card *card){ +static int bdw_rt286_resume(struct snd_soc_card *card) +{ struct snd_soc_component *component; for_each_card_components(card, component) { if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "enabling jack detect for resume.\n"); snd_soc_component_set_jack(component, &card_headset, NULL); break; } } + return 0; } @@ -291,11 +269,10 @@ static int bdw_rt286_probe(struct platform_device *pdev) int ret; bdw_rt286_card.dev = &pdev->dev; - /* override platform name, if required */ mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt286_card, - mach->mach_params.platform); + + ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt286_card, mach->mach_params.platform); if (ret) return ret; -- GitLab From 128bb6fb530841348ee4d9b4234b30006c44c803 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:57 +0200 Subject: [PATCH 614/942] ASoC: Intel: bdw_rt286: Update file comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop redundant and update valuable comments within the file to increase readability. This patch also revisits module information and kconfig help strings. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 2 +- sound/soc/intel/boards/bdw_rt286.c | 23 +++++++---------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 817b4c04bf6a9..aa12d7e3dd2f9 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -85,7 +85,7 @@ config SND_SOC_INTEL_BDW_RT5677_MACH If unsure select "N". config SND_SOC_INTEL_BROADWELL_MACH - tristate "Broadwell Wildcatpoint" + tristate "Broadwell with RT286 I2S codec" depends on I2C depends on I2C_DESIGNWARE_PLATFORM || COMPILE_TEST depends on X86_INTEL_LPSS || COMPILE_TEST diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 6c0cd53224d54..9d815c31e1f41 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Intel Broadwell Wildcatpoint SST Audio + * Sound card driver for Intel Broadwell Wildcat Point with Realtek 286 * * Copyright (C) 2013, Intel Corporation. All rights reserved. */ @@ -16,7 +16,7 @@ #include "../../codecs/rt286.h" static struct snd_soc_jack card_headset; -/* Headset jack detection DAPM pins */ + static struct snd_soc_jack_pin card_headset_pins[] = { { .pin = "Mic Jack", @@ -43,18 +43,14 @@ static const struct snd_soc_dapm_widget card_widgets[] = { }; static const struct snd_soc_dapm_route card_routes[] = { - /* speaker */ {"Speaker", NULL, "SPOR"}, {"Speaker", NULL, "SPOL"}, - /* HP jack connectors - unknown if we have jack deteck */ {"Headphone Jack", NULL, "HPO Pin"}, - /* other jacks */ {"MIC1", NULL, "Mic Jack"}, {"LINE1", NULL, "Line Jack"}, - /* digital mics */ {"DMIC1 Pin", NULL, "DMIC1"}, {"DMIC2 Pin", NULL, "DMIC2"}, @@ -84,10 +80,10 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48kHz, stereo. */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - /* set SSP0 to 16 bit */ + /* Set SSP0 to 16 bit. */ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); return 0; @@ -147,7 +143,6 @@ SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audi SND_SOC_DAILINK_DEF(codec, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); SND_SOC_DAILINK_DEF(ssp0_port, DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); -/* broadwell digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link card_dai_links[] = { /* Front End DAI links */ { @@ -240,14 +235,13 @@ static int bdw_rt286_resume(struct snd_soc_card *card) return 0; } -/* use space before codec name to simplify card ID, and simplify driver name */ +/* Use space before codec name to simplify card ID, and simplify driver name. */ #define SOF_CARD_NAME "bdw rt286" /* card name will be 'sof-bdw rt286' */ #define SOF_DRIVER_NAME "SOF" #define CARD_NAME "broadwell-rt286" #define DRIVER_NAME NULL /* card name will be used for driver name */ -/* broadwell audio machine driver for WPT + RT286S */ static struct snd_soc_card bdw_rt286_card = { .owner = THIS_MODULE, .dai_link = card_dai_links, @@ -269,14 +263,12 @@ static int bdw_rt286_probe(struct platform_device *pdev) int ret; bdw_rt286_card.dev = &pdev->dev; - /* override platform name, if required */ mach = pdev->dev.platform_data; ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt286_card, mach->mach_params.platform); if (ret) return ret; - /* set card and driver name */ if (snd_soc_acpi_sof_parent(&pdev->dev)) { bdw_rt286_card.name = SOF_CARD_NAME; bdw_rt286_card.driver_name = SOF_DRIVER_NAME; @@ -308,8 +300,7 @@ static struct platform_driver bdw_rt286_driver = { module_platform_driver(bdw_rt286_driver) -/* Module information */ MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); -MODULE_DESCRIPTION("Intel SST Audio for WPT/Broadwell"); -MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Sound card driver for Intel Broadwell Wildcat Point with Realtek 286"); +MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:bdw_rt286"); -- GitLab From 9177203c209d9137dce52c7f0bc28e54960e5a41 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:58 +0200 Subject: [PATCH 615/942] ASoC: Intel: bdw_rt286: Improve probe() function quality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare local 'dev' and make use of it plus dev_get_platdata() to improve code readability. Relocate few relevant to the function macros for the exact same read too. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-14-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 9d815c31e1f41..c5737f548befb 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -235,13 +235,6 @@ static int bdw_rt286_resume(struct snd_soc_card *card) return 0; } -/* Use space before codec name to simplify card ID, and simplify driver name. */ -#define SOF_CARD_NAME "bdw rt286" /* card name will be 'sof-bdw rt286' */ -#define SOF_DRIVER_NAME "SOF" - -#define CARD_NAME "broadwell-rt286" -#define DRIVER_NAME NULL /* card name will be used for driver name */ - static struct snd_soc_card bdw_rt286_card = { .owner = THIS_MODULE, .dai_link = card_dai_links, @@ -257,27 +250,33 @@ static struct snd_soc_card bdw_rt286_card = { .resume_post = bdw_rt286_resume, }; +/* Use space before codec name to simplify card ID, and simplify driver name. */ +#define SOF_CARD_NAME "bdw rt286" /* card name will be 'sof-bdw rt286' */ +#define SOF_DRIVER_NAME "SOF" + +#define CARD_NAME "broadwell-rt286" + static int bdw_rt286_probe(struct platform_device *pdev) { struct snd_soc_acpi_mach *mach; + struct device *dev = &pdev->dev; int ret; - bdw_rt286_card.dev = &pdev->dev; - mach = pdev->dev.platform_data; + bdw_rt286_card.dev = dev; + mach = dev_get_platdata(dev); ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt286_card, mach->mach_params.platform); if (ret) return ret; - if (snd_soc_acpi_sof_parent(&pdev->dev)) { + if (snd_soc_acpi_sof_parent(dev)) { bdw_rt286_card.name = SOF_CARD_NAME; bdw_rt286_card.driver_name = SOF_DRIVER_NAME; } else { bdw_rt286_card.name = CARD_NAME; - bdw_rt286_card.driver_name = DRIVER_NAME; } - return devm_snd_soc_register_card(&pdev->dev, &bdw_rt286_card); + return devm_snd_soc_register_card(dev, &bdw_rt286_card); } static int bdw_rt286_remove(struct platform_device *pdev) -- GitLab From 423cc2d0e8506a0ce6e3ef1806a561de1076e033 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:13:59 +0200 Subject: [PATCH 616/942] ASoC: Intel: bdw_rt286: Improve hw_params() debug-ability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Print status if setting sysclk fails. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index c5737f548befb..8604b221b60db 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -98,7 +98,7 @@ static int codec_link_hw_params(struct snd_pcm_substream *substream, ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); if (ret < 0) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); + dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret); return ret; } -- GitLab From 8fe4709962d74a19c0c1dfc877ba600101340c62 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:14:00 +0200 Subject: [PATCH 617/942] ASoC: Intel: bdw_rt286: Improve codec_init() quality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop redundant 'ret' assignemnt, stop ignoring set_jack() return value and reword local 'component' variable to 'codec' to improve readability. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-16-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 8604b221b60db..36f984ff56c50 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -61,8 +61,8 @@ static const struct snd_soc_dapm_route card_routes[] = { static int codec_link_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - int ret = 0; + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + int ret; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, &card_headset, card_headset_pins, @@ -70,8 +70,7 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - snd_soc_component_set_jack(component, &card_headset, NULL); - return 0; + return snd_soc_component_set_jack(codec, &card_headset, NULL); } static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, -- GitLab From e7f68863545163ec75b6bc3cc48fe888c28e0ec6 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 20 Jun 2022 12:14:02 +0200 Subject: [PATCH 618/942] ASoC: Intel: bdw_rt286: Remove FE DAI ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bdw_rt286_fe_ops is redundant as platform components already limit the number of channels available for the endpoint. Signed-off-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Tested-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220620101402.2684366-18-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 36f984ff56c50..47eaddb009369 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -108,30 +108,6 @@ static const struct snd_soc_ops codec_link_ops = { .hw_params = codec_link_hw_params, }; -static const unsigned int channels[] = { - 2, -}; - -static const struct snd_pcm_hw_constraint_list constraints_channels = { - .count = ARRAY_SIZE(channels), - .list = channels, - .mask = 0, -}; - -static int bdw_rt286_fe_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - /* Board supports stereo configuration only */ - runtime->hw.channels_max = 2; - return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - &constraints_channels); -} - -static const struct snd_soc_ops bdw_rt286_fe_ops = { - .startup = bdw_rt286_fe_startup, -}; - SND_SOC_DAILINK_DEF(system, DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); SND_SOC_DAILINK_DEF(offload0, DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); SND_SOC_DAILINK_DEF(offload1, DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); @@ -150,7 +126,6 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .dynamic = 1, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, - .ops = &bdw_rt286_fe_ops, .dpcm_playback = 1, .dpcm_capture = 1, SND_SOC_DAILINK_REG(system, dummy, platform), -- GitLab From d5017d1323d45db14d1db3d348779264ffce9fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 22 Jun 2022 23:06:29 +0200 Subject: [PATCH 619/942] ASoC: topology: KUnit: Followup prototype change of snd_soc_unregister_card() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit snd_soc_unregister_card() was recently converted to return void. Only the first instance was adapted, so convert the remaining ones now to fix building the topology test. Reported-by: kernel test robot Fixes: 1892a991886a ("ASoC: core: Make snd_soc_unregister_card() return void") Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220622210629.286487-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index 225d743559741..51d650bb05b72 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -313,8 +313,7 @@ static void snd_soc_tplg_test_load_with_null_ops(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -377,8 +376,7 @@ static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -426,8 +424,7 @@ static void snd_soc_tplg_test_load_empty_tplg(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -482,8 +479,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_magic(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -538,8 +534,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_abi(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -594,8 +589,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_size(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, ret); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); snd_soc_unregister_component(test_dev); } @@ -653,8 +647,7 @@ static void snd_soc_tplg_test_load_empty_tplg_bad_payload_size(struct kunit *tes /* cleanup */ snd_soc_unregister_component(test_dev); - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); } // TEST CASE @@ -702,8 +695,7 @@ static void snd_soc_tplg_test_load_pcm_tplg(struct kunit *test) snd_soc_unregister_component(test_dev); /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); } // TEST CASE @@ -755,8 +747,7 @@ static void snd_soc_tplg_test_load_pcm_tplg_reload_comp(struct kunit *test) } /* cleanup */ - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); } // TEST CASE @@ -804,8 +795,7 @@ static void snd_soc_tplg_test_load_pcm_tplg_reload_card(struct kunit *test) if (ret != 0 && ret != -EPROBE_DEFER) KUNIT_FAIL(test, "Failed to register card"); - ret = snd_soc_unregister_card(&kunit_comp->card); - KUNIT_EXPECT_EQ(test, 0, ret); + snd_soc_unregister_card(&kunit_comp->card); } /* cleanup */ -- GitLab From 4d6c2b46d81765e920007f76185a8d1fb5e41ca3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:20 +0100 Subject: [PATCH 620/942] ASoC: dapm: Move stereo autodisable check Tidy up the code a little, rather than repeating the check of mc->autodisable move the stereo error check to be under the existing if for mc->autodisable. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 869c76506b669..62c90e297aab9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -368,14 +368,14 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, case snd_soc_dapm_mixer_named_ctl: mc = (struct soc_mixer_control *)kcontrol->private_value; - if (mc->autodisable && snd_soc_volsw_is_stereo(mc)) - dev_warn(widget->dapm->dev, - "ASoC: Unsupported stereo autodisable control '%s'\n", - ctrl_name); - if (mc->autodisable) { struct snd_soc_dapm_widget template; + if (snd_soc_volsw_is_stereo(mc)) + dev_warn(widget->dapm->dev, + "ASoC: Unsupported stereo autodisable control '%s'\n", + ctrl_name); + name = kasprintf(GFP_KERNEL, "%s %s", ctrl_name, "Autodisable"); if (!name) { -- GitLab From 7f6409fd9b54b6f56444edc996cd28059f215415 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 24 Jun 2022 16:27:45 +0800 Subject: [PATCH 621/942] ASoC: rockchip: i2s: Fix missing error code in rockchip_i2s_probe() The error code is missing in this code scenario, add the error code '-EINVAL' to the return value 'ret'. This was found by coccicheck: sound/soc/rockchip/rockchip_i2s.c:810 rockchip_i2s_probe() warn: missing error code 'ret'. Signed-off-by: Jiapeng Chong Link: https://lore.kernel.org/r/20220624082745.68367-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index d300eee9ddaae..0ed01624a2dbd 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -807,6 +807,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off"); if (IS_ERR_OR_NULL(i2s->bclk_off)) { dev_err(&pdev->dev, "failed to find i2s bclk_off\n"); + ret = -EINVAL; goto err_clk; } } -- GitLab From 658e95953075ca781ef8712d0a3203e485888c7f Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 22 Jun 2022 00:38:19 +0300 Subject: [PATCH 622/942] ASoC: cs35l41: Add support for CLSA3541 ACPI device ID Add support for the CLSA3541 ACPI device ID used on Valve's Steam Deck. The driver is fully compatible with the indicated hardware, hence no additional changes are required. Signed-off-by: Cristian Ciocaltea Acked-by: David Rhodes Link: https://lore.kernel.org/r/20220621213819.262537-1-cristian.ciocaltea@collabora.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/cs35l41-spi.c b/sound/soc/codecs/cs35l41-spi.c index 9e19c946a66b5..5c8bb24909eb4 100644 --- a/sound/soc/codecs/cs35l41-spi.c +++ b/sound/soc/codecs/cs35l41-spi.c @@ -74,6 +74,7 @@ MODULE_DEVICE_TABLE(of, cs35l41_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id cs35l41_acpi_match[] = { { "CSC3541", 0 }, /* Cirrus Logic PnP ID + part ID */ + { "CLSA3541", 0 }, /* Cirrus Logic PnP ID + part ID */ {}, }; MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match); -- GitLab From b688a7629c425d7916f9bde7fce8f7da2f852ceb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:33 +0200 Subject: [PATCH 623/942] regmap: Re-introduce bulk read support check in regmap_bulk_read() Support for drivers to define bulk read/write callbacks in regmap_config was introduced by the commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config"), but this commit wrongly dropped a check in regmap_bulk_read() to determine whether bulk reads can be done or not. Before that commit, it was checked if map->bus was set. Now has to check if a map->read callback has been set. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-2-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2221d98638317..e5bb70374ffc4 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -3017,7 +3017,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, if (val_count == 0) return -EINVAL; - if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { + if (map->read && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { ret = regmap_raw_read(map, reg, val, val_bytes * val_count); if (ret != 0) return ret; -- GitLab From 147b5fffc2cfa00956552f32e64c060d10d84010 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:34 +0200 Subject: [PATCH 624/942] regmap: Make regmap_noinc_read() return -ENOTSUPP if map->read isn't set Before adding support to define bulk read/write callbacks in regmap_config by the commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config"), the regmap_noinc_read() function returned an errno early a map->bus->read callback wasn't set. But that commit dropped the check and now a call to _regmap_raw_read() is attempted even when bulk read operations are not supported. That function checks for map->read anyways but there's no point to continue if the read can't succeed. Also is a fragile assumption to make so is better to make it fail earlier. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-3-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e5bb70374ffc4..f37f80a521150 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2904,6 +2904,9 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, size_t read_len; int ret; + if (!map->read) + return -ENOTSUPP; + if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) -- GitLab From 419386b6299a01bcea20c2244dbaca4585c2ae33 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 16 Jun 2022 09:34:35 +0200 Subject: [PATCH 625/942] regmap: Wire up regmap_config provided bulk write in missed functions There are some functions that were missed by commit d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") when support to define bulk read/write callbacks in regmap_config was introduced. The regmap_bulk_write() and regmap_noinc_write() functions weren't changed to use the added map->write instead of the map->bus->write handler. Also, the regmap_can_raw_write() was not modified to take map->write into account. So will only return true if a bus with a .write callback is set. Fixes: d77e74561368 ("regmap: Add bulk read/write callbacks into regmap_config") Signed-off-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20220616073435.1988219-4-javierm@redhat.com Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index f37f80a521150..c3517ccc31591 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1880,8 +1880,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, */ bool regmap_can_raw_write(struct regmap *map) { - return map->bus && map->bus->write && map->format.format_val && - map->format.format_reg; + return map->write && map->format.format_val && map->format.format_reg; } EXPORT_SYMBOL_GPL(regmap_can_raw_write); @@ -2155,10 +2154,9 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, size_t write_len; int ret; - if (!map->bus) - return -EINVAL; - if (!map->bus->write) + if (!map->write) return -ENOTSUPP; + if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) @@ -2278,7 +2276,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, * Some devices don't support bulk write, for them we have a series of * single write operations. */ - if (!map->bus || !map->format.parse_inplace) { + if (!map->write || !map->format.parse_inplace) { map->lock(map->lock_arg); for (i = 0; i < val_count; i++) { unsigned int ival; -- GitLab From bf2aebccddef890c4385d1ef19f9fee62d51bcc2 Mon Sep 17 00:00:00 2001 From: Francesco Dolcini Date: Fri, 24 Jun 2022 12:13:01 +0200 Subject: [PATCH 626/942] ASoC: sgtl5000: Fix noise on shutdown/remove Put the SGTL5000 in a silent/safe state on shutdown/remove, this is required since the SGTL5000 produces a constant noise on its output after it is configured and its clock is removed. Without this change this is happening every time the module is unbound/removed or from reboot till the clock is enabled again. The issue was experienced on both a Toradex Colibri/Apalis iMX6, but can be easily reproduced everywhere just playing something on the codec and after that removing/unbinding the driver. Fixes: 9b34e6cc3bc2 ("ASoC: Add Freescale SGTL5000 codec support") Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Link: https://lore.kernel.org/r/20220624101301.441314-1-francesco.dolcini@toradex.com Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 9 +++++++++ sound/soc/codecs/sgtl5000.h | 1 + 2 files changed, 10 insertions(+) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 2aa48aef6a97d..3363d1696ad7c 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1795,6 +1795,9 @@ static int sgtl5000_i2c_remove(struct i2c_client *client) { struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT); + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT); + clk_disable_unprepare(sgtl5000->mclk); regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies); regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies); @@ -1802,6 +1805,11 @@ static int sgtl5000_i2c_remove(struct i2c_client *client) return 0; } +static void sgtl5000_i2c_shutdown(struct i2c_client *client) +{ + sgtl5000_i2c_remove(client); +} + static const struct i2c_device_id sgtl5000_id[] = { {"sgtl5000", 0}, {}, @@ -1822,6 +1830,7 @@ static struct i2c_driver sgtl5000_i2c_driver = { }, .probe_new = sgtl5000_i2c_probe, .remove = sgtl5000_i2c_remove, + .shutdown = sgtl5000_i2c_shutdown, .id_table = sgtl5000_id, }; diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h index 56ec5863f2507..3a808c762299e 100644 --- a/sound/soc/codecs/sgtl5000.h +++ b/sound/soc/codecs/sgtl5000.h @@ -80,6 +80,7 @@ /* * SGTL5000_CHIP_DIG_POWER */ +#define SGTL5000_DIG_POWER_DEFAULT 0x0000 #define SGTL5000_ADC_EN 0x0040 #define SGTL5000_DAC_EN 0x0020 #define SGTL5000_DAP_POWERUP 0x0010 -- GitLab From e112c42eb3b7225dd722493e9be8ce286c8a5af0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 24 Jun 2022 11:26:01 +0200 Subject: [PATCH 627/942] ASoC: audio_graph_card2: Fix port numbers in example The example in audio-graph-card2.c has multiple nodes with the same name in it. Change the port numbers to get different names. Signed-off-by: Sascha Hauer Link: https://lore.kernel.org/r/20220624092601.2445224-1-s.hauer@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 77ac4051b8276..d34b29a49268e 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -90,12 +90,12 @@ links indicates connection part of CPU side (= A). ports@0 { (X) (A) mcpu: port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; }; (y) port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; -(y) port@1 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; +(y) port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; }; ports@1 { (X) port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; }; -(y) port@0 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; -(y) port@1 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; +(y) port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; +(y) port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; }; }; }; -- GitLab From d9bd3aea31aba94b5811776e0817a15ea4420e84 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:05 +0200 Subject: [PATCH 628/942] ASoC: dt-bindings: max98396: add voltage supplies The device is supplied with 3 core voltages (DVVDIO, DVDD, AVDD), and PVDD and/or VBAT. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-2-daniel@zonque.org Signed-off-by: Mark Brown --- .../bindings/sound/adi,max98396.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/adi,max98396.yaml b/Documentation/devicetree/bindings/sound/adi,max98396.yaml index ec4c10c2598a8..a23ac8036e1c2 100644 --- a/Documentation/devicetree/bindings/sound/adi,max98396.yaml +++ b/Documentation/devicetree/bindings/sound/adi,max98396.yaml @@ -24,6 +24,21 @@ properties: maxItems: 1 description: I2C address of the device. + avdd-supply: + description: A 1.8V supply that powers up the AVDD pin. + + dvdd-supply: + description: A 1.2V supply that powers up the DVDD pin. + + dvddio-supply: + description: A 1.2V or 1.8V supply that powers up the VDDIO pin. + + pvdd-supply: + description: A 3.0V to 20V supply that powers up the PVDD pin. + + vbat-supply: + description: A 3.3V to 5.5V supply that powers up the VBAT pin. + adi,vmon-slot-no: description: slot number of the voltage sense monitor $ref: "/schemas/types.yaml#/definitions/uint32" @@ -72,6 +87,10 @@ examples: max98396: amplifier@39 { compatible = "adi,max98396"; reg = <0x39>; + dvdd-supply = <®ulator_1v2>; + dvddio-supply = <®ulator_1v8>; + avdd-supply = <®ulator_1v8>; + pvdd-supply = <®ulator_pvdd>; adi,vmon-slot-no = <0>; adi,imon-slot-no = <1>; reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>; -- GitLab From 0ce44afd29768e893ff9112ba208271e0d558780 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:07 +0200 Subject: [PATCH 629/942] ASoC: dt-bindings: max98396: Document adi,bypass-slot-no This property allows to select the PCM data input channel that is routed to the speaker audio processing bypass path. The driver already implements this property. While at it, fix the default value for adi,imon-slot-no. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-4-daniel@zonque.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/adi,max98396.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/adi,max98396.yaml b/Documentation/devicetree/bindings/sound/adi,max98396.yaml index a23ac8036e1c2..8d2ef991db40f 100644 --- a/Documentation/devicetree/bindings/sound/adi,max98396.yaml +++ b/Documentation/devicetree/bindings/sound/adi,max98396.yaml @@ -51,13 +51,22 @@ properties: $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 15 - default: 0 + default: 1 adi,spkfb-slot-no: description: slot number of speaker DSP monitor $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 15 + default: 2 + + adi,bypass-slot-no: + description: + Selects the PCM data input channel that is routed to the speaker + audio processing bypass path. + $ref: "/schemas/types.yaml#/definitions/uint32" + minimum: 0 + maximum: 15 default: 0 adi,interleave-mode: -- GitLab From 703ee0557f8921c96e8c42f832b3bd69b7bfb262 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:08 +0200 Subject: [PATCH 630/942] ASoC: max98396: add voltage regulators The device has up to 5 potentially independent power supplies: AVDD, DVDD, DVVDIO, VBAT and PVDD. The former 3 are mandatory for the device to function. One of VBAT and PVDD should also be made available. Regulators are enabled during probe time and will stay active except when in suspend mode. Futher, the chip needs to be informed about the presence of VBAT through a bit in register 0x20a0. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-5-daniel@zonque.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 117 +++++++++++++++++++++++++++++++++++- sound/soc/codecs/max98396.h | 7 +++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 56eb62bb041f9..06ac637f26963 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -5,11 +5,18 @@ #include #include #include +#include #include #include #include #include "max98396.h" +static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = { + "avdd", + "dvdd", + "dvddio", +}; + static struct reg_default max98396_reg[] = { {MAX98396_R2000_SW_RESET, 0x00}, {MAX98396_R2001_INT_RAW1, 0x00}, @@ -1329,6 +1336,12 @@ static int max98396_probe(struct snd_soc_component *component) regmap_write(max98396->regmap, MAX98397_R2057_PCM_RX_SRC2, 0x10); } + /* Supply control */ + regmap_update_bits(max98396->regmap, + MAX98396_R20A0_AMP_SUPPLY_CTL, + MAX98396_AMP_SUPPLY_NOVBAT, + (max98396->vbat == NULL) ? + MAX98396_AMP_SUPPLY_NOVBAT : 0); /* Enable DC blocker */ regmap_update_bits(max98396->regmap, MAX98396_R2092_AMP_DSP_CFG, 1, 1); @@ -1424,12 +1437,38 @@ static int max98396_suspend(struct device *dev) regcache_cache_only(max98396->regmap, true); regcache_mark_dirty(max98396->regmap); + regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (max98396->pvdd) + regulator_disable(max98396->pvdd); + + if (max98396->vbat) + regulator_disable(max98396->vbat); + return 0; } static int max98396_resume(struct device *dev) { struct max98396_priv *max98396 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) + return ret; + + if (max98396->pvdd) { + ret = regulator_enable(max98396->pvdd); + if (ret < 0) + return ret; + } + + if (max98396->vbat) { + ret = regulator_enable(max98396->vbat); + if (ret < 0) + return ret; + } regcache_cache_only(max98396->regmap, false); max98396_reset(max98396, dev); @@ -1513,11 +1552,24 @@ static void max98396_read_device_property(struct device *dev, max98396->bypass_slot = 0; } +static void max98396_core_supplies_disable(void *priv) +{ + struct max98396_priv *max98396 = priv; + + regulator_bulk_disable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); +} + +static void max98396_supply_disable(void *r) +{ + regulator_disable((struct regulator *) r); +} + static int max98396_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max98396_priv *max98396 = NULL; - int ret, reg; + int i, ret, reg; max98396 = devm_kzalloc(&i2c->dev, sizeof(*max98396), GFP_KERNEL); @@ -1543,6 +1595,69 @@ static int max98396_i2c_probe(struct i2c_client *i2c, return ret; } + /* Obtain regulator supplies */ + for (i = 0; i < MAX98396_NUM_CORE_SUPPLIES; i++) + max98396->core_supplies[i].supply = max98396_core_supplies[i]; + + ret = devm_regulator_bulk_get(&i2c->dev, MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request core supplies: %d\n", ret); + return ret; + } + + max98396->vbat = devm_regulator_get_optional(&i2c->dev, "vbat"); + if (IS_ERR(max98396->vbat)) { + if (PTR_ERR(max98396->vbat) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + max98396->vbat = NULL; + } + + max98396->pvdd = devm_regulator_get_optional(&i2c->dev, "pvdd"); + if (IS_ERR(max98396->pvdd)) { + if (PTR_ERR(max98396->pvdd) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + max98396->pvdd = NULL; + } + + ret = regulator_bulk_enable(MAX98396_NUM_CORE_SUPPLIES, + max98396->core_supplies); + if (ret < 0) { + dev_err(&i2c->dev, "Unable to enable core supplies: %d", ret); + return ret; + } + + ret = devm_add_action_or_reset(&i2c->dev, max98396_core_supplies_disable, + max98396); + if (ret < 0) + return ret; + + if (max98396->pvdd) { + ret = regulator_enable(max98396->pvdd); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(&i2c->dev, + max98396_supply_disable, + max98396->pvdd); + if (ret < 0) + return ret; + } + + if (max98396->vbat) { + ret = regulator_enable(max98396->vbat); + if (ret < 0) + return ret; + + ret = devm_add_action_or_reset(&i2c->dev, + max98396_supply_disable, + max98396->vbat); + if (ret < 0) + return ret; + } + /* update interleave mode info */ if (device_property_read_bool(&i2c->dev, "adi,interleave_mode")) max98396->interleave_mode = true; diff --git a/sound/soc/codecs/max98396.h b/sound/soc/codecs/max98396.h index 694411038597b..8fa081f5d2d36 100644 --- a/sound/soc/codecs/max98396.h +++ b/sound/soc/codecs/max98396.h @@ -274,6 +274,9 @@ #define MAX98396_DSP_SPK_SAFE_EN_SHIFT (5) #define MAX98396_DSP_SPK_WB_FLT_EN_SHIFT (6) +/* MAX98396_R20A0_AMP_SUPPLY_CTL */ +#define MAX98396_AMP_SUPPLY_NOVBAT (0x1 << 0) + /* MAX98396_R20E0_IV_SENSE_PATH_CFG */ #define MAX98396_IV_SENSE_DCBLK_EN_MASK (0x3 << 0) #define MAX98396_IV_SENSE_DCBLK_EN_SHIFT (0) @@ -291,9 +294,13 @@ enum { CODEC_TYPE_MAX98397, }; +#define MAX98396_NUM_CORE_SUPPLIES 3 + struct max98396_priv { struct regmap *regmap; struct gpio_desc *reset_gpio; + struct regulator_bulk_data core_supplies[MAX98396_NUM_CORE_SUPPLIES]; + struct regulator *pvdd, *vbat; unsigned int v_slot; unsigned int i_slot; unsigned int bypass_slot; -- GitLab From a8c1dc9e8f01811b0c3fee65b9bc4773b2d00d96 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:09 +0200 Subject: [PATCH 631/942] ASoC: max98396: Improve some error prints Let's log what actually failed and log at some more places. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-6-daniel@zonque.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 06ac637f26963..faa81b4bb7095 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -372,7 +372,8 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) break; default: - dev_err(component->dev, "DAI invert mode unsupported\n"); + dev_err(component->dev, "DAI invert mode %d unsupported\n", + fmt & SND_SOC_DAIFMT_INV_MASK); return -EINVAL; } @@ -391,6 +392,8 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) format |= MAX98396_PCM_FORMAT_TDM_MODE0; break; default: + dev_err(component->dev, "DAI format %d unsupported\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); return -EINVAL; } @@ -461,8 +464,9 @@ static int max98396_set_clock(struct snd_soc_component *component, /* BCLK configuration */ value = max98396_get_bclk_sel(blr_clk_ratio); if (!value) { - dev_err(component->dev, "format unsupported %d\n", - params_format(params)); + dev_err(component->dev, + "blr_clk_ratio %d unsupported, format %d\n", + blr_clk_ratio, params_format(params)); return -EINVAL; } @@ -647,7 +651,7 @@ static int max98396_dai_tdm_slot(struct snd_soc_dai *dai, chan_sz = MAX98396_PCM_MODE_CFG_CHANSZ_32; break; default: - dev_err(component->dev, "format unsupported %d\n", + dev_err(component->dev, "slot width %d unsupported\n", slot_width); return -EINVAL; } -- GitLab From c529fd620b842c926ccc8cea913886d802c30f16 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:10 +0200 Subject: [PATCH 632/942] ASoC: max98396: Fix register access for PCM format settings max98396_dai_set_fmt() modifes register 2041 and touches bits in the mask 0x3a. Make sure to use the right mask for that operation. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-7-daniel@zonque.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index faa81b4bb7095..0a1d98279a3e3 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -349,12 +349,15 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_component *component = codec_dai->component; struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); - unsigned int format = 0; + unsigned int format_mask, format = 0; unsigned int bclk_pol = 0; int ret, status; int reg; bool update = false; + format_mask = MAX98396_PCM_MODE_CFG_FORMAT_MASK | + MAX98396_PCM_MODE_CFG_LRCLKEDGE; + dev_dbg(component->dev, "%s: fmt 0x%08X\n", __func__, fmt); switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -405,7 +408,7 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) ret = regmap_read(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, ®); if (ret < 0) return -EINVAL; - if (format != (reg & MAX98396_PCM_BCLKEDGE_BSEL_MASK)) { + if (format != (reg & format_mask)) { update = true; } else { ret = regmap_read(max98396->regmap, @@ -422,8 +425,7 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) regmap_update_bits(max98396->regmap, MAX98396_R2041_PCM_MODE_CFG, - MAX98396_PCM_BCLKEDGE_BSEL_MASK, - format); + format_mask, format); regmap_update_bits(max98396->regmap, MAX98396_R2042_PCM_CLK_SETUP, -- GitLab From f42924b49bf7935d21e2f2e98fdc9aa8dd176699 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Jun 2022 12:47:11 +0200 Subject: [PATCH 633/942] ASoC: max98396: Implement DSP speaker monitor Allow the selection of the TDM slot that is used to send back speaker monitor data. The DT property adi,spkfb-slot-no can be used to configure this setting which defaults to 2. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220624104712.1934484-8-daniel@zonque.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 8 ++++++++ sound/soc/codecs/max98396.h | 1 + 2 files changed, 9 insertions(+) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 0a1d98279a3e3..f28831f4e74b9 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -1377,6 +1377,9 @@ static int max98396_probe(struct snd_soc_component *component) regmap_write(max98396->regmap, MAX98396_R2045_PCM_TX_CTRL_2, max98396->i_slot); + regmap_write(max98396->regmap, + MAX98396_R204A_PCM_TX_CTRL_7, + max98396->spkfb_slot); if (max98396->v_slot < 8) if (max98396->device_id == CODEC_TYPE_MAX98396) @@ -1552,6 +1555,11 @@ static void max98396_read_device_property(struct device *dev, else max98396->i_slot = 1; + if (!device_property_read_u32(dev, "adi,spkfb-slot-no", &value)) + max98396->spkfb_slot = value & 0xF; + else + max98396->spkfb_slot = 2; + if (!device_property_read_u32(dev, "adi,bypass-slot-no", &value)) max98396->bypass_slot = value & 0xF; else diff --git a/sound/soc/codecs/max98396.h b/sound/soc/codecs/max98396.h index 8fa081f5d2d36..ff330ef615680 100644 --- a/sound/soc/codecs/max98396.h +++ b/sound/soc/codecs/max98396.h @@ -303,6 +303,7 @@ struct max98396_priv { struct regulator *pvdd, *vbat; unsigned int v_slot; unsigned int i_slot; + unsigned int spkfb_slot; unsigned int bypass_slot; bool interleave_mode; unsigned int ch_size; -- GitLab From 1c348f748b4dd7711c5564a8fce0842529498dff Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:15 +0100 Subject: [PATCH 634/942] ASoC: soc-component: Add legacy_dai_naming flag Historically, the legacy DAI naming scheme was applied to platform drivers and the newer scheme to CODEC drivers. During componentisation the core lost the knowledge of if a driver was a CODEC or platform, they were all now components. To continue to support the legacy naming on older platform drivers a flag was added to the snd_soc_component_driver structure, non_legacy_dai_naming, to indicate to use the new scheme and this was applied to all CODECs as part of the migration. However, a slight issue appears to be developing with respect to this flag being opt in for the non-legacy scheme, which presumably we want to be the primary scheme used. Many codec drivers appear to forget to include this flag: grep -l -r "snd_soc_component_driver" sound/soc/codecs/*.c | xargs grep -L "non_legacy_dai_naming" | wc 48 48 556 It would seem more sensible to change the flag to legacy_dai_naming making the new scheme opt out. As a first step this patch adds a new flag for this so that the users can be updated. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 5c4cfa70b018c..96c2f5fffc51e 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -179,6 +179,7 @@ struct snd_soc_component_driver { * analogue). */ unsigned int endianness:1; + unsigned int legacy_dai_naming:1; unsigned int non_legacy_dai_naming:1; /* this component uses topology and ignore machine driver FEs */ -- GitLab From ca68202098a4416501cc9b5d68a54de22d754766 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:16 +0100 Subject: [PATCH 635/942] soundwire: intel: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Acked-By: Vinod Koul Link: https://lore.kernel.org/r/20220623125250.2355471-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/soundwire/intel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 505c5ef061e3f..0268fa527c0c0 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1097,8 +1097,9 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = { }; static const struct snd_soc_component_driver dai_component = { - .name = "soundwire", - .suspend = intel_component_dais_suspend + .name = "soundwire", + .suspend = intel_component_dais_suspend, + .legacy_dai_naming = 1, }; static int intel_create_dai(struct sdw_cdns *cdns, -- GitLab From db827cb34ca38f4106f7c667bea3bbb48bc73552 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:17 +0100 Subject: [PATCH 636/942] drm/vc4: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Acked-by: Maxime Ripard Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/gpu/drm/vc4/vc4_hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 823d812f49829..3e3bd88745b7c 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1969,6 +1969,7 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data, static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = { .name = "vc4-hdmi-cpu-dai-component", + .legacy_dai_naming = 1, }; static int vc4_hdmi_audio_cpu_dai_probe(struct snd_soc_dai *dai) -- GitLab From 5f9d69986014945b826c712081678446c1f10fd7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:18 +0100 Subject: [PATCH 637/942] ASoC: img: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/img/img-i2s-in.c | 3 ++- sound/soc/img/img-i2s-out.c | 3 ++- sound/soc/img/img-parallel-out.c | 3 ++- sound/soc/img/img-spdif-in.c | 3 ++- sound/soc/img/img-spdif-out.c | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 97cab6d95b169..56bb7bbd3976c 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -386,7 +386,8 @@ static int img_i2s_in_dai_probe(struct snd_soc_dai *dai) } static const struct snd_soc_component_driver img_i2s_in_component = { - .name = "img-i2s-in" + .name = "img-i2s-in", + .legacy_dai_naming = 1, }; static int img_i2s_in_dma_prepare_slave_config(struct snd_pcm_substream *st, diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 9ec6fc528e2b4..e3c6e662aa867 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -394,7 +394,8 @@ static int img_i2s_out_dai_probe(struct snd_soc_dai *dai) } static const struct snd_soc_component_driver img_i2s_out_component = { - .name = "img-i2s-out" + .name = "img-i2s-out", + .legacy_dai_naming = 1, }; static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st, diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c index cd6a6a8257419..08506b05e2265 100644 --- a/sound/soc/img/img-parallel-out.c +++ b/sound/soc/img/img-parallel-out.c @@ -201,7 +201,8 @@ static struct snd_soc_dai_driver img_prl_out_dai = { }; static const struct snd_soc_component_driver img_prl_out_component = { - .name = "img-prl-out" + .name = "img-prl-out", + .legacy_dai_naming = 1, }; static int img_prl_out_probe(struct platform_device *pdev) diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c index a79d1ccaeec01..3f1d1a7e8735b 100644 --- a/sound/soc/img/img-spdif-in.c +++ b/sound/soc/img/img-spdif-in.c @@ -711,7 +711,8 @@ static struct snd_soc_dai_driver img_spdif_in_dai = { }; static const struct snd_soc_component_driver img_spdif_in_component = { - .name = "img-spdif-in" + .name = "img-spdif-in", + .legacy_dai_naming = 1, }; static int img_spdif_in_probe(struct platform_device *pdev) diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c index f7062eba2611a..983761d3fa7e6 100644 --- a/sound/soc/img/img-spdif-out.c +++ b/sound/soc/img/img-spdif-out.c @@ -316,7 +316,8 @@ static struct snd_soc_dai_driver img_spdif_out_dai = { }; static const struct snd_soc_component_driver img_spdif_out_component = { - .name = "img-spdif-out" + .name = "img-spdif-out", + .legacy_dai_naming = 1, }; static int img_spdif_out_probe(struct platform_device *pdev) -- GitLab From eeb021ee8fab0baae82e3784664666fd6b826e89 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:19 +0100 Subject: [PATCH 638/942] ASoC: spear: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-6-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/spear/spdif_in.c | 3 ++- sound/soc/spear/spdif_out.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 4b68d6ee75da4..4ad8b1fc713a7 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -172,7 +172,8 @@ static struct snd_soc_dai_driver spdif_in_dai = { }; static const struct snd_soc_component_driver spdif_in_component = { - .name = "spdif-in", + .name = "spdif-in", + .legacy_dai_naming = 1, }; static irqreturn_t spdif_in_irq(int irq, void *arg) diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 549295a6ed501..fb107c5790add 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -273,7 +273,8 @@ static struct snd_soc_dai_driver spdif_out_dai = { }; static const struct snd_soc_component_driver spdif_out_component = { - .name = "spdif-out", + .name = "spdif-out", + .legacy_dai_naming = 1, }; static int spdif_out_probe(struct platform_device *pdev) -- GitLab From 2bebc3b622c3c300eb3a3f603473429d8264c3b6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:20 +0100 Subject: [PATCH 639/942] ASoC: jz4740-i2c: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/jz4740/jz4740-i2s.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 446c5e0615649..79afac0c50038 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -498,9 +498,10 @@ static const struct i2s_soc_info jz4780_i2s_soc_info = { }; static const struct snd_soc_component_driver jz4740_i2s_component = { - .name = "jz4740-i2s", - .suspend = jz4740_i2s_suspend, - .resume = jz4740_i2s_resume, + .name = "jz4740-i2s", + .suspend = jz4740_i2s_suspend, + .resume = jz4740_i2s_resume, + .legacy_dai_naming = 1, }; static const struct of_device_id jz4740_of_matches[] = { -- GitLab From fe58b58330434ffad5fa0bc97e177aa93a9a6222 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:21 +0100 Subject: [PATCH 640/942] ASoC: ep93xx: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-8-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-ac97.c | 3 ++- sound/soc/cirrus/ep93xx-i2s.c | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 16f9bb283b5cb..37593abe60532 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -355,7 +355,8 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { }; static const struct snd_soc_component_driver ep93xx_ac97_component = { - .name = "ep93xx-ac97", + .name = "ep93xx-ac97", + .legacy_dai_naming = 1, }; static int ep93xx_ac97_probe(struct platform_device *pdev) diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 47959794353a7..982151330c896 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -422,9 +422,10 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = { }; static const struct snd_soc_component_driver ep93xx_i2s_component = { - .name = "ep93xx-i2s", - .suspend = ep93xx_i2s_suspend, - .resume = ep93xx_i2s_resume, + .name = "ep93xx-i2s", + .suspend = ep93xx_i2s_suspend, + .resume = ep93xx_i2s_resume, + .legacy_dai_naming = 1, }; static int ep93xx_i2s_probe(struct platform_device *pdev) -- GitLab From 36f07985f81b7482dceb8e650d2ce1f0222294d1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:22 +0100 Subject: [PATCH 641/942] ASoC: stm32: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-9-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_adfsdm.c | 1 + sound/soc/stm/stm32_i2s.c | 1 + sound/soc/stm/stm32_sai_sub.c | 1 + sound/soc/stm/stm32_spdifrx.c | 1 + 4 files changed, 4 insertions(+) diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c index 122805160e70b..04f2912e14181 100644 --- a/sound/soc/stm/stm32_adfsdm.c +++ b/sound/soc/stm/stm32_adfsdm.c @@ -149,6 +149,7 @@ static const struct snd_soc_dai_driver stm32_adfsdm_dai = { static const struct snd_soc_component_driver stm32_adfsdm_dai_component = { .name = "stm32_dfsdm_audio", + .legacy_dai_naming = 1, }; static void stm32_memcpy_32to16(void *dest, const void *src, size_t n) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 32d885f84a922..6aafe793eec44 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -978,6 +978,7 @@ static const struct snd_dmaengine_pcm_config stm32_i2s_pcm_config = { static const struct snd_soc_component_driver stm32_i2s_component = { .name = "stm32-i2s", + .legacy_dai_naming = 1, }; static void stm32_i2s_dai_init(struct snd_soc_pcm_stream *stream, diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 03cc6d12d18bb..eb31b49e65978 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1336,6 +1336,7 @@ static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config_spdif = { static const struct snd_soc_component_driver stm32_component = { .name = "stm32-sai", + .legacy_dai_naming = 1, }; static const struct of_device_id stm32_sai_sub_ids[] = { diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 6f7882c4fe6ad..0f71467567176 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -888,6 +888,7 @@ static const struct snd_pcm_hardware stm32_spdifrx_pcm_hw = { static const struct snd_soc_component_driver stm32_spdifrx_component = { .name = "stm32-spdifrx", + .legacy_dai_naming = 1, }; static const struct snd_dmaengine_pcm_config stm32_spdifrx_pcm_config = { -- GitLab From b9a0db0ae5247d92f379107a9c479f881914999d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:23 +0100 Subject: [PATCH 642/942] ASoC: bcm: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-10-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/bcm/bcm2835-i2s.c | 3 ++- sound/soc/bcm/bcm63xx-i2s-whistler.c | 1 + sound/soc/bcm/cygnus-ssp.c | 7 ++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index e39c8d9f40995..f4d84774dac72 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -821,7 +821,8 @@ static const struct regmap_config bcm2835_regmap_config = { }; static const struct snd_soc_component_driver bcm2835_i2s_component = { - .name = "bcm2835-i2s-comp", + .name = "bcm2835-i2s-comp", + .legacy_dai_naming = 1, }; static int bcm2835_i2s_probe(struct platform_device *pdev) diff --git a/sound/soc/bcm/bcm63xx-i2s-whistler.c b/sound/soc/bcm/bcm63xx-i2s-whistler.c index 527caf430715b..2da1384ffe911 100644 --- a/sound/soc/bcm/bcm63xx-i2s-whistler.c +++ b/sound/soc/bcm/bcm63xx-i2s-whistler.c @@ -218,6 +218,7 @@ static struct snd_soc_dai_driver bcm63xx_i2s_dai = { static const struct snd_soc_component_driver bcm63xx_i2s_component = { .name = "bcm63xx", + .legacy_dai_naming = 1, }; static int bcm63xx_i2s_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c index 4bfa2d715ff4d..8b7a215730707 100644 --- a/sound/soc/bcm/cygnus-ssp.c +++ b/sound/soc/bcm/cygnus-ssp.c @@ -1201,9 +1201,10 @@ static const struct snd_soc_dai_driver cygnus_spdif_dai_info = { static struct snd_soc_dai_driver cygnus_ssp_dai[CYGNUS_MAX_PORTS]; static const struct snd_soc_component_driver cygnus_ssp_component = { - .name = "cygnus-audio", - .suspend = cygnus_ssp_suspend, - .resume = cygnus_ssp_resume, + .name = "cygnus-audio", + .suspend = cygnus_ssp_suspend, + .resume = cygnus_ssp_resume, + .legacy_dai_naming = 1, }; /* -- GitLab From f712ff57a27090baff61f92bdb6521e8781d5e6b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:24 +0100 Subject: [PATCH 643/942] ASoC: sh: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-11-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sh/hac.c | 3 ++- sound/soc/sh/rcar/core.c | 11 ++++++----- sound/soc/sh/rz-ssi.c | 9 +++++---- sound/soc/sh/siu_pcm.c | 17 +++++++++-------- sound/soc/sh/ssi.c | 3 ++- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 475fc984f8c51..46d145cbaf297 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -307,7 +307,8 @@ static struct snd_soc_dai_driver sh4_hac_dai[] = { }; static const struct snd_soc_component_driver sh4_hac_component = { - .name = "sh4-hac", + .name = "sh4-hac", + .legacy_dai_naming = 1, }; static int hac_soc_platform_probe(struct platform_device *pdev) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index a4180dc5a59ba..4973f94a21446 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1813,11 +1813,12 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, * snd_soc_component */ static const struct snd_soc_component_driver rsnd_soc_component = { - .name = "rsnd", - .probe = rsnd_debugfs_probe, - .hw_params = rsnd_hw_params, - .hw_free = rsnd_hw_free, - .pointer = rsnd_pointer, + .name = "rsnd", + .probe = rsnd_debugfs_probe, + .hw_params = rsnd_hw_params, + .hw_free = rsnd_hw_free, + .pointer = rsnd_pointer, + .legacy_dai_naming = 1, }; static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index beaf1a8d6da10..0d0594a0e4f6c 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -906,10 +906,11 @@ static struct snd_soc_dai_driver rz_ssi_soc_dai[] = { }; static const struct snd_soc_component_driver rz_ssi_soc_component = { - .name = "rz-ssi", - .open = rz_ssi_pcm_open, - .pointer = rz_ssi_pcm_pointer, - .pcm_construct = rz_ssi_pcm_new, + .name = "rz-ssi", + .open = rz_ssi_pcm_open, + .pointer = rz_ssi_pcm_pointer, + .pcm_construct = rz_ssi_pcm_new, + .legacy_dai_naming = 1, }; static int rz_ssi_probe(struct platform_device *pdev) diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 0a8a3c314a73d..f15ff36e79345 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -540,13 +540,14 @@ static void siu_pcm_free(struct snd_soc_component *component, } const struct snd_soc_component_driver siu_component = { - .name = DRV_NAME, - .open = siu_pcm_open, - .close = siu_pcm_close, - .prepare = siu_pcm_prepare, - .trigger = siu_pcm_trigger, - .pointer = siu_pcm_pointer_dma, - .pcm_construct = siu_pcm_new, - .pcm_destruct = siu_pcm_free, + .name = DRV_NAME, + .open = siu_pcm_open, + .close = siu_pcm_close, + .prepare = siu_pcm_prepare, + .trigger = siu_pcm_trigger, + .pointer = siu_pcm_pointer_dma, + .pcm_construct = siu_pcm_new, + .pcm_destruct = siu_pcm_free, + .legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(siu_component); diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index bf7a3c69920a6..96cf523c22734 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -377,7 +377,8 @@ static struct snd_soc_dai_driver sh4_ssi_dai[] = { }; static const struct snd_soc_component_driver sh4_ssi_component = { - .name = "sh4-ssi", + .name = "sh4-ssi", + .legacy_dai_naming = 1, }; static int sh4_soc_dai_probe(struct platform_device *pdev) -- GitLab From 3172582c10540d4bf1caac1c39c903793648db8f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:25 +0100 Subject: [PATCH 644/942] ASoC: tegra: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-12-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_ac97.c | 3 ++- sound/soc/tegra/tegra20_i2s.c | 3 ++- sound/soc/tegra/tegra20_spdif.c | 1 + sound/soc/tegra/tegra30_i2s.c | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index c454a34c15c4c..e17375c6cddb9 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -239,7 +239,8 @@ static struct snd_soc_dai_driver tegra20_ac97_dai = { }; static const struct snd_soc_component_driver tegra20_ac97_component = { - .name = DRV_NAME, + .name = DRV_NAME, + .legacy_dai_naming = 1, }; static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 2e1a726602f02..fff0cd6588f56 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -338,7 +338,8 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { }; static const struct snd_soc_component_driver tegra20_i2s_component = { - .name = DRV_NAME, + .name = DRV_NAME, + .legacy_dai_naming = 1, }; static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 64c2f304f2542..ca7b222e07d05 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -264,6 +264,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { static const struct snd_soc_component_driver tegra20_spdif_component = { .name = "tegra20-spdif", + .legacy_dai_naming = 1, }; static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 3aa157c82ae23..10cd37096fb33 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -331,7 +331,8 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { }; static const struct snd_soc_component_driver tegra30_i2s_component = { - .name = DRV_NAME, + .name = DRV_NAME, + .legacy_dai_naming = 1, }; static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) -- GitLab From bf6dacb784f0efb5a225f6560d693fa71c7fda64 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:26 +0100 Subject: [PATCH 645/942] ASoC: hisilicon: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/hisilicon/hi6210-i2s.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index 689ae13f34f5b..27219a9e7d0d8 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c @@ -539,6 +539,7 @@ static const struct snd_soc_dai_driver hi6210_i2s_dai_init = { static const struct snd_soc_component_driver hi6210_i2s_i2s_comp = { .name = "hi6210_i2s-i2s", + .legacy_dai_naming = 1, }; static int hi6210_i2s_probe(struct platform_device *pdev) -- GitLab From bd486b070b1e24b38b3d6d7e33abffe4a18e3296 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:27 +0100 Subject: [PATCH 646/942] ASoC: xilinx: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-14-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/xilinx/xlnx_formatter_pcm.c | 16 ++++++++-------- sound/soc/xilinx/xlnx_i2s.c | 1 + sound/soc/xilinx/xlnx_spdif.c | 1 + 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/soc/xilinx/xlnx_formatter_pcm.c b/sound/soc/xilinx/xlnx_formatter_pcm.c index 5c4158069a5a8..f5ac0aa312d6e 100644 --- a/sound/soc/xilinx/xlnx_formatter_pcm.c +++ b/sound/soc/xilinx/xlnx_formatter_pcm.c @@ -575,14 +575,14 @@ static int xlnx_formatter_pcm_new(struct snd_soc_component *component, } static const struct snd_soc_component_driver xlnx_asoc_component = { - .name = DRV_NAME, - .set_sysclk = xlnx_formatter_set_sysclk, - .open = xlnx_formatter_pcm_open, - .close = xlnx_formatter_pcm_close, - .hw_params = xlnx_formatter_pcm_hw_params, - .trigger = xlnx_formatter_pcm_trigger, - .pointer = xlnx_formatter_pcm_pointer, - .pcm_construct = xlnx_formatter_pcm_new, + .name = DRV_NAME, + .set_sysclk = xlnx_formatter_set_sysclk, + .open = xlnx_formatter_pcm_open, + .close = xlnx_formatter_pcm_close, + .hw_params = xlnx_formatter_pcm_hw_params, + .trigger = xlnx_formatter_pcm_trigger, + .pointer = xlnx_formatter_pcm_pointer, + .pcm_construct = xlnx_formatter_pcm_new, }; static int xlnx_formatter_pcm_probe(struct platform_device *pdev) diff --git a/sound/soc/xilinx/xlnx_i2s.c b/sound/soc/xilinx/xlnx_i2s.c index 4cc6ee7c81a32..9de92d35e30ee 100644 --- a/sound/soc/xilinx/xlnx_i2s.c +++ b/sound/soc/xilinx/xlnx_i2s.c @@ -158,6 +158,7 @@ static const struct snd_soc_dai_ops xlnx_i2s_dai_ops = { static const struct snd_soc_component_driver xlnx_i2s_component = { .name = DRV_NAME, + .legacy_dai_naming = 1, }; static const struct of_device_id xlnx_i2s_of_match[] = { diff --git a/sound/soc/xilinx/xlnx_spdif.c b/sound/soc/xilinx/xlnx_spdif.c index cba0e868a7d77..7342048e98751 100644 --- a/sound/soc/xilinx/xlnx_spdif.c +++ b/sound/soc/xilinx/xlnx_spdif.c @@ -226,6 +226,7 @@ static struct snd_soc_dai_driver xlnx_spdif_rx_dai = { static const struct snd_soc_component_driver xlnx_spdif_component = { .name = "xlnx-spdif", + .legacy_dai_naming = 1, }; static const struct of_device_id xlnx_spdif_of_match[] = { -- GitLab From f450b5dbce413b276e6c9215b40868b905c7b634 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:28 +0100 Subject: [PATCH 647/942] ASoC: sunxi: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-15-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 3 ++- sound/soc/sunxi/sun4i-i2s.c | 3 ++- sound/soc/sunxi/sun4i-spdif.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 53e3f43816cc2..bc634962a57ee 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -1234,7 +1234,8 @@ static const struct snd_soc_component_driver sun8i_a23_codec_codec = { }; static const struct snd_soc_component_driver sun4i_codec_component = { - .name = "sun4i-codec", + .name = "sun4i-codec", + .legacy_dai_naming = 1, }; #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 5be33d07361bd..6028871825bae 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1125,7 +1125,8 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = { }; static const struct snd_soc_component_driver sun4i_i2s_component = { - .name = "sun4i-dai", + .name = "sun4i-dai", + .legacy_dai_naming = 1, }; static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index 17090f43150e0..bcceebca915ac 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -583,7 +583,8 @@ static const struct of_device_id sun4i_spdif_of_match[] = { MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); static const struct snd_soc_component_driver sun4i_spdif_component = { - .name = "sun4i-spdif", + .name = "sun4i-spdif", + .legacy_dai_naming = 1, }; static int sun4i_spdif_runtime_suspend(struct device *dev) -- GitLab From 725cf3bc6009b7fa156b73982eddf23c71767fbb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:29 +0100 Subject: [PATCH 648/942] ASoC: Intel: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-16-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/intel/keembay/kmb_platform.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index d10881fedc8bb..b4893365d01d5 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -388,15 +388,17 @@ static snd_pcm_uframes_t kmb_pcm_pointer(struct snd_soc_component *component, } static const struct snd_soc_component_driver kmb_component = { - .name = "kmb", - .pcm_construct = kmb_platform_pcm_new, - .open = kmb_pcm_open, - .trigger = kmb_pcm_trigger, - .pointer = kmb_pcm_pointer, + .name = "kmb", + .pcm_construct = kmb_platform_pcm_new, + .open = kmb_pcm_open, + .trigger = kmb_pcm_trigger, + .pointer = kmb_pcm_pointer, + .legacy_dai_naming = 1, }; static const struct snd_soc_component_driver kmb_component_dma = { - .name = "kmb", + .name = "kmb", + .legacy_dai_naming = 1, }; static int kmb_probe(struct snd_soc_dai *cpu_dai) -- GitLab From d8572da099247860e97b27a7fddc9d80a71b8c25 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:30 +0100 Subject: [PATCH 649/942] ASoC: meson: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-17-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/meson/axg-frddr.c | 3 +++ sound/soc/meson/axg-pdm.c | 4 +++- sound/soc/meson/axg-spdifin.c | 1 + sound/soc/meson/axg-spdifout.c | 1 + sound/soc/meson/axg-toddr.c | 3 +++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/soc/meson/axg-frddr.c b/sound/soc/meson/axg-frddr.c index 37f4bb3469b5c..61f9d417fd608 100644 --- a/sound/soc/meson/axg-frddr.c +++ b/sound/soc/meson/axg-frddr.c @@ -161,6 +161,7 @@ static const struct snd_soc_component_driver axg_frddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data axg_frddr_match_data = { @@ -286,6 +287,7 @@ static const struct snd_soc_component_driver g12a_frddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data g12a_frddr_match_data = { @@ -356,6 +358,7 @@ static const struct snd_soc_component_driver sm1_frddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data sm1_frddr_match_data = { diff --git a/sound/soc/meson/axg-pdm.c b/sound/soc/meson/axg-pdm.c index 672e43a9729dc..88ac58272f95b 100644 --- a/sound/soc/meson/axg-pdm.c +++ b/sound/soc/meson/axg-pdm.c @@ -457,7 +457,9 @@ static struct snd_soc_dai_driver axg_pdm_dai_drv = { .remove = axg_pdm_dai_remove, }; -static const struct snd_soc_component_driver axg_pdm_component_drv = {}; +static const struct snd_soc_component_driver axg_pdm_component_drv = { + .legacy_dai_naming = 1, +}; static const struct regmap_config axg_pdm_regmap_cfg = { .reg_bits = 32, diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c index 4ba44e0d65d9f..e2cc4c4be7586 100644 --- a/sound/soc/meson/axg-spdifin.c +++ b/sound/soc/meson/axg-spdifin.c @@ -390,6 +390,7 @@ static const struct snd_kcontrol_new axg_spdifin_controls[] = { static const struct snd_soc_component_driver axg_spdifin_component_drv = { .controls = axg_spdifin_controls, .num_controls = ARRAY_SIZE(axg_spdifin_controls), + .legacy_dai_naming = 1, }; static const struct regmap_config axg_spdifin_regmap_cfg = { diff --git a/sound/soc/meson/axg-spdifout.c b/sound/soc/meson/axg-spdifout.c index 3960d082e1436..e8a12f15f3b4a 100644 --- a/sound/soc/meson/axg-spdifout.c +++ b/sound/soc/meson/axg-spdifout.c @@ -383,6 +383,7 @@ static const struct snd_soc_component_driver axg_spdifout_component_drv = { .dapm_routes = axg_spdifout_dapm_routes, .num_dapm_routes = ARRAY_SIZE(axg_spdifout_dapm_routes), .set_bias_level = axg_spdifout_set_bias_level, + .legacy_dai_naming = 1, }; static const struct regmap_config axg_spdifout_regmap_cfg = { diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c index d6adf7edea41f..e9208e74e9659 100644 --- a/sound/soc/meson/axg-toddr.c +++ b/sound/soc/meson/axg-toddr.c @@ -182,6 +182,7 @@ static const struct snd_soc_component_driver axg_toddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data axg_toddr_match_data = { @@ -242,6 +243,7 @@ static const struct snd_soc_component_driver g12a_toddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data g12a_toddr_match_data = { @@ -312,6 +314,7 @@ static const struct snd_soc_component_driver sm1_toddr_component_drv = { .hw_free = axg_fifo_pcm_hw_free, .pointer = axg_fifo_pcm_pointer, .trigger = axg_fifo_pcm_trigger, + .legacy_dai_naming = 1, }; static const struct axg_fifo_match_data sm1_toddr_match_data = { -- GitLab From ad483da7b0a17fdf4df0bd75b2cf29b5650ca2f7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:31 +0100 Subject: [PATCH 650/942] ASoC: sti-uniperf: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-18-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sti/sti_uniperif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c index 34668fe3909d1..a4d74d1e3c240 100644 --- a/sound/soc/sti/sti_uniperif.c +++ b/sound/soc/sti/sti_uniperif.c @@ -376,7 +376,8 @@ static const struct snd_soc_dai_driver sti_uniperiph_dai_template = { static const struct snd_soc_component_driver sti_uniperiph_dai_component = { .name = "sti_cpu_dai", .suspend = sti_uniperiph_suspend, - .resume = sti_uniperiph_resume + .resume = sti_uniperiph_resume, + .legacy_dai_naming = 1, }; static int sti_uniperiph_cpu_dai_of(struct device_node *node, -- GitLab From 0bc1e7d1fc3c50cf1eb62cd3c8d2b73c5f6d83fe Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:32 +0100 Subject: [PATCH 651/942] ASoC: amd: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-19-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-platform.c | 15 ++++++++------- sound/soc/amd/raven/acp3x-i2s.c | 3 ++- sound/soc/amd/renoir/acp3x-pdm-dma.c | 13 +++++++------ sound/soc/amd/vangogh/acp5x-i2s.c | 1 + sound/soc/amd/yc/acp6x-pdm-dma.c | 13 +++++++------ 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 65a809e2c29ff..3c4fd8b805891 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -267,13 +267,14 @@ static int acp_dma_close(struct snd_soc_component *component, } static const struct snd_soc_component_driver acp_pcm_component = { - .name = DRV_NAME, - .open = acp_dma_open, - .close = acp_dma_close, - .hw_params = acp_dma_hw_params, - .pointer = acp_dma_pointer, - .mmap = acp_dma_mmap, - .pcm_construct = acp_dma_new, + .name = DRV_NAME, + .open = acp_dma_open, + .close = acp_dma_close, + .hw_params = acp_dma_hw_params, + .pointer = acp_dma_pointer, + .mmap = acp_dma_mmap, + .pcm_construct = acp_dma_new, + .legacy_dai_naming = 1, }; int acp_platform_register(struct device *dev) diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c index de6f70d7ef364..aa38cef1776da 100644 --- a/sound/soc/amd/raven/acp3x-i2s.c +++ b/sound/soc/amd/raven/acp3x-i2s.c @@ -257,7 +257,8 @@ static const struct snd_soc_dai_ops acp3x_i2s_dai_ops = { }; static const struct snd_soc_component_driver acp3x_dai_component = { - .name = DRV_NAME, + .name = DRV_NAME, + .legacy_dai_naming = 1, }; static struct snd_soc_dai_driver acp3x_i2s_dai = { diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index 8c42345ee41e9..7203c6488df0e 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -363,12 +363,13 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = { }; static const struct snd_soc_component_driver acp_pdm_component = { - .name = DRV_NAME, - .open = acp_pdm_dma_open, - .close = acp_pdm_dma_close, - .hw_params = acp_pdm_dma_hw_params, - .pointer = acp_pdm_dma_pointer, - .pcm_construct = acp_pdm_dma_new, + .name = DRV_NAME, + .open = acp_pdm_dma_open, + .close = acp_pdm_dma_close, + .hw_params = acp_pdm_dma_hw_params, + .pointer = acp_pdm_dma_pointer, + .pcm_construct = acp_pdm_dma_new, + .legacy_dai_naming = 1, }; static int acp_pdm_audio_probe(struct platform_device *pdev) diff --git a/sound/soc/amd/vangogh/acp5x-i2s.c b/sound/soc/amd/vangogh/acp5x-i2s.c index 72c8c68e59336..773e96f1b4dd6 100644 --- a/sound/soc/amd/vangogh/acp5x-i2s.c +++ b/sound/soc/amd/vangogh/acp5x-i2s.c @@ -345,6 +345,7 @@ static const struct snd_soc_dai_ops acp5x_i2s_dai_ops = { static const struct snd_soc_component_driver acp5x_dai_component = { .name = "acp5x-i2s", + .legacy_dai_naming = 1, }; static struct snd_soc_dai_driver acp5x_i2s_dai = { diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c index 7e66393e41535..acecd6a4ec4b1 100644 --- a/sound/soc/amd/yc/acp6x-pdm-dma.c +++ b/sound/soc/amd/yc/acp6x-pdm-dma.c @@ -335,12 +335,13 @@ static struct snd_soc_dai_driver acp6x_pdm_dai_driver = { }; static const struct snd_soc_component_driver acp6x_pdm_component = { - .name = DRV_NAME, - .open = acp6x_pdm_dma_open, - .close = acp6x_pdm_dma_close, - .hw_params = acp6x_pdm_dma_hw_params, - .pointer = acp6x_pdm_dma_pointer, - .pcm_construct = acp6x_pdm_dma_new, + .name = DRV_NAME, + .open = acp6x_pdm_dma_open, + .close = acp6x_pdm_dma_close, + .hw_params = acp6x_pdm_dma_hw_params, + .pointer = acp6x_pdm_dma_pointer, + .pcm_construct = acp6x_pdm_dma_new, + .legacy_dai_naming = 1, }; static int acp6x_pdm_audio_probe(struct platform_device *pdev) -- GitLab From 7593e00807fb62e9f5e7367fc2500428cc317ff0 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:33 +0100 Subject: [PATCH 652/942] ASoC: atmel: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-20-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-classd.c | 1 + sound/soc/atmel/atmel-i2s.c | 3 ++- sound/soc/atmel/atmel-pdmic.c | 1 + sound/soc/atmel/atmel_ssc_dai.c | 7 ++++--- sound/soc/atmel/mchp-i2s-mcc.c | 3 ++- sound/soc/atmel/mchp-pdmc.c | 1 + sound/soc/atmel/mchp-spdifrx.c | 3 ++- sound/soc/atmel/mchp-spdiftx.c | 3 ++- 8 files changed, 15 insertions(+), 7 deletions(-) diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 74b7b2611aa70..87d6d6ed026b3 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -458,6 +458,7 @@ static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, + .legacy_dai_naming = 1, }; /* ASoC sound card */ diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c index ba56d6ac7e571..425d66edbf867 100644 --- a/sound/soc/atmel/atmel-i2s.c +++ b/sound/soc/atmel/atmel-i2s.c @@ -564,7 +564,8 @@ static struct snd_soc_dai_driver atmel_i2s_dai = { }; static const struct snd_soc_component_driver atmel_i2s_component = { - .name = "atmel-i2s", + .name = "atmel-i2s", + .legacy_dai_naming = 1, }; static int atmel_i2s_sama5d2_mck_init(struct atmel_i2s_dev *dev, diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index ea34efac2fff5..77ff12baead5b 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c @@ -481,6 +481,7 @@ static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, + .legacy_dai_naming = 1, }; /* ASoC sound card */ diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index c92905e343e7e..8aae0beadcfe4 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -858,9 +858,10 @@ static struct snd_soc_dai_driver atmel_ssc_dai = { }; static const struct snd_soc_component_driver atmel_ssc_component = { - .name = "atmel-ssc", - .suspend = atmel_ssc_suspend, - .resume = atmel_ssc_resume, + .name = "atmel-ssc", + .suspend = atmel_ssc_suspend, + .resume = atmel_ssc_resume, + .legacy_dai_naming = 1, }; static int asoc_ssc_init(struct device *dev) diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c index 269eab56b6dd9..6dfb96c576ff3 100644 --- a/sound/soc/atmel/mchp-i2s-mcc.c +++ b/sound/soc/atmel/mchp-i2s-mcc.c @@ -928,7 +928,8 @@ static struct snd_soc_dai_driver mchp_i2s_mcc_dai = { }; static const struct snd_soc_component_driver mchp_i2s_mcc_component = { - .name = "mchp-i2s-mcc", + .name = "mchp-i2s-mcc", + .legacy_dai_naming = 1, }; #ifdef CONFIG_OF diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index b9f6370594482..aba7c5cde62c6 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -423,6 +423,7 @@ static const struct snd_soc_component_driver mchp_pdmc_dai_component = { .num_controls = ARRAY_SIZE(mchp_pdmc_snd_controls), .open = &mchp_pdmc_open, .close = &mchp_pdmc_close, + .legacy_dai_naming = 1, }; static const unsigned int mchp_pdmc_1mic[] = {1}; diff --git a/sound/soc/atmel/mchp-spdifrx.c b/sound/soc/atmel/mchp-spdifrx.c index 5fc968483f2c8..0d37b78b94a09 100644 --- a/sound/soc/atmel/mchp-spdifrx.c +++ b/sound/soc/atmel/mchp-spdifrx.c @@ -846,7 +846,8 @@ static struct snd_soc_dai_driver mchp_spdifrx_dai = { }; static const struct snd_soc_component_driver mchp_spdifrx_component = { - .name = "mchp-spdifrx", + .name = "mchp-spdifrx", + .legacy_dai_naming = 1, }; static const struct of_device_id mchp_spdifrx_dt_ids[] = { diff --git a/sound/soc/atmel/mchp-spdiftx.c b/sound/soc/atmel/mchp-spdiftx.c index d243800464352..78d5bcf0819a3 100644 --- a/sound/soc/atmel/mchp-spdiftx.c +++ b/sound/soc/atmel/mchp-spdiftx.c @@ -753,7 +753,8 @@ static struct snd_soc_dai_driver mchp_spdiftx_dai = { }; static const struct snd_soc_component_driver mchp_spdiftx_component = { - .name = "mchp-spdiftx", + .name = "mchp-spdiftx", + .legacy_dai_naming = 1, }; static const struct of_device_id mchp_spdiftx_dt_ids[] = { -- GitLab From 1e63fcc74ace9824f3529eeabbb8f1881a7d3800 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:34 +0100 Subject: [PATCH 653/942] ASoC: fsl: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-21-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_aud2htx.c | 3 ++- sound/soc/fsl/fsl_easrc.c | 7 ++++--- sound/soc/fsl/fsl_esai.c | 3 ++- sound/soc/fsl/fsl_rpmsg.c | 3 ++- sound/soc/fsl/fsl_sai.c | 3 ++- sound/soc/fsl/fsl_spdif.c | 3 ++- sound/soc/fsl/fsl_ssi.c | 1 + sound/soc/fsl/fsl_xcvr.c | 3 ++- sound/soc/fsl/mpc5200_psc_i2s.c | 3 ++- 9 files changed, 19 insertions(+), 10 deletions(-) diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c index 422922146f2a5..873295f59ad7b 100644 --- a/sound/soc/fsl/fsl_aud2htx.c +++ b/sound/soc/fsl/fsl_aud2htx.c @@ -103,7 +103,8 @@ static struct snd_soc_dai_driver fsl_aud2htx_dai = { }; static const struct snd_soc_component_driver fsl_aud2htx_component = { - .name = "fsl-aud2htx", + .name = "fsl-aud2htx", + .legacy_dai_naming = 1, }; static const struct reg_default fsl_aud2htx_reg_defaults[] = { diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index be14f84796cb4..ea96b0fb6b202 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -1572,9 +1572,10 @@ static struct snd_soc_dai_driver fsl_easrc_dai = { }; static const struct snd_soc_component_driver fsl_easrc_component = { - .name = "fsl-easrc-dai", - .controls = fsl_easrc_snd_controls, - .num_controls = ARRAY_SIZE(fsl_easrc_snd_controls), + .name = "fsl-easrc-dai", + .controls = fsl_easrc_snd_controls, + .num_controls = ARRAY_SIZE(fsl_easrc_snd_controls), + .legacy_dai_naming = 1, }; static const struct reg_default fsl_easrc_reg_defaults[] = { diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 75f7807df29af..5c21fc490fce1 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -824,7 +824,8 @@ static struct snd_soc_dai_driver fsl_esai_dai = { }; static const struct snd_soc_component_driver fsl_esai_component = { - .name = "fsl-esai", + .name = "fsl-esai", + .legacy_dai_naming = 1, }; static const struct reg_default fsl_esai_reg_defaults[] = { diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c index 19fd312508839..bf94838bdbefe 100644 --- a/sound/soc/fsl/fsl_rpmsg.c +++ b/sound/soc/fsl/fsl_rpmsg.c @@ -135,7 +135,8 @@ static struct snd_soc_dai_driver fsl_rpmsg_dai = { }; static const struct snd_soc_component_driver fsl_component = { - .name = "fsl-rpmsg", + .name = "fsl-rpmsg", + .legacy_dai_naming = 1, }; static const struct fsl_rpmsg_soc_data imx7ulp_data = { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4f5bd9597c746..68b5b488deebd 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -767,7 +767,8 @@ static struct snd_soc_dai_driver fsl_sai_dai_template = { }; static const struct snd_soc_component_driver fsl_component = { - .name = "fsl-sai", + .name = "fsl-sai", + .legacy_dai_naming = 1, }; static struct reg_default fsl_sai_reg_defaults_ofs0[] = { diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 42d11aca38a10..0504431792cf9 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1237,7 +1237,8 @@ static struct snd_soc_dai_driver fsl_spdif_dai = { }; static const struct snd_soc_component_driver fsl_spdif_component = { - .name = "fsl-spdif", + .name = "fsl-spdif", + .legacy_dai_naming = 1, }; /* FSL SPDIF REGMAP */ diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7dd0c48cd9ae4..c9e0e31d5b34d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1182,6 +1182,7 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = { static const struct snd_soc_component_driver fsl_ssi_component = { .name = "fsl-ssi", + .legacy_dai_naming = 1, }; static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 55e640cba87d0..c043efe4548d1 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -911,7 +911,8 @@ static struct snd_soc_dai_driver fsl_xcvr_dai = { }; static const struct snd_soc_component_driver fsl_xcvr_comp = { - .name = "fsl-xcvr-dai", + .name = "fsl-xcvr-dai", + .legacy_dai_naming = 1, }; static const struct reg_default fsl_xcvr_reg_defaults[] = { diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 3149d59ae968d..73f3e61f208a7 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -148,7 +148,8 @@ static struct snd_soc_dai_driver psc_i2s_dai[] = {{ } }; static const struct snd_soc_component_driver psc_i2s_component = { - .name = "mpc5200-i2s", + .name = "mpc5200-i2s", + .legacy_dai_naming = 1, }; /* --------------------------------------------------------------------- -- GitLab From f257dea1c589fa3f558502b3ac7b1c09699a73ab Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:35 +0100 Subject: [PATCH 654/942] ASoC: xtensa: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-22-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/xtensa/xtfpga-i2s.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sound/soc/xtensa/xtfpga-i2s.c b/sound/soc/xtensa/xtfpga-i2s.c index 8bd1215460327..a8f156540b500 100644 --- a/sound/soc/xtensa/xtfpga-i2s.c +++ b/sound/soc/xtensa/xtfpga-i2s.c @@ -475,13 +475,14 @@ static int xtfpga_pcm_new(struct snd_soc_component *component, } static const struct snd_soc_component_driver xtfpga_i2s_component = { - .name = DRV_NAME, - .open = xtfpga_pcm_open, - .close = xtfpga_pcm_close, - .hw_params = xtfpga_pcm_hw_params, - .trigger = xtfpga_pcm_trigger, - .pointer = xtfpga_pcm_pointer, - .pcm_construct = xtfpga_pcm_new, + .name = DRV_NAME, + .open = xtfpga_pcm_open, + .close = xtfpga_pcm_close, + .hw_params = xtfpga_pcm_hw_params, + .trigger = xtfpga_pcm_trigger, + .pointer = xtfpga_pcm_pointer, + .pcm_construct = xtfpga_pcm_new, + .legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops xtfpga_i2s_dai_ops = { -- GitLab From 9a34161a0bc90df825694195659d894e80afe7a3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:36 +0100 Subject: [PATCH 655/942] ASoC: adi: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-23-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/adi/axi-i2s.c | 1 + sound/soc/adi/axi-spdif.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c index 1289cb4e2988c..b1342351bff43 100644 --- a/sound/soc/adi/axi-i2s.c +++ b/sound/soc/adi/axi-i2s.c @@ -161,6 +161,7 @@ static struct snd_soc_dai_driver axi_i2s_dai = { static const struct snd_soc_component_driver axi_i2s_component = { .name = "axi-i2s", + .legacy_dai_naming = 1, }; static const struct regmap_config axi_i2s_regmap_config = { diff --git a/sound/soc/adi/axi-spdif.c b/sound/soc/adi/axi-spdif.c index 8d4a6cb4e5c55..51b968ea21daa 100644 --- a/sound/soc/adi/axi-spdif.c +++ b/sound/soc/adi/axi-spdif.c @@ -167,6 +167,7 @@ static struct snd_soc_dai_driver axi_spdif_dai = { static const struct snd_soc_component_driver axi_spdif_component = { .name = "axi-spdif", + .legacy_dai_naming = 1, }; static const struct regmap_config axi_spdif_regmap_config = { -- GitLab From e740ef3d9418db78ac7a8a24071933f9146af6e4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:37 +0100 Subject: [PATCH 656/942] ASoC: dwc: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-24-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/dwc/dwc-i2s.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index e794e020052ef..7f7dd07c63b2f 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -449,9 +449,10 @@ static int dw_i2s_resume(struct snd_soc_component *component) #endif static const struct snd_soc_component_driver dw_i2s_component = { - .name = "dw-i2s", - .suspend = dw_i2s_suspend, - .resume = dw_i2s_resume, + .name = "dw-i2s", + .suspend = dw_i2s_suspend, + .resume = dw_i2s_resume, + .legacy_dai_naming = 1, }; /* -- GitLab From 8135d0290a9a1f1f752bb374f93a017b2074d09b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:38 +0100 Subject: [PATCH 657/942] ASoC: qcom: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-25-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 1 + sound/soc/qcom/qdsp6/q6asm-dai.c | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index e6846ad2b5fa4..6f1cd38000016 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -472,6 +472,7 @@ static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component, static const struct snd_soc_component_driver lpass_cpu_comp_driver = { .name = "lpass-cpu", .of_xlate_dai_name = asoc_qcom_of_xlate_dai_name, + .legacy_dai_naming = 1, }; static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index b74b67720ef43..5fc8088e63c81 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -1205,17 +1205,18 @@ static const struct snd_soc_dapm_widget q6asm_dapm_widgets[] = { }; static const struct snd_soc_component_driver q6asm_fe_dai_component = { - .name = DRV_NAME, - .open = q6asm_dai_open, - .hw_params = q6asm_dai_hw_params, - .close = q6asm_dai_close, - .prepare = q6asm_dai_prepare, - .trigger = q6asm_dai_trigger, - .pointer = q6asm_dai_pointer, - .pcm_construct = q6asm_dai_pcm_new, - .compress_ops = &q6asm_dai_compress_ops, - .dapm_widgets = q6asm_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), + .name = DRV_NAME, + .open = q6asm_dai_open, + .hw_params = q6asm_dai_hw_params, + .close = q6asm_dai_close, + .prepare = q6asm_dai_prepare, + .trigger = q6asm_dai_trigger, + .pointer = q6asm_dai_pointer, + .pcm_construct = q6asm_dai_pcm_new, + .compress_ops = &q6asm_dai_compress_ops, + .dapm_widgets = q6asm_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(q6asm_dapm_widgets), + .legacy_dai_naming = 1, }; static struct snd_soc_dai_driver q6asm_fe_dais_template[] = { -- GitLab From d73130ba523b88a3edb097ae3eb9f93df844b5e2 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:39 +0100 Subject: [PATCH 658/942] ASoC: test-component: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-26-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/generic/test-component.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c index d28712fabe3f6..e2a009bc69af2 100644 --- a/sound/soc/generic/test-component.c +++ b/sound/soc/generic/test-component.c @@ -564,6 +564,7 @@ static int test_driver_probe(struct platform_device *pdev) cdriv->pcm_construct = test_component_pcm_construct; cdriv->pointer = test_component_pointer; cdriv->trigger = test_component_trigger; + cdriv->legacy_dai_naming = 1; } else { cdriv->name = "test_codec"; cdriv->idle_bias_on = 1; -- GitLab From d48a77173534df90788075e76fa88c52b7395a1e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:40 +0100 Subject: [PATCH 659/942] ASoC: rockchip: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-27-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 1 + sound/soc/rockchip/rockchip_i2s_tdm.c | 1 + sound/soc/rockchip/rockchip_pdm.c | 1 + sound/soc/rockchip/rockchip_spdif.c | 1 + 4 files changed, 4 insertions(+) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 0ed01624a2dbd..96e7aa9eedfc0 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -561,6 +561,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { static const struct snd_soc_component_driver rockchip_i2s_component = { .name = DRV_NAME, + .legacy_dai_naming = 1, }; static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 48b3ecfa58b46..2aad0f309cb63 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -1120,6 +1120,7 @@ static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { static const struct snd_soc_component_driver rockchip_i2s_tdm_component = { .name = DRV_NAME, + .legacy_dai_naming = 1, }; static bool rockchip_i2s_tdm_wr_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 64d9891b6434f..6d93155411b03 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -405,6 +405,7 @@ static struct snd_soc_dai_driver rockchip_pdm_dai = { static const struct snd_soc_component_driver rockchip_pdm_component = { .name = "rockchip-pdm", + .legacy_dai_naming = 1, }; static int rockchip_pdm_runtime_suspend(struct device *dev) diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c index d027ca4b17964..8bef572d3cbc1 100644 --- a/sound/soc/rockchip/rockchip_spdif.c +++ b/sound/soc/rockchip/rockchip_spdif.c @@ -225,6 +225,7 @@ static struct snd_soc_dai_driver rk_spdif_dai = { static const struct snd_soc_component_driver rk_spdif_component = { .name = "rockchip-spdif", + .legacy_dai_naming = 1, }; static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg) -- GitLab From 8e750817a1943b49d81c633f48370bce93bab98c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:41 +0100 Subject: [PATCH 660/942] ASoC: au1x: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-28-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/au1x/ac97c.c | 3 ++- sound/soc/au1x/i2sc.c | 3 ++- sound/soc/au1x/psc-ac97.c | 3 ++- sound/soc/au1x/psc-i2s.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index 3b1700e665f52..b18512ca25781 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -223,7 +223,8 @@ static struct snd_soc_dai_driver au1xac97c_dai_driver = { }; static const struct snd_soc_component_driver au1xac97c_component = { - .name = "au1xac97c", + .name = "au1xac97c", + .legacy_dai_naming = 1, }; static int au1xac97c_drvprobe(struct platform_device *pdev) diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 45bb7851e75d7..b15c8baa9ee45 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -227,7 +227,8 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = { }; static const struct snd_soc_component_driver au1xi2s_component = { - .name = "au1xi2s", + .name = "au1xi2s", + .legacy_dai_naming = 1, }; static int au1xi2s_drvprobe(struct platform_device *pdev) diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 05eb36991f147..b536394b9ca08 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -356,7 +356,8 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { }; static const struct snd_soc_component_driver au1xpsc_ac97_component = { - .name = "au1xpsc-ac97", + .name = "au1xpsc-ac97", + .legacy_dai_naming = 1, }; static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 530a072d74274..79b5ae4e494cb 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -286,7 +286,8 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { }; static const struct snd_soc_component_driver au1xpsc_i2s_component = { - .name = "au1xpsc-i2s", + .name = "au1xpsc-i2s", + .legacy_dai_naming = 1, }; static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) -- GitLab From 05603f15b67a517c05ee2e2298e9accb8b7f1794 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:42 +0100 Subject: [PATCH 661/942] ASoC: pxa: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-29-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/pxa/mmp-sspa.c | 9 +++++---- sound/soc/pxa/pxa-ssp.c | 21 +++++++++++---------- sound/soc/pxa/pxa2xx-i2s.c | 21 +++++++++++---------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 382e9d8608a3f..fb5a4390443fe 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -456,10 +456,11 @@ static int mmp_sspa_close(struct snd_soc_component *component, } static const struct snd_soc_component_driver mmp_sspa_component = { - .name = "mmp-sspa", - .mmap = mmp_pcm_mmap, - .open = mmp_sspa_open, - .close = mmp_sspa_close, + .name = "mmp-sspa", + .mmap = mmp_pcm_mmap, + .open = mmp_sspa_open, + .close = mmp_sspa_close, + .legacy_dai_naming = 1, }; static int asoc_mmp_sspa_probe(struct platform_device *pdev) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 0f504a9f4983d..430dd446321e5 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -848,16 +848,17 @@ static struct snd_soc_dai_driver pxa_ssp_dai = { }; static const struct snd_soc_component_driver pxa_ssp_component = { - .name = "pxa-ssp", - .pcm_construct = pxa2xx_soc_pcm_new, - .open = pxa2xx_soc_pcm_open, - .close = pxa2xx_soc_pcm_close, - .hw_params = pxa2xx_soc_pcm_hw_params, - .prepare = pxa2xx_soc_pcm_prepare, - .trigger = pxa2xx_soc_pcm_trigger, - .pointer = pxa2xx_soc_pcm_pointer, - .suspend = pxa_ssp_suspend, - .resume = pxa_ssp_resume, + .name = "pxa-ssp", + .pcm_construct = pxa2xx_soc_pcm_new, + .open = pxa2xx_soc_pcm_open, + .close = pxa2xx_soc_pcm_close, + .hw_params = pxa2xx_soc_pcm_hw_params, + .prepare = pxa2xx_soc_pcm_prepare, + .trigger = pxa2xx_soc_pcm_trigger, + .pointer = pxa2xx_soc_pcm_pointer, + .suspend = pxa_ssp_suspend, + .resume = pxa_ssp_resume, + .legacy_dai_naming = 1, }; #ifdef CONFIG_OF diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index ffcf44e4dc8c0..3e4c704036722 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -355,16 +355,17 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { }; static const struct snd_soc_component_driver pxa_i2s_component = { - .name = "pxa-i2s", - .pcm_construct = pxa2xx_soc_pcm_new, - .open = pxa2xx_soc_pcm_open, - .close = pxa2xx_soc_pcm_close, - .hw_params = pxa2xx_soc_pcm_hw_params, - .prepare = pxa2xx_soc_pcm_prepare, - .trigger = pxa2xx_soc_pcm_trigger, - .pointer = pxa2xx_soc_pcm_pointer, - .suspend = pxa2xx_soc_pcm_suspend, - .resume = pxa2xx_soc_pcm_resume, + .name = "pxa-i2s", + .pcm_construct = pxa2xx_soc_pcm_new, + .open = pxa2xx_soc_pcm_open, + .close = pxa2xx_soc_pcm_close, + .hw_params = pxa2xx_soc_pcm_hw_params, + .prepare = pxa2xx_soc_pcm_prepare, + .trigger = pxa2xx_soc_pcm_trigger, + .pointer = pxa2xx_soc_pcm_pointer, + .suspend = pxa2xx_soc_pcm_suspend, + .resume = pxa2xx_soc_pcm_resume, + .legacy_dai_naming = 1, }; static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) -- GitLab From a718ba30038402e6daa311c566d9be39e4ab3f05 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:43 +0100 Subject: [PATCH 662/942] ASoC: sof: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-30-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 2 ++ sound/soc/sof/sof-client-probes.c | 1 + 2 files changed, 3 insertions(+) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 27504abc5385f..6cb6a432be5e9 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -682,4 +682,6 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) /* increment module refcount when a pcm is opened */ pd->module_get_upon_open = 1; + + pd->legacy_dai_naming = 1; } diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index 34e6bd356e717..1f1ea93a7fbf3 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -667,6 +667,7 @@ static const struct snd_soc_component_driver sof_probes_component = { .name = "sof-probes-component", .compress_ops = &sof_probes_compressed_ops, .module_get_upon_open = 1, + .legacy_dai_naming = 1, }; SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); -- GitLab From 768be0d633d9ff668a7ca4ba3b8e3eebea328cb8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:44 +0100 Subject: [PATCH 663/942] ASoC: ux500: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-31-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_msp_dai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index e48098f039d90..9d99ea6d7f30e 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -729,7 +729,8 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv = { }; static const struct snd_soc_component_driver ux500_msp_component = { - .name = "ux500-msp", + .name = "ux500-msp", + .legacy_dai_naming = 1, }; -- GitLab From 39c84e77da04f66f20fc54c6c6f49a5863bace5d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:45 +0100 Subject: [PATCH 664/942] ASoC: ti: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-32-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-i2s.c | 3 ++- sound/soc/ti/davinci-mcasp.c | 3 ++- sound/soc/ti/davinci-vcif.c | 3 ++- sound/soc/ti/omap-dmic.c | 3 ++- sound/soc/ti/omap-hdmi.c | 1 + sound/soc/ti/omap-mcbsp.c | 3 ++- sound/soc/ti/omap-mcpdm.c | 7 ++++--- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c index fe572b720b094..e6e77a5f3c1e7 100644 --- a/sound/soc/ti/davinci-i2s.c +++ b/sound/soc/ti/davinci-i2s.c @@ -640,7 +640,8 @@ static struct snd_soc_dai_driver davinci_i2s_dai = { }; static const struct snd_soc_component_driver davinci_i2s_component = { - .name = DRV_NAME, + .name = DRV_NAME, + .legacy_dai_naming = 1, }; static int davinci_i2s_probe(struct platform_device *pdev) diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index e2aab4729f3ab..45ffcc7aadc93 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -1765,7 +1765,8 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }; static const struct snd_soc_component_driver davinci_mcasp_component = { - .name = "davinci-mcasp", + .name = "davinci-mcasp", + .legacy_dai_naming = 1, }; /* Some HW specific values and defaults. The rest is filled in from DT. */ diff --git a/sound/soc/ti/davinci-vcif.c b/sound/soc/ti/davinci-vcif.c index f810123cc4070..36fa97e2b9e22 100644 --- a/sound/soc/ti/davinci-vcif.c +++ b/sound/soc/ti/davinci-vcif.c @@ -185,7 +185,8 @@ static struct snd_soc_dai_driver davinci_vcif_dai = { }; static const struct snd_soc_component_driver davinci_vcif_component = { - .name = "davinci-vcif", + .name = "davinci-vcif", + .legacy_dai_naming = 1, }; static int davinci_vcif_probe(struct platform_device *pdev) diff --git a/sound/soc/ti/omap-dmic.c b/sound/soc/ti/omap-dmic.c index f3eed20611a3f..825c70a443dad 100644 --- a/sound/soc/ti/omap-dmic.c +++ b/sound/soc/ti/omap-dmic.c @@ -453,7 +453,8 @@ static struct snd_soc_dai_driver omap_dmic_dai = { }; static const struct snd_soc_component_driver omap_dmic_component = { - .name = "omap-dmic", + .name = "omap-dmic", + .legacy_dai_naming = 1, }; static int asoc_dmic_probe(struct platform_device *pdev) diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c index 3328c02f93c74..0dc0475670ffe 100644 --- a/sound/soc/ti/omap-hdmi.c +++ b/sound/soc/ti/omap-hdmi.c @@ -275,6 +275,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { static const struct snd_soc_component_driver omap_hdmi_component = { .name = "omapdss_hdmi", + .legacy_dai_naming = 1, }; static struct snd_soc_dai_driver omap5_hdmi_dai = { diff --git a/sound/soc/ti/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c index 58d8e200a7b97..76df0e7844f8f 100644 --- a/sound/soc/ti/omap-mcbsp.c +++ b/sound/soc/ti/omap-mcbsp.c @@ -1317,7 +1317,8 @@ static struct snd_soc_dai_driver omap_mcbsp_dai = { }; static const struct snd_soc_component_driver omap_mcbsp_component = { - .name = "omap-mcbsp", + .name = "omap-mcbsp", + .legacy_dai_naming = 1, }; static struct omap_mcbsp_platform_data omap2420_pdata = { diff --git a/sound/soc/ti/omap-mcpdm.c b/sound/soc/ti/omap-mcpdm.c index fafb2998ad0df..0b18a7bfd3fd7 100644 --- a/sound/soc/ti/omap-mcpdm.c +++ b/sound/soc/ti/omap-mcpdm.c @@ -524,9 +524,10 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { }; static const struct snd_soc_component_driver omap_mcpdm_component = { - .name = "omap-mcpdm", - .suspend = omap_mcpdm_suspend, - .resume = omap_mcpdm_resume, + .name = "omap-mcpdm", + .suspend = omap_mcpdm_suspend, + .resume = omap_mcpdm_resume, + .legacy_dai_naming = 1, }; void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, -- GitLab From 4cc4e22843e9bec6e9083d85e8a0bfed85fe5423 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:46 +0100 Subject: [PATCH 665/942] ASoC: mxs-saif: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). This driver appears to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-33-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 467b0f2ce0bb1..ac761d3a01c05 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -663,7 +663,8 @@ static struct snd_soc_dai_driver mxs_saif_dai = { }; static const struct snd_soc_component_driver mxs_saif_component = { - .name = "mxs-saif", + .name = "mxs-saif", + .legacy_dai_naming = 1, }; static irqreturn_t mxs_saif_irq(int irq, void *dev_id) -- GitLab From f7bfa516a39a111a5d3b6473cdac20ee6075358c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:47 +0100 Subject: [PATCH 666/942] ASoC: samsung: Migrate to new style legacy DAI naming flag Change the legacy DAI naming flag from opting in to the new scheme (non_legacy_dai_naming), to opting out of it (legacy_dai_naming). These drivers appear to be on the CPU side of the DAI link and currently uses the legacy naming, so add the new flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-34-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 2 ++ sound/soc/samsung/pcm.c | 3 ++- sound/soc/samsung/s3c2412-i2s.c | 7 ++++--- sound/soc/samsung/s3c24xx-i2s.c | 7 ++++--- sound/soc/samsung/spdif.c | 7 ++++--- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index fdd9561c6a9f3..9505200f3d11b 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1143,6 +1143,8 @@ static const struct snd_soc_component_driver samsung_i2s_component = { .suspend = i2s_suspend, .resume = i2s_resume, + + .legacy_dai_naming = 1, }; #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index c2eb3534bfccb..e859252ae5e6e 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -480,7 +480,8 @@ static struct snd_soc_dai_driver s3c_pcm_dai[] = { }; static const struct snd_soc_component_driver s3c_pcm_component = { - .name = "s3c-pcm", + .name = "s3c-pcm", + .legacy_dai_naming = 1, }; static int s3c_pcm_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index ec1c6f9d76ac7..0579a352961cc 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -192,9 +192,10 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { }; static const struct snd_soc_component_driver s3c2412_i2s_component = { - .name = "s3c2412-i2s", - .suspend = s3c2412_i2s_suspend, - .resume = s3c2412_i2s_resume, + .name = "s3c2412-i2s", + .suspend = s3c2412_i2s_suspend, + .resume = s3c2412_i2s_resume, + .legacy_dai_naming = 1, }; static int s3c2412_iis_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 4082ad7cbcc11..e760fc8b42636 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -415,9 +415,10 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = { }; static const struct snd_soc_component_driver s3c24xx_i2s_component = { - .name = "s3c24xx-i2s", - .suspend = s3c24xx_i2s_suspend, - .resume = s3c24xx_i2s_resume, + .name = "s3c24xx-i2s", + .suspend = s3c24xx_i2s_suspend, + .resume = s3c24xx_i2s_resume, + .legacy_dai_naming = 1, }; static int s3c24xx_iis_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 47b6d19e43ffb..7d815e237e5c6 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -352,9 +352,10 @@ static struct snd_soc_dai_driver samsung_spdif_dai = { }; static const struct snd_soc_component_driver samsung_spdif_component = { - .name = "samsung-spdif", - .suspend = spdif_suspend, - .resume = spdif_resume, + .name = "samsung-spdif", + .suspend = spdif_suspend, + .resume = spdif_resume, + .legacy_dai_naming = 1, }; static int spdif_probe(struct platform_device *pdev) -- GitLab From 129f055a2144ab588a43c2e66d21a1f55ce54f81 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:48 +0100 Subject: [PATCH 667/942] ASoC: core: Switch core to new DAI naming flag Now all the drivers are updated to have the new legacy_dai_naming flag, update the core code so it also uses the new flag. Paving the way for the old non_legacy_dai_naming flag to be removed. It should be noted this patch will affect the CODEC drivers that don't specify the non_legacy_dai_naming flag. These drivers will update from using legacy DAI naming to the new scheme after this patch, this is being considered a fix as the intention was for all CODEC drivers to use the new scheme and all existing CODEC drivers were updated to do so before componentisation. This just corrects those devices that have snuck in since componentisation. The corrected devices are as follows: adau1372, cros_ec_codec, cs35l41, cs35l45, cx2072x, hdac_hda, jz4725/60/70, lpass-rx/tx/va/wsa-macro, max98504, max9877, mt6351/58/59, mt6660, pcm3060, rk3328, rt1308/16, rt5514, rt5677, rt700/11/15, rt9120, sdw-mockup, tlv320adc3xxx, tscs454, wcd9335/4x/8x, wsa881x Some of these devices are used in some in kernel machine drivers, however it appears all the usages use the actual DAI driver name (since snd_soc_find_dai checks both the DAI name and the DAI driver name). So it is not believed this change will break any in tree machine drivers. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-35-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 30f0da711ca95..60e21b06b1dcb 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2488,7 +2488,7 @@ static int snd_soc_register_dais(struct snd_soc_component *component, for (i = 0; i < count; i++) { dai = snd_soc_register_dai(component, dai_drv + i, count == 1 && - !component->driver->non_legacy_dai_naming); + component->driver->legacy_dai_naming); if (dai == NULL) { ret = -ENOMEM; goto err; -- GitLab From 55b566ded44db29e9c1ab61623c60ade4600301e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:49 +0100 Subject: [PATCH 668/942] media: TDA1997x: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-36-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/media/i2c/tda1997x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 8fafce26d62fa..965c7afec57d3 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2517,7 +2517,6 @@ static struct snd_soc_component_driver tda1997x_codec_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int tda1997x_probe(struct i2c_client *client, -- GitLab From 89836f00429b5c3dedb2e2f30262e53847b82ad0 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:50 +0100 Subject: [PATCH 669/942] ASoC: fsl: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-37-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_mqs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c index bb25c58e335fb..c1e2f671191b5 100644 --- a/sound/soc/fsl/fsl_mqs.c +++ b/sound/soc/fsl/fsl_mqs.c @@ -155,7 +155,6 @@ static void fsl_mqs_shutdown(struct snd_pcm_substream *substream, static const struct snd_soc_component_driver soc_codec_fsl_mqs = { .idle_bias_on = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops fsl_mqs_dai_ops = { -- GitLab From 9455e289246d8769631e6bec78c0c2ef40171b70 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:51 +0100 Subject: [PATCH 670/942] ASoC: meson: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-38-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/meson/aiu-acodec-ctrl.c | 1 - sound/soc/meson/aiu-codec-ctrl.c | 1 - sound/soc/meson/g12a-toacodec.c | 2 -- sound/soc/meson/g12a-tohdmitx.c | 1 - sound/soc/meson/t9015.c | 1 - 5 files changed, 6 deletions(-) diff --git a/sound/soc/meson/aiu-acodec-ctrl.c b/sound/soc/meson/aiu-acodec-ctrl.c index 3776b073a3dbb..d0f0ada5f4bce 100644 --- a/sound/soc/meson/aiu-acodec-ctrl.c +++ b/sound/soc/meson/aiu-acodec-ctrl.c @@ -192,7 +192,6 @@ static const struct snd_soc_component_driver aiu_acodec_ctrl_component = { .num_dapm_routes = ARRAY_SIZE(aiu_acodec_ctrl_routes), .of_xlate_dai_name = aiu_acodec_of_xlate_dai_name, .endianness = 1, - .non_legacy_dai_naming = 1, #ifdef CONFIG_DEBUG_FS .debugfs_prefix = "acodec", #endif diff --git a/sound/soc/meson/aiu-codec-ctrl.c b/sound/soc/meson/aiu-codec-ctrl.c index 286ac4983d40c..84c10956c2414 100644 --- a/sound/soc/meson/aiu-codec-ctrl.c +++ b/sound/soc/meson/aiu-codec-ctrl.c @@ -139,7 +139,6 @@ static const struct snd_soc_component_driver aiu_hdmi_ctrl_component = { .num_dapm_routes = ARRAY_SIZE(aiu_hdmi_ctrl_routes), .of_xlate_dai_name = aiu_hdmi_of_xlate_dai_name, .endianness = 1, - .non_legacy_dai_naming = 1, #ifdef CONFIG_DEBUG_FS .debugfs_prefix = "hdmi", #endif diff --git a/sound/soc/meson/g12a-toacodec.c b/sound/soc/meson/g12a-toacodec.c index 1dfee1396843c..ddc667956cf5e 100644 --- a/sound/soc/meson/g12a-toacodec.c +++ b/sound/soc/meson/g12a-toacodec.c @@ -242,7 +242,6 @@ static const struct snd_soc_component_driver g12a_toacodec_component_drv = { .dapm_routes = g12a_toacodec_routes, .num_dapm_routes = ARRAY_SIZE(g12a_toacodec_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver sm1_toacodec_component_drv = { @@ -254,7 +253,6 @@ static const struct snd_soc_component_driver sm1_toacodec_component_drv = { .dapm_routes = g12a_toacodec_routes, .num_dapm_routes = ARRAY_SIZE(g12a_toacodec_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config g12a_toacodec_regmap_cfg = { diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c index 6c99052feafd8..579a04ad4d197 100644 --- a/sound/soc/meson/g12a-tohdmitx.c +++ b/sound/soc/meson/g12a-tohdmitx.c @@ -226,7 +226,6 @@ static const struct snd_soc_component_driver g12a_tohdmitx_component_drv = { .dapm_routes = g12a_tohdmitx_routes, .num_dapm_routes = ARRAY_SIZE(g12a_tohdmitx_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config g12a_tohdmitx_regmap_cfg = { diff --git a/sound/soc/meson/t9015.c b/sound/soc/meson/t9015.c index a9b8c4e77d405..9c6b4dac68932 100644 --- a/sound/soc/meson/t9015.c +++ b/sound/soc/meson/t9015.c @@ -234,7 +234,6 @@ static const struct snd_soc_component_driver t9015_codec_driver = { .num_dapm_routes = ARRAY_SIZE(t9015_dapm_routes), .suspend_bias_off = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config t9015_regmap_config = { -- GitLab From 7e91c90863df7387b9e1f04d9bfc2a43c77d2a46 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:52 +0100 Subject: [PATCH 671/942] ASoC: pistachio: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-39-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/img/pistachio-internal-dac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/img/pistachio-internal-dac.c b/sound/soc/img/pistachio-internal-dac.c index 802c0ee63aa26..e3b858643bd5d 100644 --- a/sound/soc/img/pistachio-internal-dac.c +++ b/sound/soc/img/pistachio-internal-dac.c @@ -138,7 +138,6 @@ static const struct snd_soc_component_driver pistachio_internal_dac_driver = { .num_dapm_routes = ARRAY_SIZE(pistachio_internal_dac_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pistachio_internal_dac_probe(struct platform_device *pdev) -- GitLab From 752044db5b54c867dadfbd0daea90f1b9ecb21f1 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:53 +0100 Subject: [PATCH 672/942] ASoC: samsung: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-40-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/samsung/aries_wm8994.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index edee02d7f100a..e7d52d27132ea 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -432,7 +432,6 @@ static const struct snd_soc_component_driver aries_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver aries_ext_dai[] = { -- GitLab From 0f91b4de756415382c10c502010c7536500a1632 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:54 +0100 Subject: [PATCH 673/942] ASoC: soc-utils: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-41-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-utils.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 594cb311ff30a..70c380c0ac7b6 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -141,7 +141,6 @@ static const struct snd_soc_component_driver dummy_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define STUB_RATES SNDRV_PCM_RATE_8000_384000 -- GitLab From 4c6391f59c459e7cf8d584299d0746cb681c2cb7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:55 +0100 Subject: [PATCH 674/942] ASoC: sunxi: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-42-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 4 ---- sound/soc/sunxi/sun8i-codec.c | 1 - 2 files changed, 5 deletions(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index bc634962a57ee..830beb38bf156 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -881,7 +881,6 @@ static const struct snd_soc_component_driver sun4i_codec_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver sun7i_codec_codec = { @@ -894,7 +893,6 @@ static const struct snd_soc_component_driver sun7i_codec_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /*** sun6i Codec ***/ @@ -1202,7 +1200,6 @@ static const struct snd_soc_component_driver sun6i_codec_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* sun8i A23 codec */ @@ -1230,7 +1227,6 @@ static const struct snd_soc_component_driver sun8i_a23_codec_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver sun4i_codec_component = { diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index f797c535f2983..9844978d91e6e 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -1278,7 +1278,6 @@ static const struct snd_soc_component_driver sun8i_soc_component = { .probe = sun8i_codec_component_probe, .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sun8i_codec_regmap_config = { -- GitLab From 63c0ec9ebfec499d603993ea8244907bfbe39598 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:56 +0100 Subject: [PATCH 675/942] ASoC: tegra: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-43-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_i2s.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 01c76ba36e1ac..39ffa4d76b593 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -803,7 +803,6 @@ static const struct snd_soc_component_driver tegra210_i2s_cmpnt = { .num_dapm_routes = ARRAY_SIZE(tegra210_i2s_routes), .controls = tegra210_i2s_controls, .num_controls = ARRAY_SIZE(tegra210_i2s_controls), - .non_legacy_dai_naming = 1, }; static bool tegra210_i2s_wr_reg(struct device *dev, unsigned int reg) -- GitLab From 485c5924f262d4aef720c508ee2ff3cb8e2e531b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:57 +0100 Subject: [PATCH 676/942] ASoC: test-component: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-44-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/generic/test-component.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c index e2a009bc69af2..98c8990596a88 100644 --- a/sound/soc/generic/test-component.c +++ b/sound/soc/generic/test-component.c @@ -569,7 +569,6 @@ static int test_driver_probe(struct platform_device *pdev) cdriv->name = "test_codec"; cdriv->idle_bias_on = 1; cdriv->endianness = 1; - cdriv->non_legacy_dai_naming = 1; } cdriv->open = test_component_open; -- GitLab From 7cfb102a55556f5f165a2150a6f77a5aa7257599 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:58 +0100 Subject: [PATCH 677/942] ASoC: topology: KUnit: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-45-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index 51d650bb05b72..2cd3540cec044 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -104,7 +104,6 @@ static const struct snd_soc_component_driver test_component = { .name = "sound-soc-topology-test", .probe = d_probe, .remove = d_remove, - .non_legacy_dai_naming = 1, }; /* ===== TOPOLOGY TEMPLATES ================================================= */ @@ -238,7 +237,6 @@ static int d_probe_null_comp(struct snd_soc_component *component) static const struct snd_soc_component_driver test_component_null_comp = { .name = "sound-soc-topology-test", .probe = d_probe_null_comp, - .non_legacy_dai_naming = 1, }; static void snd_soc_tplg_test_load_with_null_comp(struct kunit *test) @@ -343,7 +341,6 @@ static int d_probe_null_fw(struct snd_soc_component *component) static const struct snd_soc_component_driver test_component_null_fw = { .name = "sound-soc-topology-test", .probe = d_probe_null_fw, - .non_legacy_dai_naming = 1, }; static void snd_soc_tplg_test_load_with_null_fw(struct kunit *test) -- GitLab From 36e79a44b12e4ce2d8659f47dbcce42690919567 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:51:59 +0100 Subject: [PATCH 678/942] ASoC: uniphier: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-46-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/uniphier/evea.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c index 96343d19a1e0f..42403ae8e31b2 100644 --- a/sound/soc/uniphier/evea.c +++ b/sound/soc/uniphier/evea.c @@ -397,7 +397,6 @@ static struct snd_soc_component_driver soc_codec_evea = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver soc_dai_evea[] = { -- GitLab From d9e7ddb98604de6470a0fe4f9e2434a55ca35730 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:00 +0100 Subject: [PATCH 679/942] ASoC: ad*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-47-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ad1836.c | 1 - sound/soc/codecs/ad193x.c | 1 - sound/soc/codecs/ad1980.c | 1 - sound/soc/codecs/ad73311.c | 1 - sound/soc/codecs/adau1373.c | 1 - sound/soc/codecs/adau1701.c | 1 - sound/soc/codecs/adau1761.c | 1 - sound/soc/codecs/adau1781.c | 1 - sound/soc/codecs/adau1977.c | 1 - sound/soc/codecs/adau7002.c | 1 - sound/soc/codecs/adau7118.c | 1 - sound/soc/codecs/adav80x.c | 1 - 12 files changed, 12 deletions(-) diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 29e1689da67ff..2c64df96b5ce9 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -332,7 +332,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad1836 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct reg_default ad1836_reg_defaults[] = { diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 30b98b4267e13..1d3c4d94b4ae9 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -523,7 +523,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad193x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct regmap_config ad193x_regmap_config = { diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9fd2023da218f..5e777d7fd5d91 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -302,7 +302,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad1980 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ad1980_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index b98bf19f594e0..f6090ac57e937 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -58,7 +58,6 @@ static const struct snd_soc_component_driver soc_component_dev_ad73311 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ad73311_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index a9032b5c8d782..7f832d00ab177 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1470,7 +1470,6 @@ static const struct snd_soc_component_driver adau1373_component_driver = { .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau1373_i2c_probe(struct i2c_client *client) diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 98768e5300f09..135a7db7fcf95 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -772,7 +772,6 @@ static const struct snd_soc_component_driver adau1701_component_drv = { .set_sysclk = adau1701_set_sysclk, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config adau1701_regmap = { diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c index 8f887227981f1..3ccc7acac2056 100644 --- a/sound/soc/codecs/adau1761.c +++ b/sound/soc/codecs/adau1761.c @@ -930,7 +930,6 @@ static const struct snd_soc_component_driver adau1761_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c index 74dc3344b2590..ff6be24863bfb 100644 --- a/sound/soc/codecs/adau1781.c +++ b/sound/soc/codecs/adau1781.c @@ -439,7 +439,6 @@ static const struct snd_soc_component_driver adau1781_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define ADAU1781_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index 5fcbdf2ec313c..7a9672f94fc6c 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -876,7 +876,6 @@ static const struct snd_soc_component_driver adau1977_component_driver = { .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau1977_setup_micbias(struct adau1977 *adau1977) diff --git a/sound/soc/codecs/adau7002.c b/sound/soc/codecs/adau7002.c index 0e00de6ce3fb1..401bafabc8eb4 100644 --- a/sound/soc/codecs/adau7002.c +++ b/sound/soc/codecs/adau7002.c @@ -91,7 +91,6 @@ static const struct snd_soc_component_driver adau7002_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int adau7002_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/adau7118.c b/sound/soc/codecs/adau7118.c index 841229dcbca10..bbb0972498876 100644 --- a/sound/soc/codecs/adau7118.c +++ b/sound/soc/codecs/adau7118.c @@ -442,7 +442,6 @@ static const struct snd_soc_component_driver adau7118_component_driver = { .num_dapm_widgets = ARRAY_SIZE(adau7118_widgets), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void adau7118_regulator_disable(void *data) diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 90f3a5e9e31f4..fcff35f26cecb 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -842,7 +842,6 @@ static const struct snd_soc_component_driver adav80x_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int adav80x_bus_probe(struct device *dev, struct regmap *regmap) -- GitLab From 410e73a5338d72c31a32a50c1629d81d8ce6a71f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:01 +0100 Subject: [PATCH 680/942] ASoC: ak*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-48-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ak4104.c | 1 - sound/soc/codecs/ak4118.c | 1 - sound/soc/codecs/ak4375.c | 1 - sound/soc/codecs/ak4458.c | 2 -- sound/soc/codecs/ak4535.c | 1 - sound/soc/codecs/ak4554.c | 1 - sound/soc/codecs/ak4613.c | 1 - sound/soc/codecs/ak4641.c | 1 - sound/soc/codecs/ak4642.c | 1 - sound/soc/codecs/ak4671.c | 1 - sound/soc/codecs/ak5386.c | 1 - sound/soc/codecs/ak5558.c | 2 -- 12 files changed, 14 deletions(-) diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index dc4747c77a7a1..ce99f30b4613a 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -248,7 +248,6 @@ static const struct snd_soc_component_driver soc_component_device_ak4104 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4104_regmap = { diff --git a/sound/soc/codecs/ak4118.c b/sound/soc/codecs/ak4118.c index 5c4a78c16733b..b6d9a10bdccdc 100644 --- a/sound/soc/codecs/ak4118.c +++ b/sound/soc/codecs/ak4118.c @@ -342,7 +342,6 @@ static const struct snd_soc_component_driver soc_component_drv_ak4118 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4118_regmap = { diff --git a/sound/soc/codecs/ak4375.c b/sound/soc/codecs/ak4375.c index 9a7b662016b9e..1ed004ba7cd23 100644 --- a/sound/soc/codecs/ak4375.c +++ b/sound/soc/codecs/ak4375.c @@ -473,7 +473,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4375 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4375_regmap = { diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c index baa9ff5d0ce50..ea33cc83c86c2 100644 --- a/sound/soc/codecs/ak4458.c +++ b/sound/soc/codecs/ak4458.c @@ -725,7 +725,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4458 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_ak4497 = { @@ -740,7 +739,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak4497 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4458_regmap = { diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index cc803e730c6ec..8c8c93eea7048 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -402,7 +402,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4535 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak4535_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index 8e60e2b56ad6d..b9607de5a1912 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -67,7 +67,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4554 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak4554_soc_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index d29d5e0db168e..f75c19ef35511 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -827,7 +827,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4613 = { .num_dapm_routes = ARRAY_SIZE(ak4613_intercon), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void ak4613_parse_of(struct ak4613_priv *priv, diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index d8d9cc712d679..88851e94b0452 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -535,7 +535,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4641 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4641_regmap = { diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3c20ff5595eb4..914d5b1969f8c 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -559,7 +559,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4642 = { .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4642_regmap = { diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 60edcbe560141..cd76765f8cc08 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -616,7 +616,6 @@ static const struct snd_soc_component_driver soc_component_dev_ak4671 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak4671_regmap = { diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index c76bfff246028..0c5e00679c7d8 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -77,7 +77,6 @@ static const struct snd_soc_component_driver soc_component_ak5386 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index c94cfde3e4a86..887d2c04d647a 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -393,7 +393,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak5558 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_ak5552 = { @@ -408,7 +407,6 @@ static const struct snd_soc_component_driver soc_codec_dev_ak5552 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ak5558_regmap = { -- GitLab From 60d28b5c47c7f02bb52fc5e52a84d669b9b54dbc Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:02 +0100 Subject: [PATCH 681/942] ASoC: alc*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-49-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/alc5623.c | 1 - sound/soc/codecs/alc5632.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 8e6235d2c5445..9ef01b1dd2941 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -956,7 +956,6 @@ static const struct snd_soc_component_driver soc_component_device_alc5623 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config alc5623_regmap = { diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 641bdfddae160..a770704a4e170 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -1078,7 +1078,6 @@ static const struct snd_soc_component_driver soc_component_device_alc5632 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config alc5632_regmap = { -- GitLab From ff946fd98bffe5de450047f54a27492827186b75 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:03 +0100 Subject: [PATCH 682/942] ASoC: cs*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-50-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 1 - sound/soc/codecs/cs35l33.c | 1 - sound/soc/codecs/cs35l34.c | 1 - sound/soc/codecs/cs35l35.c | 1 - sound/soc/codecs/cs35l36.c | 1 - sound/soc/codecs/cs4234.c | 1 - sound/soc/codecs/cs4265.c | 1 - sound/soc/codecs/cs4270.c | 1 - sound/soc/codecs/cs4271.c | 1 - sound/soc/codecs/cs42l42.c | 1 - sound/soc/codecs/cs42l51.c | 1 - sound/soc/codecs/cs42l52.c | 1 - sound/soc/codecs/cs42l56.c | 1 - sound/soc/codecs/cs42l73.c | 1 - sound/soc/codecs/cs42xx8.c | 1 - sound/soc/codecs/cs43130.c | 1 - sound/soc/codecs/cs4341.c | 1 - sound/soc/codecs/cs4349.c | 1 - sound/soc/codecs/cs47l15.c | 1 - sound/soc/codecs/cs47l24.c | 1 - sound/soc/codecs/cs47l35.c | 1 - sound/soc/codecs/cs47l85.c | 1 - sound/soc/codecs/cs47l90.c | 1 - sound/soc/codecs/cs47l92.c | 1 - sound/soc/codecs/cs53l30.c | 1 - 25 files changed, 25 deletions(-) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index badfc55bc5fa0..8ff6f66be86fa 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -236,7 +236,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l32 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Current and threshold powerup sequence Pg37 in datasheet */ diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 47dc0f6d90a2a..082025fa0370c 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -840,7 +840,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l33 = { .num_dapm_routes = ARRAY_SIZE(cs35l33_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs35l33_regmap = { diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 50d509a060713..472ac982779be 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -787,7 +787,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l34 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l34_regmap = { diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 6b70afb70a674..714a759dca21b 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1087,7 +1087,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l35 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l35_regmap = { diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index dfe85dc2cd20f..4dc13e6f4874c 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -1300,7 +1300,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l36 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs35l36_regmap = { diff --git a/sound/soc/codecs/cs4234.c b/sound/soc/codecs/cs4234.c index 881c5ba70c0ed..b49a3cf21ebe2 100644 --- a/sound/soc/codecs/cs4234.c +++ b/sound/soc/codecs/cs4234.c @@ -660,7 +660,6 @@ static const struct snd_soc_component_driver soc_component_cs4234 = { .controls = cs4234_snd_controls, .num_controls = ARRAY_SIZE(cs4234_snd_controls), .set_bias_level = cs4234_set_bias_level, - .non_legacy_dai_naming = 1, .idle_bias_on = 1, .suspend_bias_off = 1, .endianness = 1, diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c index 86bfa8d5ec787..76c19802d5fe1 100644 --- a/sound/soc/codecs/cs4265.c +++ b/sound/soc/codecs/cs4265.c @@ -553,7 +553,6 @@ static const struct snd_soc_component_driver soc_component_cs4265 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs4265_regmap = { diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 97d26b9e8f7fe..ba67e43edf351 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -619,7 +619,6 @@ static const struct snd_soc_component_driver soc_component_device_cs4270 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 7663f89ac6a24..2021cf4426061 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -642,7 +642,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs4271 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs4271_common_probe(struct device *dev, diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 6ca74c0d46eaa..d545a593a2516 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -581,7 +581,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { .num_controls = ARRAY_SIZE(cs42l42_snd_controls), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Switch to SCLK. Atomic delay after the write to allow the switch to complete. */ diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 0e933181b5dbb..51721edd8f53c 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -600,7 +600,6 @@ static const struct snd_soc_component_driver soc_component_device_cs42l51 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 10e696406a71b..90bf535fc5a52 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1061,7 +1061,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l52 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Current and threshold powerup sequence Pg37 */ diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 510c94265b1f0..03e2540a0ba12 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1114,7 +1114,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l56 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs42l56_regmap = { diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 5a9166289f366..0a146319755a6 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1256,7 +1256,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs42l73 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs42l73_regmap = { diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 5d6ef660f851f..d14eb2f6e1dd4 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c @@ -497,7 +497,6 @@ static const struct snd_soc_component_driver cs42xx8_driver = { .num_dapm_routes = ARRAY_SIZE(cs42xx8_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct cs42xx8_driver_data cs42448_data = { diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index a2bce0f9f247b..ca4d47cc9c915 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -2345,7 +2345,6 @@ static struct snd_soc_component_driver soc_component_dev_cs43130 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs43130_regmap = { diff --git a/sound/soc/codecs/cs4341.c b/sound/soc/codecs/cs4341.c index 8ac043f1aae01..ac1696034846d 100644 --- a/sound/soc/codecs/cs4341.c +++ b/sound/soc/codecs/cs4341.c @@ -202,7 +202,6 @@ static const struct snd_soc_component_driver soc_component_cs4341 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id __maybe_unused cs4341_dt_ids[] = { diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 7069e9b548576..f7c5c2fd43046 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -260,7 +260,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs4349 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config cs4349_regmap = { diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 391fd7da331fd..0193173b86376 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -1353,7 +1353,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l15 = { .num_dapm_routes = ARRAY_SIZE(cs47l15_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l15_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 6356f81aafc56..f9a2b865d7176 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1203,7 +1203,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l24 = { .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l24_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c index db2f844b8b17f..c1032d6c9143f 100644 --- a/sound/soc/codecs/cs47l35.c +++ b/sound/soc/codecs/cs47l35.c @@ -1638,7 +1638,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l35 = { .num_dapm_routes = ARRAY_SIZE(cs47l35_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l35_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c index d4fedc5ad516e..215d8211aa59b 100644 --- a/sound/soc/codecs/cs47l85.c +++ b/sound/soc/codecs/cs47l85.c @@ -2582,7 +2582,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l85 = { .num_dapm_routes = ARRAY_SIZE(cs47l85_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l85_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c index 5aec937a24629..1ad6526c78717 100644 --- a/sound/soc/codecs/cs47l90.c +++ b/sound/soc/codecs/cs47l90.c @@ -2497,7 +2497,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l90 = { .num_dapm_routes = ARRAY_SIZE(cs47l90_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l90_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs47l92.c b/sound/soc/codecs/cs47l92.c index a1b8dcdb9f7b7..59da34b480a87 100644 --- a/sound/soc/codecs/cs47l92.c +++ b/sound/soc/codecs/cs47l92.c @@ -1958,7 +1958,6 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l92 = { .num_dapm_routes = ARRAY_SIZE(cs47l92_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cs47l92_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 360ca2ffd5069..8796d8e84b7a2 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -899,7 +899,6 @@ static const struct snd_soc_component_driver cs53l30_driver = { .num_dapm_routes = ARRAY_SIZE(cs53l30_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct regmap_config cs53l30_regmap = { -- GitLab From c03a5b4c419799676013cb0c58c03e00ebe21a61 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:04 +0100 Subject: [PATCH 683/942] ASoC: da*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-51-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/da7210.c | 1 - sound/soc/codecs/da7213.c | 1 - sound/soc/codecs/da7218.c | 1 - sound/soc/codecs/da7219.c | 1 - sound/soc/codecs/da732x.c | 1 - sound/soc/codecs/da9055.c | 1 - 6 files changed, 6 deletions(-) diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 76a21976ccddb..f838466bfebf8 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1173,7 +1173,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7210 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #if IS_ENABLED(CONFIG_I2C) diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 2e645dc60eda4..544ccbcfc8844 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1922,7 +1922,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7213 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config da7213_regmap_config = { diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index a5d7c350a3ded..91372909d184b 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3040,7 +3040,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7218 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index c18f76f370fc4..50ecf30e6136a 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2647,7 +2647,6 @@ static const struct snd_soc_component_driver soc_component_dev_da7219 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 3f1cfee10df3f..2c5b0b74201c7 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1503,7 +1503,6 @@ static const struct snd_soc_component_driver soc_component_dev_da732x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int da732x_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 9d8c8adc5d768..28043b4530df8 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1460,7 +1460,6 @@ static const struct snd_soc_component_driver soc_component_dev_da9055 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config da9055_regmap_config = { -- GitLab From f0b163b4d5a215f610bd64eb8ab8a8906e53bec6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:05 +0100 Subject: [PATCH 684/942] ASoC: es*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-52-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/es7134.c | 1 - sound/soc/codecs/es7241.c | 1 - sound/soc/codecs/es8316.c | 1 - sound/soc/codecs/es8328.c | 1 - 4 files changed, 4 deletions(-) diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c index f443351677dfe..f5150d2f95da6 100644 --- a/sound/soc/codecs/es7134.c +++ b/sound/soc/codecs/es7134.c @@ -213,7 +213,6 @@ static const struct snd_soc_component_driver es7134_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver es7154_dai = { diff --git a/sound/soc/codecs/es7241.c b/sound/soc/codecs/es7241.c index 0baa86241cf93..339553cfbb48e 100644 --- a/sound/soc/codecs/es7241.c +++ b/sound/soc/codecs/es7241.c @@ -232,7 +232,6 @@ static const struct snd_soc_component_driver es7241_component_driver = { .num_dapm_routes = ARRAY_SIZE(es7241_dapm_routes), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void es7241_parse_fmt(struct device *dev, struct es7241_data *priv) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 4407166bb3388..eb15be9095e77 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -769,7 +769,6 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = { .num_dapm_routes = ARRAY_SIZE(es8316_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_range es8316_volatile_ranges[] = { diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index dd53dfd87b04e..160adc706cc69 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -844,7 +844,6 @@ static const struct snd_soc_component_driver es8328_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int es8328_probe(struct device *dev, struct regmap *regmap) -- GitLab From d2d3219ebe568fe4ee90ac748939304f7e05a8ec Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:06 +0100 Subject: [PATCH 685/942] ASoC: max*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-53-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 1 - sound/soc/codecs/max98090.c | 1 - sound/soc/codecs/max98095.c | 1 - sound/soc/codecs/max98357a.c | 1 - sound/soc/codecs/max98371.c | 1 - sound/soc/codecs/max98373.c | 2 -- sound/soc/codecs/max98390.c | 1 - sound/soc/codecs/max98396.c | 2 -- sound/soc/codecs/max9850.c | 1 - sound/soc/codecs/max98520.c | 1 - sound/soc/codecs/max9860.c | 1 - sound/soc/codecs/max9867.c | 1 - sound/soc/codecs/max98925.c | 1 - sound/soc/codecs/max98926.c | 1 - sound/soc/codecs/max98927.c | 1 - 15 files changed, 17 deletions(-) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 5ef2e1279ee71..08e5c606ff27d 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1734,7 +1734,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98088 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id max98088_i2c_id[] = { diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 72471cdb22292..142083b13ac3b 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2519,7 +2519,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98090 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98090_regmap = { diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 7bca99fa61b54..44aa58fcc23f8 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2103,7 +2103,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98095 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id max98095_i2c_id[] = { diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 9188127638848..2a2b286f1747f 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -93,7 +93,6 @@ static const struct snd_soc_component_driver max98357a_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops max98357a_dai_ops = { diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 800f2bca6a0f1..bac9d1bcf60ae 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c @@ -351,7 +351,6 @@ static const struct snd_soc_component_driver max98371_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98371_regmap = { diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index 1517c47afbf14..f90a6a7ba83b8 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -437,7 +437,6 @@ const struct snd_soc_component_driver soc_codec_dev_max98373 = { .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(soc_codec_dev_max98373); @@ -462,7 +461,6 @@ const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = { .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(soc_codec_dev_max98373_sdw); diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index d83f81d9ff4ea..5c08166a8dc62 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -983,7 +983,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98390 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98390_regmap = { diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index 56eb62bb041f9..225effede9d25 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -1453,7 +1453,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98396 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_codec_dev_max98397 = { @@ -1467,7 +1466,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98397 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98396_regmap = { diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 9ca6fc254883c..a6733396b0cad 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -296,7 +296,6 @@ static const struct snd_soc_component_driver soc_component_dev_max9850 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int max9850_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/max98520.c b/sound/soc/codecs/max98520.c index f0f085ecab550..5edd6f90f8a7b 100644 --- a/sound/soc/codecs/max98520.c +++ b/sound/soc/codecs/max98520.c @@ -657,7 +657,6 @@ static const struct snd_soc_component_driver soc_codec_dev_max98520 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98520_regmap = { diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index a1d0179e12c76..771b3dcd6cc32 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -537,7 +537,6 @@ static const struct snd_soc_component_driver max9860_component_driver = { .num_dapm_routes = ARRAY_SIZE(max9860_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #ifdef CONFIG_PM diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index eb628b7e84f55..6d2941a9dbd6e 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -589,7 +589,6 @@ static const struct snd_soc_component_driver max9867_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool max9867_volatile_register(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c index 63849ebcfd354..c24d9f2c8874d 100644 --- a/sound/soc/codecs/max98925.c +++ b/sound/soc/codecs/max98925.c @@ -544,7 +544,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98925 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98925_regmap = { diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 56e0a87c7112f..bffd56e240e9a 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c @@ -496,7 +496,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98926 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98926_regmap = { diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index b7cff76d7b5b9..9cce7c0f01424 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -832,7 +832,6 @@ static const struct snd_soc_component_driver soc_component_dev_max98927 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config max98927_regmap = { -- GitLab From 736f48714c1b85b0b1f6c88af07989a5828531c9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:07 +0100 Subject: [PATCH 686/942] ASoC: msm*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-54-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-analog.c | 1 - sound/soc/codecs/msm8916-wcd-digital.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index e52a559c52d68..78e543eb3c834 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -1128,7 +1128,6 @@ static const struct snd_soc_component_driver pm8916_wcd_analog = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pm8916_wcd_analog_parse_dt(struct device *dev, diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 098a58990f07d..d490a0f186752 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -1155,7 +1155,6 @@ static const struct snd_soc_component_driver msm8916_wcd_digital = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config msm8916_codec_regmap_config = { -- GitLab From c2fd88f0029172679917ebc536cfdc4b8fabe168 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:08 +0100 Subject: [PATCH 687/942] ASoC: nau*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-55-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8315.c | 1 - sound/soc/codecs/nau8540.c | 1 - sound/soc/codecs/nau8810.c | 1 - sound/soc/codecs/nau8821.c | 1 - sound/soc/codecs/nau8822.c | 1 - sound/soc/codecs/nau8824.c | 1 - sound/soc/codecs/nau8825.c | 1 - 7 files changed, 7 deletions(-) diff --git a/sound/soc/codecs/nau8315.c b/sound/soc/codecs/nau8315.c index 2b66e3f7a8b7f..ad4dce9e50807 100644 --- a/sound/soc/codecs/nau8315.c +++ b/sound/soc/codecs/nau8315.c @@ -93,7 +93,6 @@ static const struct snd_soc_component_driver nau8315_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops nau8315_dai_ops = { diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index 347c715e22a4b..58f70a02f18aa 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -806,7 +806,6 @@ static const struct snd_soc_component_driver nau8540_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config nau8540_regmap_config = { diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index 7b3b1e4ac2465..ccb512c21d748 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -866,7 +866,6 @@ static const struct snd_soc_component_driver nau8810_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int nau8810_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c index ce4e7f46bb067..6453e93678d22 100644 --- a/sound/soc/codecs/nau8821.c +++ b/sound/soc/codecs/nau8821.c @@ -1430,7 +1430,6 @@ static const struct snd_soc_component_driver nau8821_component_driver = { .dapm_routes = nau8821_dapm_routes, .num_dapm_routes = ARRAY_SIZE(nau8821_dapm_routes), .suspend_bias_off = 1, - .non_legacy_dai_naming = 1, .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c index 3907d1dd8ceef..1aef281a99727 100644 --- a/sound/soc/codecs/nau8822.c +++ b/sound/soc/codecs/nau8822.c @@ -1083,7 +1083,6 @@ static const struct snd_soc_component_driver soc_component_dev_nau8822 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config nau8822_regmap_config = { diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 2a7c935085353..ad54d70f7d8e7 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1544,7 +1544,6 @@ static const struct snd_soc_component_driver nau8824_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops nau8824_dai_ops = { diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 20e45a337b8f2..907ec88c759a8 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -2478,7 +2478,6 @@ static const struct snd_soc_component_driver nau8825_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void nau8825_reset_chip(struct regmap *regmap) -- GitLab From 8d4470b8d08b4aab5136cc3265eb0b05d2a1c72d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:09 +0100 Subject: [PATCH 688/942] ASoC: pcm*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-56-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm1681.c | 1 - sound/soc/codecs/pcm1789.c | 1 - sound/soc/codecs/pcm179x.c | 1 - sound/soc/codecs/pcm186x.c | 2 -- sound/soc/codecs/pcm3008.c | 1 - sound/soc/codecs/pcm3168a.c | 1 - sound/soc/codecs/pcm5102a.c | 1 - sound/soc/codecs/pcm512x.c | 1 - 8 files changed, 9 deletions(-) diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 20eb04c8a41a0..3591f6f53901f 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -290,7 +290,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm1681 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id pcm1681_i2c_id[] = { diff --git a/sound/soc/codecs/pcm1789.c b/sound/soc/codecs/pcm1789.c index 35788b57e11f9..3ab381e9a8566 100644 --- a/sound/soc/codecs/pcm1789.c +++ b/sound/soc/codecs/pcm1789.c @@ -229,7 +229,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm1789 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm1789_common_init(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index ee60373d7d254..f52ff66b6e644 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -207,7 +207,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm179x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm179x_common_init(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c index fda9d7ee3fe6b..dd21803ba13cb 100644 --- a/sound/soc/codecs/pcm186x.c +++ b/sound/soc/codecs/pcm186x.c @@ -578,7 +578,6 @@ static struct snd_soc_component_driver soc_codec_dev_pcm1863 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_component_driver soc_codec_dev_pcm1865 = { @@ -593,7 +592,6 @@ static struct snd_soc_component_driver soc_codec_dev_pcm1865 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool pcm186x_volatile(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index aef40ec40aa16..09c6c1326833d 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -102,7 +102,6 @@ static const struct snd_soc_component_driver soc_component_dev_pcm3008 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pcm3008_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index cf27f05dc46ab..9d6431338fb71 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -716,7 +716,6 @@ static const struct snd_soc_component_driver pcm3168a_driver = { .num_dapm_routes = ARRAY_SIZE(pcm3168a_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int pcm3168a_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c index f39f98bbc97fd..3401a25341e61 100644 --- a/sound/soc/codecs/pcm5102a.c +++ b/sound/soc/codecs/pcm5102a.c @@ -28,7 +28,6 @@ static struct snd_soc_component_driver soc_component_dev_pcm5102a = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pcm5102a_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index a3ff4a07aff72..767463e82665c 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -1512,7 +1512,6 @@ static const struct snd_soc_component_driver pcm512x_component_driver = { .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_range_cfg pcm512x_range = { -- GitLab From a524837ddd11bc20ec59d033d0260707cfa3cb99 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:10 +0100 Subject: [PATCH 689/942] ASoC: rt*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-57-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt1011.c | 1 - sound/soc/codecs/rt1015.c | 1 - sound/soc/codecs/rt1015p.c | 1 - sound/soc/codecs/rt1016.c | 1 - sound/soc/codecs/rt1019.c | 1 - sound/soc/codecs/rt1305.c | 1 - sound/soc/codecs/rt1308.c | 1 - sound/soc/codecs/rt274.c | 1 - sound/soc/codecs/rt286.c | 1 - sound/soc/codecs/rt298.c | 1 - sound/soc/codecs/rt5514.c | 1 - sound/soc/codecs/rt5616.c | 1 - sound/soc/codecs/rt5631.c | 1 - sound/soc/codecs/rt5640.c | 2 -- sound/soc/codecs/rt5645.c | 1 - sound/soc/codecs/rt5651.c | 1 - sound/soc/codecs/rt5659.c | 1 - sound/soc/codecs/rt5660.c | 1 - sound/soc/codecs/rt5663.c | 1 - sound/soc/codecs/rt5665.c | 1 - sound/soc/codecs/rt5668.c | 1 - sound/soc/codecs/rt5670.c | 1 - sound/soc/codecs/rt5677.c | 1 - sound/soc/codecs/rt5682.c | 1 - sound/soc/codecs/rt5682s.c | 1 - 25 files changed, 26 deletions(-) diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index 08dbaef84d4e1..c1568216126ef 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -2176,7 +2176,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1011 = { .set_pll = rt1011_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1011_regmap = { diff --git a/sound/soc/codecs/rt1015.c b/sound/soc/codecs/rt1015.c index 7a06f2654afb0..57d0f1c69e46c 100644 --- a/sound/soc/codecs/rt1015.c +++ b/sound/soc/codecs/rt1015.c @@ -1071,7 +1071,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1015 = { .set_pll = rt1015_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1015_regmap = { diff --git a/sound/soc/codecs/rt1015p.c b/sound/soc/codecs/rt1015p.c index 415cfb3b2f0d0..06800dad87981 100644 --- a/sound/soc/codecs/rt1015p.c +++ b/sound/soc/codecs/rt1015p.c @@ -89,7 +89,6 @@ static const struct snd_soc_component_driver rt1015p_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver rt1015p_dai_driver = { diff --git a/sound/soc/codecs/rt1016.c b/sound/soc/codecs/rt1016.c index e31c4736627f0..37eeec650f035 100644 --- a/sound/soc/codecs/rt1016.c +++ b/sound/soc/codecs/rt1016.c @@ -595,7 +595,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1016 = { .set_pll = rt1016_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1016_regmap = { diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c index f3f15fbe85d0e..b66bfecbb879b 100644 --- a/sound/soc/codecs/rt1019.c +++ b/sound/soc/codecs/rt1019.c @@ -522,7 +522,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1019 = { .num_dapm_widgets = ARRAY_SIZE(rt1019_dapm_widgets), .dapm_routes = rt1019_dapm_routes, .num_dapm_routes = ARRAY_SIZE(rt1019_dapm_routes), - .non_legacy_dai_naming = 1, .endianness = 1, }; diff --git a/sound/soc/codecs/rt1305.c b/sound/soc/codecs/rt1305.c index 58d97e3c5087d..5b39a440b6dc1 100644 --- a/sound/soc/codecs/rt1305.c +++ b/sound/soc/codecs/rt1305.c @@ -946,7 +946,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1305 = { .set_pll = rt1305_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1305_regmap = { diff --git a/sound/soc/codecs/rt1308.c b/sound/soc/codecs/rt1308.c index eec2b17604089..d2a8e9fe3e234 100644 --- a/sound/soc/codecs/rt1308.c +++ b/sound/soc/codecs/rt1308.c @@ -765,7 +765,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt1308 = { .set_pll = rt1308_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt1308_regmap = { diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index a5615e94ec7d0..6b208f9eb5035 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -1072,7 +1072,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt274 = { .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt274_regmap = { diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 0534a073ee695..b2b0b2b1e4d06 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1058,7 +1058,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt286 = { .num_dapm_routes = ARRAY_SIZE(rt286_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt286_regmap = { diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 1a27e5e63289c..266a2cc55b8d6 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1123,7 +1123,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt298_regmap = { diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index be8ece4630df5..b9bcf04d4dc93 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -1173,7 +1173,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5514 = { .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5514_i2c_regmap = { diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 37f1bf552eff4..970d6c4a358e0 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -1304,7 +1304,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5616 = { .num_dapm_routes = ARRAY_SIZE(rt5616_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5616_regmap = { diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index c941e878471c1..957f6b19beec9 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1666,7 +1666,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5631 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id rt5631_i2c_id[] = { diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 69c80d80ed9d5..56008e4518f3d 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2867,8 +2867,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5640 = { .num_dapm_routes = ARRAY_SIZE(rt5640_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static const struct regmap_config rt5640_regmap = { diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 507aba8de3cc9..8635bc6567dce 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3534,7 +3534,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5645 = { .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5645_regmap = { diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index d11d201b1d03e..df90af906563a 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2161,7 +2161,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5651 = { .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5651_regmap = { diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 6efa90f46362b..5e21e3c37ab57 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -3801,7 +3801,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5659 = { .set_pll = rt5659_set_component_pll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index d5f9926625d23..341baa29fdb18 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1208,7 +1208,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5660 = { .num_dapm_routes = ARRAY_SIZE(rt5660_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5660_regmap = { diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index e51eed8a79ab7..ca981b374b0c8 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -3258,7 +3258,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5663 = { .set_jack = rt5663_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5663_v2_regmap = { diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index 4a8d62e1dd2b5..6e66cc218fa8d 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -4617,7 +4617,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5665 = { .set_jack = rt5665_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 01566f036ca17..beb0951ff680b 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -2362,7 +2362,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5668 = { .set_jack = rt5668_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5668_regmap = { diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 8a97f6db04d56..60dbfa2a54f1b 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -2852,7 +2852,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5670 = { .num_dapm_routes = ARRAY_SIZE(rt5670_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5670_regmap = { diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 4a8c267d4fbc8..31a2dd0aafb64 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -5189,7 +5189,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5677 = { .num_dapm_routes = ARRAY_SIZE(rt5677_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5677_regmap_physical = { diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 2b6c6d6b9771e..2df95e792900c 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -3064,7 +3064,6 @@ const struct snd_soc_component_driver rt5682_soc_component_dev = { .set_jack = rt5682_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(rt5682_soc_component_dev); diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index 4d44eddee901c..eb47e7cd485aa 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -2893,7 +2893,6 @@ static const struct snd_soc_component_driver rt5682s_soc_component_dev = { .set_jack = rt5682s_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int rt5682s_parse_dt(struct rt5682s_priv *rt5682s, struct device *dev) -- GitLab From 792a8a944e7aa3f6ae0733429ba9937d7029ee4b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:11 +0100 Subject: [PATCH 690/942] ASoC: spdif: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-58-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/spdif_receiver.c | 1 - sound/soc/codecs/spdif_transmitter.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 276db978e5871..862e0b654a1c2 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c @@ -43,7 +43,6 @@ static struct snd_soc_component_driver soc_codec_spdif_dir = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver dir_stub_dai = { diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index 2c8cebfc66031..7365189215558 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c @@ -43,7 +43,6 @@ static struct snd_soc_component_driver soc_codec_spdif_dit = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver dit_stub_dai = { -- GitLab From a4311a5b1502f747576e5995d1b5ab04f60033f9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:12 +0100 Subject: [PATCH 691/942] ASoC: ssm*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-59-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ssm2518.c | 1 - sound/soc/codecs/ssm2602.c | 1 - sound/soc/codecs/ssm4567.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 012f209e76e90..6d88478482990 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -721,7 +721,6 @@ static const struct snd_soc_component_driver ssm2518_component_driver = { .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ssm2518_regmap_config = { diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 1821854ca0f37..cbbe83b85adaf 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -624,7 +624,6 @@ static const struct snd_soc_component_driver soc_component_dev_ssm2602 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index b47321c597d0e..4b0265617c7b5 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -427,7 +427,6 @@ static const struct snd_soc_component_driver ssm4567_component_driver = { .num_dapm_routes = ARRAY_SIZE(ssm4567_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ssm4567_regmap_config = { -- GitLab From 402f437b43870e65377bb97240ee3911858547cb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:13 +0100 Subject: [PATCH 692/942] ASoC: sta*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-60-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/sta32x.c | 1 - sound/soc/codecs/sta350.c | 1 - sound/soc/codecs/sta529.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 17e5077f26b00..8c86b578eba83 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -1014,7 +1014,6 @@ static const struct snd_soc_component_driver sta32x_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta32x_regmap = { diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c index b2d15d20fe63d..7b2c5b57d5d45 100644 --- a/sound/soc/codecs/sta350.c +++ b/sound/soc/codecs/sta350.c @@ -1057,7 +1057,6 @@ static const struct snd_soc_component_driver sta350_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta350_regmap = { diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c index d90e5512a7317..3139570991454 100644 --- a/sound/soc/codecs/sta529.c +++ b/sound/soc/codecs/sta529.c @@ -322,7 +322,6 @@ static const struct snd_soc_component_driver sta529_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sta529_regmap = { -- GitLab From 02bcc2be4c12763dd4c524e67973afe4d8ea6d4c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:14 +0100 Subject: [PATCH 693/942] ASoC: tas*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-61-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2552.c | 1 - sound/soc/codecs/tas2562.c | 2 -- sound/soc/codecs/tas2764.c | 1 - sound/soc/codecs/tas2770.c | 1 - sound/soc/codecs/tas5086.c | 1 - sound/soc/codecs/tas571x.c | 1 - sound/soc/codecs/tas5720.c | 2 -- sound/soc/codecs/tas5805m.c | 1 - sound/soc/codecs/tas6424.c | 1 - 9 files changed, 11 deletions(-) diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index c98a9332dcc0e..bf3d8539a2688 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -668,7 +668,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2552 = { .num_dapm_routes = ARRAY_SIZE(tas2552_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config tas2552_regmap_config = { diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c index e62a3da16aed3..dc088a1c67213 100644 --- a/sound/soc/codecs/tas2562.c +++ b/sound/soc/codecs/tas2562.c @@ -589,7 +589,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2110 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = { @@ -629,7 +628,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas2562 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops tas2562_speaker_dai_ops = { diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c index d395feffb30b5..42f0c1e449ba4 100644 --- a/sound/soc/codecs/tas2764.c +++ b/sound/soc/codecs/tas2764.c @@ -548,7 +548,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = { .num_dapm_routes = ARRAY_SIZE(tas2764_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct reg_default tas2764_reg_defaults[] = { diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c index f6037a148cb60..3cb634c282610 100644 --- a/sound/soc/codecs/tas2770.c +++ b/sound/soc/codecs/tas2770.c @@ -546,7 +546,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2770 = { .num_dapm_routes = ARRAY_SIZE(tas2770_audio_map), .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int tas2770_register_codec(struct tas2770_priv *tas2770) diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 05b57bb1aea04..a864984225bc4 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -888,7 +888,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5086 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct i2c_device_id tas5086_i2c_id[] = { diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index 7b599664db205..4e7f20db57c4d 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -756,7 +756,6 @@ static const struct snd_soc_component_driver tas571x_component = { .num_dapm_routes = ARRAY_SIZE(tas571x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver tas571x_dai = { diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index 2ee06a95f3e4f..3885c0bf0b01c 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -572,7 +572,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5720 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_component_driver soc_component_dev_tas5722 = { @@ -589,7 +588,6 @@ static const struct snd_soc_component_driver soc_component_dev_tas5722 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* PCM rates supported by the TAS5720 driver */ diff --git a/sound/soc/codecs/tas5805m.c b/sound/soc/codecs/tas5805m.c index fa0e81ec875ad..b1bb614534f74 100644 --- a/sound/soc/codecs/tas5805m.c +++ b/sound/soc/codecs/tas5805m.c @@ -367,7 +367,6 @@ static const struct snd_soc_component_driver soc_codec_dev_tas5805m = { .num_dapm_routes = ARRAY_SIZE(tas5805m_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction) diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c index 9c9a6ec4d9779..63d2983c3fcf4 100644 --- a/sound/soc/codecs/tas6424.c +++ b/sound/soc/codecs/tas6424.c @@ -375,7 +375,6 @@ static struct snd_soc_component_driver soc_codec_dev_tas6424 = { .num_dapm_routes = ARRAY_SIZE(tas6424_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops tas6424_speaker_dai_ops = { -- GitLab From c91f7e94ce931f058543174a409bb082208cae4a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:15 +0100 Subject: [PATCH 694/942] ASoC: tfa*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-62-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/tfa9879.c | 1 - sound/soc/codecs/tfa989x.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index 41a9b1b76e629..9f7902ec40db4 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c @@ -235,7 +235,6 @@ static const struct snd_soc_component_driver tfa9879_component = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config tfa9879_regmap = { diff --git a/sound/soc/codecs/tfa989x.c b/sound/soc/codecs/tfa989x.c index 8ab2656de7505..1c27429b9af64 100644 --- a/sound/soc/codecs/tfa989x.c +++ b/sound/soc/codecs/tfa989x.c @@ -138,7 +138,6 @@ static const struct snd_soc_component_driver tfa989x_component = { .num_dapm_routes = ARRAY_SIZE(tfa989x_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const unsigned int tfa989x_rates[] = { -- GitLab From 04f3d715df3a463985dc25e55a55dbd970dd77b7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:16 +0100 Subject: [PATCH 695/942] ASoC: tlv320*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-63-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 1 - sound/soc/codecs/tlv320aic23.c | 1 - sound/soc/codecs/tlv320aic26.c | 1 - sound/soc/codecs/tlv320aic31xx.c | 1 - sound/soc/codecs/tlv320aic32x4.c | 2 -- sound/soc/codecs/tlv320aic3x.c | 1 - sound/soc/codecs/tlv320dac33.c | 1 - 7 files changed, 8 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index de5b184a701ef..6618ac4a7d5c8 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -1053,7 +1053,6 @@ static const struct snd_soc_component_driver soc_codec_driver_adcx140 = { .idle_bias_on = 0, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver adcx140_dai_driver[] = { diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index c86ca793a2b66..c47aa4d4162dd 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -586,7 +586,6 @@ static const struct snd_soc_component_driver soc_component_dev_tlv320aic23 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int tlv320aic23_probe(struct device *dev, struct regmap *regmap) diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index f85f8061639f3..8bae4b4750688 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -331,7 +331,6 @@ static const struct snd_soc_component_driver aic26_soc_component_dev = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config aic26_regmap = { diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index aacee23679924..0847302121f6e 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1417,7 +1417,6 @@ static const struct snd_soc_component_driver soc_codec_driver_aic31xx = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_soc_dai_ops aic31xx_dai_ops = { diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index a8e6adf62ac82..4b74805cdd2e5 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -1077,7 +1077,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic32x4 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct snd_kcontrol_new aic32x4_tas2505_snd_controls[] = { @@ -1199,7 +1198,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic32x4_tas2505 = .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 610e41bbf388c..08938801daec2 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1697,7 +1697,6 @@ static const struct snd_soc_component_driver soc_component_dev_aic3x = { .num_dapm_routes = ARRAY_SIZE(intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void aic3x_configure_ocmv(struct device *dev, struct aic3x_priv *aic3x) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 371026eb8f41b..17ae3b1d96fb4 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1431,7 +1431,6 @@ static const struct snd_soc_component_driver soc_component_dev_tlv320dac33 = { .num_dapm_routes = ARRAY_SIZE(audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ -- GitLab From 5947b42cbe0ee580c31f7f327119e7f7c703c25c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:17 +0100 Subject: [PATCH 696/942] ASoC: twl*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-64-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 1 - sound/soc/codecs/twl6040.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 87b58017094b2..e48768233e208 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2195,7 +2195,6 @@ static const struct snd_soc_component_driver soc_component_dev_twl4030 = { .num_dapm_routes = ARRAY_SIZE(intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int twl4030_codec_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b37203336c4e0..dd5ee5dc0cd75 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1153,7 +1153,6 @@ static const struct snd_soc_component_driver soc_component_dev_twl6040 = { .suspend_bias_off = 1, .idle_bias_on = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int twl6040_codec_probe(struct platform_device *pdev) -- GitLab From 792008f6df86f7e5f861ef80fd4d6eb444a4aa92 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:18 +0100 Subject: [PATCH 697/942] ASoC: uda*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-65-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/uda1334.c | 1 - sound/soc/codecs/uda134x.c | 1 - sound/soc/codecs/uda1380.c | 1 - 3 files changed, 3 deletions(-) diff --git a/sound/soc/codecs/uda1334.c b/sound/soc/codecs/uda1334.c index 9d5ed34e54204..eace965336003 100644 --- a/sound/soc/codecs/uda1334.c +++ b/sound/soc/codecs/uda1334.c @@ -236,7 +236,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda1334 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id uda1334_of_match[] = { diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 037833c509f70..2db3d8a60c7a0 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -527,7 +527,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda134x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config uda134x_regmap_config = { diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index b5004842520bf..fdaaee845176e 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -736,7 +736,6 @@ static const struct snd_soc_component_driver soc_component_dev_uda1380 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int uda1380_i2c_probe(struct i2c_client *i2c) -- GitLab From 02004449dbe6ec05b5b64a88824939b8fe474b82 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:19 +0100 Subject: [PATCH 698/942] ASoC: wm*: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-66-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm0010.c | 1 - sound/soc/codecs/wm1250-ev1.c | 1 - sound/soc/codecs/wm2000.c | 1 - sound/soc/codecs/wm2200.c | 1 - sound/soc/codecs/wm5100.c | 1 - sound/soc/codecs/wm5102.c | 1 - sound/soc/codecs/wm5110.c | 1 - sound/soc/codecs/wm8350.c | 1 - sound/soc/codecs/wm8400.c | 1 - sound/soc/codecs/wm8510.c | 1 - sound/soc/codecs/wm8523.c | 1 - sound/soc/codecs/wm8524.c | 1 - sound/soc/codecs/wm8580.c | 1 - sound/soc/codecs/wm8711.c | 1 - sound/soc/codecs/wm8727.c | 1 - sound/soc/codecs/wm8728.c | 1 - sound/soc/codecs/wm8731.c | 1 - sound/soc/codecs/wm8737.c | 1 - sound/soc/codecs/wm8741.c | 1 - sound/soc/codecs/wm8750.c | 1 - sound/soc/codecs/wm8753.c | 1 - sound/soc/codecs/wm8770.c | 1 - sound/soc/codecs/wm8776.c | 1 - sound/soc/codecs/wm8782.c | 1 - sound/soc/codecs/wm8804.c | 1 - sound/soc/codecs/wm8900.c | 1 - sound/soc/codecs/wm8903.c | 1 - sound/soc/codecs/wm8904.c | 1 - sound/soc/codecs/wm8940.c | 1 - sound/soc/codecs/wm8955.c | 1 - sound/soc/codecs/wm8960.c | 1 - sound/soc/codecs/wm8961.c | 1 - sound/soc/codecs/wm8962.c | 1 - sound/soc/codecs/wm8971.c | 1 - sound/soc/codecs/wm8974.c | 1 - sound/soc/codecs/wm8978.c | 1 - sound/soc/codecs/wm8983.c | 1 - sound/soc/codecs/wm8985.c | 1 - sound/soc/codecs/wm8988.c | 1 - sound/soc/codecs/wm8990.c | 1 - sound/soc/codecs/wm8991.c | 1 - sound/soc/codecs/wm8993.c | 1 - sound/soc/codecs/wm8994.c | 1 - sound/soc/codecs/wm8995.c | 1 - sound/soc/codecs/wm8996.c | 2 -- sound/soc/codecs/wm8997.c | 1 - sound/soc/codecs/wm8998.c | 1 - sound/soc/codecs/wm9081.c | 1 - sound/soc/codecs/wm9090.c | 1 - sound/soc/codecs/wm9705.c | 1 - sound/soc/codecs/wm9712.c | 1 - sound/soc/codecs/wm9713.c | 1 - 52 files changed, 53 deletions(-) diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 1bef1c500c8e3..034a4e858c7e6 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -789,7 +789,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm0010 = { .num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; #define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index b6366dea15a67..98343626078b6 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -144,7 +144,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm1250_ev1 = { .set_bias_level = wm1250_ev1_set_bias_level, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm1250_ev1_pdata(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index ede5f2a982a63..14b4fd97488c8 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -803,7 +803,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm2000 = { .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), .idle_bias_on = 1, .use_pmdown_time = 1, - .non_legacy_dai_naming = 1, }; static int wm2000_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 1cd544580c832..7b4e162a298c0 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -2104,7 +2104,6 @@ static const struct snd_soc_component_driver soc_component_wm2200 = { .dapm_routes = wm2200_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static irqreturn_t wm2200_irq(int irq, void *data) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index a89870918174b..35a85ce6b4648 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -2389,7 +2389,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5100 = { .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm5100_regmap = { diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index da2f8998df87a..8b1caac65c3af 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2015,7 +2015,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5102 = { .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm5102_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4ab7a672f8de8..f3f4a10bf0f7c 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2385,7 +2385,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm5110 = { .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm5110_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 41504ce2a682f..66bd281095e1c 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1613,7 +1613,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8350 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8350_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index bf5e77c86aed6..19ce839f6ef7c 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1322,7 +1322,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8400 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8400_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index c6439d25006bf..e13f9780a111b 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -592,7 +592,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8510 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8510_of_match[] = { diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index ba35a0221dc84..66f6371d8acfa 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -422,7 +422,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8523 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8523_of_match[] = { diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c index 81f858f6bd676..b56dcac602448 100644 --- a/sound/soc/codecs/wm8524.c +++ b/sound/soc/codecs/wm8524.c @@ -203,7 +203,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8524 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8524_of_match[] = { diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 84020195314d9..ca796aa0aeb79 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -966,7 +966,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8580 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8580_regmap = { diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index b68a1ebcd0617..383c6796e8a39 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -378,7 +378,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8711 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8711_of_match[] = { diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 1a118b75b5398..d6b0a570dd87c 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -55,7 +55,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8727 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8727_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 119ff0a1bb35c..a3dbdbf40723e 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -221,7 +221,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8728 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8728_of_match[] = { diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 2408c4a591d55..d5ab3ba126a6b 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -561,7 +561,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8731 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; int wm8731_init(struct device *dev, struct wm8731_priv *wm8731) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 5778091d1c09f..90b54343370c4 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -583,7 +583,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8737 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8737_of_match[] = { diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 871e2c5421b86..c7afa4f2795d8 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -528,7 +528,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8741 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8741_of_match[] = { diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 1426fc1f7c5ac..2f6ee8d6639f8 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -719,7 +719,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8750 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8750_of_match[] = { diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 931134d334eca..bb18f58dc670f 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1492,7 +1492,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8753 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8753_of_match[] = { diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 5f394065030d2..e03fee8869c37 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -617,7 +617,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8770 = { .num_dapm_routes = ARRAY_SIZE(wm8770_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8770_of_match[] = { diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index f164cb6744c49..936ea24621b0d 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -436,7 +436,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8776 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id wm8776_of_match[] = { diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index f89855c616ebe..95ff4339d103b 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -99,7 +99,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8782 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8782_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 21bf0cfa1e7e7..0b234bae480e1 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -546,7 +546,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8804 = { .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; const struct regmap_config wm8804_regmap_config = { diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 84a3daf0c11e3..d6420df3505d5 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1214,7 +1214,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8900 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8900_regmap = { diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 3c95c2aea5152..54e0a7628cd57 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1893,7 +1893,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8903 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8903_regmap = { diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 04bb8e3924977..ca6a01a230af4 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -2131,7 +2131,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8904 = { .set_bias_level = wm8904_set_bias_level, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8904_regmap = { diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 589394d420ced..8dac9fd885470 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -734,7 +734,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8940 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8940_regmap = { diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 80e3cbd704ee0..05ef45672ebc7 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -952,7 +952,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8955 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8955_regmap = { diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8c8f32b230838..37956516d9976 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -1378,7 +1378,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8960 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8960_regmap = { diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 69eb731dbf4bb..7dc6aaf655767 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -895,7 +895,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8961 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8961_regmap = { diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 5cca89364280a..398c448ea8540 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3502,7 +3502,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8962 = { .set_pll = wm8962_set_fll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; /* Improve power consumption for IN4 DC measurement mode */ diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 8a289b048e66d..4db9248de54ba 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -659,7 +659,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8971 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8971_regmap = { diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index a8d7809f3f64b..010a394c705c1 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -682,7 +682,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8974 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8974_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 141f50bfec68a..a682f8020eb6d 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -1005,7 +1005,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8978 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8978_regmap_config = { diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index ae89554d47bc9..50e6ac6ccbe03 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -987,7 +987,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8983 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8983_regmap = { diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index cf2c32eac773a..751aa67308337 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1116,7 +1116,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8985 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8985_regmap = { diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 27538d6598cf1..5dbdf647cd978 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -823,7 +823,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8988 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8988_regmap = { diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c9448a59c872f..589af286f133f 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -1217,7 +1217,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8990 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8990_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 998bc89bb7e12..30121993b7b4f 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -1243,7 +1243,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8991 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8991_regmap = { diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index f4da77ec9d6c2..8db98b5a06bf4 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1621,7 +1621,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8993 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8993_i2c_probe(struct i2c_client *i2c) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f117ec0c489f0..d3cfd3788f2ab 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4614,7 +4614,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8994 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8994_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index ea9727446707d..eed48bf339f24 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2182,7 +2182,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8995 = { .num_dapm_routes = ARRAY_SIZE(wm8995_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm8995_regmap = { diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index f7bb27d1c76d0..17f307a310467 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -2695,8 +2695,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8996 = { .set_pll = wm8996_set_fll, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 38ef631d1a1ff..210ad662fc26d 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1105,7 +1105,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8997 = { .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8997_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 00b59fc9b1fe0..328f1946f584a 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c @@ -1325,7 +1325,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm8998 = { .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm8998_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 87b58448cea7c..d5151877d0fa2 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1284,7 +1284,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9081 = { .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm9081_regmap = { diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index f7d80f1e37a80..ef3524c3f07fd 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -543,7 +543,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9090 = { .suspend_bias_off = 1, .idle_bias_on = 1, .use_pmdown_time = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config wm9090_regmap = { diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 99fe8f3166248..d04902ef1d5f3 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -368,7 +368,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9705 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9705_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 7515c9d4006e7..df9b7980706b2 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -692,7 +692,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9712 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9712_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index e0ce32dd4a811..5d2e54e06e30a 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1257,7 +1257,6 @@ static const struct snd_soc_component_driver soc_component_dev_wm9713 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wm9713_probe(struct platform_device *pdev) -- GitLab From 4c90eebd97c519361f32e11de991e299f5b47e3d Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:20 +0100 Subject: [PATCH 699/942] ASoC: 88pm860x: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-67-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index c6043fa58c740..fc65283031cdc 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1345,7 +1345,6 @@ static const struct snd_soc_component_driver soc_component_dev_pm860x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int pm860x_codec_probe(struct platform_device *pdev) -- GitLab From bb426d37dcd9a1474f785fea434875233d24e537 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:21 +0100 Subject: [PATCH 700/942] ASoC: ab8500: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-68-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index cbd4a92cb06ce..68342917419e4 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2523,7 +2523,6 @@ static const struct snd_soc_component_driver ab8500_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ab8500_codec_driver_probe(struct platform_device *pdev) -- GitLab From 96b409c94d6766ae8faa9f07fabc3694ddb7d018 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:22 +0100 Subject: [PATCH 701/942] ASoC: ac97: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-69-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ac97.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 6ad9c9443b5db..cc12052e19204 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -119,7 +119,6 @@ static const struct snd_soc_component_driver soc_component_dev_ac97 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ac97_probe(struct platform_device *pdev) -- GitLab From e556a108e0aab4688cb0c7b1c0517e3fab8b5eb4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:23 +0100 Subject: [PATCH 702/942] ASoC: ads117x: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-70-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ads117x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 1d07e2699f04d..44aa06e034869 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -62,7 +62,6 @@ static const struct snd_soc_component_driver soc_component_dev_ads117x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ads117x_probe(struct platform_device *pdev) -- GitLab From 310288271f55ae0edccd01257c9fdf460dd45e30 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:24 +0100 Subject: [PATCH 703/942] ASoC: bd28623: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-71-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/bd28623.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/bd28623.c b/sound/soc/codecs/bd28623.c index a6267cb86d860..82a94211d0123 100644 --- a/sound/soc/codecs/bd28623.c +++ b/sound/soc/codecs/bd28623.c @@ -161,7 +161,6 @@ static const struct snd_soc_component_driver soc_codec_bd = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static struct snd_soc_dai_driver soc_dai_bd = { -- GitLab From 8c657358f685cec541d7ad3c54f899a65f56783e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:25 +0100 Subject: [PATCH 704/942] ASoC: bt-sco: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-72-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/bt-sco.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index cf17b9741bd83..4086b6a53de8c 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c @@ -69,7 +69,6 @@ static const struct snd_soc_component_driver soc_component_dev_bt_sco = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int bt_sco_probe(struct platform_device *pdev) -- GitLab From 35c5013ce7ca3ad55974e3517273a0e42140b5e7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:26 +0100 Subject: [PATCH 705/942] ASoC: cpcap: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-73-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cpcap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c index ffdf8b615efaa..4f9dabd9d78a6 100644 --- a/sound/soc/codecs/cpcap.c +++ b/sound/soc/codecs/cpcap.c @@ -1660,7 +1660,6 @@ static struct snd_soc_component_driver soc_codec_dev_cpcap = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cpcap_codec_probe(struct platform_device *pdev) -- GitLab From 73a3dca65cbe5e7de20f3453b6881acf3fb3cfbe Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:27 +0100 Subject: [PATCH 706/942] ASoC: cq93vc: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-74-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cq93vc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 0aae5790222ae..14403b76c7243 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -126,7 +126,6 @@ static const struct snd_soc_component_driver soc_component_dev_cq93vc = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cq93vc_platform_probe(struct platform_device *pdev) -- GitLab From a0b6e4048228829485a43247c12c7774531728c4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:28 +0100 Subject: [PATCH 707/942] ASoC: cx20442: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-75-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cx20442.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 1af0bf5f1e2f5..43c0cac0ec9e8 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -411,7 +411,6 @@ static const struct snd_soc_component_driver cx20442_component_dev = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int cx20442_platform_probe(struct platform_device *pdev) -- GitLab From 4eaf75fa427262289a2bc34d3fcfbc602ebbacfa Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:29 +0100 Subject: [PATCH 708/942] ASoC: dmic: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-76-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/dmic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index d1a30ca4571ad..4fd6f97e5a493 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -140,7 +140,6 @@ static const struct snd_soc_component_driver soc_dmic = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int dmic_dev_probe(struct platform_device *pdev) -- GitLab From 33b179e7513c30f03277f5de2a845e940a9bde9c Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:30 +0100 Subject: [PATCH 709/942] ASoC: gtm601: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-77-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/gtm601.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/gtm601.c b/sound/soc/codecs/gtm601.c index e1235e695b0fb..c6b1e77ffccd0 100644 --- a/sound/soc/codecs/gtm601.c +++ b/sound/soc/codecs/gtm601.c @@ -73,7 +73,6 @@ static const struct snd_soc_component_driver soc_component_dev_gtm601 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int gtm601_platform_probe(struct platform_device *pdev) -- GitLab From f02a7d11998eefe8c5627b93627469a0aab8d3da Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:31 +0100 Subject: [PATCH 710/942] ASoC: hdac_hdmi: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-78-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdac_hdmi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 66408a98298be..cb23650ad5223 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2058,7 +2058,6 @@ static const struct snd_soc_component_driver hdmi_hda_codec = { .remove = hdmi_codec_remove, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx, -- GitLab From f5f8019371b42c742d9777052c189e89a0745319 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:32 +0100 Subject: [PATCH 711/942] ASoC: hdmi-codec: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-79-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi-codec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 7d1e351f863a4..5679102de91f8 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -977,7 +977,6 @@ static const struct snd_soc_component_driver hdmi_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, .set_jack = hdmi_codec_set_jack, }; -- GitLab From e8f88be5c1548791397dadf2250fb5dcc9461f10 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:33 +0100 Subject: [PATCH 712/942] ASoC: ics43432: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-80-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ics43432.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c index de4c8460ab3df..58a3822547189 100644 --- a/sound/soc/codecs/ics43432.c +++ b/sound/soc/codecs/ics43432.c @@ -41,7 +41,6 @@ static const struct snd_soc_component_driver ics43432_component_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int ics43432_probe(struct platform_device *pdev) -- GitLab From 1f1ee5ae7a8b3d30cbfe18561a4e3b7430e96c9f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:34 +0100 Subject: [PATCH 713/942] ASoC: inno_rk3036: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-81-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/inno_rk3036.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index ca0f4c1911e48..8222cde6e3b90 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c @@ -387,7 +387,6 @@ static const struct snd_soc_component_driver rk3036_codec_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rk3036_codec_regmap_config = { -- GitLab From 22afe04dd84a63440e69dfc7f0e670404fbce831 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:35 +0100 Subject: [PATCH 714/942] ASoC: Intel: avs: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-82-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 668f533578a69..f21b0cdd32063 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -846,7 +846,6 @@ static const struct snd_soc_component_driver avs_component_driver = { .pcm_construct = avs_component_construct, .module_get_upon_open = 1, /* increment refcount when a pcm is opened */ .topology_name_prefix = "intel/avs", - .non_legacy_dai_naming = true, }; static int avs_soc_component_register(struct device *dev, const char *name, @@ -1172,7 +1171,6 @@ static const struct snd_soc_component_driver avs_hda_component_driver = { .remove_order = SND_SOC_COMP_ORDER_EARLY, .module_get_upon_open = 1, .topology_name_prefix = "intel/avs", - .non_legacy_dai_naming = true, }; int avs_hda_platform_register(struct avs_dev *adev, const char *name) -- GitLab From 328bd81743f0823d9604b0098c95f071e7d02805 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:36 +0100 Subject: [PATCH 715/942] ASoC: isabelle: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-83-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/isabelle.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 39be31e1282e7..50105d72b2b74 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1095,7 +1095,6 @@ static const struct snd_soc_component_driver soc_component_dev_isabelle = { .num_dapm_routes = ARRAY_SIZE(isabelle_intercon), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config isabelle_regmap_config = { -- GitLab From dd213681c801fd9d26aef95f4eb563c38f4967f9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:37 +0100 Subject: [PATCH 716/942] ASoC: jz4740: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-84-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/jz4740.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 081485f784e9b..7c25acf6ff0de 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -291,8 +291,6 @@ static const struct snd_soc_component_driver soc_codec_dev_jz4740_codec = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static const struct regmap_config jz4740_codec_regmap_config = { -- GitLab From 191889406df931cc2e40abf0a0de141b098f0481 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:38 +0100 Subject: [PATCH 717/942] ASoC: lm49453: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-85-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/lm49453.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index c4900ada86184..a2e782cc4276a 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1399,7 +1399,6 @@ static const struct snd_soc_component_driver soc_component_dev_lm49453 = { .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config lm49453_regmap_config = { -- GitLab From 34b89b309441f7f45f68d7ec3633ee3d50921bc8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:39 +0100 Subject: [PATCH 718/942] ASoC: lochnagar: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-86-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/lochnagar-sc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/lochnagar-sc.c b/sound/soc/codecs/lochnagar-sc.c index 54a8ba7ed3c20..13fbd8830b09f 100644 --- a/sound/soc/codecs/lochnagar-sc.c +++ b/sound/soc/codecs/lochnagar-sc.c @@ -217,7 +217,6 @@ static const struct snd_soc_component_driver lochnagar_sc_driver = { .dapm_routes = lochnagar_sc_routes, .num_dapm_routes = ARRAY_SIZE(lochnagar_sc_routes), - .non_legacy_dai_naming = 1, .endianness = 1, }; -- GitLab From 139db4ad9e0b793ffd3f4f23976bf72d5e4e6703 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:40 +0100 Subject: [PATCH 719/942] ASoC: mc13783: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-87-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 08517547e66c7..71490f11d96ac 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -727,7 +727,6 @@ static const struct snd_soc_component_driver soc_component_dev_mc13783 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int __init mc13783_codec_probe(struct platform_device *pdev) -- GitLab From 7e6fcd7f6223ab32bdccc5e22cdec780cde305c3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:41 +0100 Subject: [PATCH 720/942] ASoC: ml26124: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-88-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/ml26124.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index de8fcbdd85be4..3c6ac77379cbe 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -537,7 +537,6 @@ static const struct snd_soc_component_driver soc_component_dev_ml26124 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config ml26124_i2c_regmap = { -- GitLab From 2e938b8edfedb73efd07545a58fe51bb7fc48a56 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:42 +0100 Subject: [PATCH 721/942] ASoC: rk817: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-89-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/rk817_codec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/rk817_codec.c b/sound/soc/codecs/rk817_codec.c index cce6f4e7992f5..2a5b274bfc0f5 100644 --- a/sound/soc/codecs/rk817_codec.c +++ b/sound/soc/codecs/rk817_codec.c @@ -444,7 +444,6 @@ static const struct snd_soc_component_driver soc_codec_dev_rk817 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, .controls = rk817_volume_controls, .num_controls = ARRAY_SIZE(rk817_volume_controls), .dapm_routes = rk817_dapm_routes, -- GitLab From 81ed3cb8d93936fe32b2b5c213dd56d8ecae7be8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:43 +0100 Subject: [PATCH 722/942] ASoC: sgtl5000: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-90-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/sgtl5000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 2aa48aef6a97d..0b8a377ba145f 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1536,7 +1536,6 @@ static const struct snd_soc_component_driver sgtl5000_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config sgtl5000_regmap = { -- GitLab From 89571b892e74b9724e155774576651cd675b4110 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:44 +0100 Subject: [PATCH 723/942] ASoC: si476x: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-91-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 8bd2edf70f137..d87141ba84388 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -239,7 +239,6 @@ static const struct snd_soc_component_driver soc_component_dev_si476x = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int si476x_platform_probe(struct platform_device *pdev) -- GitLab From e5257aa583b6d9f80e3aaa3ed6fc68c1b1b5925a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:45 +0100 Subject: [PATCH 724/942] ASoC: stac9766: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-92-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/stac9766.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index d99f6e466d0a3..1824a71fe053d 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -313,8 +313,6 @@ static const struct snd_soc_component_driver soc_component_dev_stac9766 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, - }; static int stac9766_probe(struct platform_device *pdev) -- GitLab From 20b1894d16547dcd99f190f5a0604a06a0c4479f Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:46 +0100 Subject: [PATCH 725/942] ASoC: sti-sas: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-93-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/sti-sas.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 10a6a112f4b47..f076878908eec 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -398,7 +398,6 @@ static struct snd_soc_component_driver sti_sas_driver = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct of_device_id sti_sas_dev_match[] = { -- GitLab From c06fb318493a059ac2c47937761d048f9ab1b542 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:47 +0100 Subject: [PATCH 726/942] ASoC: tscs42xx: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-94-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/tscs42xx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c index 4fb0bb01bcdc0..fa0c525189c20 100644 --- a/sound/soc/codecs/tscs42xx.c +++ b/sound/soc/codecs/tscs42xx.c @@ -1358,7 +1358,6 @@ static const struct snd_soc_component_driver soc_codec_dev_tscs42xx = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static inline void init_coeff_ram_cache(struct tscs42xx *tscs42xx) -- GitLab From 11c8bfaacbcd6c8251f65101d5ceeb173a76b1a3 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:48 +0100 Subject: [PATCH 727/942] ASoC: wl1273: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-95-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wl1273.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 02232f64110e0..626278e4c9238 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -475,7 +475,6 @@ static const struct snd_soc_component_driver soc_component_dev_wl1273 = { .idle_bias_on = 1, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static int wl1273_platform_probe(struct platform_device *pdev) -- GitLab From 4a7a283a41dad608ce32c4ed623cc2caf68150c4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:49 +0100 Subject: [PATCH 728/942] ASoC: zl38060: Remove now redundant non_legacy_dai_naming flag The ASoC core has now been changed to default to the non-legacy DAI naming, as such drivers using the new scheme no longer need to specify the non_legacy_dai_naming flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-96-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/zl38060.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/zl38060.c b/sound/soc/codecs/zl38060.c index 6cae0fb08093b..c3d0a2a7c36f2 100644 --- a/sound/soc/codecs/zl38060.c +++ b/sound/soc/codecs/zl38060.c @@ -385,7 +385,6 @@ static const struct snd_soc_component_driver zl38_component_dev = { .dapm_routes = zl38_dapm_routes, .num_dapm_routes = ARRAY_SIZE(zl38_dapm_routes), .endianness = 1, - .non_legacy_dai_naming = 1, }; static void chip_gpio_set(struct gpio_chip *c, unsigned int offset, int val) -- GitLab From 01936221278c5af60d82b8e78ca74caa491c0d31 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 13:52:50 +0100 Subject: [PATCH 729/942] ASoC: soc-component: Remove non_legacy_dai_naming flag Now all the users are moved over to the new legacy_dai_naming flag, remove the now unused old flag. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623125250.2355471-97-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/soc-component.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 96c2f5fffc51e..c26ffb033777a 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -180,7 +180,6 @@ struct snd_soc_component_driver { */ unsigned int endianness:1; unsigned int legacy_dai_naming:1; - unsigned int non_legacy_dai_naming:1; /* this component uses topology and ignore machine driver FEs */ const char *ignore_machine; -- GitLab From 82102a24c930986aedc572f89b437cd9e4d44d7e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:17 -0500 Subject: [PATCH 730/942] ASoC: Intel: catpt: use pm_runtime_resume_and_get() The current code does not check for errors and does not release the reference on errors. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Acked-by: Cezary Rojewski Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/catpt/pcm.c | 26 ++++++++++++++++++++------ sound/soc/intel/catpt/sysfs.c | 4 +++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index a26000cd5cebc..30ca5416c9a3f 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -667,7 +667,9 @@ static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm, if (!memcmp(&cdev->devfmt[devfmt.iface], &devfmt, sizeof(devfmt))) return 0; - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; ret = catpt_ipc_set_device_format(cdev, &devfmt); @@ -853,9 +855,12 @@ static int catpt_mixer_volume_get(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct catpt_dev *cdev = dev_get_drvdata(component->dev); u32 dspvol; + int ret; int i; - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; for (i = 0; i < CATPT_CHANNELS_MAX; i++) { dspvol = catpt_mixer_volume(cdev, &cdev->mixer, i); @@ -876,7 +881,9 @@ static int catpt_mixer_volume_put(struct snd_kcontrol *kcontrol, struct catpt_dev *cdev = dev_get_drvdata(component->dev); int ret; - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; ret = catpt_set_dspvol(cdev, cdev->mixer.mixer_hw_id, ucontrol->value.integer.value); @@ -897,6 +904,7 @@ static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol, struct catpt_dev *cdev = dev_get_drvdata(component->dev); long *ctlvol = (long *)kcontrol->private_value; u32 dspvol; + int ret; int i; stream = catpt_stream_find(cdev, pin_id); @@ -906,7 +914,9 @@ static int catpt_stream_volume_get(struct snd_kcontrol *kcontrol, return 0; } - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; for (i = 0; i < CATPT_CHANNELS_MAX; i++) { dspvol = catpt_stream_volume(cdev, stream, i); @@ -937,7 +947,9 @@ static int catpt_stream_volume_put(struct snd_kcontrol *kcontrol, return 0; } - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; ret = catpt_set_dspvol(cdev, stream->info.stream_hw_id, ucontrol->value.integer.value); @@ -1013,7 +1025,9 @@ static int catpt_loopback_switch_put(struct snd_kcontrol *kcontrol, return 0; } - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; ret = catpt_ipc_mute_loopback(cdev, stream->info.stream_hw_id, mute); diff --git a/sound/soc/intel/catpt/sysfs.c b/sound/soc/intel/catpt/sysfs.c index 9579e233a15db..1bdbcc04dc712 100644 --- a/sound/soc/intel/catpt/sysfs.c +++ b/sound/soc/intel/catpt/sysfs.c @@ -15,7 +15,9 @@ static ssize_t fw_version_show(struct device *dev, struct catpt_fw_version version; int ret; - pm_runtime_get_sync(cdev->dev); + ret = pm_runtime_resume_and_get(cdev->dev); + if (ret < 0 && ret != -EACCES) + return ret; ret = catpt_ipc_get_fw_version(cdev, &version); -- GitLab From 7213170a9515109322f75c08b5268d8e9cdad8e4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:18 -0500 Subject: [PATCH 731/942] ASoC: Intel: skylake: skl-pcm: use pm_runtime_resume_and_get() The current code does not check for errors and does not release the reference on errors. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Acked-by: Cezary Rojewski Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-pcm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 55f310e91b55c..9d72ebd812af9 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -1380,7 +1380,10 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) const struct skl_dsp_ops *ops; int ret; - pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + if (bus->ppcap) { skl->component = component; -- GitLab From ddea4bbf287b6028eaa15a185d0693856956ecf2 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:20 -0500 Subject: [PATCH 732/942] ASoC: wcd-mbhc-v2: use pm_runtime_resume_and_get() simplify the flow. No functionality change, except that on -EACCESS the reference count will be decreased. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Srinivas Kandagatla Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd-mbhc-v2.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 31009283e7d4a..98baef594bf31 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -714,12 +714,11 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) struct snd_soc_component *component = mbhc->component; int ret; - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0 && ret != -EACCES) { dev_err_ratelimited(component->dev, - "pm_runtime_get_sync failed in %s, ret %d\n", + "pm_runtime_resume_and_get failed in %s, ret %d\n", __func__, ret); - pm_runtime_put_noidle(component->dev); return ret; } @@ -1097,12 +1096,11 @@ static void wcd_correct_swch_plug(struct work_struct *work) mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch); component = mbhc->component; - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0 && ret != -EACCES) { dev_err_ratelimited(component->dev, - "pm_runtime_get_sync failed in %s, ret %d\n", + "pm_runtime_resume_and_get failed in %s, ret %d\n", __func__, ret); - pm_runtime_put_noidle(component->dev); return; } micbias_mv = wcd_mbhc_get_micbias(mbhc); -- GitLab From 9a1a28610a1c49bf93777d017aa3fe121eef944e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:21 -0500 Subject: [PATCH 733/942] ASoC: wsa881x: use pm_runtime_resume_and_get() simplify the flow. No functionality change, except that on -EACCESS the reference count will be decreased. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Srinivas Kandagatla Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index f3a56f3ce4871..dc954b85a9881 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -749,11 +749,9 @@ static int wsa881x_put_pa_gain(struct snd_kcontrol *kc, unsigned int mask = (1 << fls(max)) - 1; int val, ret, min_gain, max_gain; - ret = pm_runtime_get_sync(comp->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(comp->dev); + ret = pm_runtime_resume_and_get(comp->dev); + if (ret < 0 && ret != -EACCES) return ret; - } max_gain = (max - ucontrol->value.integer.value[0]) & mask; /* -- GitLab From 8c8a13e83c29472044d733dfb1fced2ccd025d35 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:22 -0500 Subject: [PATCH 734/942] ASoC: rockchip: i2s_tdm: use pm_runtime_resume_and_get() simplify the flow. No functionality change, except that on -EACCESS the reference count will be decreased. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s_tdm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 48b3ecfa58b46..70542a402477e 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -404,11 +404,9 @@ static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai, int ret; bool is_tdm = i2s_tdm->tdm_mode; - ret = pm_runtime_get_sync(cpu_dai->dev); - if (ret < 0 && ret != -EACCES) { - pm_runtime_put_noidle(cpu_dai->dev); + ret = pm_runtime_resume_and_get(cpu_dai->dev); + if (ret < 0 && ret != -EACCES) return ret; - } mask = I2S_CKR_MSS_MASK; switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { -- GitLab From 37cb8a58013fc6ca2febaed355f6559012699542 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:23 -0500 Subject: [PATCH 735/942] ASoC: fsl: fsl_sai: use pm_runtime_resume_and_get() Simplify the flow. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4f5bd9597c746..b6407d4d3e09d 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1141,11 +1141,9 @@ static int fsl_sai_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) goto err_pm_get_sync; - } /* Get sai version */ ret = fsl_sai_check_version(dev); -- GitLab From 57d714535051b1baca9ffd92e79fbda1fae3177a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:24 -0500 Subject: [PATCH 736/942] ASoC: img: img-i2s-out: use pm_runtime_resume_and_get() Simplify the flow. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-9-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/img/img-i2s-out.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 9ec6fc528e2b4..50a522aca419a 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -346,11 +346,9 @@ static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) chan_control_mask = IMG_I2S_OUT_CHAN_CTL_CLKT_MASK; - ret = pm_runtime_get_sync(i2s->dev); - if (ret < 0) { - pm_runtime_put_noidle(i2s->dev); + ret = pm_runtime_resume_and_get(i2s->dev); + if (ret < 0) return ret; - } img_i2s_out_disable(i2s); @@ -482,11 +480,9 @@ static int img_i2s_out_probe(struct platform_device *pdev) if (ret) goto err_pm_disable; } - ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) { - pm_runtime_put_noidle(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) goto err_suspend; - } reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK; img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL); -- GitLab From 76a6f4537650e6d2211f34661de35630487c7c64 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:25 -0500 Subject: [PATCH 737/942] ASoC: rockchip: pdm: use pm_runtime_resume_and_get() Simplify the flow. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_pdm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index 64d9891b6434f..066e29b7879d1 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -688,11 +688,9 @@ static int rockchip_pdm_resume(struct device *dev) struct rk_pdm_dev *pdm = dev_get_drvdata(dev); int ret; - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) return ret; - } ret = regcache_sync(pdm->regmap); -- GitLab From 05b71fb2a5014d2430ff6c5678db021c67afa9ec Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:26 -0500 Subject: [PATCH 738/942] ASoC: tas2552: use pm_runtime_resume_and_get() The use of pm_runtime_get_sync() is buggy with no use of put_noidle() on error. Use pm_runtime_resume_and_get() instead. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/tas2552.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index c98a9332dcc0e..da744cfae611c 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -581,7 +581,7 @@ static int tas2552_component_probe(struct snd_soc_component *component) gpiod_set_value(tas2552->enable_gpio, 1); - ret = pm_runtime_get_sync(component->dev); + ret = pm_runtime_resume_and_get(component->dev); if (ret < 0) { dev_err(component->dev, "Enabling device failed: %d\n", ret); -- GitLab From cecc81d6a5deb094bdbc6a1d7f2c014ba9b71cf8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 17:04:27 -0500 Subject: [PATCH 739/942] ASoC: ti: davinci-mcasp: use pm_runtime_resume_and_get() The use of pm_runtime_get_sync() is buggy with no use of put_noidle on error. Use pm_runtime_resume_and_get() instead. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Kai Vehmanen Reviewed-by: Ranjani Sridharan Acked-by: Peter Ujfalusi Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220616220427.136036-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-mcasp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/ti/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c index e2aab4729f3ab..0201000b619f6 100644 --- a/sound/soc/ti/davinci-mcasp.c +++ b/sound/soc/ti/davinci-mcasp.c @@ -2111,8 +2111,7 @@ static int davinci_mcasp_gpio_request(struct gpio_chip *chip, unsigned offset) } /* Do not change the PIN yet */ - - return pm_runtime_get_sync(mcasp->dev); + return pm_runtime_resume_and_get(mcasp->dev); } static void davinci_mcasp_gpio_free(struct gpio_chip *chip, unsigned offset) -- GitLab From 24e0b04dd42be34ec4b18dc1a1e139d66eb572a3 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Mon, 20 Jun 2022 22:54:50 -0500 Subject: [PATCH 740/942] ASoC: dt-bindings: sun50i-codec: Add binding for internal bias In order to properly bias headset microphones, there should be a pull-up resistor between pins HBIAS and MIC2P. This can be an external resistor, but the codec also provides an internal 2.2K resistor which is enabled by a register. This patch adds a device-tree property to the sun50i-codec-analog driver to take advantage of this feature. Signed-off-by: Arnaud Ferraris [Samuel: split binding and implementation patches] Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220621035452.60272-2-samuel@sholland.org Signed-off-by: Mark Brown --- .../bindings/sound/allwinner,sun50i-a64-codec-analog.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml index 3b764415c9abf..66859eb8f79ab 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml @@ -21,6 +21,11 @@ properties: description: Regulator for the headphone amplifier + allwinner,internal-bias-resistor: + description: + Enable the internal 2.2K bias resistor between HBIAS and MICDET pins + type: boolean + required: - compatible - reg -- GitLab From 25ae1a04da0d32c22db0b018e5668129b91fa104 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Mon, 20 Jun 2022 22:54:51 -0500 Subject: [PATCH 741/942] ASoC: sun50i-codec-analog: Add support for internal bias In order to properly bias headset microphones, there should be a pull-up resistor between pins HBIAS and MIC2P. This can be an external resistor, but the codec also provides an internal 2.2K resistor which is enabled by a register. This patch enables or disables the internal bias resistor based on a device tree property. Signed-off-by: Arnaud Ferraris [Samuel: split binding and implementation; move to device probe] Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20220621035452.60272-3-samuel@sholland.org Signed-off-by: Mark Brown --- sound/soc/sunxi/sun50i-codec-analog.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index a41e25ad0aaf0..e1e5e8de01301 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -117,6 +117,7 @@ #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7 #define SUN50I_ADDA_JACK_MIC_CTRL 0x1d +#define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN 6 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN 5 /* mixer controls */ @@ -507,6 +508,7 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev) { struct regmap *regmap; void __iomem *base; + bool enable; base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) { @@ -520,6 +522,12 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev) return PTR_ERR(regmap); } + enable = device_property_read_bool(&pdev->dev, + "allwinner,internal-bias-resistor"); + regmap_update_bits(regmap, SUN50I_ADDA_JACK_MIC_CTRL, + BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN), + enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN); + return devm_snd_soc_register_component(&pdev->dev, &sun50i_codec_analog_cmpnt_drv, NULL, 0); -- GitLab From c111c2ddb3fdfca06bb5c7a56db7f97d6d9ea640 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:31 +0800 Subject: [PATCH 742/942] ASoC: fsl_sai: Add PDM daifmt support PDM format is used for 1-bit stream, so clear the FBT and SYWD, and the each dataline only has one channel data. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-2-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 17 +++++++++++++++-- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4f5bd9597c746..d11ee3b6f1639 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -224,6 +224,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, if (!sai->is_lsb_first) val_cr4 |= FSL_SAI_CR4_MF; + sai->is_pdm_mode = false; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: @@ -262,6 +263,11 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, val_cr2 |= FSL_SAI_CR2_BCP; sai->is_dsp_mode = true; break; + case SND_SOC_DAIFMT_PDM: + val_cr2 |= FSL_SAI_CR2_BCP; + val_cr4 &= ~FSL_SAI_CR4_MF; + sai->is_pdm_mode = true; + break; case SND_SOC_DAIFMT_RIGHT_J: /* To be done */ default: @@ -470,6 +476,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, pins = DIV_ROUND_UP(channels, slots); + /* + * PDM mode, channels are independent + * each channels are on one dataline/FIFO. + */ + if (sai->is_pdm_mode) + pins = channels; + if (!sai->is_consumer_mode) { if (sai->bclk_ratio) ret = fsl_sai_set_bclk(cpu_dai, tx, @@ -492,13 +505,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, } } - if (!sai->is_dsp_mode) + if (!sai->is_dsp_mode && !sai->is_pdm_mode) val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); val_cr5 |= FSL_SAI_CR5_WNW(slot_width); val_cr5 |= FSL_SAI_CR5_W0W(slot_width); - if (sai->is_lsb_first) + if (sai->is_lsb_first || sai->is_pdm_mode) val_cr5 |= FSL_SAI_CR5_FBT(0); else val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 1c8f5ca07f9d0..bc2a86a413e10 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -259,6 +259,7 @@ struct fsl_sai { bool is_consumer_mode; bool is_lsb_first; bool is_dsp_mode; + bool is_pdm_mode; bool synchronous[2]; unsigned int mclk_id[2]; -- GitLab From 4665770407de8af3b24250cec2209eaf58546f8a Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:32 +0800 Subject: [PATCH 743/942] ASoC: fsl_sai: Add DSD bit format support Support DSD_U8, DSD_U16_LE, DSD_U32_LE. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-3-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index bc2a86a413e10..e28a49ce12ef2 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -11,7 +11,10 @@ #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) + SNDRV_PCM_FMTBIT_S32_LE |\ + SNDRV_PCM_FMTBIT_DSD_U8 |\ + SNDRV_PCM_FMTBIT_DSD_U16_LE |\ + SNDRV_PCM_FMTBIT_DSD_U32_LE) /* SAI Register Map Register */ #define FSL_SAI_VERID 0x00 /* SAI Version ID Register */ -- GitLab From 0d11bab8ef3e5540dfba111947dbd8dcfb813150 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:33 +0800 Subject: [PATCH 744/942] ASoC: fsl_sai: Add support for more sample rates Add support for more sample rates, because PDM format bitstream has higher sample rates. for example DSD512 format, the bit clock is 22.5792MHz, if the word width is U8_LE, then the max sample rate is 2822400. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-4-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index d11ee3b6f1639..9d2828b55c073 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -30,7 +30,8 @@ static const unsigned int fsl_sai_rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, - 88200, 96000, 176400, 192000 + 88200, 96000, 176400, 192000, 352800, + 384000, 705600, 768000, 1411200, 2822400, }; static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { @@ -763,7 +764,7 @@ static struct snd_soc_dai_driver fsl_sai_dai_template = { .channels_min = 1, .channels_max = 32, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 2822400, .rates = SNDRV_PCM_RATE_KNOT, .formats = FSL_SAI_FORMATS, }, @@ -772,7 +773,7 @@ static struct snd_soc_dai_driver fsl_sai_dai_template = { .channels_min = 1, .channels_max = 32, .rate_min = 8000, - .rate_max = 192000, + .rate_max = 2822400, .rates = SNDRV_PCM_RATE_KNOT, .formats = FSL_SAI_FORMATS, }, -- GitLab From b4ee8a913e617a2d0f19226225bc025c8640bf34 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:34 +0800 Subject: [PATCH 745/942] ASoc: fsl_sai: Add pinctrl operation for PDM and DSD With DSD format, the pinctrl is different compare with I2S format, because one dataline only has one channel data, and the codec always mux the LRCLK pin to DSD data line, and on i.MX8MQ the BCLK pin can route to codec on DSD case for the MCLK is too high. Add pinctrl operation that the pinctrl can be switched on runtime according to the I2S format or DSD format Signed-off-by: Viorel Suman Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-5-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 70 +++++++++++++++++++++++++++++++++++------ sound/soc/fsl/fsl_sai.h | 2 ++ 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 9d2828b55c073..ddfe28cb7df0b 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,31 @@ static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir) return !sai->synchronous[dir] && sai->synchronous[adir]; } +static struct pinctrl_state *fsl_sai_get_pins_state(struct fsl_sai *sai, u32 bclk) +{ + struct pinctrl_state *state = 0; + + if (sai->is_pdm_mode) { + /* DSD512@44.1kHz, DSD512@48kHz */ + if (bclk >= 22579200) + state = pinctrl_lookup_state(sai->pinctrl, "dsd512"); + + /* Get default DSD state */ + if (IS_ERR_OR_NULL(state)) + state = pinctrl_lookup_state(sai->pinctrl, "dsd"); + } else { + /* 706k32b2c, 768k32b2c, etc */ + if (bclk >= 45158400) + state = pinctrl_lookup_state(sai->pinctrl, "pcm_b2m"); + } + + /* Get default state */ + if (IS_ERR_OR_NULL(state)) + state = pinctrl_lookup_state(sai->pinctrl, "default"); + + return state; +} + static irqreturn_t fsl_sai_isr(int irq, void *devid) { struct fsl_sai *sai = (struct fsl_sai *)devid; @@ -466,7 +492,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, u32 slots = (channels == 1) ? 2 : channels; u32 slot_width = word_width; int adir = tx ? RX : TX; - u32 pins; + u32 pins, bclk; int ret; if (sai->slots) @@ -484,15 +510,21 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, if (sai->is_pdm_mode) pins = channels; + bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width); + + if (!IS_ERR_OR_NULL(sai->pinctrl)) { + sai->pins_state = fsl_sai_get_pins_state(sai, bclk); + if (!IS_ERR_OR_NULL(sai->pins_state)) { + ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); + if (ret) { + dev_err(cpu_dai->dev, "failed to set proper pins state: %d\n", ret); + return ret; + } + } + } + if (!sai->is_consumer_mode) { - if (sai->bclk_ratio) - ret = fsl_sai_set_bclk(cpu_dai, tx, - sai->bclk_ratio * - params_rate(params)); - else - ret = fsl_sai_set_bclk(cpu_dai, tx, - slots * slot_width * - params_rate(params)); + ret = fsl_sai_set_bclk(cpu_dai, tx, bclk); if (ret) return ret; @@ -757,6 +789,23 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) return 0; } +static int fsl_sai_dai_resume(struct snd_soc_component *component) +{ + struct fsl_sai *sai = snd_soc_component_get_drvdata(component); + struct device *dev = &sai->pdev->dev; + int ret; + + if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) { + ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); + if (ret) { + dev_err(dev, "failed to set proper pins state: %d\n", ret); + return ret; + } + } + + return 0; +} + static struct snd_soc_dai_driver fsl_sai_dai_template = { .probe = fsl_sai_dai_probe, .playback = { @@ -782,6 +831,7 @@ static struct snd_soc_dai_driver fsl_sai_dai_template = { static const struct snd_soc_component_driver fsl_component = { .name = "fsl-sai", + .resume = fsl_sai_dai_resume, }; static struct reg_default fsl_sai_reg_defaults_ofs0[] = { @@ -1147,6 +1197,8 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; + sai->pinctrl = devm_pinctrl_get(&pdev->dev); + platform_set_drvdata(pdev, sai); pm_runtime_enable(dev); if (!pm_runtime_enabled(dev)) { diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index e28a49ce12ef2..c0b6bc42fc3ce 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -278,6 +278,8 @@ struct fsl_sai { struct fsl_sai_verid verid; struct fsl_sai_param param; struct pm_qos_request pm_qos_req; + struct pinctrl *pinctrl; + struct pinctrl_state *pins_state; }; #define TX 1 -- GitLab From cd640ca20095ed3b9306981f0064313a54fd4568 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:35 +0800 Subject: [PATCH 746/942] ASoC: fsl_sai: Make res a member of struct fsl_sai The resource info need to be accessed by hw_params() function for multi fifo case, the start address may be not the FIFO0. So move it to be a member of struct fsl_sai. Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-6-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 7 +++---- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index ddfe28cb7df0b..86aa0baba8480 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1077,7 +1077,6 @@ static int fsl_sai_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct fsl_sai *sai; struct regmap *gpr; - struct resource *res; void __iomem *base; char tmp[8]; int irq, ret, i; @@ -1092,7 +1091,7 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); - base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &sai->res); if (IS_ERR(base)) return PTR_ERR(base); @@ -1192,8 +1191,8 @@ static int fsl_sai_probe(struct platform_device *pdev) MCLK_DIR(index)); } - sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; - sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; + sai->dma_params_rx.addr = sai->res->start + FSL_SAI_RDR0; + sai->dma_params_tx.addr = sai->res->start + FSL_SAI_TDR0; sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index c0b6bc42fc3ce..4d657edc9c9f0 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -258,6 +258,7 @@ struct fsl_sai { struct regmap *regmap; struct clk *bus_clk; struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; + struct resource *res; bool is_consumer_mode; bool is_lsb_first; -- GitLab From 6b878ac2711056dd07c712caf89f58449cf5a592 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:36 +0800 Subject: [PATCH 747/942] ASoC: dt-bindings: fsl-sai: Add new property to configure dataline "fsl,dataline" is added to configure the dataline of SAI. It has 3 value for each configuration, first one means the type: I2S(1) or PDM(2), second one is dataline mask for 'rx', third one is dataline mask for 'tx'. for example: fsl,dataline = <1 0xff 0xff 2 0xff 0x11>, it means I2S type rx mask is 0xff, tx mask is 0xff, PDM type rx mask is 0xff, tx mask is 0x11 (dataline 1 and 4 enabled). Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1655451877-16382-7-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-sai.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index c71c5861d787e..4c66e6a1a533b 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -49,6 +49,14 @@ Required properties: receive data by following their own bit clocks and frame sync clocks separately. + - fsl,dataline : configure the dataline. it has 3 value for each configuration + first one means the type: I2S(1) or PDM(2) + second one is dataline mask for 'rx' + third one is dataline mask for 'tx'. + for example: fsl,dataline = <1 0xff 0xff 2 0xff 0x11>; + it means I2S type rx mask is 0xff, tx mask is 0xff, PDM type + rx mask is 0xff, tx mask is 0x11 (dataline 1 and 4 enabled). + Optional properties: - big-endian : Boolean property, required if all the SAI -- GitLab From e3f4e5b1a3e654d518155b37c7b2084cbce9d1a7 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 17 Jun 2022 15:44:37 +0800 Subject: [PATCH 748/942] ASoC: fsl_sai: Configure dataline/FIFO information from dts property The SAI has multiple successive FIFO registers, but in some use case the required dataline/FIFOs are not successive, so need get such information from dts property "fsl,dataline" fsl,dataline has 3 values for each configuration: first one means the type: I2S(1) or DSD(2), second one is dataline mask for 'rx', third one is dataline mask for 'tx'. Also set dma peripheral address and TRCE bits according to data lane. Signed-off-by: Shengjiu Wang Signed-off-by: Viorel Suman Link: https://lore.kernel.org/r/1655451877-16382-8-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 161 +++++++++++++++++++++++++++++++++++++++- sound/soc/fsl/fsl_sai.h | 17 +++++ 2 files changed, 174 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 86aa0baba8480..f5eabb0b10e8c 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -487,13 +487,18 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, unsigned int ofs = sai->soc_data->reg_offset; bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; unsigned int channels = params_channels(params); + struct snd_dmaengine_dai_dma_data *dma_params; + struct fsl_sai_dl_cfg *dl_cfg = sai->dl_cfg; u32 word_width = params_width(params); + int trce_mask = 0, dl_cfg_idx = 0; + int dl_cfg_cnt = sai->dl_cfg_cnt; + u32 dl_type = FSL_SAI_DL_I2S; u32 val_cr4 = 0, val_cr5 = 0; u32 slots = (channels == 1) ? 2 : channels; u32 slot_width = word_width; int adir = tx ? RX : TX; u32 pins, bclk; - int ret; + int ret, i; if (sai->slots) slots = sai->slots; @@ -507,8 +512,22 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, * PDM mode, channels are independent * each channels are on one dataline/FIFO. */ - if (sai->is_pdm_mode) + if (sai->is_pdm_mode) { pins = channels; + dl_type = FSL_SAI_DL_PDM; + } + + for (i = 0; i < dl_cfg_cnt; i++) { + if (dl_cfg[i].type == dl_type && dl_cfg[i].pins[tx] == pins) { + dl_cfg_idx = i; + break; + } + } + + if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) < pins) { + dev_err(cpu_dai->dev, "channel not supported\n"); + return -EINVAL; + } bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width); @@ -571,13 +590,28 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, FSL_SAI_CR5_FBT_MASK, val_cr5); } - if (sai->soc_data->pins > 1) + if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1) + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), + FSL_SAI_CR4_FCOMB_MASK, 0); + else regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); + dma_params = tx ? &sai->dma_params_tx : &sai->dma_params_rx; + dma_params->addr = sai->res->start + FSL_SAI_xDR0(tx) + + dl_cfg[dl_cfg_idx].start_off[tx] * 0x4; + + /* Find a proper tcre setting */ + for (i = 0; i < sai->soc_data->pins; i++) { + trce_mask = (1 << (i + 1)) - 1; + if (hweight8(dl_cfg[dl_cfg_idx].mask[tx] & trce_mask) == pins) + break; + } + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE((1 << pins) - 1)); + FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask))); + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | FSL_SAI_CR4_CHMOD_MASK, @@ -1068,6 +1102,118 @@ static int fsl_sai_check_version(struct device *dev) return 0; } +/* + * Calculate the offset between first two datalines, don't + * different offset in one case. + */ +static unsigned int fsl_sai_calc_dl_off(unsigned long dl_mask) +{ + int fbidx, nbidx, offset; + + fbidx = find_first_bit(&dl_mask, FSL_SAI_DL_NUM); + nbidx = find_next_bit(&dl_mask, FSL_SAI_DL_NUM, fbidx + 1); + offset = nbidx - fbidx - 1; + + return (offset < 0 || offset >= (FSL_SAI_DL_NUM - 1) ? 0 : offset); +} + +/* + * read the fsl,dataline property from dts file. + * It has 3 value for each configuration, first one means the type: + * I2S(1) or PDM(2), second one is dataline mask for 'rx', third one is + * dataline mask for 'tx'. for example + * + * fsl,dataline = <1 0xff 0xff 2 0xff 0x11>, + * + * It means I2S type rx mask is 0xff, tx mask is 0xff, PDM type + * rx mask is 0xff, tx mask is 0x11 (dataline 1 and 4 enabled). + * + */ +static int fsl_sai_read_dlcfg(struct fsl_sai *sai) +{ + struct platform_device *pdev = sai->pdev; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + int ret, elems, i, index, num_cfg; + char *propname = "fsl,dataline"; + struct fsl_sai_dl_cfg *cfg; + unsigned long dl_mask; + unsigned int soc_dl; + u32 rx, tx, type; + + elems = of_property_count_u32_elems(np, propname); + + if (elems <= 0) { + elems = 0; + } else if (elems % 3) { + dev_err(dev, "Number of elements must be divisible to 3.\n"); + return -EINVAL; + } + + num_cfg = elems / 3; + /* Add one more for default value */ + cfg = devm_kzalloc(&pdev->dev, (num_cfg + 1) * sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + /* Consider default value "0 0xFF 0xFF" if property is missing */ + soc_dl = BIT(sai->soc_data->pins) - 1; + cfg[0].type = FSL_SAI_DL_DEFAULT; + cfg[0].pins[0] = sai->soc_data->pins; + cfg[0].mask[0] = soc_dl; + cfg[0].start_off[0] = 0; + cfg[0].next_off[0] = 0; + + cfg[0].pins[1] = sai->soc_data->pins; + cfg[0].mask[1] = soc_dl; + cfg[0].start_off[1] = 0; + cfg[0].next_off[1] = 0; + for (i = 1, index = 0; i < num_cfg + 1; i++) { + /* + * type of dataline + * 0 means default mode + * 1 means I2S mode + * 2 means PDM mode + */ + ret = of_property_read_u32_index(np, propname, index++, &type); + if (ret) + return -EINVAL; + + ret = of_property_read_u32_index(np, propname, index++, &rx); + if (ret) + return -EINVAL; + + ret = of_property_read_u32_index(np, propname, index++, &tx); + if (ret) + return -EINVAL; + + if ((rx & ~soc_dl) || (tx & ~soc_dl)) { + dev_err(dev, "dataline cfg[%d] setting error, mask is 0x%x\n", i, soc_dl); + return -EINVAL; + } + + rx = rx & soc_dl; + tx = tx & soc_dl; + + cfg[i].type = type; + cfg[i].pins[0] = hweight8(rx); + cfg[i].mask[0] = rx; + dl_mask = rx; + cfg[i].start_off[0] = find_first_bit(&dl_mask, FSL_SAI_DL_NUM); + cfg[i].next_off[0] = fsl_sai_calc_dl_off(rx); + + cfg[i].pins[1] = hweight8(tx); + cfg[i].mask[1] = tx; + dl_mask = tx; + cfg[i].start_off[1] = find_first_bit(&dl_mask, FSL_SAI_DL_NUM); + cfg[i].next_off[1] = fsl_sai_calc_dl_off(tx); + } + + sai->dl_cfg = cfg; + sai->dl_cfg_cnt = num_cfg + 1; + return 0; +} + static int fsl_sai_runtime_suspend(struct device *dev); static int fsl_sai_runtime_resume(struct device *dev); @@ -1134,6 +1280,13 @@ static int fsl_sai_probe(struct platform_device *pdev) else sai->mclk_clk[0] = sai->bus_clk; + /* read dataline mask for rx and tx*/ + ret = fsl_sai_read_dlcfg(sai); + if (ret < 0) { + dev_err(dev, "failed to read dlcfg %d\n", ret); + return ret; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 4d657edc9c9f0..9bb8ced520c80 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -218,6 +218,13 @@ #define PMQOS_CPU_LATENCY BIT(0) +/* Max number of dataline */ +#define FSL_SAI_DL_NUM (8) +/* default dataline type is zero */ +#define FSL_SAI_DL_DEFAULT (0) +#define FSL_SAI_DL_I2S BIT(0) +#define FSL_SAI_DL_PDM BIT(1) + struct fsl_sai_soc_data { bool use_imx_pcm; bool use_edma; @@ -253,6 +260,14 @@ struct fsl_sai_param { u32 dataline; }; +struct fsl_sai_dl_cfg { + unsigned int type; + unsigned int pins[2]; + unsigned int mask[2]; + unsigned int start_off[2]; + unsigned int next_off[2]; +}; + struct fsl_sai { struct platform_device *pdev; struct regmap *regmap; @@ -265,6 +280,8 @@ struct fsl_sai { bool is_dsp_mode; bool is_pdm_mode; bool synchronous[2]; + struct fsl_sai_dl_cfg *dl_cfg; + unsigned int dl_cfg_cnt; unsigned int mclk_id[2]; unsigned int mclk_streams; -- GitLab From ccb0bbe3e93efa1c794176200785737ba65b0131 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 27 Jun 2022 10:43:35 +0100 Subject: [PATCH 749/942] ASoC: samsung: s3c24xx-i2s: Fix typo in DAIFMT handling The conversion of the set_fmt callback to direct clock specification included a small typo, correct the affected code. Reported-by: kernel test robot Signed-off-by: Charles Keepax Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220627094335.3051210-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/samsung/s3c24xx-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 4082ad7cbcc11..c1a314b86b155 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -170,7 +170,7 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, pr_debug("hw_params r: IISMOD: %x \n", iismod); switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BC_CFC: + case SND_SOC_DAIFMT_BC_FC: iismod |= S3C2410_IISMOD_SLAVE; break; case SND_SOC_DAIFMT_BP_FP: -- GitLab From 17a1ffc7bc4d5b4657d0f3fe5c01778d8fcab9a3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 27 Jun 2022 16:34:10 +0200 Subject: [PATCH 750/942] ASoC: samsung: s3c-i2s-v2: Allow build for unsupported hardware There is no particular need to restrict building of S3C I2S driver to supported platforms within the C unit, because Kconfig does it. Removing such restricting #ifdef from s3c-i2s-v2 allows compile testing it on other platforms. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220627143412.477226-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/s3c-i2s-v2.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 1bec72246ed0c..2b221cb0ed03a 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -21,17 +21,6 @@ #include "regs-i2s-v2.h" #include "s3c-i2s-v2.h" -#undef S3C_IIS_V2_SUPPORTED - -#if defined(CONFIG_CPU_S3C2412) \ - || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) -#define S3C_IIS_V2_SUPPORTED -#endif - -#ifndef S3C_IIS_V2_SUPPORTED -#error Unsupported CPU model -#endif - #define S3C2412_I2S_DEBUG_CON 0 static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -- GitLab From 3e4bac7cf06e46225322f264e7387efe6ddd457e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 27 Jun 2022 16:34:11 +0200 Subject: [PATCH 751/942] ASoC: samsung: s3c24xx-i2s: Drop unneeded gpio.h include The module does not use anything from gpio.h header. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220627143412.477226-2-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/s3c24xx-i2s.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index c1a314b86b155..44e93dc16fc3e 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include -- GitLab From f43ff8038e8289ca811b5b89e8cc15083dafe5c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 27 Jun 2022 16:34:12 +0200 Subject: [PATCH 752/942] ASoC: samsung: Enable compile test Allow compile testing of Samsung SoC Sound drivers. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220627143412.477226-3-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index a2221ebb1b6ab..2a61e620cd3b0 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -33,7 +33,8 @@ config SND_SAMSUNG_I2S config SND_SOC_SAMSUNG_NEO1973_WM8753 tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" - depends on MACH_NEO1973_GTA02 + depends on MACH_NEO1973_GTA02 || COMPILE_TEST + depends on SND_SOC_I2C_AND_SPI select SND_S3C24XX_I2S select SND_SOC_WM8753 select SND_SOC_BT_SCO @@ -43,7 +44,8 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753 config SND_SOC_SAMSUNG_JIVE_WM8750 tristate "SoC I2S Audio support for Jive" - depends on MACH_JIVE && I2C + depends on MACH_JIVE && I2C || COMPILE_TEST && ARM + depends on SND_SOC_I2C_AND_SPI select SND_SOC_WM8750 select SND_S3C2412_SOC_I2S help @@ -69,7 +71,7 @@ config SND_SOC_SAMSUNG_SMDK_WM8994 config SND_SOC_SAMSUNG_S3C24XX_UDA134X tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on ARCH_S3C24XX + depends on ARCH_S3C24XX || COMPILE_TEST select SND_S3C24XX_I2S select SND_SOC_L3 select SND_SOC_UDA134X @@ -81,21 +83,24 @@ config SND_SOC_SAMSUNG_SIMTEC config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on ARCH_S3C24XX && I2C + depends on ARCH_S3C24XX || COMPILE_TEST + depends on I2C select SND_S3C24XX_I2S select SND_SOC_TLV320AIC23_I2C select SND_SOC_SAMSUNG_SIMTEC config SND_SOC_SAMSUNG_SIMTEC_HERMES tristate "SoC I2S Audio support for Simtec Hermes board" - depends on ARCH_S3C24XX && I2C + depends on ARCH_S3C24XX || COMPILE_TEST + depends on I2C select SND_S3C24XX_I2S select SND_SOC_TLV320AIC3X select SND_SOC_SAMSUNG_SIMTEC config SND_SOC_SAMSUNG_H1940_UDA1380 tristate "Audio support for the HP iPAQ H1940" - depends on ARCH_H1940 && I2C + depends on ARCH_H1940 || COMPILE_TEST + depends on I2C select SND_S3C24XX_I2S select SND_SOC_UDA1380 help @@ -103,7 +108,8 @@ config SND_SOC_SAMSUNG_H1940_UDA1380 config SND_SOC_SAMSUNG_RX1950_UDA1380 tristate "Audio support for the HP iPAQ RX1950" - depends on MACH_RX1950 && I2C + depends on MACH_RX1950 || COMPILE_TEST + depends on I2C select SND_S3C24XX_I2S select SND_SOC_UDA1380 help -- GitLab From bd10b0dafdcf0ec1677cad70101e1f97b9e28f2e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 27 Jun 2022 16:19:00 +0200 Subject: [PATCH 753/942] ASoC: samsung: h1940_uda1380: include proepr GPIO consumer header h1940_uda1380 uses gpiod*/GPIOD* so it should include GPIO consumer header. Fixes: 9666e27f90b9 ("ASoC: samsung: h1940: turn into platform driver") Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220627141900.470469-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- sound/soc/samsung/h1940_uda1380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 907266aee839f..fa45a54ab18f9 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -8,7 +8,7 @@ // Based on version from Arnaud Patard #include -#include +#include #include #include -- GitLab From 2a2ef688b1b03eea3a5b020d9bef50d015f619be Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Tue, 28 Jun 2022 13:04:34 +0100 Subject: [PATCH 754/942] ASoC: qcom: lpass: Fix apq8016 compat string to match yaml The documented yaml compat string for the apq8016 is "qcom,apq8016-lpass-cpu" not "qcom,lpass-cpu-apq8016". Looking at the other lpass compat strings the general form is "qcom,socnum-lpass-cpu". We need to fix both the driver and dts to match. Reviewed-by: Srinivas Kandagatla Reviewed-by: Bjorn Andersson Signed-off-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20220628120435.3044939-2-bryan.odonoghue@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-apq8016.c | 1 + sound/soc/qcom/lpass-cpu.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c index 3efa133d1c641..abaf694ee9a3a 100644 --- a/sound/soc/qcom/lpass-apq8016.c +++ b/sound/soc/qcom/lpass-apq8016.c @@ -293,6 +293,7 @@ static struct lpass_variant apq8016_data = { static const struct of_device_id apq8016_lpass_cpu_device_id[] __maybe_unused = { { .compatible = "qcom,lpass-cpu-apq8016", .data = &apq8016_data }, + { .compatible = "qcom,apq8016-lpass-cpu", .data = &apq8016_data }, {} }; MODULE_DEVICE_TABLE(of, apq8016_lpass_cpu_device_id); diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index e6846ad2b5fa4..53f9bf6581d33 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1102,6 +1102,11 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) if (!match || !match->data) return -EINVAL; + if (of_device_is_compatible(dev->of_node, "qcom,lpass-cpu-apq8016")) { + dev_warn(dev, "%s compatible is deprecated\n", + match->compatible); + } + drvdata->variant = (struct lpass_variant *)match->data; variant = drvdata->variant; -- GitLab From 5f78e1fb7a3ed1acc355145536ddd54f183b635d Mon Sep 17 00:00:00 2001 From: Srinivasa Rao Mandadapu Date: Mon, 27 Jun 2022 16:14:22 +0530 Subject: [PATCH 755/942] ASoC: qcom: Add driver support for audioreach solution Add Machine driver support for audioreach solution, which uses ADSP in SC7280 based paltforms. Signed-off-by: Srinivasa Rao Mandadapu Link: https://lore.kernel.org/r/1656326662-14524-1-git-send-email-quic_srivasam@quicinc.com Signed-off-by: Mark Brown --- sound/soc/qcom/sc7280.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c index 34cdb99d4ed6a..da7469a6a267d 100644 --- a/sound/soc/qcom/sc7280.c +++ b/sound/soc/qcom/sc7280.c @@ -19,9 +19,11 @@ #include "../codecs/rt5682s.h" #include "common.h" #include "lpass.h" +#include "qdsp6/q6afe.h" #define DEFAULT_MCLK_RATE 19200000 #define RT5682_PLL_FREQ (48000 * 512) +#define MI2S_BCLK_RATE 1536000 struct sc7280_snd_data { struct snd_soc_card card; @@ -79,6 +81,7 @@ static int sc7280_headset_init(struct snd_soc_pcm_runtime *rtd) case MI2S_PRIMARY: case LPASS_CDC_DMA_RX0: case LPASS_CDC_DMA_TX3: + case TX_CODEC_DMA_TX_3: for_each_rtd_codec_dais(rtd, i, codec_dai) { rval = snd_soc_component_set_jack(component, &pdata->hs_jack, NULL); if (rval != 0 && rval != -ENOTSUPP) { @@ -164,10 +167,14 @@ static int sc7280_init(struct snd_soc_pcm_runtime *rtd) switch (cpu_dai->id) { case MI2S_PRIMARY: case LPASS_CDC_DMA_TX3: + case TX_CODEC_DMA_TX_3: return sc7280_headset_init(rtd); case LPASS_CDC_DMA_RX0: case LPASS_CDC_DMA_VA_TX0: case MI2S_SECONDARY: + case RX_CODEC_DMA_RX_0: + case SECONDARY_MI2S_RX: + case VA_CODEC_DMA_TX_0: return 0; case LPASS_DP_RX: return sc7280_hdmi_init(rtd); @@ -195,6 +202,10 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream, switch (cpu_dai->id) { case LPASS_CDC_DMA_TX3: case LPASS_CDC_DMA_RX0: + case RX_CODEC_DMA_RX_0: + case SECONDARY_MI2S_RX: + case TX_CODEC_DMA_TX_3: + case VA_CODEC_DMA_TX_0: for_each_rtd_codec_dais(rtd, i, codec_dai) { sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); if (sruntime != ERR_PTR(-ENOTSUPP)) @@ -245,6 +256,9 @@ static int sc7280_snd_prepare(struct snd_pcm_substream *substream) switch (cpu_dai->id) { case LPASS_CDC_DMA_RX0: case LPASS_CDC_DMA_TX3: + case RX_CODEC_DMA_RX_0: + case TX_CODEC_DMA_TX_3: + case VA_CODEC_DMA_TX_0: return sc7280_snd_swr_prepare(substream); default: break; @@ -263,6 +277,9 @@ static int sc7280_snd_hw_free(struct snd_pcm_substream *substream) switch (cpu_dai->id) { case LPASS_CDC_DMA_RX0: case LPASS_CDC_DMA_TX3: + case RX_CODEC_DMA_RX_0: + case TX_CODEC_DMA_TX_3: + case VA_CODEC_DMA_TX_0: if (sruntime && data->stream_prepared[cpu_dai->id]) { sdw_disable_stream(sruntime); sdw_deprepare_stream(sruntime); @@ -291,6 +308,10 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) SNDRV_PCM_STREAM_PLAYBACK); } break; + case SECONDARY_MI2S_RX: + snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + 0, SNDRV_PCM_STREAM_PLAYBACK); + break; default: break; } @@ -298,14 +319,26 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) static int sc7280_snd_startup(struct snd_pcm_substream *substream) { + unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int ret = 0; switch (cpu_dai->id) { case MI2S_PRIMARY: ret = sc7280_rt5682_init(rtd); break; + case SECONDARY_MI2S_RX: + codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; + + snd_soc_dai_set_sysclk(cpu_dai, Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, + MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); + + snd_soc_dai_set_fmt(cpu_dai, fmt); + snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); + break; default: break; } -- GitLab From 16e2f8a4e9d5e4c7653ee774d9377d602070b16e Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 29 Jun 2022 10:06:41 +0100 Subject: [PATCH 756/942] ASoC: dt-bindings: Add WSA883x bindings This patch adds bindings for WSA883x Smart Speaker Amplifier. This Amplifier also has a simple thermal sensor for temperature measurments with speaker protection. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220629090644.67982-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- .../bindings/sound/qcom,wsa883x.yaml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/qcom,wsa883x.yaml diff --git a/Documentation/devicetree/bindings/sound/qcom,wsa883x.yaml b/Documentation/devicetree/bindings/sound/qcom,wsa883x.yaml new file mode 100644 index 0000000000000..6113f65f29905 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,wsa883x.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,wsa883x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bindings for The Qualcomm WSA8830/WSA8832/WSA8835 + smart speaker amplifier + +maintainers: + - Srinivas Kandagatla + +description: | + WSA883X is the Qualcomm Aqstic smart speaker amplifier + Their primary operating mode uses a SoundWire digital audio + interface. This binding is for SoundWire interface. + +properties: + compatible: + const: sdw10217020200 + + reg: + maxItems: 1 + + powerdown-gpios: + description: GPIO spec for Powerdown/Shutdown line to use + maxItems: 1 + + vdd-supply: + description: VDD Supply for the Codec + + '#thermal-sensor-cells': + const: 0 + + '#sound-dai-cells': + const: 0 + +required: + - compatible + - reg + - vdd-supply + - powerdown-gpios + - "#thermal-sensor-cells" + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + soundwire-controller@3250000 { + #address-cells = <2>; + #size-cells = <0>; + reg = <0x3250000 0x2000>; + + speaker@0,1 { + compatible = "sdw10217020200"; + reg = <0 1>; + powerdown-gpios = <&tlmm 1 0>; + vdd-supply = <&vreg_s10b_1p8>; + #thermal-sensor-cells = <0>; + #sound-dai-cells = <0>; + }; + + speaker@0,2 { + compatible = "sdw10217020200"; + reg = <0 2>; + powerdown-gpios = <&tlmm 89 0>; + vdd-supply = <&vreg_s10b_1p8>; + #thermal-sensor-cells = <0>; + #sound-dai-cells = <0>; + }; + }; + +... -- GitLab From 43b8c7dc85a14f36048a27bb6c627fd49144a8d1 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 29 Jun 2022 10:06:42 +0100 Subject: [PATCH 757/942] ASoC: codecs: add wsa883x amplifier support This patch adds support to WSA8830/WSA8812/WSA8835 Class-D Smart Speaker Amplifier. This Amplifier is primarily interfaced with SoundWire. This patch is tested on SM8450 MTP Board. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220629090644.67982-3-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 10 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wsa883x.c | 1301 ++++++++++++++++++++++++++++++++++++ 3 files changed, 1313 insertions(+) create mode 100644 sound/soc/codecs/wsa883x.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 5a60633a196c1..ee7e028e84024 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -308,6 +308,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_WM9712 imply SND_SOC_WM9713 imply SND_SOC_WSA881X + imply SND_SOC_WSA883X imply SND_SOC_ZL38060 help Normally ASoC codec drivers are only built if a machine driver which @@ -1985,6 +1986,15 @@ config SND_SOC_WSA881X This enables support for Qualcomm WSA8810/WSA8815 Class-D Smart Speaker Amplifier. +config SND_SOC_WSA883X + tristate "WSA883X Codec" + depends on SOUNDWIRE + select REGMAP_SOUNDWIRE + tristate + help + This enables support for Qualcomm WSA8830/WSA8835 Class-D + Smart Speaker Amplifier. + config SND_SOC_ZL38060 tristate "Microsemi ZL38060 Connected Home Audio Processor" depends on SPI_MASTER diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d32026ae326f8..60354579fe5ca 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -338,6 +338,7 @@ snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o snd-soc-wsa881x-objs := wsa881x.o +snd-soc-wsa883x-objs := wsa883x.o snd-soc-zl38060-objs := zl38060.o # Amp snd-soc-max9877-objs := max9877.o @@ -690,6 +691,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o +obj-$(CONFIG_SND_SOC_WSA883X) += snd-soc-wsa883x.o obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o # Amp diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c new file mode 100644 index 0000000000000..856709ec017e6 --- /dev/null +++ b/sound/soc/codecs/wsa883x.c @@ -0,0 +1,1301 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WSA883X_BASE 0x3000 +#define WSA883X_ANA_BG_TSADC_BASE (WSA883X_BASE + 0x00000001) +#define WSA883X_REF_CTRL (WSA883X_ANA_BG_TSADC_BASE + 0x0000) +#define WSA883X_TEST_CTL_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0001) +#define WSA883X_BIAS_0 (WSA883X_ANA_BG_TSADC_BASE + 0x0002) +#define WSA883X_OP_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0003) +#define WSA883X_IREF_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0004) +#define WSA883X_ISENS_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0005) +#define WSA883X_CLK_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0006) +#define WSA883X_TEST_CTL_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0007) +#define WSA883X_BIAS_1 (WSA883X_ANA_BG_TSADC_BASE + 0x0008) +#define WSA883X_ADC_CTL (WSA883X_ANA_BG_TSADC_BASE + 0x0009) +#define WSA883X_DOUT_MSB (WSA883X_ANA_BG_TSADC_BASE + 0x000A) +#define WSA883X_DOUT_LSB (WSA883X_ANA_BG_TSADC_BASE + 0x000B) +#define WSA883X_VBAT_SNS (WSA883X_ANA_BG_TSADC_BASE + 0x000C) +#define WSA883X_ITRIM_CODE (WSA883X_ANA_BG_TSADC_BASE + 0x000D) + +#define WSA883X_ANA_IVSENSE_BASE (WSA883X_BASE + 0x0000000F) +#define WSA883X_EN (WSA883X_ANA_IVSENSE_BASE + 0x0000) +#define WSA883X_OVERRIDE1 (WSA883X_ANA_IVSENSE_BASE + 0x0001) +#define WSA883X_OVERRIDE2 (WSA883X_ANA_IVSENSE_BASE + 0x0002) +#define WSA883X_VSENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0003) +#define WSA883X_ISENSE1 (WSA883X_ANA_IVSENSE_BASE + 0x0004) +#define WSA883X_ISENSE2 (WSA883X_ANA_IVSENSE_BASE + 0x0005) +#define WSA883X_ISENSE_CAL (WSA883X_ANA_IVSENSE_BASE + 0x0006) +#define WSA883X_MISC (WSA883X_ANA_IVSENSE_BASE + 0x0007) +#define WSA883X_ADC_0 (WSA883X_ANA_IVSENSE_BASE + 0x0008) +#define WSA883X_ADC_1 (WSA883X_ANA_IVSENSE_BASE + 0x0009) +#define WSA883X_ADC_2 (WSA883X_ANA_IVSENSE_BASE + 0x000A) +#define WSA883X_ADC_3 (WSA883X_ANA_IVSENSE_BASE + 0x000B) +#define WSA883X_ADC_4 (WSA883X_ANA_IVSENSE_BASE + 0x000C) +#define WSA883X_ADC_5 (WSA883X_ANA_IVSENSE_BASE + 0x000D) +#define WSA883X_ADC_6 (WSA883X_ANA_IVSENSE_BASE + 0x000E) +#define WSA883X_ADC_7 (WSA883X_ANA_IVSENSE_BASE + 0x000F) +#define WSA883X_STATUS (WSA883X_ANA_IVSENSE_BASE + 0x0010) + +#define WSA883X_ANA_SPK_TOP_BASE (WSA883X_BASE + 0x00000025) +#define WSA883X_DAC_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0000) +#define WSA883X_DAC_EN_DEBUG_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0001) +#define WSA883X_DAC_OPAMP_BIAS1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0002) +#define WSA883X_DAC_OPAMP_BIAS2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0003) +#define WSA883X_DAC_VCM_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0004) +#define WSA883X_DAC_VOLTAGE_CTRL_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0005) +#define WSA883X_ATEST1_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0006) +#define WSA883X_ATEST2_REG (WSA883X_ANA_SPK_TOP_BASE + 0x0007) +#define WSA883X_SPKR_TOP_BIAS_REG1 (WSA883X_ANA_SPK_TOP_BASE + 0x0008) +#define WSA883X_SPKR_TOP_BIAS_REG2 (WSA883X_ANA_SPK_TOP_BASE + 0x0009) +#define WSA883X_SPKR_TOP_BIAS_REG3 (WSA883X_ANA_SPK_TOP_BASE + 0x000A) +#define WSA883X_SPKR_TOP_BIAS_REG4 (WSA883X_ANA_SPK_TOP_BASE + 0x000B) +#define WSA883X_SPKR_CLIP_DET_REG (WSA883X_ANA_SPK_TOP_BASE + 0x000C) +#define WSA883X_SPKR_DRV_LF_BLK_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000D) +#define WSA883X_SPKR_DRV_LF_EN (WSA883X_ANA_SPK_TOP_BASE + 0x000E) +#define WSA883X_SPKR_DRV_LF_MASK_DCC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x000F) +#define WSA883X_SPKR_DRV_LF_MISC_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0010) +#define WSA883X_SPKR_DRV_LF_REG_GAIN (WSA883X_ANA_SPK_TOP_BASE + 0x0011) +#define WSA883X_SPKR_DRV_OS_CAL_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0012) +#define WSA883X_SPKR_DRV_OS_CAL_CTL1 (WSA883X_ANA_SPK_TOP_BASE + 0x0013) +#define WSA883X_SPKR_PWM_CLK_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0014) +#define WSA883X_SPKR_PWM_FREQ_SEL_MASK BIT(3) +#define WSA883X_SPKR_PWM_FREQ_F300KHZ 0 +#define WSA883X_SPKR_PWM_FREQ_F600KHZ 1 +#define WSA883X_SPKR_PDRV_HS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0015) +#define WSA883X_SPKR_PDRV_LS_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0016) +#define WSA883X_SPKR_PWRSTG_DBG (WSA883X_ANA_SPK_TOP_BASE + 0x0017) +#define WSA883X_SPKR_OCP_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0018) +#define WSA883X_SPKR_BBM_CTL (WSA883X_ANA_SPK_TOP_BASE + 0x0019) +#define WSA883X_PA_STATUS0 (WSA883X_ANA_SPK_TOP_BASE + 0x001A) +#define WSA883X_PA_STATUS1 (WSA883X_ANA_SPK_TOP_BASE + 0x001B) +#define WSA883X_PA_STATUS2 (WSA883X_ANA_SPK_TOP_BASE + 0x001C) + +#define WSA883X_ANA_BOOST_BASE (WSA883X_BASE + 0x00000043) +#define WSA883X_EN_CTRL (WSA883X_ANA_BOOST_BASE + 0x0000) +#define WSA883X_CURRENT_LIMIT (WSA883X_ANA_BOOST_BASE + 0x0001) +#define WSA883X_IBIAS1 (WSA883X_ANA_BOOST_BASE + 0x0002) +#define WSA883X_IBIAS2 (WSA883X_ANA_BOOST_BASE + 0x0003) +#define WSA883X_IBIAS3 (WSA883X_ANA_BOOST_BASE + 0x0004) +#define WSA883X_LDO_PROG (WSA883X_ANA_BOOST_BASE + 0x0005) +#define WSA883X_STABILITY_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0006) +#define WSA883X_STABILITY_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0007) +#define WSA883X_PWRSTAGE_CTRL1 (WSA883X_ANA_BOOST_BASE + 0x0008) +#define WSA883X_PWRSTAGE_CTRL2 (WSA883X_ANA_BOOST_BASE + 0x0009) +#define WSA883X_BYPASS_1 (WSA883X_ANA_BOOST_BASE + 0x000A) +#define WSA883X_BYPASS_2 (WSA883X_ANA_BOOST_BASE + 0x000B) +#define WSA883X_ZX_CTRL_1 (WSA883X_ANA_BOOST_BASE + 0x000C) +#define WSA883X_ZX_CTRL_2 (WSA883X_ANA_BOOST_BASE + 0x000D) +#define WSA883X_MISC1 (WSA883X_ANA_BOOST_BASE + 0x000E) +#define WSA883X_MISC2 (WSA883X_ANA_BOOST_BASE + 0x000F) +#define WSA883X_GMAMP_SUP1 (WSA883X_ANA_BOOST_BASE + 0x0010) +#define WSA883X_PWRSTAGE_CTRL3 (WSA883X_ANA_BOOST_BASE + 0x0011) +#define WSA883X_PWRSTAGE_CTRL4 (WSA883X_ANA_BOOST_BASE + 0x0012) +#define WSA883X_TEST1 (WSA883X_ANA_BOOST_BASE + 0x0013) +#define WSA883X_SPARE1 (WSA883X_ANA_BOOST_BASE + 0x0014) +#define WSA883X_SPARE2 (WSA883X_ANA_BOOST_BASE + 0x0015) + +#define WSA883X_ANA_PON_LDOL_BASE (WSA883X_BASE + 0x00000059) +#define WSA883X_PON_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0000) +#define WSA883X_PON_CLT_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0001) +#define WSA883X_PON_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0002) +#define WSA883X_PON_CTL_3 (WSA883X_ANA_PON_LDOL_BASE + 0x0003) +#define WSA883X_CKWD_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0004) +#define WSA883X_CKWD_CTL_1 (WSA883X_ANA_PON_LDOL_BASE + 0x0005) +#define WSA883X_CKWD_CTL_2 (WSA883X_ANA_PON_LDOL_BASE + 0x0006) +#define WSA883X_CKSK_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0007) +#define WSA883X_PADSW_CTL_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0008) +#define WSA883X_TEST_0 (WSA883X_ANA_PON_LDOL_BASE + 0x0009) +#define WSA883X_TEST_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000A) +#define WSA883X_STATUS_0 (WSA883X_ANA_PON_LDOL_BASE + 0x000B) +#define WSA883X_STATUS_1 (WSA883X_ANA_PON_LDOL_BASE + 0x000C) + +#define WSA883X_DIG_CTRL_BASE (WSA883X_BASE + 0x00000400) +#define WSA883X_CHIP_ID0 (WSA883X_DIG_CTRL_BASE + 0x0001) +#define WSA883X_CHIP_ID1 (WSA883X_DIG_CTRL_BASE + 0x0002) +#define WSA883X_CHIP_ID2 (WSA883X_DIG_CTRL_BASE + 0x0003) +#define WSA883X_CHIP_ID3 (WSA883X_DIG_CTRL_BASE + 0x0004) +#define WSA883X_BUS_ID (WSA883X_DIG_CTRL_BASE + 0x0005) +#define WSA883X_CDC_RST_CTL (WSA883X_DIG_CTRL_BASE + 0x0006) +#define WSA883X_TOP_CLK_CFG (WSA883X_DIG_CTRL_BASE + 0x0007) +#define WSA883X_CDC_PATH_MODE (WSA883X_DIG_CTRL_BASE + 0x0008) +#define WSA883X_RXD_MODE_MASK BIT(1) +#define WSA883X_RXD_MODE_NORMAL 0 +#define WSA883X_RXD_MODE_HIFI 1 +#define WSA883X_CDC_CLK_CTL (WSA883X_DIG_CTRL_BASE + 0x0009) +#define WSA883X_SWR_RESET_EN (WSA883X_DIG_CTRL_BASE + 0x000A) +#define WSA883X_RESET_CTL (WSA883X_DIG_CTRL_BASE + 0x000B) +#define WSA883X_PA_FSM_CTL (WSA883X_DIG_CTRL_BASE + 0x0010) +#define WSA883X_GLOBAL_PA_EN_MASK BIT(0) +#define WSA883X_GLOBAL_PA_ENABLE 1 +#define WSA883X_PA_FSM_TIMER0 (WSA883X_DIG_CTRL_BASE + 0x0011) +#define WSA883X_PA_FSM_TIMER1 (WSA883X_DIG_CTRL_BASE + 0x0012) +#define WSA883X_PA_FSM_STA (WSA883X_DIG_CTRL_BASE + 0x0013) +#define WSA883X_PA_FSM_ERR_COND (WSA883X_DIG_CTRL_BASE + 0x0014) +#define WSA883X_PA_FSM_MSK (WSA883X_DIG_CTRL_BASE + 0x0015) +#define WSA883X_PA_FSM_BYP (WSA883X_DIG_CTRL_BASE + 0x0016) +#define WSA883X_PA_FSM_DBG (WSA883X_DIG_CTRL_BASE + 0x0017) +#define WSA883X_TADC_VALUE_CTL (WSA883X_DIG_CTRL_BASE + 0x0020) +#define WSA883X_TEMP_DETECT_CTL (WSA883X_DIG_CTRL_BASE + 0x0021) +#define WSA883X_TEMP_MSB (WSA883X_DIG_CTRL_BASE + 0x0022) +#define WSA883X_TEMP_LSB (WSA883X_DIG_CTRL_BASE + 0x0023) +#define WSA883X_TEMP_CONFIG0 (WSA883X_DIG_CTRL_BASE + 0x0024) +#define WSA883X_TEMP_CONFIG1 (WSA883X_DIG_CTRL_BASE + 0x0025) +#define WSA883X_VBAT_ADC_FLT_CTL (WSA883X_DIG_CTRL_BASE + 0x0026) +#define WSA883X_VBAT_ADC_FLT_EN_MASK BIT(0) +#define WSA883X_VBAT_ADC_COEF_SEL_MASK GENMASK(3, 1) +#define WSA883X_VBAT_ADC_COEF_F_1DIV2 0x0 +#define WSA883X_VBAT_ADC_COEF_F_1DIV16 0x3 +#define WSA883X_VBAT_DIN_MSB (WSA883X_DIG_CTRL_BASE + 0x0027) +#define WSA883X_VBAT_DIN_LSB (WSA883X_DIG_CTRL_BASE + 0x0028) +#define WSA883X_VBAT_DOUT (WSA883X_DIG_CTRL_BASE + 0x0029) +#define WSA883X_SDM_PDM9_LSB (WSA883X_DIG_CTRL_BASE + 0x002A) +#define WSA883X_SDM_PDM9_MSB (WSA883X_DIG_CTRL_BASE + 0x002B) +#define WSA883X_CDC_RX_CTL (WSA883X_DIG_CTRL_BASE + 0x0030) +#define WSA883X_CDC_SPK_DSM_A1_0 (WSA883X_DIG_CTRL_BASE + 0x0031) +#define WSA883X_CDC_SPK_DSM_A1_1 (WSA883X_DIG_CTRL_BASE + 0x0032) +#define WSA883X_CDC_SPK_DSM_A2_0 (WSA883X_DIG_CTRL_BASE + 0x0033) +#define WSA883X_CDC_SPK_DSM_A2_1 (WSA883X_DIG_CTRL_BASE + 0x0034) +#define WSA883X_CDC_SPK_DSM_A3_0 (WSA883X_DIG_CTRL_BASE + 0x0035) +#define WSA883X_CDC_SPK_DSM_A3_1 (WSA883X_DIG_CTRL_BASE + 0x0036) +#define WSA883X_CDC_SPK_DSM_A4_0 (WSA883X_DIG_CTRL_BASE + 0x0037) +#define WSA883X_CDC_SPK_DSM_A4_1 (WSA883X_DIG_CTRL_BASE + 0x0038) +#define WSA883X_CDC_SPK_DSM_A5_0 (WSA883X_DIG_CTRL_BASE + 0x0039) +#define WSA883X_CDC_SPK_DSM_A5_1 (WSA883X_DIG_CTRL_BASE + 0x003A) +#define WSA883X_CDC_SPK_DSM_A6_0 (WSA883X_DIG_CTRL_BASE + 0x003B) +#define WSA883X_CDC_SPK_DSM_A7_0 (WSA883X_DIG_CTRL_BASE + 0x003C) +#define WSA883X_CDC_SPK_DSM_C_0 (WSA883X_DIG_CTRL_BASE + 0x003D) +#define WSA883X_CDC_SPK_DSM_C_1 (WSA883X_DIG_CTRL_BASE + 0x003E) +#define WSA883X_CDC_SPK_DSM_C_2 (WSA883X_DIG_CTRL_BASE + 0x003F) +#define WSA883X_CDC_SPK_DSM_C_3 (WSA883X_DIG_CTRL_BASE + 0x0040) +#define WSA883X_CDC_SPK_DSM_R1 (WSA883X_DIG_CTRL_BASE + 0x0041) +#define WSA883X_CDC_SPK_DSM_R2 (WSA883X_DIG_CTRL_BASE + 0x0042) +#define WSA883X_CDC_SPK_DSM_R3 (WSA883X_DIG_CTRL_BASE + 0x0043) +#define WSA883X_CDC_SPK_DSM_R4 (WSA883X_DIG_CTRL_BASE + 0x0044) +#define WSA883X_CDC_SPK_DSM_R5 (WSA883X_DIG_CTRL_BASE + 0x0045) +#define WSA883X_CDC_SPK_DSM_R6 (WSA883X_DIG_CTRL_BASE + 0x0046) +#define WSA883X_CDC_SPK_DSM_R7 (WSA883X_DIG_CTRL_BASE + 0x0047) +#define WSA883X_CDC_SPK_GAIN_PDM_0 (WSA883X_DIG_CTRL_BASE + 0x0048) +#define WSA883X_CDC_SPK_GAIN_PDM_1 (WSA883X_DIG_CTRL_BASE + 0x0049) +#define WSA883X_CDC_SPK_GAIN_PDM_2 (WSA883X_DIG_CTRL_BASE + 0x004A) +#define WSA883X_PDM_WD_CTL (WSA883X_DIG_CTRL_BASE + 0x004B) +#define WSA883X_PDM_EN_MASK BIT(0) +#define WSA883X_PDM_ENABLE BIT(0) +#define WSA883X_DEM_BYPASS_DATA0 (WSA883X_DIG_CTRL_BASE + 0x004C) +#define WSA883X_DEM_BYPASS_DATA1 (WSA883X_DIG_CTRL_BASE + 0x004D) +#define WSA883X_DEM_BYPASS_DATA2 (WSA883X_DIG_CTRL_BASE + 0x004E) +#define WSA883X_DEM_BYPASS_DATA3 (WSA883X_DIG_CTRL_BASE + 0x004F) +#define WSA883X_WAVG_CTL (WSA883X_DIG_CTRL_BASE + 0x0050) +#define WSA883X_WAVG_LRA_PER_0 (WSA883X_DIG_CTRL_BASE + 0x0051) +#define WSA883X_WAVG_LRA_PER_1 (WSA883X_DIG_CTRL_BASE + 0x0052) +#define WSA883X_WAVG_DELTA_THETA_0 (WSA883X_DIG_CTRL_BASE + 0x0053) +#define WSA883X_WAVG_DELTA_THETA_1 (WSA883X_DIG_CTRL_BASE + 0x0054) +#define WSA883X_WAVG_DIRECT_AMP_0 (WSA883X_DIG_CTRL_BASE + 0x0055) +#define WSA883X_WAVG_DIRECT_AMP_1 (WSA883X_DIG_CTRL_BASE + 0x0056) +#define WSA883X_WAVG_PTRN_AMP0_0 (WSA883X_DIG_CTRL_BASE + 0x0057) +#define WSA883X_WAVG_PTRN_AMP0_1 (WSA883X_DIG_CTRL_BASE + 0x0058) +#define WSA883X_WAVG_PTRN_AMP1_0 (WSA883X_DIG_CTRL_BASE + 0x0059) +#define WSA883X_WAVG_PTRN_AMP1_1 (WSA883X_DIG_CTRL_BASE + 0x005A) +#define WSA883X_WAVG_PTRN_AMP2_0 (WSA883X_DIG_CTRL_BASE + 0x005B) +#define WSA883X_WAVG_PTRN_AMP2_1 (WSA883X_DIG_CTRL_BASE + 0x005C) +#define WSA883X_WAVG_PTRN_AMP3_0 (WSA883X_DIG_CTRL_BASE + 0x005D) +#define WSA883X_WAVG_PTRN_AMP3_1 (WSA883X_DIG_CTRL_BASE + 0x005E) +#define WSA883X_WAVG_PTRN_AMP4_0 (WSA883X_DIG_CTRL_BASE + 0x005F) +#define WSA883X_WAVG_PTRN_AMP4_1 (WSA883X_DIG_CTRL_BASE + 0x0060) +#define WSA883X_WAVG_PTRN_AMP5_0 (WSA883X_DIG_CTRL_BASE + 0x0061) +#define WSA883X_WAVG_PTRN_AMP5_1 (WSA883X_DIG_CTRL_BASE + 0x0062) +#define WSA883X_WAVG_PTRN_AMP6_0 (WSA883X_DIG_CTRL_BASE + 0x0063) +#define WSA883X_WAVG_PTRN_AMP6_1 (WSA883X_DIG_CTRL_BASE + 0x0064) +#define WSA883X_WAVG_PTRN_AMP7_0 (WSA883X_DIG_CTRL_BASE + 0x0065) +#define WSA883X_WAVG_PTRN_AMP7_1 (WSA883X_DIG_CTRL_BASE + 0x0066) +#define WSA883X_WAVG_PER_0_1 (WSA883X_DIG_CTRL_BASE + 0x0067) +#define WSA883X_WAVG_PER_2_3 (WSA883X_DIG_CTRL_BASE + 0x0068) +#define WSA883X_WAVG_PER_4_5 (WSA883X_DIG_CTRL_BASE + 0x0069) +#define WSA883X_WAVG_PER_6_7 (WSA883X_DIG_CTRL_BASE + 0x006A) +#define WSA883X_WAVG_STA (WSA883X_DIG_CTRL_BASE + 0x006B) +#define WSA883X_DRE_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x006C) +#define WSA883X_DRE_OFFSET_MASK GENMASK(2, 0) +#define WSA883X_DRE_PROG_DELAY_MASK GENMASK(7, 4) +#define WSA883X_DRE_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x006D) +#define WSA883X_DRE_GAIN_EN_MASK BIT(0) +#define WSA883X_DRE_GAIN_FROM_CSR 1 +#define WSA883X_DRE_IDLE_DET_CTL (WSA883X_DIG_CTRL_BASE + 0x006E) +#define WSA883X_CLSH_CTL_0 (WSA883X_DIG_CTRL_BASE + 0x0070) +#define WSA883X_CLSH_CTL_1 (WSA883X_DIG_CTRL_BASE + 0x0071) +#define WSA883X_CLSH_V_HD_PA (WSA883X_DIG_CTRL_BASE + 0x0072) +#define WSA883X_CLSH_V_PA_MIN (WSA883X_DIG_CTRL_BASE + 0x0073) +#define WSA883X_CLSH_OVRD_VAL (WSA883X_DIG_CTRL_BASE + 0x0074) +#define WSA883X_CLSH_HARD_MAX (WSA883X_DIG_CTRL_BASE + 0x0075) +#define WSA883X_CLSH_SOFT_MAX (WSA883X_DIG_CTRL_BASE + 0x0076) +#define WSA883X_CLSH_SIG_DP (WSA883X_DIG_CTRL_BASE + 0x0077) +#define WSA883X_TAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x0078) +#define WSA883X_TAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x0079) +#define WSA883X_TAGC_E2E_GAIN (WSA883X_DIG_CTRL_BASE + 0x007A) +#define WSA883X_TAGC_FORCE_VAL (WSA883X_DIG_CTRL_BASE + 0x007B) +#define WSA883X_VAGC_CTL (WSA883X_DIG_CTRL_BASE + 0x007C) +#define WSA883X_VAGC_TIME (WSA883X_DIG_CTRL_BASE + 0x007D) +#define WSA883X_VAGC_ATTN_LVL_1_2 (WSA883X_DIG_CTRL_BASE + 0x007E) +#define WSA883X_VAGC_ATTN_LVL_3 (WSA883X_DIG_CTRL_BASE + 0x007F) +#define WSA883X_INTR_MODE (WSA883X_DIG_CTRL_BASE + 0x0080) +#define WSA883X_INTR_MASK0 (WSA883X_DIG_CTRL_BASE + 0x0081) +#define WSA883X_INTR_MASK1 (WSA883X_DIG_CTRL_BASE + 0x0082) +#define WSA883X_INTR_STATUS0 (WSA883X_DIG_CTRL_BASE + 0x0083) +#define WSA883X_INTR_STATUS1 (WSA883X_DIG_CTRL_BASE + 0x0084) +#define WSA883X_INTR_CLEAR0 (WSA883X_DIG_CTRL_BASE + 0x0085) +#define WSA883X_INTR_CLEAR1 (WSA883X_DIG_CTRL_BASE + 0x0086) +#define WSA883X_INTR_LEVEL0 (WSA883X_DIG_CTRL_BASE + 0x0087) +#define WSA883X_INTR_LEVEL1 (WSA883X_DIG_CTRL_BASE + 0x0088) +#define WSA883X_INTR_SET0 (WSA883X_DIG_CTRL_BASE + 0x0089) +#define WSA883X_INTR_SET1 (WSA883X_DIG_CTRL_BASE + 0x008A) +#define WSA883X_INTR_TEST0 (WSA883X_DIG_CTRL_BASE + 0x008B) +#define WSA883X_INTR_TEST1 (WSA883X_DIG_CTRL_BASE + 0x008C) +#define WSA883X_OTP_CTRL0 (WSA883X_DIG_CTRL_BASE + 0x0090) +#define WSA883X_OTP_CTRL1 (WSA883X_DIG_CTRL_BASE + 0x0091) +#define WSA883X_HDRIVE_CTL_GROUP1 (WSA883X_DIG_CTRL_BASE + 0x0092) +#define WSA883X_PIN_CTL (WSA883X_DIG_CTRL_BASE + 0x0093) +#define WSA883X_PIN_CTL_OE (WSA883X_DIG_CTRL_BASE + 0x0094) +#define WSA883X_PIN_WDATA_IOPAD (WSA883X_DIG_CTRL_BASE + 0x0095) +#define WSA883X_PIN_STATUS (WSA883X_DIG_CTRL_BASE + 0x0096) +#define WSA883X_I2C_SLAVE_CTL (WSA883X_DIG_CTRL_BASE + 0x0097) +#define WSA883X_PDM_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A0) +#define WSA883X_ATE_TEST_MODE (WSA883X_DIG_CTRL_BASE + 0x00A1) +#define WSA883X_DIG_DEBUG_MODE (WSA883X_DIG_CTRL_BASE + 0x00A3) +#define WSA883X_DIG_DEBUG_SEL (WSA883X_DIG_CTRL_BASE + 0x00A4) +#define WSA883X_DIG_DEBUG_EN (WSA883X_DIG_CTRL_BASE + 0x00A5) +#define WSA883X_SWR_HM_TEST0 (WSA883X_DIG_CTRL_BASE + 0x00A6) +#define WSA883X_SWR_HM_TEST1 (WSA883X_DIG_CTRL_BASE + 0x00A7) +#define WSA883X_SWR_PAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00A8) +#define WSA883X_TADC_DETECT_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00A9) +#define WSA883X_TADC_DEBUG_MSB (WSA883X_DIG_CTRL_BASE + 0x00AA) +#define WSA883X_TADC_DEBUG_LSB (WSA883X_DIG_CTRL_BASE + 0x00AB) +#define WSA883X_SAMPLE_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AC) +#define WSA883X_SWR_EDGE_SEL (WSA883X_DIG_CTRL_BASE + 0x00AD) +#define WSA883X_TEST_MODE_CTL (WSA883X_DIG_CTRL_BASE + 0x00AE) +#define WSA883X_IOPAD_CTL (WSA883X_DIG_CTRL_BASE + 0x00AF) +#define WSA883X_ANA_CSR_DBG_ADD (WSA883X_DIG_CTRL_BASE + 0x00B0) +#define WSA883X_ANA_CSR_DBG_CTL (WSA883X_DIG_CTRL_BASE + 0x00B1) +#define WSA883X_SPARE_R (WSA883X_DIG_CTRL_BASE + 0x00BC) +#define WSA883X_SPARE_0 (WSA883X_DIG_CTRL_BASE + 0x00BD) +#define WSA883X_SPARE_1 (WSA883X_DIG_CTRL_BASE + 0x00BE) +#define WSA883X_SPARE_2 (WSA883X_DIG_CTRL_BASE + 0x00BF) +#define WSA883X_SCODE (WSA883X_DIG_CTRL_BASE + 0x00C0) + +#define WSA883X_DIG_TRIM_BASE (WSA883X_BASE + 0x00000500) +#define WSA883X_OTP_REG_0 (WSA883X_DIG_TRIM_BASE + 0x0080) +#define WSA883X_ID_MASK GENMASK(3, 0) +#define WSA883X_OTP_REG_1 (WSA883X_DIG_TRIM_BASE + 0x0081) +#define WSA883X_OTP_REG_2 (WSA883X_DIG_TRIM_BASE + 0x0082) +#define WSA883X_OTP_REG_3 (WSA883X_DIG_TRIM_BASE + 0x0083) +#define WSA883X_OTP_REG_4 (WSA883X_DIG_TRIM_BASE + 0x0084) +#define WSA883X_OTP_REG_5 (WSA883X_DIG_TRIM_BASE + 0x0085) +#define WSA883X_OTP_REG_6 (WSA883X_DIG_TRIM_BASE + 0x0086) +#define WSA883X_OTP_REG_7 (WSA883X_DIG_TRIM_BASE + 0x0087) +#define WSA883X_OTP_REG_8 (WSA883X_DIG_TRIM_BASE + 0x0088) +#define WSA883X_OTP_REG_9 (WSA883X_DIG_TRIM_BASE + 0x0089) +#define WSA883X_OTP_REG_10 (WSA883X_DIG_TRIM_BASE + 0x008A) +#define WSA883X_OTP_REG_11 (WSA883X_DIG_TRIM_BASE + 0x008B) +#define WSA883X_OTP_REG_12 (WSA883X_DIG_TRIM_BASE + 0x008C) +#define WSA883X_OTP_REG_13 (WSA883X_DIG_TRIM_BASE + 0x008D) +#define WSA883X_OTP_REG_14 (WSA883X_DIG_TRIM_BASE + 0x008E) +#define WSA883X_OTP_REG_15 (WSA883X_DIG_TRIM_BASE + 0x008F) +#define WSA883X_OTP_REG_16 (WSA883X_DIG_TRIM_BASE + 0x0090) +#define WSA883X_OTP_REG_17 (WSA883X_DIG_TRIM_BASE + 0x0091) +#define WSA883X_OTP_REG_18 (WSA883X_DIG_TRIM_BASE + 0x0092) +#define WSA883X_OTP_REG_19 (WSA883X_DIG_TRIM_BASE + 0x0093) +#define WSA883X_OTP_REG_20 (WSA883X_DIG_TRIM_BASE + 0x0094) +#define WSA883X_OTP_REG_21 (WSA883X_DIG_TRIM_BASE + 0x0095) +#define WSA883X_OTP_REG_22 (WSA883X_DIG_TRIM_BASE + 0x0096) +#define WSA883X_OTP_REG_23 (WSA883X_DIG_TRIM_BASE + 0x0097) +#define WSA883X_OTP_REG_24 (WSA883X_DIG_TRIM_BASE + 0x0098) +#define WSA883X_OTP_REG_25 (WSA883X_DIG_TRIM_BASE + 0x0099) +#define WSA883X_OTP_REG_26 (WSA883X_DIG_TRIM_BASE + 0x009A) +#define WSA883X_OTP_REG_27 (WSA883X_DIG_TRIM_BASE + 0x009B) +#define WSA883X_OTP_REG_28 (WSA883X_DIG_TRIM_BASE + 0x009C) +#define WSA883X_OTP_REG_29 (WSA883X_DIG_TRIM_BASE + 0x009D) +#define WSA883X_OTP_REG_30 (WSA883X_DIG_TRIM_BASE + 0x009E) +#define WSA883X_OTP_REG_31 (WSA883X_DIG_TRIM_BASE + 0x009F) +#define WSA883X_OTP_REG_32 (WSA883X_DIG_TRIM_BASE + 0x00A0) +#define WSA883X_OTP_REG_33 (WSA883X_DIG_TRIM_BASE + 0x00A1) +#define WSA883X_OTP_REG_34 (WSA883X_DIG_TRIM_BASE + 0x00A2) +#define WSA883X_OTP_REG_35 (WSA883X_DIG_TRIM_BASE + 0x00A3) +#define WSA883X_OTP_REG_63 (WSA883X_DIG_TRIM_BASE + 0x00BF) + +#define WSA883X_DIG_EMEM_BASE (WSA883X_BASE + 0x000005C0) +#define WSA883X_EMEM_0 (WSA883X_DIG_EMEM_BASE + 0x0000) +#define WSA883X_EMEM_1 (WSA883X_DIG_EMEM_BASE + 0x0001) +#define WSA883X_EMEM_2 (WSA883X_DIG_EMEM_BASE + 0x0002) +#define WSA883X_EMEM_3 (WSA883X_DIG_EMEM_BASE + 0x0003) +#define WSA883X_EMEM_4 (WSA883X_DIG_EMEM_BASE + 0x0004) +#define WSA883X_EMEM_5 (WSA883X_DIG_EMEM_BASE + 0x0005) +#define WSA883X_EMEM_6 (WSA883X_DIG_EMEM_BASE + 0x0006) +#define WSA883X_EMEM_7 (WSA883X_DIG_EMEM_BASE + 0x0007) +#define WSA883X_EMEM_8 (WSA883X_DIG_EMEM_BASE + 0x0008) +#define WSA883X_EMEM_9 (WSA883X_DIG_EMEM_BASE + 0x0009) +#define WSA883X_EMEM_10 (WSA883X_DIG_EMEM_BASE + 0x000A) +#define WSA883X_EMEM_11 (WSA883X_DIG_EMEM_BASE + 0x000B) +#define WSA883X_EMEM_12 (WSA883X_DIG_EMEM_BASE + 0x000C) +#define WSA883X_EMEM_13 (WSA883X_DIG_EMEM_BASE + 0x000D) +#define WSA883X_EMEM_14 (WSA883X_DIG_EMEM_BASE + 0x000E) +#define WSA883X_EMEM_15 (WSA883X_DIG_EMEM_BASE + 0x000F) +#define WSA883X_EMEM_16 (WSA883X_DIG_EMEM_BASE + 0x0010) +#define WSA883X_EMEM_17 (WSA883X_DIG_EMEM_BASE + 0x0011) +#define WSA883X_EMEM_18 (WSA883X_DIG_EMEM_BASE + 0x0012) +#define WSA883X_EMEM_19 (WSA883X_DIG_EMEM_BASE + 0x0013) +#define WSA883X_EMEM_20 (WSA883X_DIG_EMEM_BASE + 0x0014) +#define WSA883X_EMEM_21 (WSA883X_DIG_EMEM_BASE + 0x0015) +#define WSA883X_EMEM_22 (WSA883X_DIG_EMEM_BASE + 0x0016) +#define WSA883X_EMEM_23 (WSA883X_DIG_EMEM_BASE + 0x0017) +#define WSA883X_EMEM_24 (WSA883X_DIG_EMEM_BASE + 0x0018) +#define WSA883X_EMEM_25 (WSA883X_DIG_EMEM_BASE + 0x0019) +#define WSA883X_EMEM_26 (WSA883X_DIG_EMEM_BASE + 0x001A) +#define WSA883X_EMEM_27 (WSA883X_DIG_EMEM_BASE + 0x001B) +#define WSA883X_EMEM_28 (WSA883X_DIG_EMEM_BASE + 0x001C) +#define WSA883X_EMEM_29 (WSA883X_DIG_EMEM_BASE + 0x001D) +#define WSA883X_EMEM_30 (WSA883X_DIG_EMEM_BASE + 0x001E) +#define WSA883X_EMEM_31 (WSA883X_DIG_EMEM_BASE + 0x001F) +#define WSA883X_EMEM_32 (WSA883X_DIG_EMEM_BASE + 0x0020) +#define WSA883X_EMEM_33 (WSA883X_DIG_EMEM_BASE + 0x0021) +#define WSA883X_EMEM_34 (WSA883X_DIG_EMEM_BASE + 0x0022) +#define WSA883X_EMEM_35 (WSA883X_DIG_EMEM_BASE + 0x0023) +#define WSA883X_EMEM_36 (WSA883X_DIG_EMEM_BASE + 0x0024) +#define WSA883X_EMEM_37 (WSA883X_DIG_EMEM_BASE + 0x0025) +#define WSA883X_EMEM_38 (WSA883X_DIG_EMEM_BASE + 0x0026) +#define WSA883X_EMEM_39 (WSA883X_DIG_EMEM_BASE + 0x0027) +#define WSA883X_EMEM_40 (WSA883X_DIG_EMEM_BASE + 0x0028) +#define WSA883X_EMEM_41 (WSA883X_DIG_EMEM_BASE + 0x0029) +#define WSA883X_EMEM_42 (WSA883X_DIG_EMEM_BASE + 0x002A) +#define WSA883X_EMEM_43 (WSA883X_DIG_EMEM_BASE + 0x002B) +#define WSA883X_EMEM_44 (WSA883X_DIG_EMEM_BASE + 0x002C) +#define WSA883X_EMEM_45 (WSA883X_DIG_EMEM_BASE + 0x002D) +#define WSA883X_EMEM_46 (WSA883X_DIG_EMEM_BASE + 0x002E) +#define WSA883X_EMEM_47 (WSA883X_DIG_EMEM_BASE + 0x002F) +#define WSA883X_EMEM_48 (WSA883X_DIG_EMEM_BASE + 0x0030) +#define WSA883X_EMEM_49 (WSA883X_DIG_EMEM_BASE + 0x0031) +#define WSA883X_EMEM_50 (WSA883X_DIG_EMEM_BASE + 0x0032) +#define WSA883X_EMEM_51 (WSA883X_DIG_EMEM_BASE + 0x0033) +#define WSA883X_EMEM_52 (WSA883X_DIG_EMEM_BASE + 0x0034) +#define WSA883X_EMEM_53 (WSA883X_DIG_EMEM_BASE + 0x0035) +#define WSA883X_EMEM_54 (WSA883X_DIG_EMEM_BASE + 0x0036) +#define WSA883X_EMEM_55 (WSA883X_DIG_EMEM_BASE + 0x0037) +#define WSA883X_EMEM_56 (WSA883X_DIG_EMEM_BASE + 0x0038) +#define WSA883X_EMEM_57 (WSA883X_DIG_EMEM_BASE + 0x0039) +#define WSA883X_EMEM_58 (WSA883X_DIG_EMEM_BASE + 0x003A) +#define WSA883X_EMEM_59 (WSA883X_DIG_EMEM_BASE + 0x003B) +#define WSA883X_EMEM_60 (WSA883X_DIG_EMEM_BASE + 0x003C) +#define WSA883X_EMEM_61 (WSA883X_DIG_EMEM_BASE + 0x003D) +#define WSA883X_EMEM_62 (WSA883X_DIG_EMEM_BASE + 0x003E) +#define WSA883X_EMEM_63 (WSA883X_DIG_EMEM_BASE + 0x003F) + +#define WSA883X_NUM_REGISTERS (WSA883X_EMEM_63 + 1) +#define WSA883X_MAX_REGISTER (WSA883X_NUM_REGISTERS - 1) +#define WSA883X_PROBE_TIMEOUT 1000 + +#define WSA883X_VERSION_1_0 0 +#define WSA883X_VERSION_1_1 1 + +#define WSA883X_MAX_SWR_PORTS 4 +#define WSA883X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\ + SNDRV_PCM_RATE_384000) +/* Fractional Rates */ +#define WSA883X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800) + +#define WSA883X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + +struct wsa883x_priv { + struct regmap *regmap; + struct device *dev; + struct regulator *vdd; + struct sdw_slave *slave; + struct sdw_stream_config sconfig; + struct sdw_stream_runtime *sruntime; + struct sdw_port_config port_config[WSA883X_MAX_SWR_PORTS]; + struct gpio_desc *sd_n; + bool port_prepared[WSA883X_MAX_SWR_PORTS]; + bool port_enable[WSA883X_MAX_SWR_PORTS]; + int version; + int variant; + int active_ports; + int dev_mode; + int comp_offset; +}; + +enum { + WSA8830 = 0, + WSA8835, + WSA8832, + WSA8835_V2 = 5, +}; + +enum { + COMP_OFFSET0, + COMP_OFFSET1, + COMP_OFFSET2, + COMP_OFFSET3, + COMP_OFFSET4, +}; + +enum wsa_port_ids { + WSA883X_PORT_DAC, + WSA883X_PORT_COMP, + WSA883X_PORT_BOOST, + WSA883X_PORT_VISENSE, +}; + +/* 4 ports */ +static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = { + { + /* DAC */ + .num = 1, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* COMP */ + .num = 2, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* BOOST */ + .num = 3, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + }, { + /* VISENSE */ + .num = 4, + .type = SDW_DPN_SIMPLE, + .min_ch = 1, + .max_ch = 1, + .simple_ch_prep_sm = true, + .read_only_wordlength = true, + } +}; + +static struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = { + { + .num = 1, + .ch_mask = 0x1, + }, { + .num = 2, + .ch_mask = 0xf, + }, { + .num = 3, + .ch_mask = 0x3, + }, { /* IV feedback */ + .num = 4, + .ch_mask = 0x3, + }, +}; + +static struct reg_default wsa883x_defaults[] = { + { WSA883X_REF_CTRL, 0xD5 }, + { WSA883X_TEST_CTL_0, 0x06 }, + { WSA883X_BIAS_0, 0xD2 }, + { WSA883X_OP_CTL, 0xE0 }, + { WSA883X_IREF_CTL, 0x57 }, + { WSA883X_ISENS_CTL, 0x47 }, + { WSA883X_CLK_CTL, 0x87 }, + { WSA883X_TEST_CTL_1, 0x00 }, + { WSA883X_BIAS_1, 0x51 }, + { WSA883X_ADC_CTL, 0x01 }, + { WSA883X_DOUT_MSB, 0x00 }, + { WSA883X_DOUT_LSB, 0x00 }, + { WSA883X_VBAT_SNS, 0x40 }, + { WSA883X_ITRIM_CODE, 0x9F }, + { WSA883X_EN, 0x20 }, + { WSA883X_OVERRIDE1, 0x00 }, + { WSA883X_OVERRIDE2, 0x08 }, + { WSA883X_VSENSE1, 0xD3 }, + { WSA883X_ISENSE1, 0xD4 }, + { WSA883X_ISENSE2, 0x20 }, + { WSA883X_ISENSE_CAL, 0x00 }, + { WSA883X_MISC, 0x08 }, + { WSA883X_ADC_0, 0x00 }, + { WSA883X_ADC_1, 0x00 }, + { WSA883X_ADC_2, 0x40 }, + { WSA883X_ADC_3, 0x80 }, + { WSA883X_ADC_4, 0x25 }, + { WSA883X_ADC_5, 0x25 }, + { WSA883X_ADC_6, 0x08 }, + { WSA883X_ADC_7, 0x81 }, + { WSA883X_STATUS, 0x00 }, + { WSA883X_DAC_CTRL_REG, 0x53 }, + { WSA883X_DAC_EN_DEBUG_REG, 0x00 }, + { WSA883X_DAC_OPAMP_BIAS1_REG, 0x48 }, + { WSA883X_DAC_OPAMP_BIAS2_REG, 0x48 }, + { WSA883X_DAC_VCM_CTRL_REG, 0x88 }, + { WSA883X_DAC_VOLTAGE_CTRL_REG, 0xA5 }, + { WSA883X_ATEST1_REG, 0x00 }, + { WSA883X_ATEST2_REG, 0x00 }, + { WSA883X_SPKR_TOP_BIAS_REG1, 0x6A }, + { WSA883X_SPKR_TOP_BIAS_REG2, 0x65 }, + { WSA883X_SPKR_TOP_BIAS_REG3, 0x55 }, + { WSA883X_SPKR_TOP_BIAS_REG4, 0xA9 }, + { WSA883X_SPKR_CLIP_DET_REG, 0x9C }, + { WSA883X_SPKR_DRV_LF_BLK_EN, 0x0F }, + { WSA883X_SPKR_DRV_LF_EN, 0x0A }, + { WSA883X_SPKR_DRV_LF_MASK_DCC_CTL, 0x00 }, + { WSA883X_SPKR_DRV_LF_MISC_CTL, 0x3A }, + { WSA883X_SPKR_DRV_LF_REG_GAIN, 0x00 }, + { WSA883X_SPKR_DRV_OS_CAL_CTL, 0x00 }, + { WSA883X_SPKR_DRV_OS_CAL_CTL1, 0x90 }, + { WSA883X_SPKR_PWM_CLK_CTL, 0x00 }, + { WSA883X_SPKR_PDRV_HS_CTL, 0x52 }, + { WSA883X_SPKR_PDRV_LS_CTL, 0x48 }, + { WSA883X_SPKR_PWRSTG_DBG, 0x08 }, + { WSA883X_SPKR_OCP_CTL, 0xE2 }, + { WSA883X_SPKR_BBM_CTL, 0x92 }, + { WSA883X_PA_STATUS0, 0x00 }, + { WSA883X_PA_STATUS1, 0x00 }, + { WSA883X_PA_STATUS2, 0x80 }, + { WSA883X_EN_CTRL, 0x44 }, + { WSA883X_CURRENT_LIMIT, 0xCC }, + { WSA883X_IBIAS1, 0x00 }, + { WSA883X_IBIAS2, 0x00 }, + { WSA883X_IBIAS3, 0x00 }, + { WSA883X_LDO_PROG, 0x02 }, + { WSA883X_STABILITY_CTRL1, 0x8E }, + { WSA883X_STABILITY_CTRL2, 0x10 }, + { WSA883X_PWRSTAGE_CTRL1, 0x06 }, + { WSA883X_PWRSTAGE_CTRL2, 0x00 }, + { WSA883X_BYPASS_1, 0x19 }, + { WSA883X_BYPASS_2, 0x13 }, + { WSA883X_ZX_CTRL_1, 0xF0 }, + { WSA883X_ZX_CTRL_2, 0x04 }, + { WSA883X_MISC1, 0x06 }, + { WSA883X_MISC2, 0xA0 }, + { WSA883X_GMAMP_SUP1, 0x82 }, + { WSA883X_PWRSTAGE_CTRL3, 0x39 }, + { WSA883X_PWRSTAGE_CTRL4, 0x5F }, + { WSA883X_TEST1, 0x00 }, + { WSA883X_SPARE1, 0x00 }, + { WSA883X_SPARE2, 0x00 }, + { WSA883X_PON_CTL_0, 0x10 }, + { WSA883X_PON_CLT_1, 0xE0 }, + { WSA883X_PON_CTL_2, 0x90 }, + { WSA883X_PON_CTL_3, 0x70 }, + { WSA883X_CKWD_CTL_0, 0x34 }, + { WSA883X_CKWD_CTL_1, 0x0F }, + { WSA883X_CKWD_CTL_2, 0x00 }, + { WSA883X_CKSK_CTL_0, 0x00 }, + { WSA883X_PADSW_CTL_0, 0x00 }, + { WSA883X_TEST_0, 0x00 }, + { WSA883X_TEST_1, 0x00 }, + { WSA883X_STATUS_0, 0x00 }, + { WSA883X_STATUS_1, 0x00 }, + { WSA883X_CHIP_ID0, 0x00 }, + { WSA883X_CHIP_ID1, 0x00 }, + { WSA883X_CHIP_ID2, 0x02 }, + { WSA883X_CHIP_ID3, 0x02 }, + { WSA883X_BUS_ID, 0x00 }, + { WSA883X_CDC_RST_CTL, 0x01 }, + { WSA883X_TOP_CLK_CFG, 0x00 }, + { WSA883X_CDC_PATH_MODE, 0x00 }, + { WSA883X_CDC_CLK_CTL, 0xFF }, + { WSA883X_SWR_RESET_EN, 0x00 }, + { WSA883X_RESET_CTL, 0x00 }, + { WSA883X_PA_FSM_CTL, 0x00 }, + { WSA883X_PA_FSM_TIMER0, 0x80 }, + { WSA883X_PA_FSM_TIMER1, 0x80 }, + { WSA883X_PA_FSM_STA, 0x00 }, + { WSA883X_PA_FSM_ERR_COND, 0x00 }, + { WSA883X_PA_FSM_MSK, 0x00 }, + { WSA883X_PA_FSM_BYP, 0x01 }, + { WSA883X_PA_FSM_DBG, 0x00 }, + { WSA883X_TADC_VALUE_CTL, 0x03 }, + { WSA883X_TEMP_DETECT_CTL, 0x01 }, + { WSA883X_TEMP_MSB, 0x00 }, + { WSA883X_TEMP_LSB, 0x00 }, + { WSA883X_TEMP_CONFIG0, 0x00 }, + { WSA883X_TEMP_CONFIG1, 0x00 }, + { WSA883X_VBAT_ADC_FLT_CTL, 0x00 }, + { WSA883X_VBAT_DIN_MSB, 0x00 }, + { WSA883X_VBAT_DIN_LSB, 0x00 }, + { WSA883X_VBAT_DOUT, 0x00 }, + { WSA883X_SDM_PDM9_LSB, 0x00 }, + { WSA883X_SDM_PDM9_MSB, 0x00 }, + { WSA883X_CDC_RX_CTL, 0xFE }, + { WSA883X_CDC_SPK_DSM_A1_0, 0x00 }, + { WSA883X_CDC_SPK_DSM_A1_1, 0x01 }, + { WSA883X_CDC_SPK_DSM_A2_0, 0x96 }, + { WSA883X_CDC_SPK_DSM_A2_1, 0x09 }, + { WSA883X_CDC_SPK_DSM_A3_0, 0xAB }, + { WSA883X_CDC_SPK_DSM_A3_1, 0x05 }, + { WSA883X_CDC_SPK_DSM_A4_0, 0x1C }, + { WSA883X_CDC_SPK_DSM_A4_1, 0x02 }, + { WSA883X_CDC_SPK_DSM_A5_0, 0x17 }, + { WSA883X_CDC_SPK_DSM_A5_1, 0x02 }, + { WSA883X_CDC_SPK_DSM_A6_0, 0xAA }, + { WSA883X_CDC_SPK_DSM_A7_0, 0xE3 }, + { WSA883X_CDC_SPK_DSM_C_0, 0x69 }, + { WSA883X_CDC_SPK_DSM_C_1, 0x54 }, + { WSA883X_CDC_SPK_DSM_C_2, 0x02 }, + { WSA883X_CDC_SPK_DSM_C_3, 0x15 }, + { WSA883X_CDC_SPK_DSM_R1, 0xA4 }, + { WSA883X_CDC_SPK_DSM_R2, 0xB5 }, + { WSA883X_CDC_SPK_DSM_R3, 0x86 }, + { WSA883X_CDC_SPK_DSM_R4, 0x85 }, + { WSA883X_CDC_SPK_DSM_R5, 0xAA }, + { WSA883X_CDC_SPK_DSM_R6, 0xE2 }, + { WSA883X_CDC_SPK_DSM_R7, 0x62 }, + { WSA883X_CDC_SPK_GAIN_PDM_0, 0x00 }, + { WSA883X_CDC_SPK_GAIN_PDM_1, 0xFC }, + { WSA883X_CDC_SPK_GAIN_PDM_2, 0x05 }, + { WSA883X_PDM_WD_CTL, 0x00 }, + { WSA883X_DEM_BYPASS_DATA0, 0x00 }, + { WSA883X_DEM_BYPASS_DATA1, 0x00 }, + { WSA883X_DEM_BYPASS_DATA2, 0x00 }, + { WSA883X_DEM_BYPASS_DATA3, 0x00 }, + { WSA883X_WAVG_CTL, 0x06 }, + { WSA883X_WAVG_LRA_PER_0, 0xD1 }, + { WSA883X_WAVG_LRA_PER_1, 0x00 }, + { WSA883X_WAVG_DELTA_THETA_0, 0xE6 }, + { WSA883X_WAVG_DELTA_THETA_1, 0x04 }, + { WSA883X_WAVG_DIRECT_AMP_0, 0x50 }, + { WSA883X_WAVG_DIRECT_AMP_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP0_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP0_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP1_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP1_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP2_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP2_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP3_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP3_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP4_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP4_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP5_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP5_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP6_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP6_1, 0x00 }, + { WSA883X_WAVG_PTRN_AMP7_0, 0x50 }, + { WSA883X_WAVG_PTRN_AMP7_1, 0x00 }, + { WSA883X_WAVG_PER_0_1, 0x88 }, + { WSA883X_WAVG_PER_2_3, 0x88 }, + { WSA883X_WAVG_PER_4_5, 0x88 }, + { WSA883X_WAVG_PER_6_7, 0x88 }, + { WSA883X_WAVG_STA, 0x00 }, + { WSA883X_DRE_CTL_0, 0x70 }, + { WSA883X_DRE_CTL_1, 0x08 }, + { WSA883X_DRE_IDLE_DET_CTL, 0x1F }, + { WSA883X_CLSH_CTL_0, 0x37 }, + { WSA883X_CLSH_CTL_1, 0x81 }, + { WSA883X_CLSH_V_HD_PA, 0x0F }, + { WSA883X_CLSH_V_PA_MIN, 0x00 }, + { WSA883X_CLSH_OVRD_VAL, 0x00 }, + { WSA883X_CLSH_HARD_MAX, 0xFF }, + { WSA883X_CLSH_SOFT_MAX, 0xF5 }, + { WSA883X_CLSH_SIG_DP, 0x00 }, + { WSA883X_TAGC_CTL, 0x10 }, + { WSA883X_TAGC_TIME, 0x20 }, + { WSA883X_TAGC_E2E_GAIN, 0x02 }, + { WSA883X_TAGC_FORCE_VAL, 0x00 }, + { WSA883X_VAGC_CTL, 0x00 }, + { WSA883X_VAGC_TIME, 0x08 }, + { WSA883X_VAGC_ATTN_LVL_1_2, 0x21 }, + { WSA883X_VAGC_ATTN_LVL_3, 0x03 }, + { WSA883X_INTR_MODE, 0x00 }, + { WSA883X_INTR_MASK0, 0x90 }, + { WSA883X_INTR_MASK1, 0x00 }, + { WSA883X_INTR_STATUS0, 0x00 }, + { WSA883X_INTR_STATUS1, 0x00 }, + { WSA883X_INTR_CLEAR0, 0x00 }, + { WSA883X_INTR_CLEAR1, 0x00 }, + { WSA883X_INTR_LEVEL0, 0x00 }, + { WSA883X_INTR_LEVEL1, 0x00 }, + { WSA883X_INTR_SET0, 0x00 }, + { WSA883X_INTR_SET1, 0x00 }, + { WSA883X_INTR_TEST0, 0x00 }, + { WSA883X_INTR_TEST1, 0x00 }, + { WSA883X_OTP_CTRL0, 0x00 }, + { WSA883X_OTP_CTRL1, 0x00 }, + { WSA883X_HDRIVE_CTL_GROUP1, 0x00 }, + { WSA883X_PIN_CTL, 0x04 }, + { WSA883X_PIN_CTL_OE, 0x00 }, + { WSA883X_PIN_WDATA_IOPAD, 0x00 }, + { WSA883X_PIN_STATUS, 0x00 }, + { WSA883X_I2C_SLAVE_CTL, 0x00 }, + { WSA883X_PDM_TEST_MODE, 0x00 }, + { WSA883X_ATE_TEST_MODE, 0x00 }, + { WSA883X_DIG_DEBUG_MODE, 0x00 }, + { WSA883X_DIG_DEBUG_SEL, 0x00 }, + { WSA883X_DIG_DEBUG_EN, 0x00 }, + { WSA883X_SWR_HM_TEST0, 0x08 }, + { WSA883X_SWR_HM_TEST1, 0x00 }, + { WSA883X_SWR_PAD_CTL, 0x37 }, + { WSA883X_TADC_DETECT_DBG_CTL, 0x00 }, + { WSA883X_TADC_DEBUG_MSB, 0x00 }, + { WSA883X_TADC_DEBUG_LSB, 0x00 }, + { WSA883X_SAMPLE_EDGE_SEL, 0x7F }, + { WSA883X_SWR_EDGE_SEL, 0x00 }, + { WSA883X_TEST_MODE_CTL, 0x04 }, + { WSA883X_IOPAD_CTL, 0x00 }, + { WSA883X_ANA_CSR_DBG_ADD, 0x00 }, + { WSA883X_ANA_CSR_DBG_CTL, 0x12 }, + { WSA883X_SPARE_R, 0x00 }, + { WSA883X_SPARE_0, 0x00 }, + { WSA883X_SPARE_1, 0x00 }, + { WSA883X_SPARE_2, 0x00 }, + { WSA883X_SCODE, 0x00 }, + { WSA883X_OTP_REG_0, 0x05 }, + { WSA883X_OTP_REG_1, 0xFF }, + { WSA883X_OTP_REG_2, 0xC0 }, + { WSA883X_OTP_REG_3, 0xFF }, + { WSA883X_OTP_REG_4, 0xC0 }, + { WSA883X_OTP_REG_5, 0xFF }, + { WSA883X_OTP_REG_6, 0xFF }, + { WSA883X_OTP_REG_7, 0xFF }, + { WSA883X_OTP_REG_8, 0xFF }, + { WSA883X_OTP_REG_9, 0xFF }, + { WSA883X_OTP_REG_10, 0xFF }, + { WSA883X_OTP_REG_11, 0xFF }, + { WSA883X_OTP_REG_12, 0xFF }, + { WSA883X_OTP_REG_13, 0xFF }, + { WSA883X_OTP_REG_14, 0xFF }, + { WSA883X_OTP_REG_15, 0xFF }, + { WSA883X_OTP_REG_16, 0xFF }, + { WSA883X_OTP_REG_17, 0xFF }, + { WSA883X_OTP_REG_18, 0xFF }, + { WSA883X_OTP_REG_19, 0xFF }, + { WSA883X_OTP_REG_20, 0xFF }, + { WSA883X_OTP_REG_21, 0xFF }, + { WSA883X_OTP_REG_22, 0xFF }, + { WSA883X_OTP_REG_23, 0xFF }, + { WSA883X_OTP_REG_24, 0x37 }, + { WSA883X_OTP_REG_25, 0x3F }, + { WSA883X_OTP_REG_26, 0x03 }, + { WSA883X_OTP_REG_27, 0x00 }, + { WSA883X_OTP_REG_28, 0x00 }, + { WSA883X_OTP_REG_29, 0x00 }, + { WSA883X_OTP_REG_30, 0x00 }, + { WSA883X_OTP_REG_31, 0x03 }, + { WSA883X_OTP_REG_32, 0x00 }, + { WSA883X_OTP_REG_33, 0xFF }, + { WSA883X_OTP_REG_34, 0x00 }, + { WSA883X_OTP_REG_35, 0x00 }, + { WSA883X_OTP_REG_63, 0x40 }, + { WSA883X_EMEM_0, 0x00 }, + { WSA883X_EMEM_1, 0x00 }, + { WSA883X_EMEM_2, 0x00 }, + { WSA883X_EMEM_3, 0x00 }, + { WSA883X_EMEM_4, 0x00 }, + { WSA883X_EMEM_5, 0x00 }, + { WSA883X_EMEM_6, 0x00 }, + { WSA883X_EMEM_7, 0x00 }, + { WSA883X_EMEM_8, 0x00 }, + { WSA883X_EMEM_9, 0x00 }, + { WSA883X_EMEM_10, 0x00 }, + { WSA883X_EMEM_11, 0x00 }, + { WSA883X_EMEM_12, 0x00 }, + { WSA883X_EMEM_13, 0x00 }, + { WSA883X_EMEM_14, 0x00 }, + { WSA883X_EMEM_15, 0x00 }, + { WSA883X_EMEM_16, 0x00 }, + { WSA883X_EMEM_17, 0x00 }, + { WSA883X_EMEM_18, 0x00 }, + { WSA883X_EMEM_19, 0x00 }, + { WSA883X_EMEM_20, 0x00 }, + { WSA883X_EMEM_21, 0x00 }, + { WSA883X_EMEM_22, 0x00 }, + { WSA883X_EMEM_23, 0x00 }, + { WSA883X_EMEM_24, 0x00 }, + { WSA883X_EMEM_25, 0x00 }, + { WSA883X_EMEM_26, 0x00 }, + { WSA883X_EMEM_27, 0x00 }, + { WSA883X_EMEM_28, 0x00 }, + { WSA883X_EMEM_29, 0x00 }, + { WSA883X_EMEM_30, 0x00 }, + { WSA883X_EMEM_31, 0x00 }, + { WSA883X_EMEM_32, 0x00 }, + { WSA883X_EMEM_33, 0x00 }, + { WSA883X_EMEM_34, 0x00 }, + { WSA883X_EMEM_35, 0x00 }, + { WSA883X_EMEM_36, 0x00 }, + { WSA883X_EMEM_37, 0x00 }, + { WSA883X_EMEM_38, 0x00 }, + { WSA883X_EMEM_39, 0x00 }, + { WSA883X_EMEM_40, 0x00 }, + { WSA883X_EMEM_41, 0x00 }, + { WSA883X_EMEM_42, 0x00 }, + { WSA883X_EMEM_43, 0x00 }, + { WSA883X_EMEM_44, 0x00 }, + { WSA883X_EMEM_45, 0x00 }, + { WSA883X_EMEM_46, 0x00 }, + { WSA883X_EMEM_47, 0x00 }, + { WSA883X_EMEM_48, 0x00 }, + { WSA883X_EMEM_49, 0x00 }, + { WSA883X_EMEM_50, 0x00 }, + { WSA883X_EMEM_51, 0x00 }, + { WSA883X_EMEM_52, 0x00 }, + { WSA883X_EMEM_53, 0x00 }, + { WSA883X_EMEM_54, 0x00 }, + { WSA883X_EMEM_55, 0x00 }, + { WSA883X_EMEM_56, 0x00 }, + { WSA883X_EMEM_57, 0x00 }, + { WSA883X_EMEM_58, 0x00 }, + { WSA883X_EMEM_59, 0x00 }, + { WSA883X_EMEM_60, 0x00 }, + { WSA883X_EMEM_61, 0x00 }, + { WSA883X_EMEM_62, 0x00 }, + { WSA883X_EMEM_63, 0x00 }, +}; + +static bool wsa883x_readonly_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WSA883X_DOUT_MSB: + case WSA883X_DOUT_LSB: + case WSA883X_STATUS: + case WSA883X_PA_STATUS0: + case WSA883X_PA_STATUS1: + case WSA883X_PA_STATUS2: + case WSA883X_STATUS_0: + case WSA883X_STATUS_1: + case WSA883X_CHIP_ID0: + case WSA883X_CHIP_ID1: + case WSA883X_CHIP_ID2: + case WSA883X_CHIP_ID3: + case WSA883X_BUS_ID: + case WSA883X_PA_FSM_STA: + case WSA883X_PA_FSM_ERR_COND: + case WSA883X_TEMP_MSB: + case WSA883X_TEMP_LSB: + case WSA883X_VBAT_DIN_MSB: + case WSA883X_VBAT_DIN_LSB: + case WSA883X_VBAT_DOUT: + case WSA883X_SDM_PDM9_LSB: + case WSA883X_SDM_PDM9_MSB: + case WSA883X_WAVG_STA: + case WSA883X_INTR_STATUS0: + case WSA883X_INTR_STATUS1: + case WSA883X_OTP_CTRL1: + case WSA883X_PIN_STATUS: + case WSA883X_ATE_TEST_MODE: + case WSA883X_SWR_HM_TEST1: + case WSA883X_SPARE_R: + case WSA883X_OTP_REG_0: + return true; + } + return false; +} + +static bool wsa883x_writeable_register(struct device *dev, unsigned int reg) +{ + return !wsa883x_readonly_register(dev, reg); +} + +static bool wsa883x_volatile_register(struct device *dev, unsigned int reg) +{ + return wsa883x_readonly_register(dev, reg); +} + +static struct regmap_config wsa883x_regmap_config = { + .reg_bits = 32, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wsa883x_defaults, + .max_register = WSA883X_MAX_REGISTER, + .num_reg_defaults = ARRAY_SIZE(wsa883x_defaults), + .volatile_reg = wsa883x_volatile_register, + .writeable_reg = wsa883x_writeable_register, + .reg_format_endian = REGMAP_ENDIAN_NATIVE, + .val_format_endian = REGMAP_ENDIAN_NATIVE, + .can_multi_write = true, + .use_single_read = true, +}; + +static const struct reg_sequence reg_init[] = { + {WSA883X_PA_FSM_BYP, 0x00}, + {WSA883X_ADC_6, 0x02}, + {WSA883X_CDC_SPK_DSM_A2_0, 0x0A}, + {WSA883X_CDC_SPK_DSM_A2_1, 0x08}, + {WSA883X_CDC_SPK_DSM_A3_0, 0xF3}, + {WSA883X_CDC_SPK_DSM_A3_1, 0x07}, + {WSA883X_CDC_SPK_DSM_A4_0, 0x79}, + {WSA883X_CDC_SPK_DSM_A4_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A5_0, 0x0B}, + {WSA883X_CDC_SPK_DSM_A5_1, 0x02}, + {WSA883X_CDC_SPK_DSM_A6_0, 0x8A}, + {WSA883X_CDC_SPK_DSM_A7_0, 0x9B}, + {WSA883X_CDC_SPK_DSM_C_0, 0x68}, + {WSA883X_CDC_SPK_DSM_C_1, 0x54}, + {WSA883X_CDC_SPK_DSM_C_2, 0xF2}, + {WSA883X_CDC_SPK_DSM_C_3, 0x20}, + {WSA883X_CDC_SPK_DSM_R1, 0x83}, + {WSA883X_CDC_SPK_DSM_R2, 0x7F}, + {WSA883X_CDC_SPK_DSM_R3, 0x9D}, + {WSA883X_CDC_SPK_DSM_R4, 0x82}, + {WSA883X_CDC_SPK_DSM_R5, 0x8B}, + {WSA883X_CDC_SPK_DSM_R6, 0x9B}, + {WSA883X_CDC_SPK_DSM_R7, 0x3F}, + {WSA883X_VBAT_SNS, 0x20}, + {WSA883X_DRE_CTL_0, 0x92}, + {WSA883X_DRE_IDLE_DET_CTL, 0x0F}, + {WSA883X_CURRENT_LIMIT, 0xC4}, + {WSA883X_VAGC_TIME, 0x0F}, + {WSA883X_VAGC_ATTN_LVL_1_2, 0x00}, + {WSA883X_VAGC_ATTN_LVL_3, 0x01}, + {WSA883X_VAGC_CTL, 0x01}, + {WSA883X_TAGC_CTL, 0x1A}, + {WSA883X_TAGC_TIME, 0x2C}, + {WSA883X_TEMP_CONFIG0, 0x02}, + {WSA883X_TEMP_CONFIG1, 0x02}, + {WSA883X_OTP_REG_1, 0x49}, + {WSA883X_OTP_REG_2, 0x80}, + {WSA883X_OTP_REG_3, 0xC9}, + {WSA883X_OTP_REG_4, 0x40}, + {WSA883X_TAGC_CTL, 0x1B}, + {WSA883X_ADC_2, 0x00}, + {WSA883X_ADC_7, 0x85}, + {WSA883X_ADC_7, 0x87}, + {WSA883X_CKWD_CTL_0, 0x14}, + {WSA883X_CKWD_CTL_1, 0x1B}, + {WSA883X_GMAMP_SUP1, 0xE2}, +}; + +static void wsa883x_init(struct wsa883x_priv *wsa883x) +{ + struct regmap *regmap = wsa883x->regmap; + int variant, version; + + regmap_read(regmap, WSA883X_OTP_REG_0, &variant); + wsa883x->variant = variant & WSA883X_ID_MASK; + + regmap_read(regmap, WSA883X_CHIP_ID0, &version); + wsa883x->version = version; + + switch (wsa883x->variant) { + case WSA8830: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n", + wsa883x->version); + break; + case WSA8835: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n", + wsa883x->version); + break; + case WSA8832: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n", + wsa883x->version); + break; + case WSA8835_V2: + dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n", + wsa883x->version); + break; + default: + break; + } + + wsa883x->comp_offset = COMP_OFFSET2; + + /* Initial settings */ + regmap_multi_reg_write(regmap, reg_init, ARRAY_SIZE(reg_init)); + + if (wsa883x->variant == WSA8830 || wsa883x->variant == WSA8832) { + wsa883x->comp_offset = COMP_OFFSET3; + regmap_update_bits(regmap, WSA883X_DRE_CTL_0, + WSA883X_DRE_OFFSET_MASK, + wsa883x->comp_offset); + } +} + +static int wsa883x_update_status(struct sdw_slave *slave, + enum sdw_slave_status status) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) + wsa883x_init(wsa883x); + + return 0; +} + +static int wsa883x_port_prep(struct sdw_slave *slave, + struct sdw_prepare_ch *prepare_ch, + enum sdw_port_prep_ops state) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + + if (state == SDW_OPS_PORT_POST_PREP) + wsa883x->port_prepared[prepare_ch->num - 1] = true; + else + wsa883x->port_prepared[prepare_ch->num - 1] = false; + + return 0; +} + +static struct sdw_slave_ops wsa883x_slave_ops = { + .update_status = wsa883x_update_status, + .port_prep = wsa883x_port_prep, +}; + +static int wsa883x_codec_probe(struct snd_soc_component *comp) +{ + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(comp); + + snd_soc_component_init_regmap(comp, wsa883x->regmap); + + return 0; +} + +static const struct snd_soc_component_driver wsa883x_component_drv = { + .name = "WSA883x", + .probe = wsa883x_codec_probe, +}; + +static int wsa883x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + int i; + + wsa883x->active_ports = 0; + for (i = 0; i < WSA883X_MAX_SWR_PORTS; i++) { + if (!wsa883x->port_enable[i]) + continue; + + wsa883x->port_config[wsa883x->active_ports] = wsa883x_pconfig[i]; + wsa883x->active_ports++; + } + + wsa883x->sconfig.frame_rate = params_rate(params); + + return sdw_stream_add_slave(wsa883x->slave, &wsa883x->sconfig, + wsa883x->port_config, wsa883x->active_ports, + wsa883x->sruntime); +} + +static int wsa883x_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + + sdw_stream_remove_slave(wsa883x->slave, wsa883x->sruntime); + + return 0; +} + +static int wsa883x_set_sdw_stream(struct snd_soc_dai *dai, + void *stream, int direction) +{ + struct wsa883x_priv *wsa883x = dev_get_drvdata(dai->dev); + + wsa883x->sruntime = stream; + + return 0; +} + +static int wsa883x_digital_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_component *component = dai->component; + + if (mute) { + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, 0); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 0); + + } else { + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, + WSA883X_DRE_GAIN_FROM_CSR); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 1); + + } + + return 0; +} + +static const struct snd_soc_dai_ops wsa883x_dai_ops = { + .hw_params = wsa883x_hw_params, + .hw_free = wsa883x_hw_free, + .mute_stream = wsa883x_digital_mute, + .set_stream = wsa883x_set_sdw_stream, +}; + +static struct snd_soc_dai_driver wsa883x_dais[] = { + { + .name = "SPKR", + .playback = { + .stream_name = "SPKR Playback", + .rates = WSA883X_RATES | WSA883X_FRAC_RATES, + .formats = WSA883X_FORMATS, + .rate_max = 8000, + .rate_min = 352800, + .channels_min = 1, + .channels_max = 1, + }, + .ops = &wsa883x_dai_ops, + }, +}; + +static int wsa883x_probe(struct sdw_slave *pdev, + const struct sdw_device_id *id) +{ + struct wsa883x_priv *wsa883x; + struct device *dev = &pdev->dev; + int ret; + + wsa883x = devm_kzalloc(&pdev->dev, sizeof(*wsa883x), GFP_KERNEL); + if (!wsa883x) + return -ENOMEM; + + wsa883x->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(wsa883x->vdd)) { + dev_err(dev, "No vdd regulator found\n"); + return PTR_ERR(wsa883x->vdd); + } + + ret = regulator_enable(wsa883x->vdd); + if (ret) { + dev_err(dev, "Failed to enable vdd regulator (%d)\n", ret); + return ret; + } + + wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown", + GPIOD_FLAGS_BIT_NONEXCLUSIVE); + if (IS_ERR(wsa883x->sd_n)) { + dev_err(&pdev->dev, "Shutdown Control GPIO not found\n"); + ret = PTR_ERR(wsa883x->sd_n); + goto err; + } + + dev_set_drvdata(&pdev->dev, wsa883x); + wsa883x->slave = pdev; + wsa883x->dev = &pdev->dev; + wsa883x->sconfig.ch_count = 1; + wsa883x->sconfig.bps = 1; + wsa883x->sconfig.direction = SDW_DATA_DIR_RX; + wsa883x->sconfig.type = SDW_STREAM_PDM; + + pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); + pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; + pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; + gpiod_direction_output(wsa883x->sd_n, 1); + + wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config); + if (IS_ERR(wsa883x->regmap)) { + dev_err(&pdev->dev, "regmap_init failed\n"); + ret = PTR_ERR(wsa883x->regmap); + goto err; + } + pm_runtime_set_autosuspend_delay(dev, 3000); + pm_runtime_use_autosuspend(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + ret = devm_snd_soc_register_component(&pdev->dev, + &wsa883x_component_drv, + wsa883x_dais, + ARRAY_SIZE(wsa883x_dais)); +err: + if (ret) + regulator_disable(wsa883x->vdd); + + return ret; + +} + +static int __maybe_unused wsa883x_runtime_suspend(struct device *dev) +{ + struct regmap *regmap = dev_get_regmap(dev, NULL); + struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); + + gpiod_direction_output(wsa883x->sd_n, 0); + + regcache_cache_only(regmap, true); + regcache_mark_dirty(regmap); + + regulator_disable(wsa883x->vdd); + return 0; +} + +static int __maybe_unused wsa883x_runtime_resume(struct device *dev) +{ + struct sdw_slave *slave = dev_to_sdw_dev(dev); + struct regmap *regmap = dev_get_regmap(dev, NULL); + struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); + int ret; + + ret = regulator_enable(wsa883x->vdd); + if (ret) { + dev_err(dev, "Failed to enable vdd regulator (%d)\n", ret); + return ret; + } + + gpiod_direction_output(wsa883x->sd_n, 1); + + wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA883X_PROBE_TIMEOUT)); + + usleep_range(20000, 20010); + regcache_cache_only(regmap, false); + regcache_sync(regmap); + + return 0; +} + +static const struct dev_pm_ops wsa883x_pm_ops = { + SET_RUNTIME_PM_OPS(wsa883x_runtime_suspend, wsa883x_runtime_resume, NULL) +}; + +static const struct sdw_device_id wsa883x_swr_id[] = { + SDW_SLAVE_ENTRY(0x0217, 0x0202, 0), + {}, +}; + +static struct sdw_driver wsa883x_codec_driver = { + .driver = { + .name = "wsa883x-codec", + .pm = &wsa883x_pm_ops, + .suppress_bind_attrs = true, + }, + .probe = wsa883x_probe, + .ops = &wsa883x_slave_ops, + .id_table = wsa883x_swr_id, +}; + +module_sdw_driver(wsa883x_codec_driver); + +MODULE_DESCRIPTION("WSA883x codec driver"); +MODULE_LICENSE("GPL"); -- GitLab From a7b028e4252bc1e8b5646657fd45a68792826c23 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 29 Jun 2022 10:06:44 +0100 Subject: [PATCH 758/942] MAINTAINERS: add ASoC Qualcomm codecs Add missing Qualcomm codes to the list. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220629090644.67982-5-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- MAINTAINERS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 171fa31606960..c4648e86dc14b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16250,6 +16250,8 @@ M: Srinivas Kandagatla M: Banajit Goswami L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported +F: sound/soc/codecs/lpass-rx-macro.* +F: sound/soc/codecs/lpass-tx-macro.* F: sound/soc/codecs/lpass-va-macro.c F: sound/soc/codecs/lpass-wsa-macro.* F: sound/soc/codecs/msm8916-wcd-analog.c @@ -16257,7 +16259,9 @@ F: sound/soc/codecs/msm8916-wcd-digital.c F: sound/soc/codecs/wcd9335.* F: sound/soc/codecs/wcd934x.c F: sound/soc/codecs/wcd-clsh-v2.* +F: sound/soc/codecs/wcd-mbhc-v2.* F: sound/soc/codecs/wsa881x.c +F: sound/soc/codecs/wsa883x.c F: sound/soc/qcom/ QCOM EMBEDDED USB DEBUGGER (EUD) -- GitLab From 48620f17e071060092197a09663a1c1fe6207829 Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Wed, 29 Jun 2022 08:03:45 +0000 Subject: [PATCH 759/942] ASoC: rockchip: i2s: Fix the debug level on missing pinctrl Use dev_dbg on missing i2s->pinctrl as the pinctrl property is optional. Fixes: 44f362c2cc6d ("ASoC: rockchip: i2s: switch BCLK to GPIO") Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20220629080345.2427872-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 0ed01624a2dbd..ebd829ac09fec 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -812,7 +812,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) } } } else { - dev_err(&pdev->dev, "failed to find i2s pinctrl\n"); + dev_dbg(&pdev->dev, "failed to find i2s pinctrl\n"); } i2s_pinctrl_select_bclk_off(i2s); -- GitLab From d29e0a6e3631724c0b36786c6d9616b6e4ebeaa4 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 29 Jun 2022 07:06:30 +0200 Subject: [PATCH 760/942] ASoC: max98396: Fix TDM mode BSEL settings In TDM mode, the BSEL register value must be set according to table 5 in the datasheet. This patch adds a lookup function and uses it in max98396_dai_tdm_slot(). As the first 3 entries can also be used for non-TDM setups, the code re-uses the same table for such scenarios. Signed-off-by: Daniel Mack Link: https://lore.kernel.org/r/20220629050630.2848317-1-daniel@zonque.org Signed-off-by: Mark Brown --- sound/soc/codecs/max98396.c | 138 +++++++++++++++++++++++++----------- sound/soc/codecs/max98396.h | 2 +- 2 files changed, 96 insertions(+), 44 deletions(-) diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index f28831f4e74b9..1b6f053adba2a 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -438,47 +438,68 @@ static int max98396_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) return 0; } -/* BCLKs per LRCLK */ -static const int bclk_sel_table[] = { - 32, 48, 64, 96, 128, 192, 256, 384, 512, 320, +#define MAX98396_BSEL_32 0x2 +#define MAX98396_BSEL_48 0x3 +#define MAX98396_BSEL_64 0x4 +#define MAX98396_BSEL_96 0x5 +#define MAX98396_BSEL_128 0x6 +#define MAX98396_BSEL_192 0x7 +#define MAX98396_BSEL_256 0x8 +#define MAX98396_BSEL_384 0x9 +#define MAX98396_BSEL_512 0xa +#define MAX98396_BSEL_320 0xb +#define MAX98396_BSEL_250 0xc +#define MAX98396_BSEL_125 0xd + +/* Refer to table 5 in the datasheet */ +static const struct max98396_pcm_config { + int in, out, width, bsel, max_sr; +} max98396_pcm_configs[] = { + { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 192000 }, + { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 192000 }, + { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 192000 }, + { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 192000 }, + { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 192000 }, + { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 192000 }, + { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 192000 }, + { .in = 2, .out = 4, .width = 16, .bsel = MAX98396_BSEL_32, .max_sr = 96000 }, + { .in = 2, .out = 6, .width = 24, .bsel = MAX98396_BSEL_48, .max_sr = 96000 }, + { .in = 2, .out = 8, .width = 32, .bsel = MAX98396_BSEL_64, .max_sr = 96000 }, + { .in = 3, .out = 15, .width = 32, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 4, .out = 8, .width = 16, .bsel = MAX98396_BSEL_64, .max_sr = 96000 }, + { .in = 4, .out = 12, .width = 24, .bsel = MAX98396_BSEL_96, .max_sr = 96000 }, + { .in = 4, .out = 16, .width = 32, .bsel = MAX98396_BSEL_128, .max_sr = 96000 }, + { .in = 5, .out = 15, .width = 24, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 7, .out = 15, .width = 16, .bsel = MAX98396_BSEL_125, .max_sr = 96000 }, + { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 8, .out = 16, .width = 16, .bsel = MAX98396_BSEL_128, .max_sr = 96000 }, + { .in = 8, .out = 24, .width = 24, .bsel = MAX98396_BSEL_192, .max_sr = 96000 }, + { .in = 8, .out = 32, .width = 32, .bsel = MAX98396_BSEL_256, .max_sr = 96000 }, + { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 96000 }, + { .in = 16, .out = 32, .width = 16, .bsel = MAX98396_BSEL_256, .max_sr = 96000 }, + { .in = 7, .out = 31, .width = 32, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 10, .out = 31, .width = 24, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 10, .out = 40, .width = 32, .bsel = MAX98396_BSEL_320, .max_sr = 48000 }, + { .in = 15, .out = 31, .width = 16, .bsel = MAX98396_BSEL_250, .max_sr = 48000 }, + { .in = 16, .out = 48, .width = 24, .bsel = MAX98396_BSEL_384, .max_sr = 48000 }, + { .in = 16, .out = 64, .width = 32, .bsel = MAX98396_BSEL_512, .max_sr = 48000 }, }; -static int max98396_get_bclk_sel(int bclk) +static int max98396_pcm_config_index(int in_slots, int out_slots, int width) { int i; - /* match BCLKs per LRCLK */ - for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) { - if (bclk_sel_table[i] == bclk) - return i + 2; - } - return 0; -} - -static int max98396_set_clock(struct snd_soc_component *component, - struct snd_pcm_hw_params *params) -{ - struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); - /* BCLK/LRCLK ratio calculation */ - int blr_clk_ratio = params_channels(params) * max98396->ch_size; - int value; - if (!max98396->tdm_mode) { - /* BCLK configuration */ - value = max98396_get_bclk_sel(blr_clk_ratio); - if (!value) { - dev_err(component->dev, - "blr_clk_ratio %d unsupported, format %d\n", - blr_clk_ratio, params_format(params)); - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(max98396_pcm_configs); i++) { + const struct max98396_pcm_config *c = &max98396_pcm_configs[i]; - regmap_update_bits(max98396->regmap, - MAX98396_R2042_PCM_CLK_SETUP, - MAX98396_PCM_CLK_SETUP_BSEL_MASK, - value); + if (in_slots == c->in && out_slots <= c->out && width == c->width) + return i; } - return 0; + return -1; } static int max98396_dai_hw_params(struct snd_pcm_substream *substream, @@ -489,8 +510,7 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, struct max98396_priv *max98396 = snd_soc_component_get_drvdata(component); unsigned int sampling_rate = 0; unsigned int chan_sz = 0; - int ret, reg; - int status; + int ret, reg, status, bsel = 0; bool update = false; /* pcm mode configuration */ @@ -510,8 +530,6 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, goto err; } - max98396->ch_size = snd_pcm_format_width(params_format(params)); - dev_dbg(component->dev, "format supported %d", params_format(params)); @@ -559,6 +577,33 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, goto err; } + if (max98396->tdm_mode) { + if (params_rate(params) > max98396->tdm_max_samplerate) { + dev_err(component->dev, "TDM sample rate %d too high", + params_rate(params)); + goto err; + } + } else { + /* BCLK configuration */ + ret = max98396_pcm_config_index(params_channels(params), + params_channels(params), + snd_pcm_format_width(params_format(params))); + if (ret < 0) { + dev_err(component->dev, + "no PCM config for %d channels, format %d\n", + params_channels(params), params_format(params)); + goto err; + } + + bsel = max98396_pcm_configs[ret].bsel; + + if (params_rate(params) > max98396_pcm_configs[ret].max_sr) { + dev_err(component->dev, "sample rate %d too high", + params_rate(params)); + goto err; + } + } + ret = regmap_read(max98396->regmap, MAX98396_R210F_GLOBAL_EN, &status); if (ret < 0) goto err; @@ -604,12 +649,16 @@ static int max98396_dai_hw_params(struct snd_pcm_substream *substream, MAX98396_IVADC_SR_MASK, sampling_rate << MAX98396_IVADC_SR_SHIFT); - ret = max98396_set_clock(component, params); + if (bsel) + regmap_update_bits(max98396->regmap, + MAX98396_R2042_PCM_CLK_SETUP, + MAX98396_PCM_CLK_SETUP_BSEL_MASK, + bsel); if (status && update) max98396_global_enable_onoff(max98396->regmap, true); - return ret; + return 0; err: return -EINVAL; @@ -634,13 +683,16 @@ static int max98396_dai_tdm_slot(struct snd_soc_dai *dai, max98396->tdm_mode = true; /* BCLK configuration */ - bsel = max98396_get_bclk_sel(slots * slot_width); - if (bsel == 0) { - dev_err(component->dev, "BCLK %d not supported\n", - slots * slot_width); + ret = max98396_pcm_config_index(slots, slots, slot_width); + if (ret < 0) { + dev_err(component->dev, "no TDM config for %d slots %d bits\n", + slots, slot_width); return -EINVAL; } + bsel = max98396_pcm_configs[ret].bsel; + max98396->tdm_max_samplerate = max98396_pcm_configs[ret].max_sr; + /* Channel size configuration */ switch (slot_width) { case 16: diff --git a/sound/soc/codecs/max98396.h b/sound/soc/codecs/max98396.h index ff330ef615680..7278c779989a2 100644 --- a/sound/soc/codecs/max98396.h +++ b/sound/soc/codecs/max98396.h @@ -306,8 +306,8 @@ struct max98396_priv { unsigned int spkfb_slot; unsigned int bypass_slot; bool interleave_mode; - unsigned int ch_size; bool tdm_mode; + int tdm_max_samplerate; int device_id; }; #endif -- GitLab From 3b13b1437dcce4469db575c60d1da4fa9ff80694 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 28 Jun 2022 16:39:49 +0800 Subject: [PATCH 761/942] ASoC: fsl_micfil: change micfil default settings Previous default settings resulted in loose dynamic range and low sound level. New default configuration changes: - outgain = 2 - quality mode = VLOW0 - dc remover = bypass Signed-off-by: Irina Patru Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656405589-29850-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 22 ++++++++++++++++++---- sound/soc/fsl/fsl_micfil.h | 9 +++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 7b88d52f27de2..53e105a93d758 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -48,6 +48,7 @@ struct fsl_micfil { char name[32]; int irq[MICFIL_IRQ_LINES]; enum quality quality; + int dc_remover; }; struct fsl_micfil_soc_data { @@ -317,12 +318,25 @@ static const struct snd_soc_dai_ops fsl_micfil_dai_ops = { static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) { struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev); - int ret; + struct device *dev = cpu_dai->dev; + unsigned int val = 0; + int ret, i; + + micfil->quality = QUALITY_VLOW0; - micfil->quality = QUALITY_MEDIUM; + /* set default gain to 2 */ + regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222); - /* set default gain to max_gain */ - regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x77777777); + /* set DC Remover in bypass mode*/ + for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++) + val |= MICFIL_DC_BYPASS << MICFIL_DC_CHX_SHIFT(i); + ret = regmap_update_bits(micfil->regmap, REG_MICFIL_DC_CTRL, + MICFIL_DC_CTRL_CONFIG, val); + if (ret) { + dev_err(dev, "failed to set DC Remover mode bits\n"); + return ret; + } + micfil->dc_remover = MICFIL_DC_BYPASS; snd_soc_dai_init_dma_data(cpu_dai, NULL, &micfil->dma_params_rx); diff --git a/sound/soc/fsl/fsl_micfil.h b/sound/soc/fsl/fsl_micfil.h index 053caba3caf37..d60285dd07bc5 100644 --- a/sound/soc/fsl/fsl_micfil.h +++ b/sound/soc/fsl/fsl_micfil.h @@ -73,6 +73,15 @@ #define MICFIL_FIFO_STAT_FIFOX_OVER(ch) BIT(ch) #define MICFIL_FIFO_STAT_FIFOX_UNDER(ch) BIT((ch) + 8) +/* MICFIL DC Remover Control Register -- REG_MICFIL_DC_CTRL */ +#define MICFIL_DC_CTRL_CONFIG GENMASK(15, 0) +#define MICFIL_DC_CHX_SHIFT(ch) ((ch) << 1) +#define MICFIL_DC_CHX(ch) GENMASK((((ch) << 1) + 1), ((ch) << 1)) +#define MICFIL_DC_CUTOFF_21HZ 0 +#define MICFIL_DC_CUTOFF_83HZ 1 +#define MICFIL_DC_CUTOFF_152Hz 2 +#define MICFIL_DC_BYPASS 3 + /* MICFIL HWVAD0 Control 1 Register -- REG_MICFIL_VAD0_CTRL1*/ #define MICFIL_VAD0_CTRL1_CHSEL GENMASK(26, 24) #define MICFIL_VAD0_CTRL1_CICOSR GENMASK(19, 16) -- GitLab From 02d91fe47100a29a79fcb8798e45c22591ca852d Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 28 Jun 2022 11:13:25 +0800 Subject: [PATCH 762/942] ASoC: dt-bindings: fsl,micfil: Convert format to json-schema Convert the NXP MICFIL binding to DT schema format using json-schema. Signed-off-by: Shengjiu Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/1656386005-29376-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl,micfil.txt | 33 ------- .../devicetree/bindings/sound/fsl,micfil.yaml | 85 +++++++++++++++++++ 2 files changed, 85 insertions(+), 33 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/fsl,micfil.txt create mode 100644 Documentation/devicetree/bindings/sound/fsl,micfil.yaml diff --git a/Documentation/devicetree/bindings/sound/fsl,micfil.txt b/Documentation/devicetree/bindings/sound/fsl,micfil.txt deleted file mode 100644 index 1ea05d4996c73..0000000000000 --- a/Documentation/devicetree/bindings/sound/fsl,micfil.txt +++ /dev/null @@ -1,33 +0,0 @@ -NXP MICFIL Digital Audio Interface (MICFIL). - -The MICFIL digital interface provides a 16-bit audio signal from a PDM -microphone bitstream in a configurable output sampling rate. - -Required properties: - - - compatible : Compatible list, contains "fsl,imx8mm-micfil" - or "fsl,imx8mp-micfil" - - - reg : Offset and length of the register set for the device. - - - interrupts : Contains the micfil interrupts. - - - clocks : Must contain an entry for each entry in clock-names. - - - clock-names : Must include the "ipg_clk" for register access and - "ipg_clk_app" for internal micfil clock. - - - dmas : Generic dma devicetree binding as described in - Documentation/devicetree/bindings/dma/dma.txt. - -Example: -micfil: micfil@30080000 { - compatible = "fsl,imx8mm-micfil"; - reg = <0x0 0x30080000 0x0 0x10000>; - interrupts = , - ; - clocks = <&clk IMX8MM_CLK_PDM_IPG>, - <&clk IMX8MM_CLK_PDM_ROOT>; - clock-names = "ipg_clk", "ipg_clk_app"; - dmas = <&sdma2 24 26 0x80000000>; -}; diff --git a/Documentation/devicetree/bindings/sound/fsl,micfil.yaml b/Documentation/devicetree/bindings/sound/fsl,micfil.yaml new file mode 100644 index 0000000000000..64d57758ee671 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,micfil.yaml @@ -0,0 +1,85 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/fsl,micfil.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP MICFIL Digital Audio Interface (MICFIL) + +maintainers: + - Shengjiu Wang + +description: | + The MICFIL digital interface provides a 16-bit or 24-bit audio signal + from a PDM microphone bitstream in a configurable output sampling rate. + +properties: + compatible: + enum: + - fsl,imx8mm-micfil + - fsl,imx8mp-micfil + + reg: + maxItems: 1 + + interrupts: + items: + - description: Digital Microphone interface interrupt + - description: Digital Microphone interface error interrupt + - description: voice activity detector event interrupt + - description: voice activity detector error interrupt + + dmas: + items: + - description: DMA controller phandle and request line for RX + + dma-names: + items: + - const: rx + + clocks: + items: + - description: The ipg clock for register access + - description: internal micfil clock + - description: PLL clock source for 8kHz series + - description: PLL clock source for 11kHz series + - description: External clock 3 + minItems: 2 + + clock-names: + items: + - const: ipg_clk + - const: ipg_clk_app + - const: pll8k + - const: pll11k + - const: clkext3 + minItems: 2 + +required: + - compatible + - reg + - interrupts + - dmas + - dma-names + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + micfil: audio-controller@30080000 { + compatible = "fsl,imx8mm-micfil"; + reg = <0x30080000 0x10000>; + interrupts = , + , + , + ; + clocks = <&clk IMX8MM_CLK_PDM_IPG>, + <&clk IMX8MM_CLK_PDM_ROOT>; + clock-names = "ipg_clk", "ipg_clk_app"; + dmas = <&sdma2 24 25 0>; + dma-names = "rx"; + }; -- GitLab From d6910eaa6fc71c0307e16b310a07cdb347d26d7d Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Wed, 29 Jun 2022 08:04:21 +0000 Subject: [PATCH 763/942] ASoC: rockchip: i2s: Remove unwanted dma settings in rockchip_i2s_probe Remove the unwanted dma settings in rockchip_i2s_probe. Fixes: 44f362c2cc6d ("ASoC: rockchip: i2s: switch BCLK to GPIO") Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20220629080421.2427933-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index ebd829ac09fec..f783994cc16ad 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -817,14 +817,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s_pinctrl_select_bclk_off(i2s); - i2s->playback_dma_data.addr = res->start + I2S_TXDR; - i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->playback_dma_data.maxburst = 4; - - i2s->capture_dma_data.addr = res->start + I2S_RXDR; - i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->capture_dma_data.maxburst = 4; - dev_set_drvdata(&pdev->dev, i2s); pm_runtime_enable(&pdev->dev); -- GitLab From 586fb2641371cf7f23a401ab1c79b17e3ec457f4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 22 Jun 2022 05:54:06 +0000 Subject: [PATCH 764/942] ASoC: soc-core.c: fixup snd_soc_of_get_dai_link_cpus() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 900dedd7e47cc3f ("ASoC: Introduce snd_soc_of_get_dai_link_cpus") adds new snd_soc_of_get_dai_link_cpus(), but it is using "codec" everywhere. It is very strange, and is issue when error case. It should call cpu instead of codec in error case. This patch tidyup it. Fixes: 900dedd7e47cc3f ("ASoC: Introduce snd_soc_of_get_dai_link_cpus") Signed-off-by: Kuninori Morimoto Reviewed-by: Martin Povišer Link: https://lore.kernel.org/r/87zgi5p7k1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 60e21b06b1dcb..89d0163238884 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3424,26 +3424,26 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, struct of_phandle_args args; struct snd_soc_dai_link_component *component; char *name; - int index, num_codecs, ret; + int index, num_cpus, ret; - /* Count the number of CODECs */ + /* Count the number of CPUs */ name = "sound-dai"; - num_codecs = of_count_phandle_with_args(of_node, name, + num_cpus = of_count_phandle_with_args(of_node, name, "#sound-dai-cells"); - if (num_codecs <= 0) { - if (num_codecs == -ENOENT) + if (num_cpus <= 0) { + if (num_cpus == -ENOENT) dev_err(dev, "No 'sound-dai' property\n"); else dev_err(dev, "Bad phandle in 'sound-dai'\n"); - return num_codecs; + return num_cpus; } component = devm_kcalloc(dev, - num_codecs, sizeof(*component), + num_cpus, sizeof(*component), GFP_KERNEL); if (!component) return -ENOMEM; dai_link->cpus = component; - dai_link->num_cpus = num_codecs; + dai_link->num_cpus = num_cpus; /* Parse the list */ for_each_link_cpus(dai_link, index, component) { @@ -3459,7 +3459,7 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, } return 0; err: - snd_soc_of_put_dai_link_codecs(dai_link); + snd_soc_of_put_dai_link_cpus(dai_link); dai_link->cpus = NULL; dai_link->num_cpus = 0; return ret; -- GitLab From 9cc69528188a4e3eb24370f6c05a92791ac249ba Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 22 Jun 2022 05:54:13 +0000 Subject: [PATCH 765/942] ASoC: soc-core.c: share code for snd_soc_of_get_dai_link_cpus/codecs() ASoC has snd_soc_of_get_dai_link_cpus/codecs(), and these are almost same code. The main difference are below. for_each_link_cpus() dai_link->cpus dai_link->num_cpus for_each_link_codecs() dai_link->codecs dai_link->num_codecs Because we need to use these parameters, we can't share full-code for now, but can share some codes. This patch adds __snd_soc_of_get/put_xxx() functions, and share the code. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87y1xpp7ju.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 140 ++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 68 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 89d0163238884..e824ff1a9fc09 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3303,6 +3303,61 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, } EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name); +static void __snd_soc_of_put_component(struct snd_soc_dai_link_component *component) +{ + if (component->of_node) { + of_node_put(component->of_node); + component->of_node = NULL; + } +} + +static int __snd_soc_of_get_dai_link_component_alloc( + struct device *dev, struct device_node *of_node, + struct snd_soc_dai_link_component **ret_component, + int *ret_num) +{ + struct snd_soc_dai_link_component *component; + int num; + + /* Count the number of CPUs/CODECs */ + num = of_count_phandle_with_args(of_node, "sound-dai", "#sound-dai-cells"); + if (num <= 0) { + if (num == -ENOENT) + dev_err(dev, "No 'sound-dai' property\n"); + else + dev_err(dev, "Bad phandle in 'sound-dai'\n"); + return num; + } + component = devm_kcalloc(dev, num, sizeof(*component), GFP_KERNEL); + if (!component) + return -ENOMEM; + + *ret_component = component; + *ret_num = num; + + return 0; +} + +static int __snd_soc_of_get_dai_link_component_parse( + struct device_node *of_node, + struct snd_soc_dai_link_component *component, int index) +{ + struct of_phandle_args args; + int ret; + + ret = of_parse_phandle_with_args(of_node, "sound-dai", "#sound-dai-cells", + index, &args); + if (ret) + return ret; + + ret = snd_soc_get_dai_name(&args, &component->dai_name); + if (ret < 0) + return ret; + + component->of_node = args.np; + return 0; +} + /* * snd_soc_of_put_dai_link_codecs - Dereference device nodes in the codecs array * @dai_link: DAI link @@ -3314,12 +3369,8 @@ void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link) struct snd_soc_dai_link_component *component; int index; - for_each_link_codecs(dai_link, index, component) { - if (!component->of_node) - break; - of_node_put(component->of_node); - component->of_node = NULL; - } + for_each_link_codecs(dai_link, index, component) + __snd_soc_of_put_component(component); } EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_codecs); @@ -3341,41 +3392,19 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev, struct device_node *of_node, struct snd_soc_dai_link *dai_link) { - struct of_phandle_args args; struct snd_soc_dai_link_component *component; - char *name; - int index, num_codecs, ret; - - /* Count the number of CODECs */ - name = "sound-dai"; - num_codecs = of_count_phandle_with_args(of_node, name, - "#sound-dai-cells"); - if (num_codecs <= 0) { - if (num_codecs == -ENOENT) - dev_err(dev, "No 'sound-dai' property\n"); - else - dev_err(dev, "Bad phandle in 'sound-dai'\n"); - return num_codecs; - } - component = devm_kcalloc(dev, - num_codecs, sizeof(*component), - GFP_KERNEL); - if (!component) - return -ENOMEM; - dai_link->codecs = component; - dai_link->num_codecs = num_codecs; + int index, ret; + + ret = __snd_soc_of_get_dai_link_component_alloc(dev, of_node, + &dai_link->codecs, &dai_link->num_codecs); + if (ret < 0) + return ret; /* Parse the list */ for_each_link_codecs(dai_link, index, component) { - ret = of_parse_phandle_with_args(of_node, name, - "#sound-dai-cells", - index, &args); + ret = __snd_soc_of_get_dai_link_component_parse(of_node, component, index); if (ret) goto err; - component->of_node = args.np; - ret = snd_soc_get_dai_name(&args, &component->dai_name); - if (ret < 0) - goto err; } return 0; err: @@ -3397,12 +3426,8 @@ void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link) struct snd_soc_dai_link_component *component; int index; - for_each_link_cpus(dai_link, index, component) { - if (!component->of_node) - break; - of_node_put(component->of_node); - component->of_node = NULL; - } + for_each_link_cpus(dai_link, index, component) + __snd_soc_of_put_component(component); } EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_cpus); @@ -3421,41 +3446,20 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, struct device_node *of_node, struct snd_soc_dai_link *dai_link) { - struct of_phandle_args args; struct snd_soc_dai_link_component *component; - char *name; - int index, num_cpus, ret; + int index, ret; /* Count the number of CPUs */ - name = "sound-dai"; - num_cpus = of_count_phandle_with_args(of_node, name, - "#sound-dai-cells"); - if (num_cpus <= 0) { - if (num_cpus == -ENOENT) - dev_err(dev, "No 'sound-dai' property\n"); - else - dev_err(dev, "Bad phandle in 'sound-dai'\n"); - return num_cpus; - } - component = devm_kcalloc(dev, - num_cpus, sizeof(*component), - GFP_KERNEL); - if (!component) - return -ENOMEM; - dai_link->cpus = component; - dai_link->num_cpus = num_cpus; + ret = __snd_soc_of_get_dai_link_component_alloc(dev, of_node, + &dai_link->cpus, &dai_link->num_cpus); + if (ret < 0) + return ret; /* Parse the list */ for_each_link_cpus(dai_link, index, component) { - ret = of_parse_phandle_with_args(of_node, name, - "#sound-dai-cells", - index, &args); + ret = __snd_soc_of_get_dai_link_component_parse(of_node, component, index); if (ret) goto err; - component->of_node = args.np; - ret = snd_soc_get_dai_name(&args, &component->dai_name); - if (ret < 0) - goto err; } return 0; err: -- GitLab From 57b8b2113e2056d72dbe1d6123950f145c874168 Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Wed, 22 Jun 2022 20:13:20 +0400 Subject: [PATCH 766/942] ASoC: dt-bindings: Add bindings for WCD9335 DAIs Add bindings for the DAIs available in WCD9335 to avoid having to use unclear number indices in device trees. Signed-off-by: Yassine Oudjana Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220622161322.168017-2-y.oudjana@protonmail.com Signed-off-by: Mark Brown --- MAINTAINERS | 1 + include/dt-bindings/sound/qcom,wcd9335.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 include/dt-bindings/sound/qcom,wcd9335.h diff --git a/MAINTAINERS b/MAINTAINERS index c4648e86dc14b..e9d5b052cd418 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16250,6 +16250,7 @@ M: Srinivas Kandagatla M: Banajit Goswami L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported +F: include/dt-bindings/sound/qcom,wcd9335.h F: sound/soc/codecs/lpass-rx-macro.* F: sound/soc/codecs/lpass-tx-macro.* F: sound/soc/codecs/lpass-va-macro.c diff --git a/include/dt-bindings/sound/qcom,wcd9335.h b/include/dt-bindings/sound/qcom,wcd9335.h new file mode 100644 index 0000000000000..f5e9f1db091e4 --- /dev/null +++ b/include/dt-bindings/sound/qcom,wcd9335.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef __DT_SOUND_QCOM_WCD9335_H +#define __DT_SOUND_QCOM_WCD9335_H + +#define AIF1_PB 0 +#define AIF1_CAP 1 +#define AIF2_PB 2 +#define AIF2_CAP 3 +#define AIF3_PB 4 +#define AIF3_CAP 5 +#define AIF4_PB 6 +#define NUM_CODEC_DAIS 7 + +#endif -- GitLab From 66348f178d5a842c8afe52c3b743fb4af24cdb2a Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Wed, 22 Jun 2022 20:13:21 +0400 Subject: [PATCH 767/942] ASoC: wcd9335: Use DT bindings instead of local DAI definitions Get DAI indices from DT bindings and remove the currently used local definitions. Signed-off-by: Yassine Oudjana Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220622161322.168017-3-y.oudjana@protonmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 7d40a61b03b0b..3554b95462e8c 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -24,6 +24,8 @@ #include "wcd9335.h" #include "wcd-clsh-v2.h" +#include + #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) @@ -203,17 +205,6 @@ enum wcd9335_sido_voltage { SIDO_VOLTAGE_NOMINAL_MV = 1100, }; -enum { - AIF1_PB = 0, - AIF1_CAP, - AIF2_PB, - AIF2_CAP, - AIF3_PB, - AIF3_CAP, - AIF4_PB, - NUM_CODEC_DAIS, -}; - enum { COMPANDER_1, /* HPH_L */ COMPANDER_2, /* HPH_R */ -- GitLab From d2294461b90e0c5b3bbfaaf2c8baff4fd3e2bb13 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 29 Jun 2022 14:53:45 -0400 Subject: [PATCH 768/942] ASoC: samsung: change gpiod_speaker_power and rx1950_audio from global to static variables sparse reports sound/soc/samsung/rx1950_uda1380.c:131:18: warning: symbol 'gpiod_speaker_power' was not declared. Should it be static? sound/soc/samsung/rx1950_uda1380.c:231:24: warning: symbol 'rx1950_audio' was not declared. Should it be static? Both gpiod_speaker_power and rx1950_audio are only used in rx1950_uda1380.c, so their storage class specifiers should be static. Fixes: 83d74e354200 ("ASoC: samsung: rx1950: turn into platform driver") Signed-off-by: Tom Rix Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220629185345.910406-1-trix@redhat.com Signed-off-by: Mark Brown --- sound/soc/samsung/rx1950_uda1380.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index ff3acc94a454c..abf28321f7d76 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -128,7 +128,7 @@ static int rx1950_startup(struct snd_pcm_substream *substream) &hw_rates); } -struct gpio_desc *gpiod_speaker_power; +static struct gpio_desc *gpiod_speaker_power; static int rx1950_spk_power(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -228,7 +228,7 @@ static int rx1950_probe(struct platform_device *pdev) return devm_snd_soc_register_card(dev, &rx1950_asoc); } -struct platform_driver rx1950_audio = { +static struct platform_driver rx1950_audio = { .driver = { .name = "rx1950-audio", .pm = &snd_soc_pm_ops, -- GitLab From d15534a6f4cff031f1233154f1e275302c03e5d4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 28 Jun 2022 18:58:07 +0200 Subject: [PATCH 769/942] ASoC: doc: Update dead links The alsa-project documentation is now part of the kernel docs, the original links are long dead, update links. Signed-off-by: Marek Vasut Cc: Mark Brown Cc: Takashi Iwai Link: https://lore.kernel.org/r/20220628165807.152191-1-marex@denx.de Signed-off-by: Mark Brown --- Documentation/process/kernel-docs.rst | 2 +- Documentation/sound/soc/codec.rst | 2 +- Documentation/sound/soc/platform.rst | 2 +- sound/pci/ens1370.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/process/kernel-docs.rst b/Documentation/process/kernel-docs.rst index da9527502ef0e..644f9200fd919 100644 --- a/Documentation/process/kernel-docs.rst +++ b/Documentation/process/kernel-docs.rst @@ -108,7 +108,7 @@ On-line docs * Title: **Writing an ALSA Driver** :Author: Takashi Iwai - :URL: http://www.alsa-project.org/~iwai/writing-an-alsa-driver/index.html + :URL: https://www.kernel.org/doc/html/latest/sound/kernel-api/writing-an-alsa-driver.html :Date: 2005 :Keywords: ALSA, sound, soundcard, driver, lowlevel, hardware. :Description: Advanced Linux Sound Architecture for developers, diff --git a/Documentation/sound/soc/codec.rst b/Documentation/sound/soc/codec.rst index 57df149acafc5..af973c4cac930 100644 --- a/Documentation/sound/soc/codec.rst +++ b/Documentation/sound/soc/codec.rst @@ -132,7 +132,7 @@ The codec driver also supports the following ALSA PCM operations:- }; Please refer to the ALSA driver PCM documentation for details. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ +https://www.kernel.org/doc/html/latest/sound/kernel-api/writing-an-alsa-driver.html DAPM description diff --git a/Documentation/sound/soc/platform.rst b/Documentation/sound/soc/platform.rst index c1badea53d3d3..7036630eaf016 100644 --- a/Documentation/sound/soc/platform.rst +++ b/Documentation/sound/soc/platform.rst @@ -46,7 +46,7 @@ snd_soc_component_driver:- }; Please refer to the ALSA driver documentation for details of audio DMA. -http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ +https://www.kernel.org/doc/html/latest/sound/kernel-api/writing-an-alsa-driver.html An example DMA driver is soc/pxa/pxa2xx-pcm.c diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 94efe347a97a9..89210b2c73424 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -8,7 +8,7 @@ /* Power-Management-Code ( CONFIG_PM ) * for ens1371 only ( FIXME ) * derived from cs4281.c, atiixp.c and via82xx.c - * using http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/ + * using https://www.kernel.org/doc/html/latest/sound/kernel-api/writing-an-alsa-driver.html * by Kurt J. Bosch */ -- GitLab From cdb09e6231433b65e31c40fbe298099db6513a7f Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 30 Jun 2022 13:36:33 +0100 Subject: [PATCH 770/942] ASoC: codecs: wsa883x: add control, dapm widgets and map Add controls, dapm widgets along with route. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220630123633.8047-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 200 +++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 856709ec017e6..e8f519e892135 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -473,6 +473,19 @@ enum wsa_port_ids { WSA883X_PORT_VISENSE, }; +static const char * const wsa_dev_mode_text[] = { + "Speaker", "Receiver", "Ultrasound" +}; + +enum { + SPEAKER, + RECEIVER, + ULTRASOUND, +}; + +static const struct soc_enum wsa_dev_mode_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_dev_mode_text), wsa_dev_mode_text); + /* 4 ports */ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = { { @@ -1066,6 +1079,94 @@ static struct sdw_slave_ops wsa883x_slave_ops = { .port_prep = wsa883x_port_prep, }; +static int wsa_dev_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.enumerated.item[0] = wsa883x->dev_mode; + + return 0; +} + +static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (wsa883x->dev_mode == ucontrol->value.enumerated.item[0]) + return 0; + + wsa883x->dev_mode = ucontrol->value.enumerated.item[0]; + + return 1; +} + +static const DECLARE_TLV_DB_SCALE(pa_gain, -300, 150, -300); + +static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp); + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + int portidx = mixer->reg; + + ucontrol->value.integer.value[0] = data->port_enable[portidx]; + + return 0; +} + +static int wsa883x_set_swr_port(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *data = snd_soc_component_get_drvdata(comp); + struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value; + int portidx = mixer->reg; + + if (ucontrol->value.integer.value[0]) { + if (data->port_enable[portidx]) + return 0; + + data->port_enable[portidx] = true; + } else { + if (!data->port_enable[portidx]) + return 0; + + data->port_enable[portidx] = false; + } + + return 1; +} + +static int wsa883x_get_comp_offset(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = wsa883x->comp_offset; + + return 0; +} + +static int wsa883x_set_comp_offset(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + if (wsa883x->comp_offset == ucontrol->value.integer.value[0]) + return 0; + + wsa883x->comp_offset = ucontrol->value.integer.value[0]; + + return 1; +} + static int wsa883x_codec_probe(struct snd_soc_component *comp) { struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(comp); @@ -1075,9 +1176,108 @@ static int wsa883x_codec_probe(struct snd_soc_component *comp) return 0; } +static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (wsa883x->dev_mode) { + case RECEIVER: + snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE, + WSA883X_RXD_MODE_MASK, + WSA883X_RXD_MODE_HIFI); + snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL, + WSA883X_SPKR_PWM_FREQ_SEL_MASK, + WSA883X_SPKR_PWM_FREQ_F600KHZ); + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_PROG_DELAY_MASK, 0x0); + break; + case SPEAKER: + snd_soc_component_write_field(component, WSA883X_CDC_PATH_MODE, + WSA883X_RXD_MODE_MASK, + WSA883X_RXD_MODE_NORMAL); + snd_soc_component_write_field(component, WSA883X_SPKR_PWM_CLK_CTL, + WSA883X_SPKR_PWM_FREQ_SEL_MASK, + WSA883X_SPKR_PWM_FREQ_F300KHZ); + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_PROG_DELAY_MASK, 0x9); + default: + break; + } + + snd_soc_component_write_field(component, WSA883X_DRE_CTL_1, + WSA883X_DRE_GAIN_EN_MASK, + WSA883X_DRE_GAIN_FROM_CSR); + if (wsa883x->port_enable[WSA883X_PORT_COMP]) + snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, + WSA883X_DRE_OFFSET_MASK, + wsa883x->comp_offset); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_COEF_SEL_MASK, + WSA883X_VBAT_ADC_COEF_F_1DIV16); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_FLT_EN_MASK, 0x1); + snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL, + WSA883X_PDM_EN_MASK, + WSA883X_PDM_ENABLE); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, + WSA883X_GLOBAL_PA_ENABLE); + + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_FLT_EN_MASK, 0x0); + snd_soc_component_write_field(component, WSA883X_VBAT_ADC_FLT_CTL, + WSA883X_VBAT_ADC_COEF_SEL_MASK, + WSA883X_VBAT_ADC_COEF_F_1DIV2); + snd_soc_component_write_field(component, WSA883X_PA_FSM_CTL, + WSA883X_GLOBAL_PA_EN_MASK, 0); + snd_soc_component_write_field(component, WSA883X_PDM_WD_CTL, + WSA883X_PDM_EN_MASK, 0); + break; + } + return 0; +} + +static const struct snd_soc_dapm_widget wsa883x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("IN"), + SND_SOC_DAPM_SPK("SPKR", wsa883x_spkr_event), +}; + +static const struct snd_kcontrol_new wsa883x_snd_controls[] = { + SOC_SINGLE_RANGE_TLV("PA Volume", WSA883X_DRE_CTL_1, 1, + 0x0, 0x1f, 1, pa_gain), + SOC_ENUM_EXT("WSA MODE", wsa_dev_mode_enum, + wsa_dev_mode_get, wsa_dev_mode_put), + SOC_SINGLE_EXT("COMP Offset", SND_SOC_NOPM, 0, 4, 0, + wsa883x_get_comp_offset, wsa883x_set_comp_offset), + SOC_SINGLE_EXT("DAC Switch", WSA883X_PORT_DAC, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("COMP Switch", WSA883X_PORT_COMP, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("BOOST Switch", WSA883X_PORT_BOOST, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), + SOC_SINGLE_EXT("VISENSE Switch", WSA883X_PORT_VISENSE, 0, 1, 0, + wsa883x_get_swr_port, wsa883x_set_swr_port), +}; + +static const struct snd_soc_dapm_route wsa883x_audio_map[] = { + {"SPKR", NULL, "IN"}, +}; + static const struct snd_soc_component_driver wsa883x_component_drv = { .name = "WSA883x", .probe = wsa883x_codec_probe, + .controls = wsa883x_snd_controls, + .num_controls = ARRAY_SIZE(wsa883x_snd_controls), + .dapm_widgets = wsa883x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wsa883x_dapm_widgets), + .dapm_routes = wsa883x_audio_map, + .num_dapm_routes = ARRAY_SIZE(wsa883x_audio_map), }; static int wsa883x_hw_params(struct snd_pcm_substream *substream, -- GitLab From 871325d800ed532ba5874257f04bb4ae75125bc4 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 29 Jun 2022 16:18:11 -0400 Subject: [PATCH 771/942] ASoC: samsung: change neo1973_audio from a global to static sparse reports sound/soc/samsung/neo1973_wm8753.c:347:24: warning: symbol 'neo1973_audio' was not declared. Should it be static? neo1973_audio is only used in neo1973_wm8753.c, so it's storage class specifier should be static. Fixes: e26a2abcc246 ("ASoC: samsung: neo1973: turn into platform driver") Signed-off-by: Tom Rix Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20220629201811.2537853-1-trix@redhat.com Signed-off-by: Mark Brown --- sound/soc/samsung/neo1973_wm8753.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index c98b68567a89d..e9f2334028bfc 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -344,7 +344,7 @@ static int neo1973_probe(struct platform_device *pdev) return devm_snd_soc_register_card(dev, &neo1973); } -struct platform_driver neo1973_audio = { +static struct platform_driver neo1973_audio = { .driver = { .name = "neo1973-audio", .pm = &snd_soc_pm_ops, -- GitLab From e8010efc7b83038d1c18abe1b8d171e3c7d4ed92 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 30 Jun 2022 11:14:59 +0100 Subject: [PATCH 772/942] ASoC: wm_adsp: Minor clean and redundant code removal The cs_dsp core will return an error if passed a NULL cs_dsp struct so there is no need for the wm_adsp_write|read_ctl functions to manually check that. The cs_dsp core will also check the data is within bounds of the control so the additional bounds check is redundant too. Simplify things a bit by removing said code. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220630101459.3442327-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index a7784ac15dde6..cfaa45ede916a 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -675,21 +675,12 @@ static void wm_adsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - struct cs_dsp_coeff_ctl *cs_ctl; + struct cs_dsp_coeff_ctl *cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); struct wm_coeff_ctl *ctl; struct snd_kcontrol *kcontrol; char ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; int ret; - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - ctl = cs_ctl->priv; - - if (len > cs_ctl->len) - return -EINVAL; - ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); if (ret) return ret; @@ -697,6 +688,8 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) return 0; + ctl = cs_ctl->priv; + if (dsp->component->name_prefix) snprintf(ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s", dsp->component->name_prefix, ctl->name); @@ -720,16 +713,8 @@ EXPORT_SYMBOL_GPL(wm_adsp_write_ctl); int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, unsigned int alg, void *buf, size_t len) { - struct cs_dsp_coeff_ctl *cs_ctl; - - cs_ctl = cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg); - if (!cs_ctl) - return -EINVAL; - - if (len > cs_ctl->len) - return -EINVAL; - - return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); + return cs_dsp_coeff_read_ctrl(cs_dsp_get_ctl(&dsp->cs_dsp, name, type, alg), + 0, buf, len); } EXPORT_SYMBOL_GPL(wm_adsp_read_ctl); -- GitLab From d8d6253b36f55d199590ef908712fe52bb39ee97 Mon Sep 17 00:00:00 2001 From: Li kunyu Date: Thu, 30 Jun 2022 10:03:47 +0800 Subject: [PATCH 773/942] ASoC: tegra: delete a semicolon extra semicolons could be deleted. Signed-off-by: Li kunyu Link: https://lore.kernel.org/r/20220630020347.7148-1-kunyu@nfschina.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_adx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index 3785cade2d9a9..49691d2cce509 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -191,7 +191,7 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol, unsigned char *bytes_map = (unsigned char *)&adx->map; int value = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value;; + (struct soc_mixer_control *)kcontrol->private_value; if (value == bytes_map[mc->reg]) return 0; -- GitLab From cf6af24b54903f9f70c29b3e5b19cb72cc862d60 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 30 Jun 2022 14:00:22 +0100 Subject: [PATCH 774/942] ASoC: codecs: wsa881x: handle timeouts in resume path Currently we do not check if SoundWire slave initialization timeout expired before continuing to access its registers. Its possible that the registers are not accessible if timeout is expired. Handle this by returning timeout in resume path. Reported-by: Pierre-Louis Bossart Fixes: 8dd552458361 ("ASoC: codecs: wsa881x: add runtime pm support") Signed-off-by: Srinivas Kandagatla Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220630130023.9308-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index dc954b85a9881..6c8b1db649b89 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -1173,11 +1173,17 @@ static int __maybe_unused wsa881x_runtime_resume(struct device *dev) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); struct wsa881x_priv *wsa881x = dev_get_drvdata(dev); + unsigned long time; gpiod_direction_output(wsa881x->sd_n, 1); - wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA881X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); + gpiod_direction_output(wsa881x->sd_n, 0); + return -ETIMEDOUT; + } regcache_cache_only(regmap, false); regcache_sync(regmap); -- GitLab From 0df73e1a9f7b1152ace21b6406138f7487239128 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 30 Jun 2022 14:00:23 +0100 Subject: [PATCH 775/942] ASoC: codecs: wsa883x: handle timeouts in resume path Currently we do not check if SoundWire slave initialization timeout expired before continuing to access its registers. Its possible that the registers are not accessible if timeout is expired. Handle this by returning timeout in resume path. Reported-by: Pierre-Louis Bossart Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220630130023.9308-2-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index e8f519e892135..40c7d64a9c41d 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1455,6 +1455,7 @@ static int __maybe_unused wsa883x_runtime_resume(struct device *dev) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct regmap *regmap = dev_get_regmap(dev, NULL); struct wsa883x_priv *wsa883x = dev_get_drvdata(dev); + unsigned long time; int ret; ret = regulator_enable(wsa883x->vdd); @@ -1465,8 +1466,14 @@ static int __maybe_unused wsa883x_runtime_resume(struct device *dev) gpiod_direction_output(wsa883x->sd_n, 1); - wait_for_completion_timeout(&slave->initialization_complete, - msecs_to_jiffies(WSA883X_PROBE_TIMEOUT)); + time = wait_for_completion_timeout(&slave->initialization_complete, + msecs_to_jiffies(WSA883X_PROBE_TIMEOUT)); + if (!time) { + dev_err(dev, "Initialization not complete, timed out\n"); + gpiod_direction_output(wsa883x->sd_n, 0); + regulator_disable(wsa883x->vdd); + return -ETIMEDOUT; + } usleep_range(20000, 20010); regcache_cache_only(regmap, false); -- GitLab From 68f26639dc40b5d6aca201f3e250a1538e68eae6 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 1 Jul 2022 13:55:15 +0100 Subject: [PATCH 776/942] ASoC: codecs: wsa883x: add missing break statement Add missing break in one of the switch statement. Reported-by: kernel test robot Fixes: cdb09e623143 ("ASoC: codecs: wsa883x: add control, dapm widgets and map") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220701125515.32332-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 40c7d64a9c41d..dcd88175b9cd7 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1204,6 +1204,7 @@ static int wsa883x_spkr_event(struct snd_soc_dapm_widget *w, WSA883X_SPKR_PWM_FREQ_F300KHZ); snd_soc_component_write_field(component, WSA883X_DRE_CTL_0, WSA883X_DRE_PROG_DELAY_MASK, 0x9); + break; default: break; } -- GitLab From f507c0c67dac57d2bcd5dcae4b6139b0305d8957 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sat, 2 Jul 2022 10:01:09 +0800 Subject: [PATCH 777/942] ASoC: qcom: Fix missing of_node_put() in asoc_qcom_lpass_cpu_platform_probe() We should call of_node_put() for the reference 'dsp_of_node' returned by of_parse_phandle() which will increase the refcount. Fixes: 9bae4880acee ("ASoC: qcom: move ipq806x specific bits out of lpass driver.") Co-authored-by: Miaoqian Lin Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220702020109.263980-1-windhl@126.com Signed-off-by: Mark Brown --- sound/soc/qcom/lpass-cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 263a066769d47..8a56f38dc7e86 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1091,6 +1091,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0); if (dsp_of_node) { dev_err(dev, "DSP exists and holds audio resources\n"); + of_node_put(dsp_of_node); return -EBUSY; } -- GitLab From bc4c9d85179ca90679c8bb046cf7aad16fb88076 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Fri, 1 Jul 2022 20:22:49 +0100 Subject: [PATCH 778/942] ASoC: dt-bindings: convert designware-i2s to dt-schema Convert the Synopsys DesignWare I2S controller binding to dt-schema. There was no listed maintainer but Jose Abreu was the last editor of the txt binding so add him as maintainer. Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20220701192300.2293643-4-conor@kernel.org Signed-off-by: Mark Brown --- .../bindings/sound/designware-i2s.txt | 35 ------- .../bindings/sound/snps,designware-i2s.yaml | 94 +++++++++++++++++++ 2 files changed, 94 insertions(+), 35 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/designware-i2s.txt create mode 100644 Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml diff --git a/Documentation/devicetree/bindings/sound/designware-i2s.txt b/Documentation/devicetree/bindings/sound/designware-i2s.txt deleted file mode 100644 index 6a536d570e294..0000000000000 --- a/Documentation/devicetree/bindings/sound/designware-i2s.txt +++ /dev/null @@ -1,35 +0,0 @@ -DesignWare I2S controller - -Required properties: - - compatible : Must be "snps,designware-i2s" - - reg : Must contain the I2S core's registers location and length - - clocks : Pairs of phandle and specifier referencing the controller's - clocks. The controller expects one clock: the clock used as the sampling - rate reference clock sample. - - clock-names : "i2sclk" for the sample rate reference clock. - - dmas: Pairs of phandle and specifier for the DMA channels that are used by - the core. The core expects one or two dma channels: one for transmit and - one for receive. - - dma-names : "tx" for the transmit channel, "rx" for the receive channel. - -Optional properties: - - interrupts: The interrupt line number for the I2S controller. Add this - parameter if the I2S controller that you are using does not support DMA. - -For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' -properties please check: - * resource-names.txt - * clock/clock-bindings.txt - * dma/dma.txt - -Example: - - soc_i2s: i2s@7ff90000 { - compatible = "snps,designware-i2s"; - reg = <0x0 0x7ff90000 0x0 0x1000>; - clocks = <&scpi_i2sclk 0>; - clock-names = "i2sclk"; - #sound-dai-cells = <0>; - dmas = <&dma0 5>; - dma-names = "tx"; - }; diff --git a/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml b/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml new file mode 100644 index 0000000000000..4b07958190647 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/snps,designware-i2s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: DesignWare I2S controller + +maintainers: + - Jose Abreu + +properties: + compatible: + oneOf: + - items: + - const: canaan,k210-i2s + - const: snps,designware-i2s + - enum: + - snps,designware-i2s + + reg: + maxItems: 1 + + interrupts: + description: | + The interrupt line number for the I2S controller. Add this + parameter if the I2S controller that you are using does not + support DMA. + maxItems: 1 + + clocks: + description: Sampling rate reference clock + maxItems: 1 + + clock-names: + const: i2sclk + + resets: + maxItems: 1 + + dmas: + items: + - description: TX DMA Channel + - description: RX DMA Channel + minItems: 1 + + dma-names: + items: + - const: tx + - const: rx + minItems: 1 + +if: + properties: + compatible: + contains: + const: canaan,k210-i2s + +then: + properties: + "#sound-dai-cells": + const: 1 + +else: + properties: + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + +oneOf: + - required: + - dmas + - dma-names + - required: + - interrupts + +unevaluatedProperties: false + +examples: + - | + soc_i2s: i2s@7ff90000 { + compatible = "snps,designware-i2s"; + reg = <0x7ff90000 0x1000>; + clocks = <&scpi_i2sclk 0>; + clock-names = "i2sclk"; + #sound-dai-cells = <0>; + dmas = <&dma0 5>; + dma-names = "tx"; + }; -- GitLab From 1d5c7a91dfc2b7a5672a2706553e5782482d6e6f Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 1 Jul 2022 15:30:39 +0800 Subject: [PATCH 779/942] ASoC: codecs: max98088: Clean up some inconsistent indenting This was found by coccicheck: sound/soc/codecs/max98088.c:1761 max98088_i2c_probe() warn: inconsistent indenting. Signed-off-by: Jiapeng Chong Link: https://lore.kernel.org/r/20220701073039.64556-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 08e5c606ff27d..5435a49604cf1 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1745,18 +1745,18 @@ MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); static int max98088_i2c_probe(struct i2c_client *i2c) { - struct max98088_priv *max98088; - int ret; - const struct i2c_device_id *id; + struct max98088_priv *max98088; + int ret; + const struct i2c_device_id *id; - max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), - GFP_KERNEL); - if (max98088 == NULL) - return -ENOMEM; + max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), + GFP_KERNEL); + if (max98088 == NULL) + return -ENOMEM; - max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); - if (IS_ERR(max98088->regmap)) - return PTR_ERR(max98088->regmap); + max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap); + if (IS_ERR(max98088->regmap)) + return PTR_ERR(max98088->regmap); max98088->mclk = devm_clk_get(&i2c->dev, "mclk"); if (IS_ERR(max98088->mclk)) @@ -1764,14 +1764,14 @@ static int max98088_i2c_probe(struct i2c_client *i2c) return PTR_ERR(max98088->mclk); id = i2c_match_id(max98088_i2c_id, i2c); - max98088->devtype = id->driver_data; + max98088->devtype = id->driver_data; - i2c_set_clientdata(i2c, max98088); - max98088->pdata = i2c->dev.platform_data; + i2c_set_clientdata(i2c, max98088); + max98088->pdata = i2c->dev.platform_data; - ret = devm_snd_soc_register_component(&i2c->dev, - &soc_component_dev_max98088, &max98088_dai[0], 2); - return ret; + ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_max98088, + &max98088_dai[0], 2); + return ret; } #if defined(CONFIG_OF) -- GitLab From 679139ea62e3e78542cd409c2437ac1da9f31026 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 4 Jul 2022 15:51:34 +0800 Subject: [PATCH 780/942] ASoC: fsl: pcm030-audio-fabric: use platform_device_unregsiter() Replace platform_device_del/put() with platform_device_unregsiter() to simplify code. Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220704075134.26230-1-yangyingliang@huawei.com Signed-off-by: Mark Brown --- sound/soc/fsl/pcm030-audio-fabric.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index e4c805acc3497..997c3e66c6365 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -101,8 +101,7 @@ static int pcm030_fabric_probe(struct platform_device *op) ret = snd_soc_register_card(card); if (ret) { dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret); - platform_device_del(pdata->codec_device); - platform_device_put(pdata->codec_device); + platform_device_unregister(pdata->codec_device); } platform_set_drvdata(op, pdata); -- GitLab From 3684020a82ff43a64b5a7e42564ee7e2065d3011 Mon Sep 17 00:00:00 2001 From: Zhu Ning Date: Mon, 4 Jul 2022 09:24:16 +0800 Subject: [PATCH 781/942] ASoC: codes: Add support for ES8316 producer mode The AMD acp-es8336 machine driver requires ES8316 run in producer mode, which is not supported previously. Signed-off-by: David Yang Signed-off-by: Zhu Ning Link: https://lore.kernel.org/r/20220704012416.3165-1-zhuning0077@gmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/es8316.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index eb15be9095e77..de7185f73e1e7 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -401,10 +401,8 @@ static int es8316_set_dai_fmt(struct snd_soc_dai *codec_dai, u8 clksw; u8 mask; - if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC) { - dev_err(component->dev, "Codec driver only supports consumer mode\n"); - return -EINVAL; - } + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBP_CFP) + serdata1 |= ES8316_SERDATA1_MASTER; if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) { dev_err(component->dev, "Codec driver only supports I2S format\n"); @@ -464,6 +462,8 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_component *component = dai->component; struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); u8 wordlen = 0; + u8 bclk_divider; + u16 lrck_divider; int i; /* Validate supported sample rates that are autodetected from MCLK */ @@ -477,19 +477,24 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, } if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS) return -EINVAL; - + lrck_divider = es8316->sysclk / params_rate(params); + bclk_divider = lrck_divider / 4; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: wordlen = ES8316_SERDATA2_LEN_16; + bclk_divider /= 16; break; case SNDRV_PCM_FORMAT_S20_3LE: wordlen = ES8316_SERDATA2_LEN_20; + bclk_divider /= 20; break; case SNDRV_PCM_FORMAT_S24_LE: wordlen = ES8316_SERDATA2_LEN_24; + bclk_divider /= 24; break; case SNDRV_PCM_FORMAT_S32_LE: wordlen = ES8316_SERDATA2_LEN_32; + bclk_divider /= 32; break; default: return -EINVAL; @@ -499,6 +504,11 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, ES8316_SERDATA2_LEN_MASK, wordlen); snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, ES8316_SERDATA2_LEN_MASK, wordlen); + snd_soc_component_update_bits(component, ES8316_SERDATA1, 0x1f, bclk_divider); + snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV1, 0x0f, lrck_divider >> 8); + snd_soc_component_update_bits(component, ES8316_CLKMGR_ADCDIV2, 0xff, lrck_divider & 0xff); + snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV1, 0x0f, lrck_divider >> 8); + snd_soc_component_update_bits(component, ES8316_CLKMGR_DACDIV2, 0xff, lrck_divider & 0xff); return 0; } -- GitLab From 978bd27c9aed13d7d739bdcdcf98cbca9106b0ec Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 4 Jul 2022 09:50:16 +0800 Subject: [PATCH 782/942] ASoC: fsl_micfil: Add legacy_dai_naming flag Need to add legacy_dai_naming flag otherwise there will be issue when registerring component, that cause the probe failure. Fixes: 1e63fcc74ace ("ASoC: fsl: Migrate to new style legacy DAI naming flag") Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656899417-4775-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 53e105a93d758..be9781ad88493 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -367,7 +367,7 @@ static const struct snd_soc_component_driver fsl_micfil_component = { .name = "fsl-micfil-dai", .controls = fsl_micfil_snd_controls, .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls), - + .legacy_dai_naming = 1, }; /* REGMAP */ -- GitLab From 446499743b26958a58891a8f9a061deb5cce7c82 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 4 Jul 2022 09:50:17 +0800 Subject: [PATCH 783/942] ASoC: fsl_asrc_dma: Add legacy_dai_naming flag Need to add legacy_dai_naming flag otherwise there will be issue when registerring component, that cause the probe failure. Fixes: 1e63fcc74ace ("ASoC: fsl: Migrate to new style legacy DAI naming flag") Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656899417-4775-2-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_asrc_dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 33eabb96340eb..12ddf2320f2db 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -455,5 +455,6 @@ struct snd_soc_component_driver fsl_asrc_component = { .close = fsl_asrc_dma_shutdown, .pointer = fsl_asrc_dma_pcm_pointer, .pcm_construct = fsl_asrc_dma_pcm_new, + .legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(fsl_asrc_component); -- GitLab From acf981f94edca13c85fa24dd8511cdc6bd4c98ed Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 1 Jul 2022 15:28:50 +0800 Subject: [PATCH 784/942] ASoC: tegra20_ac97: Fix missing error code in tegra20_ac97_platform_probe() The error code is missing in this code scenario, add the error code '-EINVAL' to the return value 'ret'. This was found by coccicheck: sound/soc/tegra/tegra20_ac97.c:357 tegra20_ac97_platform_probe() warn: missing error code 'ret'. Signed-off-by: Jiapeng Chong Link: https://lore.kernel.org/r/20220701072850.62408-1-jiapeng.chong@linux.alibaba.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_ac97.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index e17375c6cddb9..87facfbcdd110 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -354,6 +354,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) } } else { dev_err(&pdev->dev, "no codec-reset GPIO supplied\n"); + ret = -EINVAL; goto err_clk_put; } @@ -361,6 +362,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) "nvidia,codec-sync-gpio", 0); if (!gpio_is_valid(ac97->sync_gpio)) { dev_err(&pdev->dev, "no codec-sync GPIO supplied\n"); + ret = -EINVAL; goto err_clk_put; } -- GitLab From 4b8ea38fabab45ad911a32a336416062553dfe9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Mon, 27 Jun 2022 19:18:54 +0200 Subject: [PATCH 785/942] ALSA: usb-audio: Support jack detection on Dell dock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Dell WD15 dock has a headset and a line out port. Add support for detecting if a jack is inserted into one of these ports. For the headset jack, additionally determine if a mic is present. The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec from Realtek. It is a UAC 1 device, and UAC 1 does not support jack detection. Instead, jack detection works by sending HD Audio commands over vendor-type USB messages. I found out how it works by looking at USB captures on Windows. The audio codec is very similar to the one supported by sound/soc/codecs/rt298.c / rt298.h, some constant names and the mic detection are adapted from there. The realtek_add_jack function is adapted from build_connector_control in sound/usb/mixer.c. I tested this on a WD15 dock with the latest firmware. Signed-off-by: Jan Schär Link: https://lore.kernel.org/r/20220627171855.42338-1-jan@jschaer.ch Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 167 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index d35cf54cab338..66b6476994eb9 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1934,6 +1935,169 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) NULL); } +/* + * Dell WD15 dock jack detection + * + * The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec + * from Realtek. It is a UAC 1 device, and UAC 1 does not support jack + * detection. Instead, jack detection works by sending HD Audio commands over + * vendor-type USB messages. + */ + +#define HDA_VERB_CMD(V, N, D) (((N) << 20) | ((V) << 8) | (D)) + +#define REALTEK_HDA_VALUE 0x0038 + +#define REALTEK_HDA_SET 62 +#define REALTEK_HDA_GET_OUT 88 +#define REALTEK_HDA_GET_IN 89 + +#define REALTEK_LINE1 0x1a +#define REALTEK_VENDOR_REGISTERS 0x20 +#define REALTEK_HP_OUT 0x21 + +#define REALTEK_CBJ_CTRL2 0x50 + +#define REALTEK_JACK_INTERRUPT_NODE 5 + +#define REALTEK_MIC_FLAG 0x100 + +static int realtek_hda_set(struct snd_usb_audio *chip, u32 cmd) +{ + struct usb_device *dev = chip->dev; + u32 buf = cpu_to_be32(cmd); + + return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_SET, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, + REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); +} + +static int realtek_hda_get(struct snd_usb_audio *chip, u32 cmd, u32 *value) +{ + struct usb_device *dev = chip->dev; + int err; + u32 buf = cpu_to_be32(cmd); + + err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_GET_OUT, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, + REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); + if (err < 0) + return err; + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), REALTEK_HDA_GET_IN, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_IN, + REALTEK_HDA_VALUE, 0, &buf, sizeof(buf)); + if (err < 0) + return err; + + *value = be32_to_cpu(buf); + return 0; +} + +static int realtek_ctl_connector_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_info *cval = kcontrol->private_data; + struct snd_usb_audio *chip = cval->head.mixer->chip; + u32 pv = kcontrol->private_value; + u32 node_id = pv & 0xff; + u32 sense; + u32 cbj_ctrl2; + bool presence; + int err; + + err = snd_usb_lock_shutdown(chip); + if (err < 0) + return err; + err = realtek_hda_get(chip, + HDA_VERB_CMD(AC_VERB_GET_PIN_SENSE, node_id, 0), + &sense); + if (err < 0) + goto err; + if (pv & REALTEK_MIC_FLAG) { + err = realtek_hda_set(chip, + HDA_VERB_CMD(AC_VERB_SET_COEF_INDEX, + REALTEK_VENDOR_REGISTERS, + REALTEK_CBJ_CTRL2)); + if (err < 0) + goto err; + err = realtek_hda_get(chip, + HDA_VERB_CMD(AC_VERB_GET_PROC_COEF, + REALTEK_VENDOR_REGISTERS, 0), + &cbj_ctrl2); + if (err < 0) + goto err; + } +err: + snd_usb_unlock_shutdown(chip); + if (err < 0) + return err; + + presence = sense & AC_PINSENSE_PRESENCE; + if (pv & REALTEK_MIC_FLAG) + presence = presence && (cbj_ctrl2 & 0x0070) == 0x0070; + ucontrol->value.integer.value[0] = presence; + return 0; +} + +static const struct snd_kcontrol_new realtek_connector_ctl_ro = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .name = "", /* will be filled later manually */ + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .info = snd_ctl_boolean_mono_info, + .get = realtek_ctl_connector_get, +}; + +static int realtek_resume_jack(struct usb_mixer_elem_list *list) +{ + snd_ctl_notify(list->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, + &list->kctl->id); + return 0; +} + +static int realtek_add_jack(struct usb_mixer_interface *mixer, + char *name, u32 val) +{ + struct usb_mixer_elem_info *cval; + struct snd_kcontrol *kctl; + + cval = kzalloc(sizeof(*cval), GFP_KERNEL); + if (!cval) + return -ENOMEM; + snd_usb_mixer_elem_init_std(&cval->head, mixer, + REALTEK_JACK_INTERRUPT_NODE); + cval->head.resume = realtek_resume_jack; + cval->val_type = USB_MIXER_BOOLEAN; + cval->channels = 1; + cval->min = 0; + cval->max = 1; + kctl = snd_ctl_new1(&realtek_connector_ctl_ro, cval); + if (!kctl) { + kfree(cval); + return -ENOMEM; + } + kctl->private_value = val; + strscpy(kctl->id.name, name, sizeof(kctl->id.name)); + kctl->private_free = snd_usb_mixer_elem_free; + return snd_usb_mixer_add_control(&cval->head, kctl); +} + +static int dell_dock_mixer_create(struct usb_mixer_interface *mixer) +{ + int err; + + err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1); + if (err < 0) + return err; + err = realtek_add_jack(mixer, "Headphone Jack", REALTEK_HP_OUT); + if (err < 0) + return err; + err = realtek_add_jack(mixer, "Headset Mic Jack", + REALTEK_HP_OUT | REALTEK_MIC_FLAG); + if (err < 0) + return err; + return 0; +} + static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id) { u16 buf = 0; @@ -3245,6 +3409,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err = snd_soundblaster_e1_switch_create(mixer); break; case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */ + err = dell_dock_mixer_create(mixer); + if (err < 0) + break; err = dell_dock_mixer_init(mixer); break; -- GitLab From 2e57a3358dda20128593fff9b39b522f1bdd26c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Mon, 27 Jun 2022 19:18:55 +0200 Subject: [PATCH 786/942] ALSA: usb-audio: Turn off 'manual mode' on Dell dock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes the need to power cycle the Dell WD15 dock if it has been attached to a Windows machine. The Windows driver puts the ALC4020 USB audio controller into 'manual mode', and then does all the power management and other configuration itself, by sending HD audio commands directly to the ALC3263 audio codec via vendor-type USB messages. If manual mode is off, this is all handled by the firmware, and works well enough. If manual mode is turned on, the latency of the SET INTERFACE command goes from several hundred ms to less than 1 ms (see https://bugzilla.suse.com/show_bug.cgi?id=1089467), but I'm not sure if the additional code that would be required is worth it. Funnily enough, the Windows driver tries to turn off manual mode when the dock is disconnected, which doesn't work for obvious reasons. Additionally, fix a bug in dell_dock_init_vol, which didn't work because the Control Selector was missing. Now, it properly resets the volume to 0dB. Fixes: 964af639ad69 ("ALSA: usb-audio: Initialize Dell Dock playback volumes") Signed-off-by: Jan Schär Link: https://lore.kernel.org/r/20220627171855.42338-2-jan@jschaer.ch Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 66b6476994eb9..5a45822e60e74 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1949,9 +1949,11 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) #define REALTEK_HDA_VALUE 0x0038 #define REALTEK_HDA_SET 62 +#define REALTEK_MANUAL_MODE 72 #define REALTEK_HDA_GET_OUT 88 #define REALTEK_HDA_GET_IN 89 +#define REALTEK_AUDIO_FUNCTION_GROUP 0x01 #define REALTEK_LINE1 0x1a #define REALTEK_VENDOR_REGISTERS 0x20 #define REALTEK_HP_OUT 0x21 @@ -2084,6 +2086,21 @@ static int realtek_add_jack(struct usb_mixer_interface *mixer, static int dell_dock_mixer_create(struct usb_mixer_interface *mixer) { int err; + struct usb_device *dev = mixer->chip->dev; + + /* Power down the audio codec to avoid loud pops in the next step. */ + realtek_hda_set(mixer->chip, + HDA_VERB_CMD(AC_VERB_SET_POWER_STATE, + REALTEK_AUDIO_FUNCTION_GROUP, + AC_PWRST_D3)); + + /* + * Turn off 'manual mode' in case it was enabled. This removes the need + * to power cycle the dock after it was attached to a Windows machine. + */ + snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_MANUAL_MODE, + USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, + 0, 0, NULL, 0); err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1); if (err < 0) @@ -2104,7 +2121,8 @@ static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id) snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - ch, snd_usb_ctrl_intf(chip) | (id << 8), + (UAC_FU_VOLUME << 8) | ch, + snd_usb_ctrl_intf(chip) | (id << 8), &buf, 2); } -- GitLab From df98a94ce9c450a1af1193e06add37e601cbf2df Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 29 Jun 2022 11:27:43 +0100 Subject: [PATCH 787/942] ALSA: wavefront: remove redundant assignment to pointer end Pointer end is being re-assigned the same value as it was initialized with in the previous statement. The re-assignment is redundant and can be removed. Cleans up clang scan-build warning: sound/isa/wavefront/wavefront_synth.c:582:17: warning: Value stored to 'end' during its initialization is never read Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20220629102744.139673-1-colin.i.king@gmail.com Signed-off-by: Takashi Iwai --- sound/isa/wavefront/wavefront_synth.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 2aaaa68071744..13ce96148fa3b 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -581,8 +581,6 @@ demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes) int i; unsigned char *end = src + src_bytes; - end = src + src_bytes; - /* NOTE: src and dst *CAN* point to the same address */ for (i = 0; src != end; i++) { -- GitLab From c71531007ef0fe5cd64a8aa9b86bdb53ccef1504 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Google)" Date: Sun, 3 Jul 2022 11:06:05 -0400 Subject: [PATCH 788/942] tracing: ALSA: hda: Remove string manipulation out of the fast path The TRACE_EVENT() macro is broken up into various parts to be efficient. The TP_fast_assign() is just to record the event into the ring buffer, and is to be done as fast as possible as this occurs during the actual running of the code. The slower this is, the slower the code that is being traced becomes. The TP_printk() is processed when reading the tracing buffer. This is considered the slow path. Any processing that can be moved from the TP_fast_assign() to the TP_printk() should do so. For some reason, the entire string processing of the trace events hda_send_cmd, hda_get_response, and hda_unsol_event was moved from the TP_printk() into the TP_fast_assign(). On top of that, the __dynamic_array() was used with a fixed size of HDAC_MSG_MAX, which is useless as a dynamic_array as it will always allocate HDAC_MSG_MAX bytes on the ring buffer and even save that amount into the event (as it expects the size to be dynamic, which using a fixed size defeats that purpose). Instead, just save the necessary elements in the TP_fast_assign() and do the string manipulation in the slow path. The output should be the same. Signed-off-by: Steven Rostedt (Google) Link: https://lore.kernel.org/r/20220703110605.07a86fb2@rorschach.local.home Signed-off-by: Takashi Iwai --- sound/hda/trace.h | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/sound/hda/trace.h b/sound/hda/trace.h index 70af6c8150898..2cc493434a8fd 100644 --- a/sound/hda/trace.h +++ b/sound/hda/trace.h @@ -19,37 +19,48 @@ struct hdac_codec; TRACE_EVENT(hda_send_cmd, TP_PROTO(struct hdac_bus *bus, unsigned int cmd), TP_ARGS(bus, cmd), - TP_STRUCT__entry(__dynamic_array(char, msg, HDAC_MSG_MAX)), + TP_STRUCT__entry( + __string(name, dev_name((bus)->dev)) + __field(u32, cmd) + ), TP_fast_assign( - snprintf(__get_str(msg), HDAC_MSG_MAX, - "[%s:%d] val=0x%08x", - dev_name((bus)->dev), (cmd) >> 28, cmd); + __assign_str(name, dev_name((bus)->dev)); + __entry->cmd = cmd; ), - TP_printk("%s", __get_str(msg)) + TP_printk("[%s:%d] val=0x%08x", __get_str(name), __entry->cmd >> 28, __entry->cmd) ); TRACE_EVENT(hda_get_response, TP_PROTO(struct hdac_bus *bus, unsigned int addr, unsigned int res), TP_ARGS(bus, addr, res), - TP_STRUCT__entry(__dynamic_array(char, msg, HDAC_MSG_MAX)), + TP_STRUCT__entry( + __string(name, dev_name((bus)->dev)) + __field(u32, addr) + __field(u32, res) + ), TP_fast_assign( - snprintf(__get_str(msg), HDAC_MSG_MAX, - "[%s:%d] val=0x%08x", - dev_name((bus)->dev), addr, res); + __assign_str(name, dev_name((bus)->dev)); + __entry->addr = addr; + __entry->res = res; ), - TP_printk("%s", __get_str(msg)) + TP_printk("[%s:%d] val=0x%08x", __get_str(name), __entry->addr, __entry->res) ); TRACE_EVENT(hda_unsol_event, TP_PROTO(struct hdac_bus *bus, u32 res, u32 res_ex), TP_ARGS(bus, res, res_ex), - TP_STRUCT__entry(__dynamic_array(char, msg, HDAC_MSG_MAX)), + TP_STRUCT__entry( + __string(name, dev_name((bus)->dev)) + __field(u32, res) + __field(u32, res_ex) + ), TP_fast_assign( - snprintf(__get_str(msg), HDAC_MSG_MAX, - "[%s:%d] res=0x%08x, res_ex=0x%08x", - dev_name((bus)->dev), res_ex & 0x0f, res, res_ex); + __assign_str(name, dev_name((bus)->dev)); + __entry->res = res; + __entry->res_ex = res_ex; ), - TP_printk("%s", __get_str(msg)) + TP_printk("[%s:%d] res=0x%08x, res_ex=0x%08x", __get_str(name), + __entry->res_ex & 0x0f, __entry->res, __entry->res_ex) ); DECLARE_EVENT_CLASS(hdac_stream, -- GitLab From 65123b899818b1adf7388b3583624e0f1d8d6858 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Mon, 4 Jul 2022 10:28:36 -0400 Subject: [PATCH 789/942] ALSA: hda/cs8409: change cs8409_fixups v.pins initializers to static sparse reports sound/pci/hda/patch_cs8409-tables.c:79:25: warning: symbol 'cs8409_cs42l42_pincfgs_no_dmic' was not declared. Should it be static? cs8409_cs42l42_pincfgs_no_dmic is only used by cs8409_fixups table as an initializer for the hda_fixup element v.pins. Both are defined in the patch_cs8408-table.c file but only cs8409_fixups is used externally in patch_cs8409.c. So cs8409_cs42l42_pincfgs_no_dmic should have a static storage class specifier. The other v.pins initializers in cs8409_fixups table, though declared extern in patch_cs8409.h are also only used in patch_cs8409-tables.c. So change all the v.pins initializers to static. Fixes: 9e7647b5070f ("ALSA: hda/cs8409: Move arrays of configuration to a new file") Signed-off-by: Tom Rix Link: https://lore.kernel.org/r/20220704142836.636204-1-trix@redhat.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cs8409-tables.c | 6 +++--- sound/pci/hda/patch_cs8409.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 4f4cc82159179..e0d3a8be2e38b 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -68,7 +68,7 @@ const struct hda_verb cs8409_cs42l42_init_verbs[] = { {} /* terminator */ }; -const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { +static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ @@ -76,7 +76,7 @@ const struct hda_pintbl cs8409_cs42l42_pincfgs[] = { {} /* terminator */ }; -const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = { +static const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = { { CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */ { CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */ { CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */ @@ -279,7 +279,7 @@ const struct hda_verb dolphin_init_verbs[] = { {} /* terminator */ }; -const struct hda_pintbl dolphin_pincfgs[] = { +static const struct hda_pintbl dolphin_pincfgs[] = { { 0x24, 0x022210f0 }, /* ASP-1-TX-A */ { 0x25, 0x010240f0 }, /* ASP-1-TX-B */ { 0x34, 0x02a21050 }, /* ASP-1-RX */ diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 260388a6256cd..2a8dfb4ff046b 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -358,13 +358,11 @@ extern const struct snd_pci_quirk cs8409_fixup_tbl[]; extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; extern const struct hda_verb cs8409_cs42l42_init_verbs[]; -extern const struct hda_pintbl cs8409_cs42l42_pincfgs[]; extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[]; extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[]; extern struct sub_codec cs8409_cs42l42_codec; extern const struct hda_verb dolphin_init_verbs[]; -extern const struct hda_pintbl dolphin_pincfgs[]; extern const struct cs8409_cir_param dolphin_hw_cfg[]; extern struct sub_codec dolphin_cs42l42_0; extern struct sub_codec dolphin_cs42l42_1; -- GitLab From 7bad8125549cda14d9ccf97d7d76f7ef6ac9d206 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:36 +0800 Subject: [PATCH 790/942] ASoC: fsl_utils: Add function to handle PLL clock source i.MX8MQ/MN/MM/MP platforms typically have 2 AUDIO PLLs being configured to handle 8kHz and 11kHz series audio rates. Add common function in fsl_utils to handle these two PLL clock source, which are needed by CPU DAI drivers Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656667961-1799-2-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_utils.c | 69 +++++++++++++++++++++++++++++++++++++++ sound/soc/fsl/fsl_utils.h | 7 ++++ 2 files changed, 76 insertions(+) diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index 9bab202569af8..b75843e31f004 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c @@ -6,6 +6,8 @@ // // Copyright 2010 Freescale Semiconductor, Inc. +#include +#include #include #include #include @@ -83,6 +85,73 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, } EXPORT_SYMBOL(fsl_asoc_get_dma_channel); +/** + * fsl_asoc_get_pll_clocks - get two PLL clock source + * + * @dev: device pointer + * @pll8k_clk: PLL clock pointer for 8kHz + * @pll11k_clk: PLL clock pointer for 11kHz + * + * This function get two PLL clock source + */ +void fsl_asoc_get_pll_clocks(struct device *dev, struct clk **pll8k_clk, + struct clk **pll11k_clk) +{ + *pll8k_clk = devm_clk_get(dev, "pll8k"); + if (IS_ERR(*pll8k_clk)) + *pll8k_clk = NULL; + + *pll11k_clk = devm_clk_get(dev, "pll11k"); + if (IS_ERR(*pll11k_clk)) + *pll11k_clk = NULL; +} +EXPORT_SYMBOL(fsl_asoc_get_pll_clocks); + +/** + * fsl_asoc_reparent_pll_clocks - set clock parent if necessary + * + * @dev: device pointer + * @clk: root clock pointer + * @pll8k_clk: PLL clock pointer for 8kHz + * @pll11k_clk: PLL clock pointer for 11kHz + * @ratio: target requency for root clock + * + * This function set root clock parent according to the target ratio + */ +void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk, + struct clk *pll8k_clk, + struct clk *pll11k_clk, u64 ratio) +{ + struct clk *p, *pll = 0, *npll = 0; + bool reparent = false; + int ret = 0; + + if (!clk || !pll8k_clk || !pll11k_clk) + return; + + p = clk; + while (p && pll8k_clk && pll11k_clk) { + struct clk *pp = clk_get_parent(p); + + if (clk_is_match(pp, pll8k_clk) || + clk_is_match(pp, pll11k_clk)) { + pll = pp; + break; + } + p = pp; + } + + npll = (do_div(ratio, 8000) ? pll11k_clk : pll8k_clk); + reparent = (pll && !clk_is_match(pll, npll)); + + if (reparent) { + ret = clk_set_parent(p, npll); + if (ret < 0) + dev_warn(dev, "failed to set parent %s: %d\n", __clk_get_name(npll), ret); + } +} +EXPORT_SYMBOL(fsl_asoc_reparent_pll_clocks); + MODULE_AUTHOR("Timur Tabi "); MODULE_DESCRIPTION("Freescale ASoC utility code"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h index c5dc2a14b492c..4d5f3d93bc813 100644 --- a/sound/soc/fsl/fsl_utils.h +++ b/sound/soc/fsl/fsl_utils.h @@ -19,4 +19,11 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name, struct snd_soc_dai_link *dai, unsigned int *dma_channel_id, unsigned int *dma_id); + +void fsl_asoc_get_pll_clocks(struct device *dev, struct clk **pll8k_clk, + struct clk **pll11k_clk); + +void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk, + struct clk *pll8k_clk, + struct clk *pll11k_clk, u64 ratio); #endif /* _FSL_UTILS_H */ -- GitLab From 34dcdebecf2f05e1b275e1da8352f8e4c1aab6f6 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:37 +0800 Subject: [PATCH 791/942] ASoC: fsl_spdif: Add support for PLL switch at runtime. i.MX8MQ/MN/MM/MP platforms typically have 2 AUDIO PLLs being configured to handle 8kHz and 11kHz series audio rates. The patch implements the functionality to select at runtime the appropriate AUDIO PLL as function of audio file rate. As the clock parent may be changed, need to probe txclk according to sample rate again. Signed-off-by: Viorel Suman Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656667961-1799-3-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + sound/soc/fsl/fsl_spdif.c | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 10fa387534533..910b8747b6bdf 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -59,6 +59,7 @@ config SND_SOC_FSL_SPDIF select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC) select BITREVERSE + select SND_SOC_FSL_UTILS help Say Y if you want to add Sony/Philips Digital Interface (SPDIF) support for the Freescale CPUs. diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 0504431792cf9..7fc1c96929bb8 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -23,6 +23,7 @@ #include #include "fsl_spdif.h" +#include "fsl_utils.h" #include "imx-pcm.h" #define FSL_SPDIF_TXFIFO_WML 0x8 @@ -114,6 +115,8 @@ struct spdif_mixer_control { * @dma_params_rx: DMA parameters for receive channel * @regcache_srpc: regcache for SRPC * @bypass: status of bypass input to output + * @pll8k_clk: PLL clock for the rate of multiply of 8kHz + * @pll11k_clk: PLL clock for the rate of multiply of 11kHz */ struct fsl_spdif_priv { const struct fsl_spdif_soc_data *soc; @@ -137,6 +140,8 @@ struct fsl_spdif_priv { /* regcache for SRPC */ u32 regcache_srpc; bool bypass; + struct clk *pll8k_clk; + struct clk *pll11k_clk; }; static struct fsl_spdif_soc_data fsl_spdif_vf610 = { @@ -480,6 +485,8 @@ static int spdif_set_rx_clksrc(struct fsl_spdif_priv *spdif_priv, return 0; } +static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, enum spdif_txrate index); + static int spdif_set_sample_rate(struct snd_pcm_substream *substream, int sample_rate) { @@ -528,6 +535,10 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, return -EINVAL; } + ret = fsl_spdif_probe_txclk(spdif_priv, rate); + if (ret) + return ret; + clk = spdif_priv->txclk_src[rate]; if (clk >= STC_TXCLK_SRC_MAX) { dev_err(&pdev->dev, "tx clock source is out of range\n"); @@ -647,6 +658,29 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, } } +static int spdif_reparent_rootclk(struct fsl_spdif_priv *spdif_priv, unsigned int sample_rate) +{ + struct platform_device *pdev = spdif_priv->pdev; + struct clk *clk; + int ret; + + /* Reparent clock if required condition is true */ + if (!fsl_spdif_can_set_clk_rate(spdif_priv, STC_TXCLK_SPDIF_ROOT)) + return 0; + + /* Get root clock */ + clk = spdif_priv->txclk[STC_TXCLK_SPDIF_ROOT]; + + /* Disable clock first, for it was enabled by pm_runtime */ + clk_disable_unprepare(clk); + fsl_asoc_reparent_pll_clocks(&pdev->dev, clk, spdif_priv->pll8k_clk, + spdif_priv->pll11k_clk, sample_rate); + ret = clk_prepare_enable(clk); + if (ret) + return ret; + + return 0; +} static int fsl_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -659,6 +693,13 @@ static int fsl_spdif_hw_params(struct snd_pcm_substream *substream, int ret = 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ret = spdif_reparent_rootclk(spdif_priv, sample_rate); + if (ret) { + dev_err(&pdev->dev, "%s: reparent root clk failed: %d\n", + __func__, sample_rate); + return ret; + } + ret = spdif_set_sample_rate(substream, sample_rate); if (ret) { dev_err(&pdev->dev, "%s: set sample rate failed: %d\n", @@ -1548,11 +1589,8 @@ static int fsl_spdif_probe(struct platform_device *pdev) } spdif_priv->rxclk_src = DEFAULT_RXCLK_SRC; - for (i = 0; i < SPDIF_TXRATE_MAX; i++) { - ret = fsl_spdif_probe_txclk(spdif_priv, i); - if (ret) - return ret; - } + fsl_asoc_get_pll_clocks(&pdev->dev, &spdif_priv->pll8k_clk, + &spdif_priv->pll11k_clk); /* Initial spinlock for control data */ ctrl = &spdif_priv->fsl_spdif_control; -- GitLab From 93f54100fbdedc22e8d88d037a8a3e32101724eb Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:38 +0800 Subject: [PATCH 792/942] ASoC: fsl_micfil: Add support for PLL switch at runtime i.MX8MQ/MN/MM/MP platforms typically have 2 AUDIO PLLs being configured to handle 8kHz and 11kHz series audio rates. The patch implements the functionality to select at runtime the appropriate AUDIO PLL as function of audio file rate. Signed-off-by: Viorel Suman Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656667961-1799-4-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + sound/soc/fsl/fsl_micfil.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 910b8747b6bdf..533937166b4af 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -81,6 +81,7 @@ config SND_SOC_FSL_MICFIL select REGMAP_MMIO select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SOC_FSL_UTILS help Say Y if you want to add Pulse Density Modulation microphone interface (MICFIL) support for NXP. diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index be9781ad88493..79ef4e269bc95 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -24,6 +24,7 @@ #include #include "fsl_micfil.h" +#include "fsl_utils.h" #define MICFIL_OSR_DEFAULT 16 @@ -42,6 +43,8 @@ struct fsl_micfil { const struct fsl_micfil_soc_data *soc; struct clk *busclk; struct clk *mclk; + struct clk *pll8k_clk; + struct clk *pll11k_clk; struct snd_dmaengine_dai_dma_data dma_params_rx; struct sdma_peripheral_config sdmacfg; unsigned int dataline; @@ -264,6 +267,27 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } +static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate) +{ + struct device *dev = &micfil->pdev->dev; + u64 ratio = sample_rate; + struct clk *clk; + int ret; + + /* Get root clock */ + clk = micfil->mclk; + + /* Disable clock first, for it was enabled by pm_runtime */ + clk_disable_unprepare(clk); + fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, + micfil->pll11k_clk, ratio); + ret = clk_prepare_enable(clk); + if (ret) + return ret; + + return 0; +} + static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -287,6 +311,10 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; + ret = fsl_micfil_reparent_rootclk(micfil, rate); + if (ret) + return ret; + ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8); if (ret) return ret; @@ -591,6 +619,9 @@ static int fsl_micfil_probe(struct platform_device *pdev) return PTR_ERR(micfil->busclk); } + fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk, + &micfil->pll11k_clk); + /* init regmap */ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(regs)) -- GitLab From 7cb7f07d2491a3435578ab97eeeb70fadac6385c Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:39 +0800 Subject: [PATCH 793/942] ASoC: fsl_sai: Add support for PLL switch at runtime i.MX8MQ/MN/MM/MP platforms typically have 2 AUDIO PLLs being configured to handle 8kHz and 11kHz series audio rates. The patch implements the functionality to select at runtime the appropriate AUDIO PLL as function of sysclk rate. Signed-off-by: Viorel Suman Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1656667961-1799-5-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + sound/soc/fsl/fsl_sai.c | 38 ++++++++++++++++++++++++++++++++++++++ sound/soc/fsl/fsl_sai.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 533937166b4af..614eceda6b9e3 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -19,6 +19,7 @@ config SND_SOC_FSL_SAI select REGMAP_MMIO select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SOC_FSL_UTILS help Say Y if you want to add Synchronous Audio Interface (SAI) support for the Freescale CPUs. diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a0ddaf7e9f608..974ba0780b198 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -23,6 +23,7 @@ #include #include "fsl_sai.h" +#include "fsl_utils.h" #include "imx-pcm.h" #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ @@ -220,14 +221,48 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, return 0; } +static int fsl_sai_set_mclk_rate(struct snd_soc_dai *dai, int clk_id, unsigned int freq) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); + int ret; + + fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id], + sai->pll8k_clk, sai->pll11k_clk, freq); + + ret = clk_set_rate(sai->mclk_clk[clk_id], freq); + if (ret < 0) + dev_err(dai->dev, "failed to set clock rate (%u): %d\n", freq, ret); + + return ret; +} + static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); int ret; if (dir == SND_SOC_CLOCK_IN) return 0; + if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) { + if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { + dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); + return -EINVAL; + } + + if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { + dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); + return -EINVAL; + } + + if (sai->mclk_streams == 0) { + ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); + if (ret < 0) + return ret; + } + } + ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, true); if (ret) { dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); @@ -1281,6 +1316,9 @@ static int fsl_sai_probe(struct platform_device *pdev) else sai->mclk_clk[0] = sai->bus_clk; + fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk, + &sai->pll11k_clk); + /* read dataline mask for rx and tx*/ ret = fsl_sai_read_dlcfg(sai); if (ret < 0) { diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 9bb8ced520c80..17956b5731dc3 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -273,6 +273,8 @@ struct fsl_sai { struct regmap *regmap; struct clk *bus_clk; struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; + struct clk *pll8k_clk; + struct clk *pll11k_clk; struct resource *res; bool is_consumer_mode; -- GitLab From df0835a810c1585bd54ffb10db92b455e922c7ec Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:40 +0800 Subject: [PATCH 794/942] ASoC: dt-bindings: fsl_spdif: Add two PLL clock source Add two PLL clock source, they are the parent clocks of root clock one is for 8kHz series rates, another one is for 11kHz series rates. They are optional clocks, if there are such clocks, then driver can switch between them for supporting more accurate rates. Signed-off-by: Shengjiu Wang Acked-by: Rob Herring Link: https://lore.kernel.org/r/1656667961-1799-6-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl,spdif.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.yaml b/Documentation/devicetree/bindings/sound/fsl,spdif.yaml index f226ec13167ad..1d64e8337aa4b 100644 --- a/Documentation/devicetree/bindings/sound/fsl,spdif.yaml +++ b/Documentation/devicetree/bindings/sound/fsl,spdif.yaml @@ -58,6 +58,8 @@ properties: slave of the Shared Peripheral Bus and when two or more bus masters (CPU, DMA or DSP) try to access it. This property is optional depending on the SoC design. + - description: PLL clock source for 8kHz series rate, optional. + - description: PLL clock source for 11khz series rate, optional. minItems: 9 clock-names: @@ -72,6 +74,8 @@ properties: - const: rxtx6 - const: rxtx7 - const: spba + - const: pll8k + - const: pll11k minItems: 9 big-endian: -- GitLab From 6c06ad34eda9e1990313ff80999e1a75a02fa1c0 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 1 Jul 2022 17:32:41 +0800 Subject: [PATCH 795/942] ASoC: dt-bindings: fsl-sai: Add two PLL clock source Add two PLL clock source, they are the parent clocks of root clock one is for 8kHz series rates, another one is for 11kHz series rates. They are optional clocks, if there are such clocks, then driver can switch between them for supporting more accurate rates. Signed-off-by: Shengjiu Wang Acked-by: Rob Herring Link: https://lore.kernel.org/r/1656667961-1799-7-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-sai.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 4c66e6a1a533b..fbdefc3fade79 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -21,6 +21,9 @@ Required properties: - clock-names : Must include the "bus" for register access and "mclk1", "mclk2", "mclk3" for bit clock and frame clock providing. + "pll8k", "pll11k" are optional, they are the clock + source for root clock, one is for 8kHz series rates + another one is for 11kHz series rates. - dmas : Generic dma devicetree binding as described in Documentation/devicetree/bindings/dma/dma.txt. -- GitLab From 3eb8440d0d268437202ccbd28a3ca3212e02e57f Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 1 Jul 2022 17:11:05 +0530 Subject: [PATCH 796/942] ASoC: amd: add I2S MICSP instance support Add I2S MICSP instance support for Stoney variant. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20220701114107.1105948-4-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-pcm-dma.c | 50 +++++++++++++++++++++++++++++++++++-- sound/soc/amd/acp.h | 13 ++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 1cd2e70a57dfc..198358d28ea9b 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -433,6 +433,7 @@ static void acp_dma_start(void __iomem *acp_mmio, u16 ch_num, bool is_circular) case I2S_TO_ACP_DMA_CH_NUM: case ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM: case I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM: + case ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM: dma_ctrl |= ACP_DMA_CNTL_0__DMAChIOCEn_MASK; break; default: @@ -710,6 +711,13 @@ static irqreturn_t dma_irq_handler(int irq, void *arg) acp_mmio, mmACP_EXTERNAL_INTR_STAT); } + if ((intr_flag & BIT(ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM)) != 0) { + valid_irq = true; + snd_pcm_period_elapsed(irq_data->play_i2s_micsp_stream); + acp_reg_write((intr_flag & BIT(ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM)) << 16, + acp_mmio, mmACP_EXTERNAL_INTR_STAT); + } + if ((intr_flag & BIT(ACP_TO_I2S_DMA_BT_INSTANCE_CH_NUM)) != 0) { valid_irq = true; snd_pcm_period_elapsed(irq_data->play_i2sbt_stream); @@ -807,7 +815,8 @@ static int acp_dma_open(struct snd_soc_component *component, * stream is not closed */ if (!intr_data->play_i2ssp_stream && !intr_data->capture_i2ssp_stream && - !intr_data->play_i2sbt_stream && !intr_data->capture_i2sbt_stream) + !intr_data->play_i2sbt_stream && !intr_data->capture_i2sbt_stream && + !intr_data->play_i2s_micsp_stream) acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -867,6 +876,9 @@ static int acp_dma_hw_params(struct snd_soc_component *component, case I2S_BT_INSTANCE: val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; break; + case I2S_MICSP_INSTANCE: + val |= ACP_I2S_MICSP_16BIT_RESOLUTION_EN; + break; case I2S_SP_INSTANCE: default: val |= ACP_I2S_SP_16BIT_RESOLUTION_EN; @@ -876,6 +888,7 @@ static int acp_dma_hw_params(struct snd_soc_component *component, case I2S_BT_INSTANCE: val |= ACP_I2S_BT_16BIT_RESOLUTION_EN; break; + case I2S_MICSP_INSTANCE: case I2S_SP_INSTANCE: default: val |= ACP_I2S_MIC_16BIT_RESOLUTION_EN; @@ -901,6 +914,27 @@ static int acp_dma_hw_params(struct snd_soc_component *component, mmACP_I2S_BT_TRANSMIT_BYTE_CNT_LOW; adata->play_i2sbt_stream = substream; break; + case I2S_MICSP_INSTANCE: + switch (adata->asic_type) { + case CHIP_STONEY: + rtd->pte_offset = ACP_ST_PLAYBACK_PTE_OFFSET; + break; + default: + rtd->pte_offset = ACP_PLAYBACK_PTE_OFFSET; + } + rtd->ch1 = SYSRAM_TO_ACP_MICSP_INSTANCE_CH_NUM; + rtd->ch2 = ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM; + rtd->sram_bank = ACP_SRAM_BANK_1_ADDRESS; + rtd->destination = TO_ACP_I2S_2; + rtd->dma_dscr_idx_1 = PLAYBACK_START_DMA_DESCR_CH4; + rtd->dma_dscr_idx_2 = PLAYBACK_START_DMA_DESCR_CH5; + rtd->byte_cnt_high_reg_offset = + mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_HIGH; + rtd->byte_cnt_low_reg_offset = + mmACP_I2S_MICSP_TRANSMIT_BYTE_CNT_LOW; + + adata->play_i2s_micsp_stream = substream; + break; case I2S_SP_INSTANCE: default: switch (adata->asic_type) { @@ -939,6 +973,7 @@ static int acp_dma_hw_params(struct snd_soc_component *component, rtd->dma_curr_dscr = mmACP_DMA_CUR_DSCR_11; adata->capture_i2sbt_stream = substream; break; + case I2S_MICSP_INSTANCE: case I2S_SP_INSTANCE: default: rtd->pte_offset = ACP_CAPTURE_PTE_OFFSET; @@ -1160,6 +1195,9 @@ static int acp_dma_close(struct snd_soc_component *component, case I2S_BT_INSTANCE: adata->play_i2sbt_stream = NULL; break; + case I2S_MICSP_INSTANCE: + adata->play_i2s_micsp_stream = NULL; + break; case I2S_SP_INSTANCE: default: adata->play_i2ssp_stream = NULL; @@ -1181,6 +1219,7 @@ static int acp_dma_close(struct snd_soc_component *component, case I2S_BT_INSTANCE: adata->capture_i2sbt_stream = NULL; break; + case I2S_MICSP_INSTANCE: case I2S_SP_INSTANCE: default: adata->capture_i2ssp_stream = NULL; @@ -1197,7 +1236,8 @@ static int acp_dma_close(struct snd_soc_component *component, * another stream is also not active. */ if (!adata->play_i2ssp_stream && !adata->capture_i2ssp_stream && - !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream) + !adata->play_i2sbt_stream && !adata->capture_i2sbt_stream && + !adata->play_i2s_micsp_stream) acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); kfree(rtd); return 0; @@ -1245,6 +1285,7 @@ static int acp_audio_probe(struct platform_device *pdev) audio_drv_data->capture_i2ssp_stream = NULL; audio_drv_data->play_i2sbt_stream = NULL; audio_drv_data->capture_i2sbt_stream = NULL; + audio_drv_data->play_i2s_micsp_stream = NULL; audio_drv_data->asic_type = *pdata; @@ -1333,6 +1374,11 @@ static int acp_pcm_resume(struct device *dev) config_acp_dma(adata->acp_mmio, rtd, adata->asic_type); } if (adata->asic_type != CHIP_CARRIZO) { + if (adata->play_i2s_micsp_stream && + adata->play_i2s_micsp_stream->runtime) { + rtd = adata->play_i2s_micsp_stream->runtime->private_data; + config_acp_dma(adata->acp_mmio, rtd, adata->asic_type); + } if (adata->play_i2sbt_stream && adata->play_i2sbt_stream->runtime) { rtd = adata->play_i2sbt_stream->runtime->private_data; diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index db80a73aa5932..b29bef90f886b 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -55,6 +55,7 @@ #define I2S_SP_INSTANCE 0x01 #define I2S_BT_INSTANCE 0x02 +#define I2S_MICSP_INSTANCE 0x03 #define CAP_CHANNEL0 0x00 #define CAP_CHANNEL1 0x01 @@ -85,6 +86,10 @@ #define I2S_TO_ACP_DMA_BT_INSTANCE_CH_NUM 10 #define ACP_TO_SYSRAM_BT_INSTANCE_CH_NUM 11 +/* Playback DMA channels for I2S MICSP instance */ +#define SYSRAM_TO_ACP_MICSP_INSTANCE_CH_NUM 4 +#define ACP_TO_I2S_DMA_MICSP_INSTANCE_CH_NUM 5 + #define NUM_DSCRS_PER_CHANNEL 2 #define PLAYBACK_START_DMA_DESCR_CH12 0 @@ -108,8 +113,15 @@ #define CAPTURE_START_DMA_DESCR_CH11 14 #define CAPTURE_END_DMA_DESCR_CH11 15 +/* I2S MICSP Instance DMA Descriptors */ +#define PLAYBACK_START_DMA_DESCR_CH4 0 +#define PLAYBACK_END_DMA_DESCR_CH4 1 +#define PLAYBACK_START_DMA_DESCR_CH5 2 +#define PLAYBACK_END_DMA_DESCR_CH5 3 + #define mmACP_I2S_16BIT_RESOLUTION_EN 0x5209 #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 +#define ACP_I2S_MICSP_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 #define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 #define ACP_BT_UART_PAD_SELECT_MASK 0x1 @@ -149,6 +161,7 @@ struct audio_drv_data { struct snd_pcm_substream *capture_i2ssp_stream; struct snd_pcm_substream *play_i2sbt_stream; struct snd_pcm_substream *capture_i2sbt_stream; + struct snd_pcm_substream *play_i2s_micsp_stream; void __iomem *acp_mmio; u32 asic_type; snd_pcm_sframes_t delay; -- GitLab From 02527c3f2300100a25524c8c020d98c7957e485e Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 1 Jul 2022 17:11:06 +0530 Subject: [PATCH 797/942] ASoC: amd: add Machine driver for Jadeite platform Add Machine driver for Jadeite platform which uses ES8336 codec. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20220701114107.1105948-5-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 324 +++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 sound/soc/amd/acp-es8336.c diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c new file mode 100644 index 0000000000000..eec3d57092fa3 --- /dev/null +++ b/sound/soc/amd/acp-es8336.c @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Machine driver for AMD Stoney platform using ES8336 Codec + * + * Copyright 2022 Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../codecs/es8316.h" +#include "acp.h" + +#define DUAL_CHANNEL 2 +#define DRV_NAME "acp2x_mach" +#define ST_JADEITE 1 +#define ES8336_PLL_FREQ (48000 * 256) + +static unsigned long acp2x_machine_id; +static struct snd_soc_jack st_jack; +struct device *codec_dev; +struct gpio_desc *gpio_pa; + +static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) + gpiod_set_value_cansleep(gpio_pa, true); + else + gpiod_set_value_cansleep(gpio_pa, false); + + return 0; +} + +static struct snd_soc_jack_pin st_es8316_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int st_es8336_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + struct snd_soc_card *card; + struct snd_soc_component *codec; + + codec = asoc_rtd_to_codec(rtd, 0)->component; + card = rtd->card; + + ret = snd_soc_card_jack_new_pins(card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, + &st_jack, st_es8316_jack_pins, + ARRAY_SIZE(st_es8316_jack_pins)); + if (ret) { + dev_err(card->dev, "HP jack creation failed %d\n", ret); + return ret; + } + snd_jack_set_key(st_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + ret = snd_soc_component_set_jack(codec, &st_jack, NULL); + if (ret) { + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + return 0; +} + +static const unsigned int st_channels[] = { + DUAL_CHANNEL, +}; + +static const unsigned int st_rates[] = { + 48000, +}; + +static const struct snd_pcm_hw_constraint_list st_constraints_rates = { + .count = ARRAY_SIZE(st_rates), + .list = st_rates, + .mask = 0, +}; + +static const struct snd_pcm_hw_constraint_list st_constraints_channels = { + .count = ARRAY_SIZE(st_channels), + .list = st_channels, + .mask = 0, +}; + +static int st_es8336_codec_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_card *card; + struct acp_platform_info *machine; + struct snd_soc_dai *codec_dai; + int ret; + + runtime = substream->runtime; + rtd = asoc_substream_to_rtd(substream); + card = rtd->card; + machine = snd_soc_card_get_drvdata(card); + codec_dai = asoc_rtd_to_codec(rtd, 0); + ret = snd_soc_dai_set_sysclk(codec_dai, 0, ES8336_PLL_FREQ, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + runtime->hw.channels_max = DUAL_CHANNEL; + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + &st_constraints_channels); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &st_constraints_rates); + + machine->play_i2s_instance = I2S_MICSP_INSTANCE; + machine->cap_i2s_instance = I2S_MICSP_INSTANCE; + machine->capture_channel = CAP_CHANNEL0; + return 0; +} + +static const struct snd_soc_ops st_es8336_ops = { + .startup = st_es8336_codec_startup, +}; + +SND_SOC_DAILINK_DEF(designware1, + DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto"))); +SND_SOC_DAILINK_DEF(codec, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8336:00", "ES8316 HiFi"))); +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.1.auto"))); + +static struct snd_soc_dai_link st_dai_es8336[] = { + { + .name = "amdes8336", + .stream_name = "ES8336 HiFi Play", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBP_CFP, + .stop_dma_first = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .init = st_es8336_init, + .ops = &st_es8336_ops, + SND_SOC_DAILINK_REG(designware1, codec, platform), + }, +}; + +static const struct snd_soc_dapm_widget st_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Internal Mic", NULL), + + SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, + sof_es8316_speaker_power_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +}; + +static const struct snd_soc_dapm_route st_audio_route[] = { + {"Speaker", NULL, "HPOL"}, + {"Speaker", NULL, "HPOR"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"MIC1", NULL, "Headset Mic"}, + {"MIC2", NULL, "Internal Mic"}, + {"Speaker", NULL, "Speaker Power"}, +}; + +static const struct snd_kcontrol_new st_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Internal Mic"), +}; + +static const struct acpi_gpio_params pa_enable_gpio = { 0, 0, false }; +static const struct acpi_gpio_mapping acpi_es8336_gpios[] = { + { "pa-enable-gpios", &pa_enable_gpio, 1 }, + { } +}; + +static int st_es8336_late_probe(struct snd_soc_card *card) +{ + struct acpi_device *adev; + int ret; + + adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1); + if (adev) + put_device(&adev->dev); + codec_dev = acpi_get_first_physical_node(adev); + if (!codec_dev) + dev_err(card->dev, "can not find codec dev\n"); + + ret = devm_acpi_dev_add_driver_gpios(codec_dev, acpi_es8336_gpios); + + gpio_pa = gpiod_get_optional(codec_dev, "pa-enable", GPIOD_OUT_LOW); + if (IS_ERR(gpio_pa)) { + ret = dev_err_probe(card->dev, PTR_ERR(gpio_pa), + "could not get pa-enable GPIO\n"); + gpiod_put(gpio_pa); + put_device(codec_dev); + } + return 0; +} + +static struct snd_soc_card st_card = { + .name = "acpes8336", + .owner = THIS_MODULE, + .dai_link = st_dai_es8336, + .num_links = ARRAY_SIZE(st_dai_es8336), + .dapm_widgets = st_widgets, + .num_dapm_widgets = ARRAY_SIZE(st_widgets), + .dapm_routes = st_audio_route, + .num_dapm_routes = ARRAY_SIZE(st_audio_route), + .controls = st_mc_controls, + .num_controls = ARRAY_SIZE(st_mc_controls), + .late_probe = st_es8336_late_probe, +}; + +static int st_es8336_quirk_cb(const struct dmi_system_id *id) +{ + acp2x_machine_id = ST_JADEITE; + return 1; +} + +static const struct dmi_system_id st_es8336_quirk_table[] = { + { + .callback = st_es8336_quirk_cb, + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jadeite"), + }, + }, + { + .callback = st_es8336_quirk_cb, + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "IP3 Technology CO.,Ltd."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN1D"), + }, + }, + { + .callback = st_es8336_quirk_cb, + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Standard"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN10"), + }, + }, + {} +}; + +static int st_es8336_probe(struct platform_device *pdev) +{ + int ret; + struct snd_soc_card *card; + struct acp_platform_info *machine; + + machine = devm_kzalloc(&pdev->dev, sizeof(struct acp_platform_info), GFP_KERNEL); + if (!machine) + return -ENOMEM; + + dmi_check_system(st_es8336_quirk_table); + switch (acp2x_machine_id) { + case ST_JADEITE: + card = &st_card; + st_card.dev = &pdev->dev; + break; + default: + return -ENODEV; + } + + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, machine); + ret = devm_snd_soc_register_card(&pdev->dev, &st_card); + if (ret) { + return dev_err_probe(&pdev->dev, ret, + "devm_snd_soc_register_card(%s) failed\n", + card->name); + } + return 0; +} + +static int st_es8336_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id st_audio_acpi_match[] = { + {"AMDI8336", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, st_audio_acpi_match); +#endif + +static struct platform_driver st_mach_driver = { + .driver = { + .name = "st-es8316", + .acpi_match_table = ACPI_PTR(st_audio_acpi_match), + .pm = &snd_soc_pm_ops, + }, + .probe = st_es8336_probe, + .remove = st_es8336_remove, +}; + +module_platform_driver(st_mach_driver); + +MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); +MODULE_DESCRIPTION("st-es8316 audio support"); +MODULE_LICENSE("GPL v2"); -- GitLab From f94fa84058014f81ad526641f1b1f583ca2cf32f Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Fri, 1 Jul 2022 17:11:07 +0530 Subject: [PATCH 798/942] ASoC: amd: enable machine driver build for Jadeite platform Enable machine driver build for Jadeite platform using ES8336 Codec. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20220701114107.1105948-6-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/Kconfig | 13 +++++++++++++ sound/soc/amd/Makefile | 2 ++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 1381aec230481..c373f08234623 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -23,6 +23,19 @@ config SND_SOC_AMD_CZ_RT5645_MACH help This option enables machine driver for rt5645. +config SND_SOC_AMD_ST_ES8336_MACH + tristate "AMD ST support for ES8336" + select SND_SOC_ACPI + select SND_SOC_ES8316 + depends on SND_SOC_AMD_ACP + depends on ACPI || COMPILE_TEST + depends on I2C || COMPILE_TEST + help + This option enables machine driver for Jadeite platform + using es8336 codec. + Say m if you have such a device. + If unsure select "N". + config SND_SOC_AMD_ACP3x tristate "AMD Audio Coprocessor-v3.x support" depends on X86 && PCI diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile index 4b1f77930a4a8..8823f6f286119 100644 --- a/sound/soc/amd/Makefile +++ b/sound/soc/amd/Makefile @@ -2,12 +2,14 @@ acp_audio_dma-objs := acp-pcm-dma.o snd-soc-acp-da7219mx98357-mach-objs := acp-da7219-max98357a.o snd-soc-acp-rt5645-mach-objs := acp-rt5645.o +snd-soc-acp-es8336-mach-objs := acp-es8336.o snd-soc-acp-rt5682-mach-objs := acp3x-rt5682-max9836.o snd-acp-config-objs := acp-config.o obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o +obj-$(CONFIG_SND_SOC_AMD_ST_ES8336_MACH) += snd-soc-acp-es8336-mach.o obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/ obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/ -- GitLab From 8dbefb20b2d0fa8dbf81db161db443096120b326 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Tue, 5 Jul 2022 18:11:34 +0800 Subject: [PATCH 799/942] ASoC: rt5640: Add the MICBIAS1 to the dapm routing The patch adds the MICBIAS1 to the dapm routing while the HDA header used. Signed-off-by: Oder Chiou Reported-by: Sameer Pujar Link: https://lore.kernel.org/r/20220705101134.16792-2-oder_chiou@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 56008e4518f3d..5092856a262d1 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2556,10 +2556,18 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); } +static const struct snd_soc_dapm_route rt5640_hda_jack_dapm_routes[] = { + {"IN1P", NULL, "MICBIAS1"}, + {"IN2P", NULL, "MICBIAS1"}, + {"IN3P", NULL, "MICBIAS1"}, +}; + static void rt5640_enable_hda_jack_detect( struct snd_soc_component *component, struct snd_soc_jack *jack) { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = + snd_soc_component_get_dapm(component); int ret; /* Select JD1 for Mic */ @@ -2592,6 +2600,9 @@ static void rt5640_enable_hda_jack_detect( /* sync initial jack state */ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); + + snd_soc_dapm_add_routes(dapm, rt5640_hda_jack_dapm_routes, + ARRAY_SIZE(rt5640_hda_jack_dapm_routes)); } static int rt5640_set_jack(struct snd_soc_component *component, -- GitLab From dcc165d6179c3934b93b8c3bffde1ed9710fd7ef Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 3 Jun 2022 20:07:07 +0300 Subject: [PATCH 800/942] ASoC: madera: Replace kernel.h with the necessary inclusions When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved. Replace kernel.h inclusion with the list of what is really being used. Signed-off-by: Andy Shevchenko Reviewed-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20220603170707.48728-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- include/sound/madera-pdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/madera-pdata.h b/include/sound/madera-pdata.h index e3060f48f1081..58398d80c3de3 100644 --- a/include/sound/madera-pdata.h +++ b/include/sound/madera-pdata.h @@ -9,7 +9,7 @@ #ifndef MADERA_CODEC_PDATA_H #define MADERA_CODEC_PDATA_H -#include +#include #define MADERA_MAX_INPUT 6 #define MADERA_MAX_MUXED_CHANNELS 4 -- GitLab From 61c606a43b6c74556e35acc645c7a1b6a67c2af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Tue, 5 Jul 2022 15:57:46 +0200 Subject: [PATCH 801/942] ALSA: usb-audio: Add endianness annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 4b8ea38fabab ("ALSA: usb-audio: Support jack detection on Dell dock") Reported-by: kernel test robot Link: https://lore.kernel.org/r/202207051932.qUilU0am-lkp@intel.com Signed-off-by: Jan Schär Link: https://lore.kernel.org/r/20220705135746.13713-1-jan@jschaer.ch Signed-off-by: Takashi Iwai --- sound/usb/mixer_quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 5a45822e60e74..c06d6dfa81392 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -1967,7 +1967,7 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) static int realtek_hda_set(struct snd_usb_audio *chip, u32 cmd) { struct usb_device *dev = chip->dev; - u32 buf = cpu_to_be32(cmd); + __be32 buf = cpu_to_be32(cmd); return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_SET, USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, @@ -1978,7 +1978,7 @@ static int realtek_hda_get(struct snd_usb_audio *chip, u32 cmd, u32 *value) { struct usb_device *dev = chip->dev; int err; - u32 buf = cpu_to_be32(cmd); + __be32 buf = cpu_to_be32(cmd); err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_GET_OUT, USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT, -- GitLab From eec8a5f44e4f68c64ce21d90e438e31e85b92178 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Tue, 5 Jul 2022 08:53:15 +0800 Subject: [PATCH 802/942] ASoC: codecs: wsa883x: fix warning using-module-alias-sdw.cocci This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module. Reported-by: Hulk Robot Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20220705005315.663920-1-cuigaosheng1@huawei.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index dcd88175b9cd7..63e1d7aa61379 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1492,6 +1492,8 @@ static const struct sdw_device_id wsa883x_swr_id[] = { {}, }; +MODULE_DEVICE_TABLE(sdw, wsa883x_swr_id); + static struct sdw_driver wsa883x_codec_driver = { .driver = { .name = "wsa883x-codec", -- GitLab From 275cc7f5bd6f60565672ce339505b77fd47a8157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Jul 2022 11:26:45 +0200 Subject: [PATCH 803/942] ASoC: xilinx: Suppress second error message about reset failure in .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Returning an error value in a platform remove callback results in an error message being emitted by the platform core, but otherwise it doesn't make a difference. If ret is != 0, there is already an error message and another very generic doesn't add any value, so return 0 unconditionally. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220705092645.101343-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/xilinx/xlnx_formatter_pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/xilinx/xlnx_formatter_pcm.c b/sound/soc/xilinx/xlnx_formatter_pcm.c index f5ac0aa312d6e..ff1fe62fea702 100644 --- a/sound/soc/xilinx/xlnx_formatter_pcm.c +++ b/sound/soc/xilinx/xlnx_formatter_pcm.c @@ -703,7 +703,7 @@ static int xlnx_formatter_pcm_remove(struct platform_device *pdev) dev_err(&pdev->dev, "audio formatter reset failed\n"); clk_disable_unprepare(adata->axi_clk); - return ret; + return 0; } static const struct of_device_id xlnx_formatter_pcm_of_match[] = { -- GitLab From f4ba35b79bd0104f00e8e21e400b980bfaa2f17e Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 5 Jul 2022 12:32:38 +0200 Subject: [PATCH 804/942] ASoC: Intel: avs: correct config reference for I2S test board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit e39acc4cfd92 ("ASoC: Intel: avs: Add I2S-test machine board") adds the config "SND_SOC_INTEL_AVS_MACH_I2S_TEST", but in the Makefile refers to config "SND_SOC_INTEL_AVS_MACH_i2s_TEST" (notice the uppercase and lowercase difference). Adjust the Makefile to refer to the actual existing config. Signed-off-by: Lukas Bulwahn Acked-by: Cezary Rojewski Reviewed-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220705103238.7484-1-lukas.bulwahn@gmail.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 25e8c4bb07dbf..bc75376d58c29 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -16,7 +16,7 @@ snd-soc-avs-ssm4567-objs := ssm4567.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219) += snd-soc-avs-da7219.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o -obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_i2s_TEST) += snd-soc-avs-i2s-test.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST) += snd-soc-avs-i2s-test.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o -- GitLab From b03bd215742c620812e47a9ef5f08e4e0e5f0a1a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 5 Jul 2022 18:58:13 +0300 Subject: [PATCH 805/942] ASoC: Intel: catpt: remove duplicating driver data retrieval device_get_match_data() in ACPI case calls similar to acpi_match_device(). Hence there is no need to duplicate the call. Just assign what is in the id->driver_data. Signed-off-by: Andy Shevchenko Acked-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220705155813.75917-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/catpt/device.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/soc/intel/catpt/device.c b/sound/soc/intel/catpt/device.c index 85a34e37316d0..d48a71d2cf1ec 100644 --- a/sound/soc/intel/catpt/device.c +++ b/sound/soc/intel/catpt/device.c @@ -254,14 +254,11 @@ static int catpt_acpi_probe(struct platform_device *pdev) return -ENODEV; } - spec = device_get_match_data(dev); - if (!spec) - return -ENODEV; - cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL); if (!cdev) return -ENOMEM; + spec = (const struct catpt_spec *)id->driver_data; catpt_dev_init(cdev, dev, spec); /* map DSP bar address */ -- GitLab From 50791dcb7de32f9f78061f7f460966ac5616b38e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 5 Jul 2022 20:28:02 +0200 Subject: [PATCH 806/942] ASoC: dt-bindings: qcom,sm8250: add SDM845 sound The Qualcomm SDM845 sound card bindings are almost the same as SM8250, except "pin-switches" and "widgets" properties. These were not documented in SDM845 text bindings but are actually valid for SDM845. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Stephan Gerhold Link: https://lore.kernel.org/r/20220705182802.775803-1-krzysztof.kozlowski@linaro.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/qcom,sdm845.txt | 91 ------------------- .../bindings/sound/qcom,sm8250.yaml | 3 + 2 files changed, 3 insertions(+), 91 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/qcom,sdm845.txt diff --git a/Documentation/devicetree/bindings/sound/qcom,sdm845.txt b/Documentation/devicetree/bindings/sound/qcom,sdm845.txt deleted file mode 100644 index de4c604641da0..0000000000000 --- a/Documentation/devicetree/bindings/sound/qcom,sdm845.txt +++ /dev/null @@ -1,91 +0,0 @@ -* Qualcomm Technologies Inc. SDM845 ASoC sound card driver - -This binding describes the SDM845 sound card, which uses qdsp for audio. - -- compatible: - Usage: required - Value type: - Definition: must be one of this - "qcom,sdm845-sndcard" - "qcom,db845c-sndcard" - "lenovo,yoga-c630-sndcard" - -- audio-routing: - Usage: Optional - Value type: - Definition: A list of the connections between audio components. - Each entry is a pair of strings, the first being the - connection's sink, the second being the connection's - source. Valid names could be power supplies, MicBias - of codec and the jacks on the board. - -- model: - Usage: required - Value type: - Definition: The user-visible name of this sound card. - -- aux-devs - Usage: optional - Value type: - Definition: A list of phandles for auxiliary devices (e.g. analog - amplifiers) that do not appear directly within the DAI - links. Should be connected to another audio component - using "audio-routing". - -= dailinks -Each subnode of sndcard represents either a dailink, and subnodes of each -dailinks would be cpu/codec/platform dais. - -- link-name: - Usage: required - Value type: - Definition: User friendly name for dai link - -= CPU, PLATFORM, CODEC dais subnodes -- cpu: - Usage: required - Value type: - Definition: cpu dai sub-node - -- codec: - Usage: required - Value type: - Definition: codec dai sub-node - -- platform: - Usage: Optional - Value type: - Definition: platform dai sub-node - -- sound-dai: - Usage: required - Value type: - Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node. - -Example: - -audio { - compatible = "qcom,sdm845-sndcard"; - model = "sdm845-snd-card"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&pri_mi2s_active &pri_mi2s_ws_active>; - pinctrl-1 = <&pri_mi2s_sleep &pri_mi2s_ws_sleep>; - - mm1-dai-link { - link-name = "MultiMedia1"; - cpu { - sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>; - }; - }; - - pri-mi2s-dai-link { - link-name = "PRI MI2S Playback"; - cpu { - sound-dai = <&q6afedai PRIMARY_MI2S_RX>; - }; - - platform { - sound-dai = <&q6routing>; - }; - }; -}; diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml index 4ecd4080bb962..e6e27d09783ec 100644 --- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml @@ -16,8 +16,11 @@ description: properties: compatible: enum: + - lenovo,yoga-c630-sndcard - qcom,apq8016-sbc-sndcard + - qcom,db845c-sndcard - qcom,msm8916-qdsp6-sndcard + - qcom,sdm845-sndcard - qcom,sm8250-sndcard - qcom,qrb5165-rb5-sndcard -- GitLab From 0ff9f8b9f59208332c6707e37d5739c57c7f7bce Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Fri, 1 Jul 2022 02:14:27 +0000 Subject: [PATCH 807/942] ASoC: rockchip: i2s: Fix error code when fail to read I2S_CLR Add the error code '-EBUSY' when fail to read I2S_CLR in rockchip_snd_rxctrl() and rockchip_snd_txctrl() Fixes: 44f362c2cc6d ("ASoC: rockchip: i2s: switch BCLK to GPIO") Signed-off-by: Judy Hsiao Reviewed-by: Brian Norris Link: https://lore.kernel.org/r/20220701021427.3120549-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 22ba1066c9336..ee33c5d2e948f 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -171,6 +171,7 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) retry--; if (!retry) { dev_warn(i2s->dev, "fail to clear\n"); + ret = -EBUSY; break; } } @@ -232,6 +233,7 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) retry--; if (!retry) { dev_warn(i2s->dev, "fail to clear\n"); + ret = -EBUSY; break; } } -- GitLab From 6dbc34d9c31e71aeb8175ce443c11b9e19e9f8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Jun 2022 21:42:20 +0200 Subject: [PATCH 808/942] ASoC: tegra: tegra20_das: Fold header file into only user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit fcff5f99742e ("ASoC: tegra: remove unnecessary includes") the header file (which at the time was named tegra_das.h) there is only the actual driver that includes it. Just move the definitions into the driver, drop the exports and remove the completely unused function. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220629194224.175607-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_das.c | 110 +++++++++++++++++++++++-------- sound/soc/tegra/tegra20_das.h | 120 ---------------------------------- 2 files changed, 83 insertions(+), 147 deletions(-) delete mode 100644 sound/soc/tegra/tegra20_das.h diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 69c651274c12f..d2801130a986d 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -13,10 +13,90 @@ #include #include #include -#include "tegra20_das.h" #define DRV_NAME "tegra20-das" +/* Register TEGRA20_DAS_DAP_CTRL_SEL */ +#define TEGRA20_DAS_DAP_CTRL_SEL 0x00 +#define TEGRA20_DAS_DAP_CTRL_SEL_COUNT 5 +#define TEGRA20_DAS_DAP_CTRL_SEL_STRIDE 4 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0 +#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5 + +/* Values for field TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */ +#define TEGRA20_DAS_DAP_SEL_DAC1 0 +#define TEGRA20_DAS_DAP_SEL_DAC2 1 +#define TEGRA20_DAS_DAP_SEL_DAC3 2 +#define TEGRA20_DAS_DAP_SEL_DAP1 16 +#define TEGRA20_DAS_DAP_SEL_DAP2 17 +#define TEGRA20_DAS_DAP_SEL_DAP3 18 +#define TEGRA20_DAS_DAP_SEL_DAP4 19 +#define TEGRA20_DAS_DAP_SEL_DAP5 20 + +/* Register TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL */ +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL 0x40 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0 +#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4 + +/* + * Values for: + * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL + * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL + * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL + */ +#define TEGRA20_DAS_DAC_SEL_DAP1 0 +#define TEGRA20_DAS_DAC_SEL_DAP2 1 +#define TEGRA20_DAS_DAC_SEL_DAP3 2 +#define TEGRA20_DAS_DAC_SEL_DAP4 3 +#define TEGRA20_DAS_DAC_SEL_DAP5 4 + +/* + * Names/IDs of the DACs/DAPs. + */ + +#define TEGRA20_DAS_DAP_ID_1 0 +#define TEGRA20_DAS_DAP_ID_2 1 +#define TEGRA20_DAS_DAP_ID_3 2 +#define TEGRA20_DAS_DAP_ID_4 3 +#define TEGRA20_DAS_DAP_ID_5 4 + +#define TEGRA20_DAS_DAC_ID_1 0 +#define TEGRA20_DAS_DAC_ID_2 1 +#define TEGRA20_DAS_DAC_ID_3 2 + +struct tegra20_das { + struct device *dev; + struct regmap *regmap; +}; + +/* + * Terminology: + * DAS: Digital audio switch (HW module controlled by this driver) + * DAP: Digital audio port (port/pins on Tegra device) + * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere) + * + * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific + * DAC, or another DAP. When DAPs are connected, one must be the master and + * one the slave. Each DAC allows selection of a specific DAP for input, to + * cater for the case where N DAPs are connected to 1 DAC for broadcast + * output. + * + * This driver is dumb; no attempt is made to ensure that a valid routing + * configuration is programmed. + */ + static struct tegra20_das *das; static inline void tegra20_das_write(u32 reg, u32 val) @@ -32,7 +112,7 @@ static inline u32 tegra20_das_read(u32 reg) return val; } -int tegra20_das_connect_dap_to_dac(int dap, int dac) +static int tegra20_das_connect_dap_to_dac(int dap, int dac) { u32 addr; u32 reg; @@ -48,31 +128,8 @@ int tegra20_das_connect_dap_to_dac(int dap, int dac) return 0; } -EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dac); - -int tegra20_das_connect_dap_to_dap(int dap, int otherdap, int master, - int sdata1rx, int sdata2rx) -{ - u32 addr; - u32 reg; - - if (!das) - return -ENODEV; - - addr = TEGRA20_DAS_DAP_CTRL_SEL + - (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE); - reg = (otherdap << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P) | - (!!sdata2rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P) | - (!!sdata1rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P) | - (!!master << TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P); - - tegra20_das_write(addr, reg); - - return 0; -} -EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dap); -int tegra20_das_connect_dac_to_dap(int dac, int dap) +static int tegra20_das_connect_dac_to_dap(int dac, int dap) { u32 addr; u32 reg; @@ -90,7 +147,6 @@ int tegra20_das_connect_dac_to_dap(int dac, int dap) return 0; } -EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap); #define LAST_REG(name) \ (TEGRA20_DAS_##name + \ diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h deleted file mode 100644 index 18e832ded73a3..0000000000000 --- a/sound/soc/tegra/tegra20_das.h +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra20_das.h - Definitions for Tegra20 DAS driver - * - * Author: Stephen Warren - * Copyright (C) 2010,2012 - NVIDIA, Inc. - */ - -#ifndef __TEGRA20_DAS_H__ -#define __TEGRA20_DAS_H__ - -/* Register TEGRA20_DAS_DAP_CTRL_SEL */ -#define TEGRA20_DAS_DAP_CTRL_SEL 0x00 -#define TEGRA20_DAS_DAP_CTRL_SEL_COUNT 5 -#define TEGRA20_DAS_DAP_CTRL_SEL_STRIDE 4 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0 -#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5 - -/* Values for field TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */ -#define TEGRA20_DAS_DAP_SEL_DAC1 0 -#define TEGRA20_DAS_DAP_SEL_DAC2 1 -#define TEGRA20_DAS_DAP_SEL_DAC3 2 -#define TEGRA20_DAS_DAP_SEL_DAP1 16 -#define TEGRA20_DAS_DAP_SEL_DAP2 17 -#define TEGRA20_DAS_DAP_SEL_DAP3 18 -#define TEGRA20_DAS_DAP_SEL_DAP4 19 -#define TEGRA20_DAS_DAP_SEL_DAP5 20 - -/* Register TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL */ -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL 0x40 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0 -#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4 - -/* - * Values for: - * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL - * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL - * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL - */ -#define TEGRA20_DAS_DAC_SEL_DAP1 0 -#define TEGRA20_DAS_DAC_SEL_DAP2 1 -#define TEGRA20_DAS_DAC_SEL_DAP3 2 -#define TEGRA20_DAS_DAC_SEL_DAP4 3 -#define TEGRA20_DAS_DAC_SEL_DAP5 4 - -/* - * Names/IDs of the DACs/DAPs. - */ - -#define TEGRA20_DAS_DAP_ID_1 0 -#define TEGRA20_DAS_DAP_ID_2 1 -#define TEGRA20_DAS_DAP_ID_3 2 -#define TEGRA20_DAS_DAP_ID_4 3 -#define TEGRA20_DAS_DAP_ID_5 4 - -#define TEGRA20_DAS_DAC_ID_1 0 -#define TEGRA20_DAS_DAC_ID_2 1 -#define TEGRA20_DAS_DAC_ID_3 2 - -struct tegra20_das { - struct device *dev; - struct regmap *regmap; -}; - -/* - * Terminology: - * DAS: Digital audio switch (HW module controlled by this driver) - * DAP: Digital audio port (port/pins on Tegra device) - * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere) - * - * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific - * DAC, or another DAP. When DAPs are connected, one must be the master and - * one the slave. Each DAC allows selection of a specific DAP for input, to - * cater for the case where N DAPs are connected to 1 DAC for broadcast - * output. - * - * This driver is dumb; no attempt is made to ensure that a valid routing - * configuration is programmed. - */ - -/* - * Connect a DAP to a DAC - * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_* - * dac_sel: DAC to connect to: TEGRA20_DAS_DAP_SEL_DAC* - */ -extern int tegra20_das_connect_dap_to_dac(int dap, int dac); - -/* - * Connect a DAP to another DAP - * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_* - * other_dap_sel: DAP to connect to: TEGRA20_DAS_DAP_SEL_DAP* - * master: Is this DAP the master (1) or slave (0) - * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0) - * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0) - */ -extern int tegra20_das_connect_dap_to_dap(int dap, int otherdap, - int master, int sdata1rx, - int sdata2rx); - -/* - * Connect a DAC's input to a DAP - * (DAC outputs are selected by the DAP) - * dac_id: DAC ID to connect: TEGRA20_DAS_DAC_ID_* - * dap_sel: DAP to receive input from: TEGRA20_DAS_DAC_SEL_DAP* - */ -extern int tegra20_das_connect_dac_to_dap(int dac, int dap); - -#endif -- GitLab From 9a99b9b26451ca2a81867ce0cd8fe18dce856a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Jun 2022 21:42:21 +0200 Subject: [PATCH 809/942] ASoC: tegra: tegra20_das: Remove unused function tegra20_das_read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is unused since commit 7203a62562dc ("ASoC: convert Tegra20 DAS driver to regmap"). Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220629194224.175607-2-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_das.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index d2801130a986d..4e23fd96c7454 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -104,14 +104,6 @@ static inline void tegra20_das_write(u32 reg, u32 val) regmap_write(das->regmap, reg, val); } -static inline u32 tegra20_das_read(u32 reg) -{ - u32 val; - - regmap_read(das->regmap, reg, &val); - return val; -} - static int tegra20_das_connect_dap_to_dac(int dap, int dac) { u32 addr; -- GitLab From eefaea93235523d248cc8cadcd6be9f47b03b9d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Jun 2022 21:42:22 +0200 Subject: [PATCH 810/942] ASoC: tegra: tegra20_das: Get rid of global pointer for driver data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This enables the driver (at least theoretically) to bind to more than one device. The remove function has nothing to do now, so it is dropped. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220629194224.175607-3-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_das.c | 66 +++++++++++------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 4e23fd96c7454..8637a0cc1f5e5 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -97,14 +97,12 @@ struct tegra20_das { * configuration is programmed. */ -static struct tegra20_das *das; - -static inline void tegra20_das_write(u32 reg, u32 val) +static inline void tegra20_das_write(struct tegra20_das *das, u32 reg, u32 val) { regmap_write(das->regmap, reg, val); } -static int tegra20_das_connect_dap_to_dac(int dap, int dac) +static int tegra20_das_connect_dap_to_dac(struct tegra20_das *das, int dap, int dac) { u32 addr; u32 reg; @@ -116,12 +114,12 @@ static int tegra20_das_connect_dap_to_dac(int dap, int dac) (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE); reg = dac << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P; - tegra20_das_write(addr, reg); + tegra20_das_write(das, addr, reg); return 0; } -static int tegra20_das_connect_dac_to_dap(int dac, int dap) +static int tegra20_das_connect_dac_to_dap(struct tegra20_das *das, int dac, int dap) { u32 addr; u32 reg; @@ -135,7 +133,7 @@ static int tegra20_das_connect_dac_to_dap(int dac, int dap) dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P | dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P; - tegra20_das_write(addr, reg); + tegra20_das_write(das, addr, reg); return 0; } @@ -168,74 +166,51 @@ static const struct regmap_config tegra20_das_regmap_config = { static int tegra20_das_probe(struct platform_device *pdev) { void __iomem *regs; + struct tegra20_das *das; int ret = 0; - if (das) - return -ENODEV; - das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL); - if (!das) { - ret = -ENOMEM; - goto err; - } + if (!das) + return -ENOMEM; + das->dev = &pdev->dev; regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(regs)) { - ret = PTR_ERR(regs); - goto err; - } + if (IS_ERR(regs)) + return PTR_ERR(regs); das->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra20_das_regmap_config); if (IS_ERR(das->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); - ret = PTR_ERR(das->regmap); - goto err; + return PTR_ERR(das->regmap); } - ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1, + ret = tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_1, TEGRA20_DAS_DAP_SEL_DAC1); if (ret) { dev_err(&pdev->dev, "Can't set up DAS DAP connection\n"); - goto err; + return ret; } - ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_1, + ret = tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_1, TEGRA20_DAS_DAC_SEL_DAP1); if (ret) { dev_err(&pdev->dev, "Can't set up DAS DAC connection\n"); - goto err; + return ret; } - - ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_3, + ret = tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_3, TEGRA20_DAS_DAP_SEL_DAC3); if (ret) { dev_err(&pdev->dev, "Can't set up DAS DAP connection\n"); - goto err; + return ret; } - ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_3, + ret = tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_3, TEGRA20_DAS_DAC_SEL_DAP3); if (ret) { dev_err(&pdev->dev, "Can't set up DAS DAC connection\n"); - goto err; + return ret; } - platform_set_drvdata(pdev, das); - - return 0; - -err: - das = NULL; - return ret; -} - -static int tegra20_das_remove(struct platform_device *pdev) -{ - if (!das) - return -ENODEV; - - das = NULL; - return 0; } @@ -246,7 +221,6 @@ static const struct of_device_id tegra20_das_of_match[] = { static struct platform_driver tegra20_das_driver = { .probe = tegra20_das_probe, - .remove = tegra20_das_remove, .driver = { .name = DRV_NAME, .of_match_table = tegra20_das_of_match, -- GitLab From a10a8b6661c478dac3a8c55ad41f5cb00779c6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Jun 2022 21:42:23 +0200 Subject: [PATCH 811/942] ASoC: tegra: tegra20_das: Make helper functions return void MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These only ever return a value != 0 if the parameter das is NULL. In the only caller however it's already asserted this isn't the case. So convert the functions to return void and simplify the caller accordingly. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220629194224.175607-4-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_das.c | 47 ++++++++--------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 8637a0cc1f5e5..39a6135dd0d0c 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -102,31 +102,23 @@ static inline void tegra20_das_write(struct tegra20_das *das, u32 reg, u32 val) regmap_write(das->regmap, reg, val); } -static int tegra20_das_connect_dap_to_dac(struct tegra20_das *das, int dap, int dac) +static void tegra20_das_connect_dap_to_dac(struct tegra20_das *das, int dap, int dac) { u32 addr; u32 reg; - if (!das) - return -ENODEV; - addr = TEGRA20_DAS_DAP_CTRL_SEL + (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE); reg = dac << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P; tegra20_das_write(das, addr, reg); - - return 0; } -static int tegra20_das_connect_dac_to_dap(struct tegra20_das *das, int dac, int dap) +static void tegra20_das_connect_dac_to_dap(struct tegra20_das *das, int dac, int dap) { u32 addr; u32 reg; - if (!das) - return -ENODEV; - addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL + (dac * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE); reg = dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P | @@ -134,8 +126,6 @@ static int tegra20_das_connect_dac_to_dap(struct tegra20_das *das, int dac, int dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P; tegra20_das_write(das, addr, reg); - - return 0; } #define LAST_REG(name) \ @@ -167,7 +157,6 @@ static int tegra20_das_probe(struct platform_device *pdev) { void __iomem *regs; struct tegra20_das *das; - int ret = 0; das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL); if (!das) @@ -186,30 +175,14 @@ static int tegra20_das_probe(struct platform_device *pdev) return PTR_ERR(das->regmap); } - ret = tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_1, - TEGRA20_DAS_DAP_SEL_DAC1); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAS DAP connection\n"); - return ret; - } - ret = tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_1, - TEGRA20_DAS_DAC_SEL_DAP1); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAS DAC connection\n"); - return ret; - } - ret = tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_3, - TEGRA20_DAS_DAP_SEL_DAC3); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAS DAP connection\n"); - return ret; - } - ret = tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_3, - TEGRA20_DAS_DAC_SEL_DAP3); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAS DAC connection\n"); - return ret; - } + tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_1, + TEGRA20_DAS_DAP_SEL_DAC1); + tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_1, + TEGRA20_DAS_DAC_SEL_DAP1); + tegra20_das_connect_dap_to_dac(das, TEGRA20_DAS_DAP_ID_3, + TEGRA20_DAS_DAP_SEL_DAC3); + tegra20_das_connect_dac_to_dap(das, TEGRA20_DAS_DAC_ID_3, + TEGRA20_DAS_DAC_SEL_DAP3); return 0; } -- GitLab From fb617612fd8e017720d7fe907b22b4bb44027948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 29 Jun 2022 21:42:24 +0200 Subject: [PATCH 812/942] ASoC: tegra: tegra20_das: Drop write-only driver data member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dev member of struct tegra20_das is only written once in .probe(). There is no loss of functionality if the member and the assignment go away. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220629194224.175607-5-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_das.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c index 39a6135dd0d0c..c620ab0c601fa 100644 --- a/sound/soc/tegra/tegra20_das.c +++ b/sound/soc/tegra/tegra20_das.c @@ -77,7 +77,6 @@ #define TEGRA20_DAS_DAC_ID_3 2 struct tegra20_das { - struct device *dev; struct regmap *regmap; }; @@ -162,8 +161,6 @@ static int tegra20_das_probe(struct platform_device *pdev) if (!das) return -ENOMEM; - das->dev = &pdev->dev; - regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(regs)) return PTR_ERR(regs); -- GitLab From 0d356c186ffd6d4c3e10abb283379d09a93d2515 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 5 Jul 2022 19:11:01 +0300 Subject: [PATCH 813/942] ASoC: SOF: Intel: bdw: remove duplicating driver data retrieval device_get_match_data() in ACPI case calls similar to acpi_match_device(). Hence there is no need to duplicate the call. Just assign what is in the id->driver_data. Signed-off-by: Andy Shevchenko Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220705161102.76250-1-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/bdw.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index 26df780c702e8..a446154f28032 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -681,11 +681,8 @@ static int sof_broadwell_probe(struct platform_device *pdev) return -ENODEV; } - desc = device_get_match_data(dev); - if (!desc) - return -ENODEV; - - return sof_acpi_probe(pdev, device_get_match_data(dev)); + desc = (const struct sof_dev_desc *)id->driver_data; + return sof_acpi_probe(pdev, desc); } /* acpi_driver definition */ -- GitLab From 65b6851d243ff54cbd4adfb887a8af9d04b7f286 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 5 Jul 2022 19:11:02 +0300 Subject: [PATCH 814/942] ASoC: SOF: Intel: byt: remove duplicating driver data retrieval device_get_match_data() in ACPI case calls similar to acpi_match_device(). Hence there is no need to duplicate the call. Just assign what is in the id->driver_data. Signed-off-by: Andy Shevchenko Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220705161102.76250-2-andriy.shevchenko@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/byt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 4ed8381ecedaa..e6dc4ff531c34 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -465,10 +465,7 @@ static int sof_baytrail_probe(struct platform_device *pdev) return -ENODEV; } - desc = device_get_match_data(&pdev->dev); - if (!desc) - return -ENODEV; - + desc = (const struct sof_dev_desc *)id->driver_data; if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev)) desc = &sof_acpi_baytrailcr_desc; -- GitLab From c0fabd12a8570cb932f13d9388f3d887ad44369b Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 6 Jul 2022 17:42:55 +0800 Subject: [PATCH 815/942] ASoC: imx-card: Fix DSD/PDM mclk frequency The DSD/PDM rate not only DSD64/128/256/512, which are the multiple rate of 44.1kHz, but also support the multiple rate of 8kHz, so can't force all mclk frequency to be 22579200Hz, need to assign the frequency according to rate. Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1657100575-8261-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/imx-card.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c index 1797d777b1b87..ccc4194dc5e79 100644 --- a/sound/soc/fsl/imx-card.c +++ b/sound/soc/fsl/imx-card.c @@ -17,6 +17,9 @@ #include "fsl_sai.h" +#define IMX_CARD_MCLK_22P5792MHZ 22579200 +#define IMX_CARD_MCLK_24P576MHZ 24576000 + enum codec_type { CODEC_DUMMY = 0, CODEC_AK5558 = 1, @@ -353,9 +356,14 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream, mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width); else mclk_freq = params_rate(params) * slots * slot_width; - /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ - if (format_is_dsd(params)) - mclk_freq = 22579200; + + if (format_is_dsd(params)) { + /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ + if (!(params_rate(params) % 11025)) + mclk_freq = IMX_CARD_MCLK_22P5792MHZ; + else + mclk_freq = IMX_CARD_MCLK_24P576MHZ; + } ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq, SND_SOC_CLOCK_OUT); -- GitLab From f1fd46e068f52893608469df98d4608672e3e45f Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 08:29:52 +0200 Subject: [PATCH 816/942] ASoC: Intel: avs: Fix i2s_test card name initialization Update printf formatting as 'ssp_port' argument is of type 'int', not 'long int'. Fixes: e39acc4cfd92 ("ASoC: Intel: avs: Add I2S-test machine board") Reported-by: kernel test robot Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706062952.251704-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/i2s_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c index 461b651cd3314..8f0fd87bc8663 100644 --- a/sound/soc/intel/avs/boards/i2s_test.c +++ b/sound/soc/intel/avs/boards/i2s_test.c @@ -127,7 +127,7 @@ static int avs_i2s_test_probe(struct platform_device *pdev) if (!card) return -ENOMEM; - card->name = devm_kasprintf(dev, GFP_KERNEL, "ssp%ld-loopback", ssp_port); + card->name = devm_kasprintf(dev, GFP_KERNEL, "ssp%d-loopback", ssp_port); if (!card->name) return -ENOMEM; -- GitLab From e57297fc0915e2f95de26d18ad8ab6f17c068658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 5 Jul 2022 08:36:13 +0200 Subject: [PATCH 817/942] ASoC: rsnd: Emit useful error messages in .remove() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If more than one call of rsnd_dai_call(remove, ...) fails the platform remove callback returns all values orred together which then makes the driver core emit a generic error message which is little helpful. Instead emit details of which call failed exactly and return 0. Note returning 0 instead of an error code doesn't make a difference in the driver core apart from the error message. This is a preparation for making platform remove callbacks return void. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20220705063613.93770-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 4973f94a21446..7e380d71b0f88 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1969,19 +1969,26 @@ static int rsnd_remove(struct platform_device *pdev) rsnd_cmd_remove, rsnd_adg_remove, }; - int ret = 0, i; + int i; pm_runtime_disable(&pdev->dev); for_each_rsnd_dai(rdai, priv, i) { - ret |= rsnd_dai_call(remove, &rdai->playback, priv); - ret |= rsnd_dai_call(remove, &rdai->capture, priv); + int ret; + + ret = rsnd_dai_call(remove, &rdai->playback, priv); + if (ret) + dev_warn(&pdev->dev, "Failed to remove playback dai #%d\n", i); + + ret = rsnd_dai_call(remove, &rdai->capture, priv); + if (ret) + dev_warn(&pdev->dev, "Failed to remove capture dai #%d\n", i); } for (i = 0; i < ARRAY_SIZE(remove_func); i++) remove_func[i](priv); - return ret; + return 0; } static int __maybe_unused rsnd_suspend(struct device *dev) -- GitLab From ab34403db24233e603338b70deb9a84093c88397 Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 7 Jul 2022 02:25:14 +0530 Subject: [PATCH 818/942] ASoC: amd: fix ACPI dependency compile errors and warnings Fixed ACPI dependency complie errors and warnings as listed below. All warnings (new ones prefixed by >>): sound/soc/soc-acpi.c:34:1: error: redefinition of 'snd_soc_acpi_find_machine' 34 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) | ^~~~~~~~~~~~~~~~~~~~~~~~~ In file included from sound/soc/soc-acpi.c:9: include/sound/soc-acpi.h:38:1: note: previous definition of 'snd_soc_acpi_find_machine' with type 'struct snd_soc_acpi_mach *(struct snd_soc_acpi_mach *)' 38 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) | ^~~~~~~~~~~~~~~~~~~~~~~~~ sound/soc/soc-acpi.c: In function 'snd_soc_acpi_find_package': sound/soc/soc-acpi.c:58:36: error: implicit declaration of function 'acpi_fetch_acpi_dev'; did you mean 'device_match_acpi_dev'? [-Werror=implicit-function-declaration] 58 | struct acpi_device *adev = acpi_fetch_acpi_dev(handle); | ^~~~~~~~~~~~~~~~~~~ | device_match_acpi_dev >> sound/soc/soc-acpi.c:58:36: warning: initialization of 'struct acpi_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion] sound/soc/soc-acpi.c:64:25: error: invalid use of undefined type 'struct acpi_device' 64 | if (adev && adev->status.present && adev->status.functional) { | ^~ sound/soc/soc-acpi.c:64:49: error: invalid use of undefined type 'struct acpi_device' 64 | if (adev && adev->status.present && adev->status.functional) { | ^~ sound/soc/soc-acpi.c:80:26: error: implicit declaration of function 'acpi_extract_package' [-Werror=implicit-function-declaration] 80 | status = acpi_extract_package(myobj, | ^~~~~~~~~~~~~~~~~~~~ sound/soc/soc-acpi.c: At top level: sound/soc/soc-acpi.c:95:6: error: redefinition of 'snd_soc_acpi_find_package_from_hid' 95 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from sound/soc/soc-acpi.c:9: include/sound/soc-acpi.h:44:1: note: previous definition of 'snd_soc_acpi_find_package_from_hid' with type 'bool(const u8 *, struct snd_soc_acpi_package_context *)' {aka '_Bool(const unsigned char *, struct snd_soc_acpi_package_context *)'} 44 | snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sound/soc/soc-acpi.c:109:27: error: redefinition of 'snd_soc_acpi_codec_list' 109 | struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) | ^~~~~~~~~~~~~~~~~~~~~~~ In file included from sound/soc/soc-acpi.c:9: include/sound/soc-acpi.h:51:41: note: previous definition of 'snd_soc_acpi_codec_list' with type 'struct snd_soc_acpi_mach *(void *)' 51 | static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) | ^~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Vijendar Mukunda Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220706205515.2485601-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index c373f08234623..9629328c419ea 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -25,10 +25,9 @@ config SND_SOC_AMD_CZ_RT5645_MACH config SND_SOC_AMD_ST_ES8336_MACH tristate "AMD ST support for ES8336" - select SND_SOC_ACPI + select SND_SOC_ACPI if ACPI select SND_SOC_ES8316 - depends on SND_SOC_AMD_ACP - depends on ACPI || COMPILE_TEST + depends on SND_SOC_AMD_ACP && ACPI depends on I2C || COMPILE_TEST help This option enables machine driver for Jadeite platform -- GitLab From 98356c89d44dac838dfbab02975645d828de3099 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Wed, 6 Jul 2022 22:13:20 +0100 Subject: [PATCH 819/942] ASoC: jz4740-i2s: Remove Open Firmware dependency This driver doesn't require Open Firmware support. Remove the OF-specific includes and drop the Kconfig dependency. Signed-off-by: Aidan MacDonald Acked-by: Paul Cercueil Link: https://lore.kernel.org/r/20220706211330.120198-2-aidanmacdonald.0x0@gmail.com Signed-off-by: Mark Brown --- sound/soc/jz4740/Kconfig | 2 +- sound/soc/jz4740/jz4740-i2s.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig index 29144720cb622..e72f826062e96 100644 --- a/sound/soc/jz4740/Kconfig +++ b/sound/soc/jz4740/Kconfig @@ -2,7 +2,7 @@ config SND_JZ4740_SOC_I2S tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC" depends on MIPS || COMPILE_TEST - depends on OF && HAS_IOMEM + depends on HAS_IOMEM select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740 diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 79afac0c50038..298ff0a839319 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -5,10 +5,9 @@ #include #include -#include -#include #include #include +#include #include #include -- GitLab From 8a7691010992886290b340a1ba943067c2e70f85 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Wed, 6 Jul 2022 22:13:21 +0100 Subject: [PATCH 820/942] ASoC: jz4740-i2s: Refactor DMA channel setup It's simpler to set up the playback and capture DMA settings at driver probe time instead of during DAI probing. Signed-off-by: Aidan MacDonald Acked-by: Paul Cercueil Link: https://lore.kernel.org/r/20220706211330.120198-3-aidanmacdonald.0x0@gmail.com Signed-off-by: Mark Brown --- sound/soc/jz4740/jz4740-i2s.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 298ff0a839319..ecd8df70d39c5 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -95,7 +95,6 @@ struct i2s_soc_info { struct jz4740_i2s { struct resource *mem; void __iomem *base; - dma_addr_t phys_base; struct clk *clk_aic; struct clk *clk_i2s; @@ -370,21 +369,6 @@ static int jz4740_i2s_resume(struct snd_soc_component *component) return 0; } -static void jz4740_i2s_init_pcm_config(struct jz4740_i2s *i2s) -{ - struct snd_dmaengine_dai_dma_data *dma_data; - - /* Playback */ - dma_data = &i2s->playback_dma_data; - dma_data->maxburst = 16; - dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; - - /* Capture */ - dma_data = &i2s->capture_dma_data; - dma_data->maxburst = 16; - dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; -} - static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); @@ -395,7 +379,6 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) if (ret) return ret; - jz4740_i2s_init_pcm_config(i2s); snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, &i2s->capture_dma_data); @@ -529,7 +512,11 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev) if (IS_ERR(i2s->base)) return PTR_ERR(i2s->base); - i2s->phys_base = mem->start; + i2s->playback_dma_data.maxburst = 16; + i2s->playback_dma_data.addr = mem->start + JZ_REG_AIC_FIFO; + + i2s->capture_dma_data.maxburst = 16; + i2s->capture_dma_data.addr = mem->start + JZ_REG_AIC_FIFO; i2s->clk_aic = devm_clk_get(dev, "aic"); if (IS_ERR(i2s->clk_aic)) -- GitLab From 050237e6b0bea0fafbf7d3d57e717c6fa1e4e819 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 7 Jul 2022 19:20:06 +0800 Subject: [PATCH 821/942] ASoC: fsl_utils: Don't use plain integer as NULL pointer Fix sparse warning: sound/soc/fsl/fsl_utils.c:125:31: sparse: warning: Using plain integer as NULL pointer sound/soc/fsl/fsl_utils.c:125:42: sparse: warning: Using plain integer as NULL pointer Fixes: 7bad8125549c ("ASoC: fsl_utils: Add function to handle PLL clock source") Reported-by: kernel test robot Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1657192806-10569-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index b75843e31f004..3e969c7bc1c52 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c @@ -122,7 +122,7 @@ void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk, struct clk *pll8k_clk, struct clk *pll11k_clk, u64 ratio) { - struct clk *p, *pll = 0, *npll = 0; + struct clk *p, *pll = NULL, *npll = NULL; bool reparent = false; int ret = 0; -- GitLab From 817a62108dfacebd548e38451bf0e7eee023e97f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:14 +0000 Subject: [PATCH 822/942] ASoC: audio-graph-card2.c: use of_property_read_u32() for rate Audio Graph Card2 is using of_get_property(), but it should use of_property_read_u32() to getting rate. Otherwise the setting will be strange value. This patch fixup it. Fixes: c3a15c92a67b701 ("ASoC: audio-graph-card2: add Codec2Codec support") Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87h741s961.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index d34b29a49268e..8e0628e6f2a0f 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -856,7 +856,7 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, struct device_node *port0, *port1, *ports; struct device_node *codec0_port, *codec1_port; struct device_node *ep0, *ep1; - u32 val; + u32 val = 0; int ret = -EINVAL; /* @@ -880,7 +880,8 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, ports = of_get_parent(port0); port1 = of_get_next_child(ports, lnk); - if (!of_get_property(ports, "rate", &val)) { + of_property_read_u32(ports, "rate", &val); + if (!val) { struct device *dev = simple_priv_to_dev(priv); dev_err(dev, "Codec2Codec needs rate settings\n"); -- GitLab From c2ff7f15a4ef74b8cb6d425dfa8d8b928f193a80 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:21 +0000 Subject: [PATCH 823/942] ASoC: audio-graph-card2.c: make Codec2Codec settings optional Current audio-graph-card2 can use Codec2Codec, and having its original parameter (= rate) on DT is mandatory for now. But simple-card-utils.c has asoc_simple_init_for_codec2codec() to setup *default* Codec2Codec settings. This patch makes Audio Graph Card2 Codec2Codec rate settings optional. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87fsjls95u.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- .../audio-graph-card2-custom-sample.dtsi | 3 +- sound/soc/generic/audio-graph-card2.c | 36 +++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi index 8eee7b821ff74..053d987a1feca 100644 --- a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi +++ b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi @@ -154,11 +154,12 @@ codec2codec { ports@0 { - rate = <48000>; + /* use default settings */ c2c: port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec6_ep>; }; }; port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec7_ep>; }; }; }; ports@1 { + /* use original settings */ rate = <48000>; c2c_m: port@0 { c2cmf_ep: endpoint { remote-endpoint = <&mc2c0_ep>; }; }; port@1 { c2cmb_ep: endpoint { remote-endpoint = <&mc2c1_ep>; }; }; diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 8e0628e6f2a0f..510058c47a921 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -851,8 +851,6 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, struct link_info *li) { struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); - struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); - struct snd_soc_pcm_stream *c2c_conf = dai_props->c2c_conf; struct device_node *port0, *port1, *ports; struct device_node *codec0_port, *codec1_port; struct device_node *ep0, *ep1; @@ -880,21 +878,30 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, ports = of_get_parent(port0); port1 = of_get_next_child(ports, lnk); + /* + * Card2 can use original Codec2Codec settings if DT has. + * It will use default settings if no settings on DT. + * see + * asoc_simple_init_for_codec2codec() + * + * Add more settings here if needed + */ of_property_read_u32(ports, "rate", &val); - if (!val) { - struct device *dev = simple_priv_to_dev(priv); - - dev_err(dev, "Codec2Codec needs rate settings\n"); - goto err1; + if (val) { + struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); + struct snd_soc_pcm_stream *c2c_conf = dai_props->c2c_conf; + + c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ + c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; + c2c_conf->rate_min = + c2c_conf->rate_max = val; + c2c_conf->channels_min = + c2c_conf->channels_max = 2; /* update ME */ + + dai_link->params = c2c_conf; + dai_link->num_params = 1; } - c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ - c2c_conf->rate_min = - c2c_conf->rate_max = val; - c2c_conf->channels_min = - c2c_conf->channels_max = 2; /* update ME */ - dai_link->params = c2c_conf; - ep0 = port_to_endpoint(port0); ep1 = port_to_endpoint(port1); @@ -923,7 +930,6 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, of_node_put(ep1); of_node_put(codec0_port); of_node_put(codec1_port); -err1: of_node_put(ports); of_node_put(port0); of_node_put(port1); -- GitLab From 6976ed0137d98c2ec0f11af8a01716e9f3af873d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:27 +0000 Subject: [PATCH 824/942] ASoC: audio-graph-card2.c: remove pre-alloced Codec2Codec space Because Codec2Codec settings becomes optional, we don't need to keep its parameter space when init time. This patch removes its default memory allocation from simple-card-utils.c, and allocate it at audio-graph-card2 ondemand. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87edz5s95o.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/simple_card_utils.h | 3 --- sound/soc/generic/audio-graph-card2.c | 10 +++++++--- sound/soc/generic/simple-card-utils.c | 18 +----------------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index fe2337fde1f46..ab55f40896e0a 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -51,7 +51,6 @@ struct prop_nums { int cpus; int codecs; int platforms; - int c2c; }; struct asoc_simple_priv { @@ -64,7 +63,6 @@ struct asoc_simple_priv { struct snd_soc_dai_link_component *platforms; struct asoc_simple_data adata; struct snd_soc_codec_conf *codec_conf; - struct snd_soc_pcm_stream *c2c_conf; struct prop_nums num; unsigned int mclk_fs; } *dai_props; @@ -75,7 +73,6 @@ struct asoc_simple_priv { struct snd_soc_dai_link_component *dlcs; struct snd_soc_dai_link_component dummy; struct snd_soc_codec_conf *codec_conf; - struct snd_soc_pcm_stream *c2c_conf; struct gpio_desc *pa_gpio; const struct snd_soc_ops *ops; unsigned int dpcm_selectable:1; diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 510058c47a921..19e31d53422ab 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -888,8 +888,12 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, */ of_property_read_u32(ports, "rate", &val); if (val) { - struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); - struct snd_soc_pcm_stream *c2c_conf = dai_props->c2c_conf; + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_pcm_stream *c2c_conf; + + c2c_conf = devm_kzalloc(dev, sizeof(*c2c_conf), GFP_KERNEL); + if (!c2c_conf) + goto err1; c2c_conf->formats = SNDRV_PCM_FMTBIT_S32_LE; /* update ME */ c2c_conf->rates = SNDRV_PCM_RATE_8000_384000; @@ -930,6 +934,7 @@ int audio_graph2_link_c2c(struct asoc_simple_priv *priv, of_node_put(ep1); of_node_put(codec0_port); of_node_put(codec1_port); +err1: of_node_put(ports); of_node_put(port0); of_node_put(port1); @@ -1093,7 +1098,6 @@ static int graph_count_c2c(struct asoc_simple_priv *priv, li->num[li->link].cpus = li->num[li->link].platforms = graph_counter(codec0); li->num[li->link].codecs = graph_counter(codec1); - li->num[li->link].c2c = 1; of_node_put(ports); of_node_put(port1); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 7be84c7840cbb..a761af6b13b62 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -746,8 +746,7 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, struct asoc_simple_dai *dais; struct snd_soc_dai_link_component *dlcs; struct snd_soc_codec_conf *cconf = NULL; - struct snd_soc_pcm_stream *c2c_conf = NULL; - int i, dai_num = 0, dlc_num = 0, cnf_num = 0, c2c_num = 0; + int i, dai_num = 0, dlc_num = 0, cnf_num = 0; dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL); dai_link = devm_kcalloc(dev, li->link, sizeof(*dai_link), GFP_KERNEL); @@ -766,8 +765,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, if (!li->num[i].cpus) cnf_num += li->num[i].codecs; - - c2c_num += li->num[i].c2c; } dais = devm_kcalloc(dev, dai_num, sizeof(*dais), GFP_KERNEL); @@ -781,12 +778,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, return -ENOMEM; } - if (c2c_num) { - c2c_conf = devm_kcalloc(dev, c2c_num, sizeof(*c2c_conf), GFP_KERNEL); - if (!c2c_conf) - return -ENOMEM; - } - dev_dbg(dev, "link %d, dais %d, ccnf %d\n", li->link, dai_num, cnf_num); @@ -800,7 +791,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, priv->dais = dais; priv->dlcs = dlcs; priv->codec_conf = cconf; - priv->c2c_conf = c2c_conf; card->dai_link = priv->dai_link; card->num_links = li->link; @@ -818,12 +808,6 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, dlcs += li->num[i].cpus; dais += li->num[i].cpus; - - if (li->num[i].c2c) { - /* Codec2Codec */ - dai_props[i].c2c_conf = c2c_conf; - c2c_conf += li->num[i].c2c; - } } else { /* DPCM Be's CPU = dummy */ dai_props[i].cpus = -- GitLab From d33083f941150dc2079975d032547f6ce9a8e81b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:34 +0000 Subject: [PATCH 825/942] ASoC: audio-graph-card2-custom-sample.dtsi: add verbose explanation audio-graph-card2-custom-sample.dtsi will be used to test Audio-Graph-Card2 behavior. But it is difficult to say that it is easy to understand, because the comment/explanation are not so many. This patch add verbose explanation to it. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87czeps95h.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- .../audio-graph-card2-custom-sample.dtsi | 98 +++++++++++++++++-- 1 file changed, 90 insertions(+), 8 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi index 053d987a1feca..fe547c18771ff 100644 --- a/sound/soc/generic/audio-graph-card2-custom-sample.dtsi +++ b/sound/soc/generic/audio-graph-card2-custom-sample.dtsi @@ -17,6 +17,23 @@ * CONFIG_SND_AUDIO_GRAPH_CARD2 * CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE * CONFIG_SND_TEST_COMPONENT + * + * + * You can indicate more detail each device behavior as debug if you modify + * "compatible" on each test-component. see below + * + * test_cpu { + * - compatible = "test-cpu"; + * + compatible = "test-cpu-verbose"; + * ... + * }; + * + * test_codec { + * - compatible = "test-codec"; + * + compatible = "test-codec-verbose"; + * ... + * }; + * */ / { /* @@ -101,35 +118,74 @@ "TC OUT", "TC DAI11 Playback", "TC DAI9 Capture", "TC IN"; - links = <&cpu0 /* normal: cpu side only */ - &mcpu0 /* multi: cpu side only */ - &fe00 &fe01 &be0 /* dpcm: both FE / BE */ - &fe10 &fe11 &be1 /* dpcm-m: both FE / BE */ - &c2c /* c2c: cpu side only */ - &c2c_m /* c2c: cpu side only */ + links = < + /* + * [Normal]: cpu side only + * cpu0/codec0 + */ + &cpu0 + + /* + * [Multi-CPU/Codec]: cpu side only + * cpu1/cpu2/codec1/codec2 + */ + &mcpu0 + + /* + * [DPCM]: both FE / BE + * cpu3/cpu4/codec3 + */ + &fe00 &fe01 &be0 + + /* + * [DPCM-Multi]: both FE / BE + * cpu5/cpu6/codec4/codec5 + */ + &fe10 &fe11 &be1 + + /* + * [Codec2Codec]: cpu side only + * codec6/codec7 + */ + &c2c + + /* + * [Codec2Codec-Multi]: cpu side only + * codec8/codec9/codec10/codec11 + */ + &c2c_m >; multi { ports@0 { + /* [Multi-CPU] */ mcpu0: port@0 { mcpu0_ep: endpoint { remote-endpoint = <&mcodec0_ep>; }; }; port@1 { mcpu1_ep: endpoint { remote-endpoint = <&cpu1_ep>; }; }; port@2 { mcpu2_ep: endpoint { remote-endpoint = <&cpu2_ep>; }; }; }; + + /* [Multi-Codec] */ ports@1 { port@0 { mcodec0_ep: endpoint { remote-endpoint = <&mcpu0_ep>; }; }; port@1 { mcodec1_ep: endpoint { remote-endpoint = <&codec1_ep>; }; }; port@2 { mcodec2_ep: endpoint { remote-endpoint = <&codec2_ep>; }; }; }; + + /* [DPCM-Multi]::BE */ ports@2 { port@0 { mbe_ep: endpoint { remote-endpoint = <&be10_ep>; }; }; port@1 { mbe1_ep: endpoint { remote-endpoint = <&codec4_ep>; }; }; port@2 { mbe2_ep: endpoint { remote-endpoint = <&codec5_ep>; }; }; }; + + /* [Codec2Codec-Multi]::CPU */ ports@3 { port@0 { mc2c0_ep: endpoint { remote-endpoint = <&c2cmf_ep>; }; }; port@1 { mc2c00_ep: endpoint { remote-endpoint = <&codec8_ep>; }; }; port@2 { mc2c01_ep: endpoint { remote-endpoint = <&codec9_ep>; }; }; }; + + /* [Codec2Codec-Multi]::Codec */ ports@4 { port@0 { mc2c1_ep: endpoint { remote-endpoint = <&c2cmb_ep>; }; }; port@1 { mc2c10_ep: endpoint { remote-endpoint = <&codec10_ep>; }; }; @@ -138,26 +194,34 @@ }; dpcm { - /* FE */ ports@0 { + /* [DPCM]::FE */ fe00: port@0 { fe00_ep: endpoint { remote-endpoint = <&cpu3_ep>; }; }; fe01: port@1 { fe01_ep: endpoint { remote-endpoint = <&cpu4_ep>; }; }; + + /* [DPCM-Multi]::FE */ fe10: port@2 { fe10_ep: endpoint { remote-endpoint = <&cpu5_ep>; }; }; fe11: port@3 { fe11_ep: endpoint { remote-endpoint = <&cpu6_ep>; }; }; }; - /* BE */ + ports@1 { + /* [DPCM]::BE */ be0: port@0 { be00_ep: endpoint { remote-endpoint = <&codec3_ep>; }; }; + + /* [DPCM-Multi]::BE */ be1: port@1 { be10_ep: endpoint { remote-endpoint = <&mbe_ep>; }; }; }; }; codec2codec { + /* [Codec2Codec] */ ports@0 { /* use default settings */ c2c: port@0 { c2cf_ep: endpoint { remote-endpoint = <&codec6_ep>; }; }; port@1 { c2cb_ep: endpoint { remote-endpoint = <&codec7_ep>; }; }; }; + + /* [Codec2Codec-Multi] */ ports@1 { /* use original settings */ rate = <48000>; @@ -180,11 +244,18 @@ ports { bitclock-master; frame-master; + /* [Normal] */ cpu0: port@0 { cpu0_ep: endpoint { remote-endpoint = <&codec0_ep>; }; }; + + /* [Multi-CPU] */ port@1 { cpu1_ep: endpoint { remote-endpoint = <&mcpu1_ep>; }; }; port@2 { cpu2_ep: endpoint { remote-endpoint = <&mcpu2_ep>; }; }; + + /* [DPCM]::FE */ port@3 { cpu3_ep: endpoint { remote-endpoint = <&fe00_ep>; }; }; port@4 { cpu4_ep: endpoint { remote-endpoint = <&fe01_ep>; }; }; + + /* [DPCM-Multi]::FE */ port@5 { cpu5_ep: endpoint { remote-endpoint = <&fe10_ep>; }; }; port@6 { cpu6_ep: endpoint { remote-endpoint = <&fe11_ep>; }; }; }; @@ -207,16 +278,27 @@ */ prefix = "TC"; + /* [Normal] */ port@0 { codec0_ep: endpoint { remote-endpoint = <&cpu0_ep>; }; }; + + /* [Multi-Codec] */ port@1 { codec1_ep: endpoint { remote-endpoint = <&mcodec1_ep>; }; }; port@2 { codec2_ep: endpoint { remote-endpoint = <&mcodec2_ep>; }; }; + + /* [DPCM]::BE */ port@3 { codec3_ep: endpoint { remote-endpoint = <&be00_ep>; }; }; + + /* [DPCM-Multi]::BE */ port@4 { codec4_ep: endpoint { remote-endpoint = <&mbe1_ep>; }; }; port@5 { codec5_ep: endpoint { remote-endpoint = <&mbe2_ep>; }; }; + + /* [Codec2Codec] */ port@6 { bitclock-master; frame-master; codec6_ep: endpoint { remote-endpoint = <&c2cf_ep>; }; }; port@7 { codec7_ep: endpoint { remote-endpoint = <&c2cb_ep>; }; }; + + /* [Codec2Codec-Multi] */ port@8 { bitclock-master; frame-master; codec8_ep: endpoint { remote-endpoint = <&mc2c00_ep>; }; }; -- GitLab From 75d1b39067ed6699ec8a906fa9d83609bca9113b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:40 +0000 Subject: [PATCH 826/942] ASoC: simple-card-utils.c: ignore Codec2Codec setting if it already have Audio Graph Card2 setups own Codec2Codec settings, but current simple-card-utils.c will try to setup Codec2Codec default settings if needed, it will overwirtes the settings. This patch ignores default Codec2Codec settings if it already have. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87bku9s95b.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index a761af6b13b62..b8a3da692ee84 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -527,6 +527,10 @@ static int asoc_simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hardware hw; int i, ret, stream; + /* Do nothing if it already has Codec2Codec settings */ + if (dai_link->params) + return 0; + /* Only Codecs */ for_each_rtd_components(rtd, i, component) { if (!asoc_simple_component_is_codec(component)) -- GitLab From 16b7ba9c0f53032e2a9365f3de89b66426b5716c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 1 Jul 2022 05:18:51 +0000 Subject: [PATCH 827/942] ASoC: simple-card-utils.c: care Codec2Codec vs DPCM:BE Current asoc_simple_init_for_codec2codec() adds default Codec2Codec settings if rtd was Codec only. But DPCM:BE also judged as Codec only, because dummy-DAI doesn't have "endianness" (which is key parameter to judge as Codec). This patch ignores setup Codec2Codec settings if it was DPCM:BE case. Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87a69ts950.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index b8a3da692ee84..4a29e314fa953 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -531,6 +531,10 @@ static int asoc_simple_init_for_codec2codec(struct snd_soc_pcm_runtime *rtd, if (dai_link->params) return 0; + /* Do nothing if it was DPCM :: BE */ + if (dai_link->no_pcm) + return 0; + /* Only Codecs */ for_each_rtd_components(rtd, i, component) { if (!asoc_simple_component_is_codec(component)) -- GitLab From f460e3a9740b8c1ec5a9a034262674514bbbdcac Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 7 Jul 2022 16:46:14 -0500 Subject: [PATCH 828/942] ASoC: amd: acp-es8336: use static variables Sparse warnings: sound/soc/amd/acp-es8336.c:36:15: error: symbol 'codec_dev' was not declared. Should it be static? sound/soc/amd/acp-es8336.c:37:18: error: symbol 'gpio_pa' was not declared. Should it be static? Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220707214614.61081-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index eec3d57092fa3..4f3992532332c 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -33,8 +33,8 @@ static unsigned long acp2x_machine_id; static struct snd_soc_jack st_jack; -struct device *codec_dev; -struct gpio_desc *gpio_pa; +static struct device *codec_dev; +static struct gpio_desc *gpio_pa; static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -- GitLab From d7e5d8d24c1179b36a3cb40b3f785e23a8992acd Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 7 Jul 2022 18:56:08 +0530 Subject: [PATCH 829/942] ASoC: amd: remove unused header file inclusion Removed unused header file inclusion from Jadeite platform machine driver. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20220707132613.3150931-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index 4f3992532332c..54ba399fe5968 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -23,7 +23,6 @@ #include #include -#include "../codecs/es8316.h" #include "acp.h" #define DUAL_CHANNEL 2 -- GitLab From 8d9cd3ead42a6d3bac131c4331acfa5244674fbb Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 7 Jul 2022 18:56:09 +0530 Subject: [PATCH 830/942] ASoC: amd: drop machine driver remove function Drop machine driver remove() function. Signed-off-by: Vijendar Mukunda Link: https://lore.kernel.org/r/20220707132613.3150931-2-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index 54ba399fe5968..a9997627f991b 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -293,11 +293,6 @@ static int st_es8336_probe(struct platform_device *pdev) return 0; } -static int st_es8336_remove(struct platform_device *pdev) -{ - return 0; -} - #ifdef CONFIG_ACPI static const struct acpi_device_id st_audio_acpi_match[] = { {"AMDI8336", 0}, @@ -313,7 +308,6 @@ static struct platform_driver st_mach_driver = { .pm = &snd_soc_pm_ops, }, .probe = st_es8336_probe, - .remove = st_es8336_remove, }; module_platform_driver(st_mach_driver); -- GitLab From 0de876c125188e502d2899de4bcba8d4a6b1f98c Mon Sep 17 00:00:00 2001 From: Vijendar Mukunda Date: Thu, 7 Jul 2022 18:56:10 +0530 Subject: [PATCH 831/942] ASoC: amd: fix for variable set but not used warning Fix below kernel warning. >>> sound/soc/amd/acp-es8336.c:200:13: warning: variable 'ret' set but >>> not used [-Wunused-but-set-variable] Signed-off-by: Vijendar Mukunda Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220707132613.3150931-3-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index a9997627f991b..ebd4fa9f1f004 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -206,6 +206,8 @@ static int st_es8336_late_probe(struct snd_soc_card *card) dev_err(card->dev, "can not find codec dev\n"); ret = devm_acpi_dev_add_driver_gpios(codec_dev, acpi_es8336_gpios); + if (ret) + dev_warn(card->dev, "Failed to add driver gpios\n"); gpio_pa = gpiod_get_optional(codec_dev, "pa-enable", GPIOD_OUT_LOW); if (IS_ERR(gpio_pa)) { @@ -213,6 +215,7 @@ static int st_es8336_late_probe(struct snd_soc_card *card) "could not get pa-enable GPIO\n"); gpiod_put(gpio_pa); put_device(codec_dev); + return ret; } return 0; } -- GitLab From eae9f9ce181be4f47dcba1ee93185b71cac3f312 Mon Sep 17 00:00:00 2001 From: Raphael-Xu <13691752556@139.com> Date: Thu, 7 Jul 2022 20:33:42 +0800 Subject: [PATCH 832/942] ASoC: add tas2780 driver 1.update Kconfig and Makefile 2.add tas2780.c and tas2780.h Signed-off-by: Raphael-Xu <13691752556@139.com> Link: https://lore.kernel.org/r/20220707123343.2403-1-13691752556@139.com Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 8 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tas2780.c | 663 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/tas2780.h | 101 ++++++ 4 files changed, 774 insertions(+) create mode 100644 sound/soc/codecs/tas2780.c create mode 100644 sound/soc/codecs/tas2780.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ee7e028e84024..d16b4efb88a77 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -219,6 +219,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_TAS2562 imply SND_SOC_TAS2764 imply SND_SOC_TAS2770 + imply SND_SOC_TAS2780 imply SND_SOC_TAS5086 imply SND_SOC_TAS571X imply SND_SOC_TAS5720 @@ -1535,6 +1536,13 @@ config SND_SOC_TAS2770 tristate "Texas Instruments TAS2770 speaker amplifier" depends on I2C +config SND_SOC_TAS2780 + tristate "Texas Instruments TAS2780 Mono Audio amplifier" + depends on I2C + help + Enable support for Texas Instruments TAS2780 high-efficiency + digital input mono Class-D audio power amplifiers. + config SND_SOC_TAS5086 tristate "Texas Instruments TAS5086 speaker amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 60354579fe5ca..92fd441d426a8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -348,6 +348,7 @@ snd-soc-tpa6130a2-objs := tpa6130a2.o snd-soc-tas2552-objs := tas2552.o snd-soc-tas2562-objs := tas2562.o snd-soc-tas2764-objs := tas2764.o +snd-soc-tas2780-objs := tas2780.o # Mux snd-soc-simple-mux-objs := simple-mux.o @@ -592,6 +593,7 @@ obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2562) += snd-soc-tas2562.o obj-$(CONFIG_SND_SOC_TAS2764) += snd-soc-tas2764.o +obj-$(CONFIG_SND_SOC_TAS2780) += snd-soc-tas2780.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o diff --git a/sound/soc/codecs/tas2780.c b/sound/soc/codecs/tas2780.c new file mode 100644 index 0000000000000..a6db6f0e5431f --- /dev/null +++ b/sound/soc/codecs/tas2780.c @@ -0,0 +1,663 @@ +// SPDX-License-Identifier: GPL-2.0 +// Driver for the Texas Instruments TAS2780 Mono +// Audio amplifier +// Copyright (C) 2022 Texas Instruments Inc. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2780.h" + +struct tas2780_priv { + struct snd_soc_component *component; + struct gpio_desc *reset_gpio; + struct regmap *regmap; + struct device *dev; + int v_sense_slot; + int i_sense_slot; +}; + +static void tas2780_reset(struct tas2780_priv *tas2780) +{ + int ret = 0; + + if (tas2780->reset_gpio) { + gpiod_set_value_cansleep(tas2780->reset_gpio, 0); + usleep_range(2000, 2050); + gpiod_set_value_cansleep(tas2780->reset_gpio, 1); + usleep_range(2000, 2050); + } + + snd_soc_component_write(tas2780->component, TAS2780_SW_RST, + TAS2780_RST); + if (ret) + dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n", + __func__, ret); +} + +#ifdef CONFIG_PM +static int tas2780_codec_suspend(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_SHUTDOWN); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", + __func__, ret); + goto err; + } + ret = 0; + regcache_cache_only(tas2780->regmap, true); + regcache_mark_dirty(tas2780->regmap); +err: + return ret; +} + +static int tas2780_codec_resume(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_ACTIVE); + + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", + __func__, ret); + goto err; + } + ret = 0; + regcache_cache_only(tas2780->regmap, false); + ret = regcache_sync(tas2780->regmap); +err: + return ret; +} +#endif + +static const char * const tas2780_ASI1_src[] = { + "I2C offset", "Left", "Right", "LeftRightDiv2", +}; + +static SOC_ENUM_SINGLE_DECL( + tas2780_ASI1_src_enum, TAS2780_TDM_CFG2, 4, tas2780_ASI1_src); + +static const struct snd_kcontrol_new tas2780_asi1_mux = + SOC_DAPM_ENUM("ASI1 Source", tas2780_ASI1_src_enum); + +static const struct snd_kcontrol_new isense_switch = + SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, + TAS2780_ISENSE_POWER_EN, 1, 1); +static const struct snd_kcontrol_new vsense_switch = + SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, + TAS2780_VSENSE_POWER_EN, 1, 1); + +static const struct snd_soc_dapm_widget tas2780_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2780_asi1_mux), + SND_SOC_DAPM_SWITCH("ISENSE", TAS2780_PWR_CTRL, + TAS2780_ISENSE_POWER_EN, 1, &isense_switch), + SND_SOC_DAPM_SWITCH("VSENSE", TAS2780_PWR_CTRL, + TAS2780_VSENSE_POWER_EN, 1, &vsense_switch), + SND_SOC_DAPM_OUTPUT("OUT"), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON") +}; + +static const struct snd_soc_dapm_route tas2780_audio_map[] = { + {"ASI1 Sel", "I2C offset", "ASI1"}, + {"ASI1 Sel", "Left", "ASI1"}, + {"ASI1 Sel", "Right", "ASI1"}, + {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, + {"OUT", NULL, "ASI1 Sel"}, + {"ISENSE", "Switch", "IMON"}, + {"VSENSE", "Switch", "VMON"}, +}; + +static int tas2780_mute(struct snd_soc_dai *dai, int mute, int direction) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, + TAS2780_PWR_CTRL_MASK, + mute ? TAS2780_PWR_CTRL_MUTE : 0); + if (ret < 0) { + dev_err(tas2780->dev, "%s: Failed to set powercontrol\n", + __func__); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_bitwidth(struct tas2780_priv *tas2780, int bitwidth) +{ + struct snd_soc_component *component = tas2780->component; + int sense_en; + int val; + int ret; + int slot_size; + + switch (bitwidth) { + case SNDRV_PCM_FORMAT_S16_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_16BITS); + slot_size = TAS2780_TDM_CFG2_RXS_16BITS; + break; + case SNDRV_PCM_FORMAT_S24_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_24BITS); + slot_size = TAS2780_TDM_CFG2_RXS_24BITS; + break; + case SNDRV_PCM_FORMAT_S32_LE: + ret = snd_soc_component_update_bits(component, + TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXW_MASK, + TAS2780_TDM_CFG2_RXW_32BITS); + slot_size = TAS2780_TDM_CFG2_RXS_32BITS; + break; + + default: + ret = -EINVAL; + } + + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x set bitwidth error\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXS_MASK, slot_size); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x set RX slot size error\n", + __func__, ret); + goto err; + } + + val = snd_soc_component_read(tas2780->component, TAS2780_PWR_CTRL); + if (val < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x read PWR_CTRL error\n", + __func__, val); + ret = val; + goto err; + } + + if (val & (1 << TAS2780_VSENSE_POWER_EN)) + sense_en = 0; + else + sense_en = TAS2780_TDM_CFG5_VSNS_ENABLE; + + ret = snd_soc_component_update_bits(tas2780->component, + TAS2780_TDM_CFG5, TAS2780_TDM_CFG5_VSNS_ENABLE, sense_en); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x enable vSNS error\n", + __func__, ret); + goto err; + } + + if (val & (1 << TAS2780_ISENSE_POWER_EN)) + sense_en = 0; + else + sense_en = TAS2780_TDM_CFG6_ISNS_ENABLE; + + ret = snd_soc_component_update_bits(tas2780->component, + TAS2780_TDM_CFG6, TAS2780_TDM_CFG6_ISNS_ENABLE, sense_en); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x enable iSNS error\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_samplerate( + struct tas2780_priv *tas2780, int samplerate) +{ + struct snd_soc_component *component = tas2780->component; + int ramp_rate_val; + int ret; + + switch (samplerate) { + case 48000: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | + TAS2780_TDM_CFG0_44_1_48KHZ; + break; + case 44100: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | + TAS2780_TDM_CFG0_44_1_48KHZ; + break; + case 96000: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | + TAS2780_TDM_CFG0_88_2_96KHZ; + break; + case 88200: + ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | + TAS2780_TDM_CFG0_88_2_96KHZ; + break; + default: + return -EINVAL; + } + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG0, + TAS2780_TDM_CFG0_SMP_MASK | TAS2780_TDM_CFG0_MASK, + ramp_rate_val); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set ramp_rate_val\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret; + + ret = tas2780_set_bitwidth(tas2780, params_format(params)); + if (ret < 0) + return ret; + + return tas2780_set_samplerate(tas2780, params_rate(params)); +} + +static int tas2780_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; + int iface; + int ret = 0; + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + asi_cfg_1 = TAS2780_TDM_CFG1_RX_RISING; + break; + case SND_SOC_DAIFMT_IB_NF: + asi_cfg_1 = TAS2780_TDM_CFG1_RX_FALLING; + break; + default: + dev_err(tas2780->dev, "ASI format Inverse is not found\n"); + return -EINVAL; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, + TAS2780_TDM_CFG1_RX_MASK, asi_cfg_1); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set asi_cfg_1\n", + __func__, ret); + goto err; + } + + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) + || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_DSP_A)){ + iface = TAS2780_TDM_CFG2_SCFG_I2S; + tdm_rx_start_slot = 1; + } else { + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_DSP_B) + || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) + == SND_SOC_DAIFMT_LEFT_J)) { + iface = TAS2780_TDM_CFG2_SCFG_LEFT_J; + tdm_rx_start_slot = 0; + } else { + dev_err(tas2780->dev, + "%s:DAI Format is not found, fmt=0x%x\n", + __func__, fmt); + ret = -EINVAL; + goto err; + } + } + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, + TAS2780_TDM_CFG1_MASK, + (tdm_rx_start_slot << TAS2780_TDM_CFG1_51_SHIFT)); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set tdm_rx_start_slot\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_SCFG_MASK, iface); + if (ret < 0) { + dev_err(tas2780->dev, "%s:errCode:0x%x Failed to set iface\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, + unsigned int rx_mask, + int slots, int slot_width) +{ + struct snd_soc_component *component = dai->component; + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int left_slot, right_slot; + int slots_cfg; + int slot_size; + int ret = 0; + + if (tx_mask == 0 || rx_mask != 0) + return -EINVAL; + + if (slots == 1) { + if (tx_mask != 1) + return -EINVAL; + left_slot = 0; + right_slot = 0; + } else { + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); + if (tx_mask == 0) { + right_slot = left_slot; + } else { + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); + } + } + + if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) + return -EINVAL; + + slots_cfg = (right_slot << TAS2780_TDM_CFG3_RXS_SHIFT) | left_slot; + ret = snd_soc_component_write(component, TAS2780_TDM_CFG3, slots_cfg); + if (ret) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set slots_cfg\n", + __func__, ret); + goto err; + } + + switch (slot_width) { + case 16: + slot_size = TAS2780_TDM_CFG2_RXS_16BITS; + break; + case 24: + slot_size = TAS2780_TDM_CFG2_RXS_24BITS; + break; + case 32: + slot_size = TAS2780_TDM_CFG2_RXS_32BITS; + break; + default: + ret = -EINVAL; + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, + TAS2780_TDM_CFG2_RXS_MASK, slot_size); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set slot_size\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG5, + TAS2780_TDM_CFG5_50_MASK, tas2780->v_sense_slot); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set v_sense_slot\n", + __func__, ret); + goto err; + } + + ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG6, + TAS2780_TDM_CFG6_50_MASK, tas2780->i_sense_slot); + if (ret < 0) { + dev_err(tas2780->dev, + "%s:errCode:0x%x Failed to set i_sense_slot\n", + __func__, ret); + goto err; + } + ret = 0; +err: + return ret; +} + +static const struct snd_soc_dai_ops tas2780_dai_ops = { + .mute_stream = tas2780_mute, + .hw_params = tas2780_hw_params, + .set_fmt = tas2780_set_fmt, + .set_tdm_slot = tas2780_set_dai_tdm_slot, + .no_capture_mute = 1, +}; + +#define TAS2780_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +#define TAS2780_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) + +static struct snd_soc_dai_driver tas2780_dai_driver[] = { + { + .name = "tas2780 ASI1", + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = TAS2780_RATES, + .formats = TAS2780_FORMATS, + }, + .capture = { + .stream_name = "ASI1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = TAS2780_RATES, + .formats = TAS2780_FORMATS, + }, + .ops = &tas2780_dai_ops, + .symmetric_rate = 1, + }, +}; + +static int tas2780_codec_probe(struct snd_soc_component *component) +{ + struct tas2780_priv *tas2780 = + snd_soc_component_get_drvdata(component); + int ret = 0; + + tas2780->component = component; + + tas2780_reset(tas2780); + ret = snd_soc_component_update_bits(component, + TAS2780_IC_CFG, TAS2780_IC_CFG_MASK, + TAS2780_IC_CFG_ENABLE); + if (ret < 0) + dev_err(tas2780->dev, "%s:errCode:0x%0x\n", + __func__, ret); + + return ret; +} + +static DECLARE_TLV_DB_SCALE(tas2780_digital_tlv, 1100, 50, 0); +static DECLARE_TLV_DB_SCALE(tas2780_playback_volume, -10000, 50, 0); + +static const struct snd_kcontrol_new tas2780_snd_controls[] = { + SOC_SINGLE_TLV("Speaker Volume", TAS2780_DVC, 0, + TAS2780_DVC_MAX, 1, tas2780_playback_volume), + SOC_SINGLE_TLV("Amp Gain Volume", TAS2780_CHNL_0, 0, 0x14, 0, + tas2780_digital_tlv), +}; + +static const struct snd_soc_component_driver soc_component_driver_tas2780 = { + .probe = tas2780_codec_probe, +#ifdef CONFIG_PM + .suspend = tas2780_codec_suspend, + .resume = tas2780_codec_resume, +#endif + .controls = tas2780_snd_controls, + .num_controls = ARRAY_SIZE(tas2780_snd_controls), + .dapm_widgets = tas2780_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tas2780_dapm_widgets), + .dapm_routes = tas2780_audio_map, + .num_dapm_routes = ARRAY_SIZE(tas2780_audio_map), + .idle_bias_on = 1, + .endianness = 1, +}; + +static const struct reg_default tas2780_reg_defaults[] = { + { TAS2780_PAGE, 0x00 }, + { TAS2780_SW_RST, 0x00 }, + { TAS2780_PWR_CTRL, 0x1a }, + { TAS2780_DVC, 0x00 }, + { TAS2780_CHNL_0, 0x00 }, + { TAS2780_TDM_CFG0, 0x09 }, + { TAS2780_TDM_CFG1, 0x02 }, + { TAS2780_TDM_CFG2, 0x0a }, + { TAS2780_TDM_CFG3, 0x10 }, + { TAS2780_TDM_CFG5, 0x42 }, +}; + +static const struct regmap_range_cfg tas2780_regmap_ranges[] = { + { + .range_min = 0, + .range_max = 1 * 128, + .selector_reg = TAS2780_PAGE, + .selector_mask = 0xff, + .selector_shift = 0, + .window_start = 0, + .window_len = 128, + }, +}; + +static const struct regmap_config tas2780_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .reg_defaults = tas2780_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tas2780_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .ranges = tas2780_regmap_ranges, + .num_ranges = ARRAY_SIZE(tas2780_regmap_ranges), + .max_register = 1 * 128, +}; + +static int tas2780_parse_dt(struct device *dev, struct tas2780_priv *tas2780) +{ + int ret = 0; + + tas2780->reset_gpio = devm_gpiod_get_optional(tas2780->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(tas2780->reset_gpio)) { + if (PTR_ERR(tas2780->reset_gpio) == -EPROBE_DEFER) { + tas2780->reset_gpio = NULL; + return -EPROBE_DEFER; + } + } + + ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", + &tas2780->i_sense_slot); + if (ret) + tas2780->i_sense_slot = 0; + + ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", + &tas2780->v_sense_slot); + if (ret) + tas2780->v_sense_slot = 2; + + return 0; +} + +static int tas2780_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tas2780_priv *tas2780; + int result; + + tas2780 = devm_kzalloc(&client->dev, sizeof(struct tas2780_priv), + GFP_KERNEL); + if (!tas2780) + return -ENOMEM; + tas2780->dev = &client->dev; + i2c_set_clientdata(client, tas2780); + dev_set_drvdata(&client->dev, tas2780); + + tas2780->regmap = devm_regmap_init_i2c(client, &tas2780_i2c_regmap); + if (IS_ERR(tas2780->regmap)) { + result = PTR_ERR(tas2780->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + result); + return result; + } + + if (client->dev.of_node) { + result = tas2780_parse_dt(&client->dev, tas2780); + if (result) { + dev_err(tas2780->dev, + "%s: Failed to parse devicetree\n", __func__); + return result; + } + } + + return devm_snd_soc_register_component(tas2780->dev, + &soc_component_driver_tas2780, tas2780_dai_driver, + ARRAY_SIZE(tas2780_dai_driver)); +} + +static const struct i2c_device_id tas2780_i2c_id[] = { + { "tas2780", 0}, + { } +}; +MODULE_DEVICE_TABLE(i2c, tas2780_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id tas2780_of_match[] = { + { .compatible = "ti,tas2780" }, + {}, +}; +MODULE_DEVICE_TABLE(of, tas2780_of_match); +#endif + +static struct i2c_driver tas2780_i2c_driver = { + .driver = { + .name = "tas2780", + .of_match_table = of_match_ptr(tas2780_of_match), + }, + .probe = tas2780_i2c_probe, + .id_table = tas2780_i2c_id, +}; +module_i2c_driver(tas2780_i2c_driver); + +MODULE_AUTHOR("Raphael Xu "); +MODULE_DESCRIPTION("TAS2780 I2C Smart Amplifier driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tas2780.h b/sound/soc/codecs/tas2780.h new file mode 100644 index 0000000000000..661c25df4e293 --- /dev/null +++ b/sound/soc/codecs/tas2780.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * TAS2780.h - ALSA SoC Texas Instruments TAS2780 Mono Audio Amplifier + * + * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com + * + * Author: Raphael Xu + */ + +#ifndef __TAS2780_H__ +#define __TAS2780_H__ + +/* Book Control Register */ +#define TAS2780_BOOKCTL_PAGE 0 +#define TAS2780_BOOKCTL_REG 127 +#define TAS2780_REG(page, reg) ((page * 128) + reg) + +/* Page */ +#define TAS2780_PAGE TAS2780_REG(0X0, 0x00) +#define TAS2780_PAGE_PAGE_MASK 255 + +/* Software Reset */ +#define TAS2780_SW_RST TAS2780_REG(0X0, 0x01) +#define TAS2780_RST BIT(0) + +/* Power Control */ +#define TAS2780_PWR_CTRL TAS2780_REG(0X0, 0x02) +#define TAS2780_PWR_CTRL_MASK GENMASK(1, 0) +#define TAS2780_PWR_CTRL_ACTIVE 0x0 +#define TAS2780_PWR_CTRL_MUTE BIT(0) +#define TAS2780_PWR_CTRL_SHUTDOWN BIT(1) + +#define TAS2780_VSENSE_POWER_EN 3 +#define TAS2780_ISENSE_POWER_EN 4 + +/* Digital Volume Control */ +#define TAS2780_DVC TAS2780_REG(0X0, 0x1a) +#define TAS2780_DVC_MAX 0xc9 + +#define TAS2780_CHNL_0 TAS2780_REG(0X0, 0x03) + +/* TDM Configuration Reg0 */ +#define TAS2780_TDM_CFG0 TAS2780_REG(0X0, 0x08) +#define TAS2780_TDM_CFG0_SMP_MASK BIT(5) +#define TAS2780_TDM_CFG0_SMP_48KHZ 0x0 +#define TAS2780_TDM_CFG0_SMP_44_1KHZ BIT(5) +#define TAS2780_TDM_CFG0_MASK GENMASK(3, 1) +#define TAS2780_TDM_CFG0_44_1_48KHZ BIT(3) +#define TAS2780_TDM_CFG0_88_2_96KHZ (BIT(3) | BIT(1)) + +/* TDM Configuration Reg1 */ +#define TAS2780_TDM_CFG1 TAS2780_REG(0X0, 0x09) +#define TAS2780_TDM_CFG1_MASK GENMASK(5, 1) +#define TAS2780_TDM_CFG1_51_SHIFT 1 +#define TAS2780_TDM_CFG1_RX_MASK BIT(0) +#define TAS2780_TDM_CFG1_RX_RISING 0x0 +#define TAS2780_TDM_CFG1_RX_FALLING BIT(0) + +/* TDM Configuration Reg2 */ +#define TAS2780_TDM_CFG2 TAS2780_REG(0X0, 0x0a) +#define TAS2780_TDM_CFG2_RXW_MASK GENMASK(3, 2) +#define TAS2780_TDM_CFG2_RXW_16BITS 0x0 +#define TAS2780_TDM_CFG2_RXW_24BITS BIT(3) +#define TAS2780_TDM_CFG2_RXW_32BITS (BIT(3) | BIT(2)) +#define TAS2780_TDM_CFG2_RXS_MASK GENMASK(1, 0) +#define TAS2780_TDM_CFG2_RXS_16BITS 0x0 +#define TAS2780_TDM_CFG2_RXS_24BITS BIT(0) +#define TAS2780_TDM_CFG2_RXS_32BITS BIT(1) +#define TAS2780_TDM_CFG2_SCFG_MASK GENMASK(5, 4) +#define TAS2780_TDM_CFG2_SCFG_I2S 0x0 +#define TAS2780_TDM_CFG2_SCFG_LEFT_J BIT(4) +#define TAS2780_TDM_CFG2_SCFG_RIGHT_J BIT(5) + +/* TDM Configuration Reg3 */ +#define TAS2780_TDM_CFG3 TAS2780_REG(0X0, 0x0c) +#define TAS2780_TDM_CFG3_RXS_MASK GENMASK(7, 4) +#define TAS2780_TDM_CFG3_RXS_SHIFT 0x4 +#define TAS2780_TDM_CFG3_MASK GENMASK(3, 0) + +/* TDM Configuration Reg4 */ +#define TAS2780_TDM_CFG4 TAS2780_REG(0X0, 0x0d) +#define TAS2780_TDM_CFG4_TX_OFFSET_MASK GENMASK(3, 1) + +/* TDM Configuration Reg5 */ +#define TAS2780_TDM_CFG5 TAS2780_REG(0X0, 0x0e) +#define TAS2780_TDM_CFG5_VSNS_MASK BIT(6) +#define TAS2780_TDM_CFG5_VSNS_ENABLE BIT(6) +#define TAS2780_TDM_CFG5_50_MASK GENMASK(5, 0) + +/* TDM Configuration Reg6 */ +#define TAS2780_TDM_CFG6 TAS2780_REG(0X0, 0x0f) +#define TAS2780_TDM_CFG6_ISNS_MASK BIT(6) +#define TAS2780_TDM_CFG6_ISNS_ENABLE BIT(6) +#define TAS2780_TDM_CFG6_50_MASK GENMASK(5, 0) + +/* IC CFG */ +#define TAS2780_IC_CFG TAS2780_REG(0X0, 0x5c) +#define TAS2780_IC_CFG_MASK GENMASK(7, 6) +#define TAS2780_IC_CFG_ENABLE (BIT(7) | BIT(6)) + +#endif /* __TAS2780_H__ */ -- GitLab From a6426e7189e09bdf8decffd8a539f3727b672d3e Mon Sep 17 00:00:00 2001 From: Raphael-Xu <13691752556@139.com> Date: Thu, 7 Jul 2022 20:33:43 +0800 Subject: [PATCH 833/942] ASoC: add tas2780 DT binding add tas2780.yaml Signed-off-by: Raphael-Xu <13691752556@139.com> Link: https://lore.kernel.org/r/20220707123343.2403-2-13691752556@139.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/tas2780.yaml | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/tas2780.yaml diff --git a/Documentation/devicetree/bindings/sound/tas2780.yaml b/Documentation/devicetree/bindings/sound/tas2780.yaml new file mode 100644 index 0000000000000..5a0de09950665 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tas2780.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2020-2022 Texas Instruments Incorporated +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/sound/tas2780.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Texas Instruments TAS2780 Smart PA + +maintainers: + - Raphael Xu + +description: | + The TAS2780 is a mono, digital input Class-D audio amplifier optimized for + efficiently driving high peak power into small loudspeakers. + Integrated speaker voltage and current sense provides for + real time monitoring of loudspeaker behavior. + +properties: + compatible: + enum: + - ti,tas2780 + + reg: + maxItems: 1 + description: | + I2C address of the device can be between 0x38 to 0x45. + + reset-gpios: + maxItems: 1 + description: GPIO used to reset the device. + + interrupts: + maxItems: 1 + + ti,imon-slot-no: + $ref: /schemas/types.yaml#/definitions/uint32 + description: TDM TX current sense time slot. + + ti,vmon-slot-no: + $ref: /schemas/types.yaml#/definitions/uint32 + description: TDM TX voltage sense time slot. + + '#sound-dai-cells': + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + codec: codec@38 { + compatible = "ti,tas2780"; + reg = <0x38>; + #sound-dai-cells = <1>; + interrupt-parent = <&gpio1>; + interrupts = <14>; + reset-gpios = <&gpio1 15 0>; + shutdown-gpios = <&gpio1 15 0>; + ti,imon-slot-no = <0>; + ti,vmon-slot-no = <2>; + }; + }; + +... -- GitLab From 657efd9c985255960cdd90bafc382a39dc303277 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 8 Jul 2022 07:25:40 +0800 Subject: [PATCH 834/942] ASoC: amd: Remove duplicated include in acp-es8336.c Fix following includecheck warning: ./sound/soc/amd/acp-es8336.c: linux/module.h is included more than once. Signed-off-by: Yang Li Link: https://lore.kernel.org/r/20220707232540.22589-1-yang.lee@linux.alibaba.com Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index ebd4fa9f1f004..d501618b78f6e 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "acp.h" -- GitLab From 0ca3d2ba1dfd110bf5e0b25ebeb8f1e1587598fb Mon Sep 17 00:00:00 2001 From: David Lin Date: Fri, 8 Jul 2022 13:46:48 +0800 Subject: [PATCH 835/942] ASoC: nau8825: Declare 2 channels for DAI of capture stream The patch is to make driver with flexibility for more platforms support even if the internal design is just one ADC. Besides, many I2S controllers only support 2 channels. Signed-off-by: David Lin Link: https://lore.kernel.org/r/20220708054647.540621-1-CTLIN0@nuvoton.com Signed-off-by: Mark Brown --- sound/soc/codecs/nau8825.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 907ec88c759a8..54ef7b0fa8786 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -1440,7 +1440,7 @@ static struct snd_soc_dai_driver nau8825_dai = { .capture = { .stream_name = "Capture", .channels_min = 1, - .channels_max = 1, + .channels_max = 2, /* Only 1 channel of data */ .rates = NAU8825_RATES, .formats = NAU8825_FORMATS, }, -- GitLab From 1460b85daa0af45c1cd2c5e20133ce413184e3d6 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Fri, 8 Jul 2022 19:00:29 +0800 Subject: [PATCH 836/942] ASoC: Intel: sof_cs42l42: support BT offload audio Add the capability to machine driver of creating DAI Link for BT offload. Although BT offload always uses SSP2 port but we reserve the flexibility to assign the port number in macro. Signed-off-by: Brent Lu Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220708110030.658468-2-brent.lu@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cs42l42.c | 75 ++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index a1a14d6d7c238..3d53bb420c66e 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -41,8 +41,13 @@ #define SOF_CS42L42_DAILINK_MASK (GENMASK(24, 10)) #define SOF_CS42L42_DAILINK(link1, link2, link3, link4, link5) \ ((((link1) | ((link2) << 3) | ((link3) << 6) | ((link4) << 9) | ((link5) << 12)) << SOF_CS42L42_DAILINK_SHIFT) & SOF_CS42L42_DAILINK_MASK) -#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(25) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(26) +#define SOF_BT_OFFLOAD_PRESENT BIT(25) +#define SOF_CS42L42_SSP_BT_SHIFT 26 +#define SOF_CS42L42_SSP_BT_MASK (GENMASK(28, 26)) +#define SOF_CS42L42_SSP_BT(quirk) \ + (((quirk) << SOF_CS42L42_SSP_BT_SHIFT) & SOF_CS42L42_SSP_BT_MASK) +#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(29) +#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(30) enum { LINK_NONE = 0, @@ -50,6 +55,7 @@ enum { LINK_SPK = 2, LINK_DMIC = 3, LINK_HDMI = 4, + LINK_BT = 5, }; static struct snd_soc_jack_pin jack_pins[] = { @@ -290,6 +296,13 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; +static struct snd_soc_dai_link_component dummy_component[] = { + { + .name = "snd-soc-dummy", + .dai_name = "snd-soc-dummy-dai", + } +}; + static int create_spk_amp_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -479,9 +492,50 @@ static int create_hdmi_dai_links(struct device *dev, return -ENOMEM; } +static int create_bt_offload_dai_links(struct device *dev, + struct snd_soc_dai_link *links, + struct snd_soc_dai_link_component *cpus, + int *id, int ssp_bt) +{ + /* bt offload */ + if (!(sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT)) + return 0; + + links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", + ssp_bt); + if (!links[*id].name) + goto devm_err; + + links[*id].id = *id; + links[*id].codecs = dummy_component; + links[*id].num_codecs = ARRAY_SIZE(dummy_component); + links[*id].platforms = platform_component; + links[*id].num_platforms = ARRAY_SIZE(platform_component); + + links[*id].dpcm_playback = 1; + links[*id].dpcm_capture = 1; + links[*id].no_pcm = 1; + links[*id].cpus = &cpus[*id]; + links[*id].num_cpus = 1; + + links[*id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "SSP%d Pin", + ssp_bt); + if (!links[*id].cpus->dai_name) + goto devm_err; + + (*id)++; + + return 0; + +devm_err: + return -ENOMEM; +} + static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int ssp_codec, int ssp_amp, + int ssp_bt, int dmic_be_num, int hdmi_num) { @@ -534,6 +588,14 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, goto devm_err; } break; + case LINK_BT: + ret = create_bt_offload_dai_links(dev, links, cpus, &id, ssp_bt); + if (ret < 0) { + dev_err(dev, "fail to create bt offload dai links, ret %d\n", + ret); + goto devm_err; + } + break; case LINK_NONE: /* caught here if it's not used as terminator in macro */ default: @@ -555,7 +617,7 @@ static int sof_audio_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; int dmic_be_num, hdmi_num; - int ret, ssp_amp, ssp_codec; + int ret, ssp_bt, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -580,6 +642,9 @@ static int sof_audio_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk); + ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >> + SOF_CS42L42_SSP_BT_SHIFT; + ssp_amp = (sof_cs42l42_quirk & SOF_CS42L42_SSP_AMP_MASK) >> SOF_CS42L42_SSP_AMP_SHIFT; @@ -590,9 +655,11 @@ static int sof_audio_probe(struct platform_device *pdev) if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) sof_audio_card_cs42l42.num_links++; + if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT) + sof_audio_card_cs42l42.num_links++; dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_be_num, hdmi_num); + ssp_bt, dmic_be_num, hdmi_num); if (!dai_links) return -ENOMEM; -- GitLab From cd486d37493357369ec1d8f130d93806418def84 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Fri, 8 Jul 2022 19:00:30 +0800 Subject: [PATCH 837/942] ASoC: Intel: sof_cs42l42: add adl_mx98360a_cs4242 board config This patch adds driver data for adl_mx98360a_cs4242 which supports two max98360a speaker amplifiers on SSP1 and cs42l42 headphone codec on SSP0 running on ADL platform. Signed-off-by: Brent Lu Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220708110030.658468-3-brent.lu@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cs42l42.c | 11 +++++++++++ sound/soc/intel/common/soc-acpi-intel-adl-match.c | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index 3d53bb420c66e..85ffd065895d3 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -700,6 +700,17 @@ static const struct platform_device_id board_ids[] = { SOF_CS42L42_SSP_AMP(1)) | SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_NONE), }, + { + .name = "adl_mx98360a_cs4242", + .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_MAX98360A_SPEAKER_AMP_PRESENT | + SOF_CS42L42_SSP_AMP(1) | + SOF_CS42L42_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_PRESENT | + SOF_CS42L42_SSP_BT(2) | + SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_BT)), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index c1385161cdc84..fea087d3fa15c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -479,6 +479,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .drv_name = "adl_rt5682", .sof_tplg_filename = "sof-adl-rt5682.tplg", }, + { + .id = "10134242", + .drv_name = "adl_mx98360a_cs4242", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_max98360a_amp, + .sof_tplg_filename = "sof-adl-max98360a-cs42l42.tplg", + }, /* place amp-only boards in the end of table */ { .id = "CSC3541", -- GitLab From ac2606df8a3fb4450240cf0893ff3934b5882c69 Mon Sep 17 00:00:00 2001 From: V sujith kumar Reddy Date: Thu, 7 Jul 2022 21:41:40 +0530 Subject: [PATCH 838/942] ASoC: amd: acp: Remove rt1019_1 codec conf from machine driver Remove rt1019_1 codec configuration which has i2c-10EC1019:01 and i2c-10EC1019:02 codec components, Now Using default i2c-10EC1019:00 and i2c-10EC1019:01 codec components. Signed-off-by: V sujith kumar Reddy Link: https://lore.kernel.org/r/20220707161142.491034-2-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-mach-common.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index 7530cab24bc8b..86145398fa254 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -313,9 +313,6 @@ static const struct snd_soc_ops acp_card_dmic_ops = { SND_SOC_DAILINK_DEF(rt1019, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); -SND_SOC_DAILINK_DEF(rt1019_1, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:02", "rt1019-aif"), - COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); static const struct snd_soc_dapm_route rt1019_map_lr[] = { { "Left Spk", NULL, "Left SPO" }, @@ -333,17 +330,6 @@ static struct snd_soc_codec_conf rt1019_conf[] = { }, }; -static struct snd_soc_codec_conf rt1019_1_conf[] = { - { - .dlc = COMP_CODEC_CONF("i2c-10EC1019:02"), - .name_prefix = "Left", - }, - { - .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"), - .name_prefix = "Right", - }, -}; - static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -716,10 +702,6 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) links[i].init = acp_card_rt1019_init; card->codec_conf = rt1019_conf; card->num_configs = ARRAY_SIZE(rt1019_conf); - links[i].codecs = rt1019_1; - links[i].num_codecs = ARRAY_SIZE(rt1019_1); - card->codec_conf = rt1019_1_conf; - card->num_configs = ARRAY_SIZE(rt1019_1_conf); } i++; } -- GitLab From b24484c18b1089f9dd1ef7901b05a85e315e9f41 Mon Sep 17 00:00:00 2001 From: V sujith kumar Reddy Date: Thu, 7 Jul 2022 21:41:41 +0530 Subject: [PATCH 839/942] ASoC: amd: acp: ACP code generic to support newer platforms ADD Generic code to support to newer platforms, add control threshold, irq control macros ,added structure for register offset differences. Signed-off-by: V sujith kumar Reddy Link: https://lore.kernel.org/r/20220707161142.491034-3-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/acp-i2s.c | 34 +++++++++++++++---------- sound/soc/amd/acp/acp-pdm.c | 8 +++--- sound/soc/amd/acp/acp-platform.c | 16 +++++++----- sound/soc/amd/acp/acp-renoir.c | 38 ++++++++++++++++++++-------- sound/soc/amd/acp/amd.h | 24 +++++++++++++----- sound/soc/amd/acp/chip_offset_byte.h | 12 +++++---- 6 files changed, 86 insertions(+), 46 deletions(-) diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index ce9aca8dd6f51..a736c00db86ef 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -199,6 +199,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d { struct device *dev = dai->component->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_resource *rsrc = adata->rsrc; struct acp_stream *stream = substream->runtime->private_data; u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; @@ -208,7 +209,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { reg_dma_size = ACP_I2S_TX_DMA_SIZE; - acp_fifo_addr = ACP_SRAM_PTE_OFFSET + + acp_fifo_addr = rsrc->sram_pte_offset + SP_PB_FIFO_ADDR_OFFSET; reg_fifo_addr = ACP_I2S_TX_FIFOADDR; reg_fifo_size = ACP_I2S_TX_FIFOSIZE; @@ -217,7 +218,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR); } else { reg_dma_size = ACP_I2S_RX_DMA_SIZE; - acp_fifo_addr = ACP_SRAM_PTE_OFFSET + + acp_fifo_addr = rsrc->sram_pte_offset + SP_CAPT_FIFO_ADDR_OFFSET; reg_fifo_addr = ACP_I2S_RX_FIFOADDR; reg_fifo_size = ACP_I2S_RX_FIFOSIZE; @@ -228,7 +229,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { reg_dma_size = ACP_BT_TX_DMA_SIZE; - acp_fifo_addr = ACP_SRAM_PTE_OFFSET + + acp_fifo_addr = rsrc->sram_pte_offset + BT_PB_FIFO_ADDR_OFFSET; reg_fifo_addr = ACP_BT_TX_FIFOADDR; reg_fifo_size = ACP_BT_TX_FIFOSIZE; @@ -237,7 +238,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR); } else { reg_dma_size = ACP_BT_RX_DMA_SIZE; - acp_fifo_addr = ACP_SRAM_PTE_OFFSET + + acp_fifo_addr = rsrc->sram_pte_offset + BT_CAPT_FIFO_ADDR_OFFSET; reg_fifo_addr = ACP_BT_RX_FIFOADDR; reg_fifo_size = ACP_BT_RX_FIFOSIZE; @@ -255,11 +256,13 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr); writel(FIFO_SIZE, adata->acp_base + reg_fifo_size); - ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL); - ext_int_ctrl |= BIT(I2S_RX_THRESHOLD) | BIT(BT_RX_THRESHOLD) - | BIT(I2S_TX_THRESHOLD) | BIT(BT_TX_THRESHOLD); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | + BIT(BT_RX_THRESHOLD(rsrc->offset)) | + BIT(I2S_TX_THRESHOLD(rsrc->offset)) | + BIT(BT_TX_THRESHOLD(rsrc->offset)); - writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); return 0; } @@ -268,28 +271,30 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d { struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; + struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_resource *rsrc = adata->rsrc; unsigned int dir = substream->stream; unsigned int irq_bit = 0; switch (dai->driver->id) { case I2S_SP_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - irq_bit = BIT(I2S_TX_THRESHOLD); + irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset)); stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET; stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET; } else { - irq_bit = BIT(I2S_RX_THRESHOLD); + irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset)); stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET; stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET; } break; case I2S_BT_INSTANCE: if (dir == SNDRV_PCM_STREAM_PLAYBACK) { - irq_bit = BIT(BT_TX_THRESHOLD); + irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset)); stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET; stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET; } else { - irq_bit = BIT(BT_RX_THRESHOLD); + irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset)); stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET; stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET; } @@ -319,6 +324,7 @@ int asoc_acp_i2s_probe(struct snd_soc_dai *dai) { struct device *dev = dai->component->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_resource *rsrc = adata->rsrc; unsigned int val; if (!adata->acp_base) { @@ -326,8 +332,8 @@ int asoc_acp_i2s_probe(struct snd_soc_dai *dai) return -EINVAL; } - val = readl(adata->acp_base + ACP_I2S_PIN_CONFIG); - if (val != I2S_MODE) { + val = readl(adata->acp_base + rsrc->i2s_pin_cfg_offset); + if (val != rsrc->i2s_mode) { dev_err(dev, "I2S Mode not supported val %x\n", val); return -EINVAL; } diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c index 7a0b26a30051c..66ec6b6a59723 100644 --- a/sound/soc/amd/acp/acp-pdm.c +++ b/sound/soc/amd/acp/acp-pdm.c @@ -160,9 +160,9 @@ static int acp_dmic_dai_startup(struct snd_pcm_substream *substream, stream->reg_offset = ACP_REGION2_OFFSET; /* Enable DMIC Interrupts */ - ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); ext_int_ctrl |= PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); return 0; } @@ -175,9 +175,9 @@ static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream, u32 ext_int_ctrl; /* Disable DMIC interrupts */ - ext_int_ctrl = readl(adata->acp_base + ACP_EXTERNAL_INTR_CNTL); + ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0)); ext_int_ctrl |= ~PDM_DMA_INTR_MASK; - writel(ext_int_ctrl, adata->acp_base + ACP_EXTERNAL_INTR_CNTL); + writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0)); } const struct snd_soc_dai_ops acp_dmic_dai_ops = { diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index 3c4fd8b805891..e93c9e478cfac 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -91,6 +91,7 @@ EXPORT_SYMBOL_NS_GPL(acp_machine_select, SND_SOC_ACP_COMMON); static irqreturn_t i2s_irq_handler(int irq, void *data) { struct acp_dev_data *adata = data; + struct acp_resource *rsrc = adata->rsrc; struct acp_stream *stream; u16 i2s_flag = 0; u32 val, i; @@ -98,12 +99,13 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) if (!adata) return IRQ_NONE; - val = readl(adata->acp_base + ACP_EXTERNAL_INTR_STAT); + val = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); for (i = 0; i < ACP_MAX_STREAM; i++) { stream = adata->stream[i]; if (stream && (val & stream->irq_bit)) { - writel(stream->irq_bit, adata->acp_base + ACP_EXTERNAL_INTR_STAT); + writel(stream->irq_bit, + ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); snd_pcm_period_elapsed(stream->substream); i2s_flag = 1; break; @@ -118,6 +120,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) { + struct acp_resource *rsrc = adata->rsrc; u32 pte_reg, pte_size, reg_val; /* Use ATU base Group5 */ @@ -126,7 +129,7 @@ static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream stream->reg_offset = 0x02000000; /* Group Enable */ - reg_val = ACP_SRAM_PTE_OFFSET; + reg_val = rsrc->sram_pte_offset; writel(reg_val | BIT(31), adata->acp_base + pte_reg); writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size); } @@ -135,6 +138,7 @@ static void config_acp_dma(struct acp_dev_data *adata, int cpu_id, int size) { struct acp_stream *stream = adata->stream[cpu_id]; struct snd_pcm_substream *substream = stream->substream; + struct acp_resource *rsrc = adata->rsrc; dma_addr_t addr = substream->dma_buffer.addr; int num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); u32 low, high, val; @@ -146,9 +150,9 @@ static void config_acp_dma(struct acp_dev_data *adata, int cpu_id, int size) /* Load the low address of page int ACP SRAM through SRBM */ low = lower_32_bits(addr); high = upper_32_bits(addr); - writel(low, adata->acp_base + ACP_SCRATCH_REG_0 + val); + writel(low, adata->acp_base + rsrc->scratch_reg_offset + val); high |= BIT(31); - writel(high, adata->acp_base + ACP_SCRATCH_REG_0 + val + 4); + writel(high, adata->acp_base + rsrc->scratch_reg_offset + val + 4); /* Move to next physically contiguous page */ val += 8; @@ -187,7 +191,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs } runtime->private_data = stream; - writel(1, adata->acp_base + ACP_EXTERNAL_INTR_ENB); + writel(1, ACP_EXTERNAL_INTR_ENB(adata)); return ret; } diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c index 8375c00ff4c37..2a89a0d2e6019 100644 --- a/sound/soc/amd/acp/acp-renoir.c +++ b/sound/soc/amd/acp/acp-renoir.c @@ -39,6 +39,17 @@ #define ACP_ERROR_MASK 0x20000000 #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF +static struct acp_resource rsrc = { + .offset = 20, + .no_of_ctrls = 1, + .irqp_used = 0, + .irq_reg_offset = 0x1800, + .i2s_pin_cfg_offset = 0x1400, + .i2s_mode = 0x04, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x02052800, +}; + static struct snd_soc_acpi_codecs amp_rt1019 = { .num_codecs = 1, .codecs = {"10EC1019"} @@ -186,20 +197,24 @@ static int acp3x_reset(void __iomem *base) return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT); } -static void acp3x_enable_interrupts(void __iomem *base) +static void acp3x_enable_interrupts(struct acp_dev_data *adata) { + struct acp_resource *rsrc = adata->rsrc; u32 ext_intr_ctrl; - writel(0x01, base + ACP_EXTERNAL_INTR_ENB); - ext_intr_ctrl = readl(base + ACP_EXTERNAL_INTR_CNTL); + writel(0x01, ACP_EXTERNAL_INTR_ENB(adata)); + ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); ext_intr_ctrl |= ACP_ERROR_MASK; - writel(ext_intr_ctrl, base + ACP_EXTERNAL_INTR_CNTL); + writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); } -static void acp3x_disable_interrupts(void __iomem *base) +static void acp3x_disable_interrupts(struct acp_dev_data *adata) { - writel(ACP_EXT_INTR_STAT_CLEAR_MASK, base + ACP_EXTERNAL_INTR_STAT); - writel(0x00, base + ACP_EXTERNAL_INTR_ENB); + struct acp_resource *rsrc = adata->rsrc; + + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, + ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); + writel(0x00, ACP_EXTERNAL_INTR_ENB(adata)); } static int rn_acp_init(void __iomem *base) @@ -218,8 +233,6 @@ static int rn_acp_init(void __iomem *base) if (ret) return ret; - acp3x_enable_interrupts(base); - return 0; } @@ -227,8 +240,6 @@ static int rn_acp_deinit(void __iomem *base) { int ret = 0; - acp3x_disable_interrupts(base); - /* Reset */ ret = acp3x_reset(base); if (ret) @@ -290,11 +301,13 @@ static int renoir_audio_probe(struct platform_device *pdev) adata->dev = dev; adata->dai_driver = acp_renoir_dai; adata->num_dai = ARRAY_SIZE(acp_renoir_dai); + adata->rsrc = &rsrc; adata->machines = snd_soc_acpi_amd_acp_machines; acp_machine_select(adata); dev_set_drvdata(dev, adata); + acp3x_enable_interrupts(adata); acp_platform_register(dev); return 0; @@ -303,11 +316,14 @@ static int renoir_audio_probe(struct platform_device *pdev) static int renoir_audio_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; int ret; chip = dev_get_platdata(&pdev->dev); + acp3x_disable_interrupts(adata); + ret = rn_acp_deinit(chip->base); if (ret) dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret)); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 8fd38bf4d3bd6..186cb8b261754 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -32,13 +32,12 @@ #define ACP3x_I2STDM_REG_END 0x1242410 #define ACP3x_BT_TDM_REG_START 0x1242800 #define ACP3x_BT_TDM_REG_END 0x1242810 -#define I2S_MODE 0x04 -#define I2S_RX_THRESHOLD 27 -#define I2S_TX_THRESHOLD 28 -#define BT_TX_THRESHOLD 26 -#define BT_RX_THRESHOLD 25 -#define ACP_SRAM_PTE_OFFSET 0x02052800 +#define THRESHOLD(bit, base) ((bit) + (base)) +#define I2S_RX_THRESHOLD(base) THRESHOLD(7, base) +#define I2S_TX_THRESHOLD(base) THRESHOLD(8, base) +#define BT_TX_THRESHOLD(base) THRESHOLD(6, base) +#define BT_RX_THRESHOLD(base) THRESHOLD(5, base) #define ACP_SRAM_SP_PB_PTE_OFFSET 0x0 #define ACP_SRAM_SP_CP_PTE_OFFSET 0x100 @@ -92,6 +91,17 @@ struct acp_stream { u32 fifo_offset; }; +struct acp_resource { + int offset; + int no_of_ctrls; + int irqp_used; + u32 irq_reg_offset; + u32 i2s_pin_cfg_offset; + int i2s_mode; + u64 scratch_reg_offset; + u64 sram_pte_offset; +}; + struct acp_dev_data { char *name; struct device *dev; @@ -106,6 +116,8 @@ struct acp_dev_data { struct snd_soc_acpi_mach *machines; struct platform_device *mach_dev; + + struct acp_resource *rsrc; }; extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h index 88f6fa597cd6b..fff7e80475ba1 100644 --- a/sound/soc/amd/acp/chip_offset_byte.h +++ b/sound/soc/amd/acp/chip_offset_byte.h @@ -20,11 +20,13 @@ #define ACP_SOFT_RESET 0x1000 #define ACP_CONTROL 0x1004 -#define ACP_EXTERNAL_INTR_ENB 0x1800 -#define ACP_EXTERNAL_INTR_CNTL 0x1804 -#define ACP_EXTERNAL_INTR_STAT 0x1808 -#define ACP_I2S_PIN_CONFIG 0x1400 -#define ACP_SCRATCH_REG_0 0x12800 +#define ACP_EXTERNAL_INTR_REG_ADDR(adata, offset, ctrl) \ + (adata->acp_base + adata->rsrc->irq_reg_offset + offset + (ctrl * 0x04)) + +#define ACP_EXTERNAL_INTR_ENB(adata) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x0, 0x0) +#define ACP_EXTERNAL_INTR_CNTL(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x4, ctrl) +#define ACP_EXTERNAL_INTR_STAT(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, \ + (0x4 + (adata->rsrc->no_of_ctrls * 0x04)), ctrl) /* Registers from ACP_AUDIO_BUFFERS block */ -- GitLab From e8a33a94078560df73761f6d6147a25bda07605c Mon Sep 17 00:00:00 2001 From: V sujith kumar Reddy Date: Thu, 7 Jul 2022 21:41:42 +0530 Subject: [PATCH 840/942] ASoC: amd: acp: Add legacy audio driver support for Rembrandt platform Add i2s and dmic support for Rembrandt platform, Add machine support for nau8825, max98360 and rt5682s,rt1019 codec in legacy driver for rembrandt platform. Here codec is in a slave mode. Signed-off-by: V sujith kumar Reddy Link: https://lore.kernel.org/r/20220707161142.491034-4-Vsujithkumar.Reddy@amd.com Signed-off-by: Mark Brown --- sound/soc/amd/acp/Kconfig | 11 + sound/soc/amd/acp/Makefile | 2 + sound/soc/amd/acp/acp-i2s.c | 137 ++++++++- sound/soc/amd/acp/acp-legacy-mach.c | 32 +++ sound/soc/amd/acp/acp-mach-common.c | 86 +++++- sound/soc/amd/acp/acp-mach.h | 6 + sound/soc/amd/acp/acp-pci.c | 6 + sound/soc/amd/acp/acp-platform.c | 16 +- sound/soc/amd/acp/acp-rembrandt.c | 401 +++++++++++++++++++++++++++ sound/soc/amd/acp/amd.h | 62 ++++- sound/soc/amd/acp/chip_offset_byte.h | 28 ++ 11 files changed, 781 insertions(+), 6 deletions(-) create mode 100644 sound/soc/amd/acp/acp-rembrandt.c diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig index 7e56d26441058..ce00378107431 100644 --- a/sound/soc/amd/acp/Kconfig +++ b/sound/soc/amd/acp/Kconfig @@ -40,6 +40,17 @@ config SND_AMD_ASOC_RENOIR help This option enables Renoir I2S support on AMD platform. +config SND_AMD_ASOC_REMBRANDT + tristate "AMD ACP ASOC Rembrandt Support" + select SND_SOC_AMD_ACP_PCM + select SND_SOC_AMD_ACP_I2S + select SND_SOC_AMD_ACP_PDM + depends on X86 && PCI + help + This option enables Rembrandt I2S support on AMD platform. + Say Y if you want to enable AUDIO on Rembrandt + If unsure select "N". + config SND_SOC_AMD_MACH_COMMON tristate depends on X86 && PCI && I2C diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile index 657ddfadf0bbf..d9abb0ee5218f 100644 --- a/sound/soc/amd/acp/Makefile +++ b/sound/soc/amd/acp/Makefile @@ -12,6 +12,7 @@ snd-acp-pci-objs := acp-pci.o #platform specific driver snd-acp-renoir-objs := acp-renoir.o +snd-acp-rembrandt-objs := acp-rembrandt.o #machine specific driver snd-acp-mach-objs := acp-mach-common.o @@ -24,6 +25,7 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o +obj-$(CONFIG_SND_AMD_ASOC_REMBRANDT) += snd-acp-rembrandt.o obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c index a736c00db86ef..393f729ef561b 100644 --- a/sound/soc/amd/acp/acp-i2s.c +++ b/sound/soc/amd/acp/acp-i2s.c @@ -30,11 +30,14 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ { struct device *dev = dai->component->dev; struct acp_dev_data *adata; + struct acp_resource *rsrc; u32 val; u32 xfer_resolution; u32 reg_val; + u32 lrclk_div_val, bclk_div_val; adata = snd_soc_dai_get_drvdata(dai); + rsrc = adata->rsrc; /* These values are as per Hardware Spec */ switch (params_format(params)) { @@ -63,6 +66,9 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ case I2S_SP_INSTANCE: reg_val = ACP_I2STDM_ITER; break; + case I2S_HS_INSTANCE: + reg_val = ACP_HSTDM_ITER; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -75,6 +81,9 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ case I2S_SP_INSTANCE: reg_val = ACP_I2STDM_IRER; break; + case I2S_HS_INSTANCE: + reg_val = ACP_HSTDM_IRER; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -86,6 +95,74 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ val = val | (xfer_resolution << 3); writel(val, adata->acp_base + reg_val); + if (rsrc->soc_mclk) { + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + switch (params_rate(params)) { + case 8000: + bclk_div_val = 768; + break; + case 16000: + bclk_div_val = 384; + break; + case 24000: + bclk_div_val = 256; + break; + case 32000: + bclk_div_val = 192; + break; + case 44100: + case 48000: + bclk_div_val = 128; + break; + case 88200: + case 96000: + bclk_div_val = 64; + break; + case 192000: + bclk_div_val = 32; + break; + default: + return -EINVAL; + } + lrclk_div_val = 32; + break; + case SNDRV_PCM_FORMAT_S32_LE: + switch (params_rate(params)) { + case 8000: + bclk_div_val = 384; + break; + case 16000: + bclk_div_val = 192; + break; + case 24000: + bclk_div_val = 128; + break; + case 32000: + bclk_div_val = 96; + break; + case 44100: + case 48000: + bclk_div_val = 64; + break; + case 88200: + case 96000: + bclk_div_val = 32; + break; + case 192000: + bclk_div_val = 16; + break; + default: + return -EINVAL; + } + lrclk_div_val = 64; + break; + default: + return -EINVAL; + } + adata->lrclk_div = lrclk_div_val; + adata->bclk_div = bclk_div_val; + } return 0; } @@ -94,6 +171,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct struct acp_stream *stream = substream->runtime->private_data; struct device *dev = dai->component->dev; struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_resource *rsrc = adata->rsrc; u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); @@ -118,6 +196,12 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct ier_val = ACP_I2STDM_IER; buf_reg = ACP_I2S_TX_RINGBUFSIZE; break; + case I2S_HS_INSTANCE: + water_val = ACP_HS_TX_INTR_WATERMARK_SIZE; + reg_val = ACP_HSTDM_ITER; + ier_val = ACP_HSTDM_IER; + buf_reg = ACP_HS_TX_RINGBUFSIZE; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -136,6 +220,12 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct ier_val = ACP_I2STDM_IER; buf_reg = ACP_I2S_RX_RINGBUFSIZE; break; + case I2S_HS_INSTANCE: + water_val = ACP_HS_RX_INTR_WATERMARK_SIZE; + reg_val = ACP_HSTDM_IRER; + ier_val = ACP_HSTDM_IER; + buf_reg = ACP_HS_RX_RINGBUFSIZE; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -147,6 +237,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct val = val | BIT(0); writel(val, adata->acp_base + reg_val); writel(1, adata->acp_base + ier_val); + if (rsrc->soc_mclk) + acp_set_i2s_clk(adata, dai->driver->id); return 0; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: @@ -159,6 +251,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct case I2S_SP_INSTANCE: reg_val = ACP_I2STDM_ITER; break; + case I2S_HS_INSTANCE: + reg_val = ACP_HSTDM_ITER; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -172,6 +267,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct case I2S_SP_INSTANCE: reg_val = ACP_I2STDM_IRER; break; + case I2S_HS_INSTANCE: + reg_val = ACP_HSTDM_IRER; + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -187,6 +285,9 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) && !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0))) writel(0, adata->acp_base + ACP_I2STDM_IER); + if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) && + !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0))) + writel(0, adata->acp_base + ACP_HSTDM_IER); return 0; default: return -EINVAL; @@ -247,6 +348,27 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR); } break; + case I2S_HS_INSTANCE: + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { + reg_dma_size = ACP_HS_TX_DMA_SIZE; + acp_fifo_addr = rsrc->sram_pte_offset + + HS_PB_FIFO_ADDR_OFFSET; + reg_fifo_addr = ACP_HS_TX_FIFOADDR; + reg_fifo_size = ACP_HS_TX_FIFOSIZE; + + phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; + writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR); + } else { + reg_dma_size = ACP_HS_RX_DMA_SIZE; + acp_fifo_addr = rsrc->sram_pte_offset + + HS_CAPT_FIFO_ADDR_OFFSET; + reg_fifo_addr = ACP_HS_RX_FIFOADDR; + reg_fifo_size = ACP_HS_RX_FIFOSIZE; + + phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; + writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR); + } + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; @@ -260,7 +382,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | BIT(BT_RX_THRESHOLD(rsrc->offset)) | BIT(I2S_TX_THRESHOLD(rsrc->offset)) | - BIT(BT_TX_THRESHOLD(rsrc->offset)); + BIT(BT_TX_THRESHOLD(rsrc->offset)) | + BIT(HS_RX_THRESHOLD(rsrc->offset)) | + BIT(HS_TX_THRESHOLD(rsrc->offset)); writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); @@ -299,6 +423,17 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET; } break; + case I2S_HS_INSTANCE: + if (dir == SNDRV_PCM_STREAM_PLAYBACK) { + irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset)); + stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET; + stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET; + } else { + irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset)); + stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET; + stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET; + } + break; default: dev_err(dev, "Invalid dai id %x\n", dai->driver->id); return -EINVAL; diff --git a/sound/soc/amd/acp/acp-legacy-mach.c b/sound/soc/amd/acp/acp-legacy-mach.c index 7f04a048ca3a2..1f4878ff7d372 100644 --- a/sound/soc/amd/acp/acp-legacy-mach.c +++ b/sound/soc/amd/acp/acp-legacy-mach.c @@ -47,6 +47,28 @@ static struct acp_card_drvdata rt5682s_rt1019_data = { .dmic_codec_id = DMIC, }; +static struct acp_card_drvdata max_nau8825_data = { + .hs_cpu_id = I2S_HS, + .amp_cpu_id = I2S_HS, + .dmic_cpu_id = DMIC, + .hs_codec_id = NAU8825, + .amp_codec_id = MAX98360A, + .dmic_codec_id = DMIC, + .soc_mclk = true, + .platform = REMBRANDT, +}; + +static struct acp_card_drvdata rt5682s_rt1019_rmb_data = { + .hs_cpu_id = I2S_HS, + .amp_cpu_id = I2S_HS, + .dmic_cpu_id = DMIC, + .hs_codec_id = RT5682S, + .amp_codec_id = RT1019, + .dmic_codec_id = DMIC, + .soc_mclk = true, + .platform = REMBRANDT, +}; + static const struct snd_kcontrol_new acp_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -112,6 +134,14 @@ static const struct platform_device_id board_ids[] = { .name = "acp3xalc5682s1019", .driver_data = (kernel_ulong_t)&rt5682s_rt1019_data, }, + { + .name = "rmb-nau8825-max", + .driver_data = (kernel_ulong_t)&max_nau8825_data, + }, + { + .name = "rmb-rt5682s-rt1019", + .driver_data = (kernel_ulong_t)&rt5682s_rt1019_rmb_data, + }, { } }; static struct platform_driver acp_asoc_audio = { @@ -130,4 +160,6 @@ MODULE_DESCRIPTION("ACP chrome audio support"); MODULE_ALIAS("platform:acp3xalc56821019"); MODULE_ALIAS("platform:acp3xalc5682sm98360"); MODULE_ALIAS("platform:acp3xalc5682s1019"); +MODULE_ALIAS("platform:rmb-nau8825-max"); +MODULE_ALIAS("platform:rmb-rt5682s-rt1019"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index 86145398fa254..f0c49127aad11 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -545,6 +545,12 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; +static struct snd_soc_dai_link_component platform_rmb_component[] = { + { + .name = "acp_asoc_rembrandt.0", + } +}; + static struct snd_soc_dai_link_component sof_component[] = { { .name = "0000:04:00.5", @@ -553,6 +559,8 @@ static struct snd_soc_dai_link_component sof_component[] = { SND_SOC_DAILINK_DEF(i2s_sp, DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp"))); +SND_SOC_DAILINK_DEF(i2s_hs, + DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs"))); SND_SOC_DAILINK_DEF(sof_sp, DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp"))); SND_SOC_DAILINK_DEF(sof_hs, @@ -774,6 +782,40 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card) i++; } + if (drv_data->hs_cpu_id == I2S_HS) { + links[i].name = "acp-headset-codec"; + links[i].id = HEADSET_BE_ID; + links[i].cpus = i2s_hs; + links[i].num_cpus = ARRAY_SIZE(i2s_hs); + if (drv_data->platform == REMBRANDT) { + links[i].platforms = platform_rmb_component; + links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); + } else { + links[i].platforms = platform_component; + links[i].num_platforms = ARRAY_SIZE(platform_component); + } + links[i].dpcm_playback = 1; + links[i].dpcm_capture = 1; + if (!drv_data->hs_codec_id) { + /* Use dummy codec if codec id not specified */ + links[i].codecs = dummy_codec; + links[i].num_codecs = ARRAY_SIZE(dummy_codec); + } + if (drv_data->hs_codec_id == NAU8825) { + links[i].codecs = nau8825; + links[i].num_codecs = ARRAY_SIZE(nau8825); + links[i].init = acp_card_nau8825_init; + links[i].ops = &acp_card_nau8825_ops; + } + if (drv_data->hs_codec_id == RT5682S) { + links[i].codecs = rt5682s; + links[i].num_codecs = ARRAY_SIZE(rt5682s); + links[i].init = acp_card_rt5682s_init; + links[i].ops = &acp_card_rt5682s_ops; + } + i++; + } + if (drv_data->amp_cpu_id == I2S_SP) { links[i].name = "acp-amp-codec"; links[i].id = AMP_BE_ID; @@ -804,6 +846,41 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card) i++; } + if (drv_data->amp_cpu_id == I2S_HS) { + links[i].name = "acp-amp-codec"; + links[i].id = AMP_BE_ID; + links[i].cpus = i2s_hs; + links[i].num_cpus = ARRAY_SIZE(i2s_hs); + if (drv_data->platform == REMBRANDT) { + links[i].platforms = platform_rmb_component; + links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); + } else { + links[i].platforms = platform_component; + links[i].num_platforms = ARRAY_SIZE(platform_component); + } + links[i].dpcm_playback = 1; + if (!drv_data->amp_codec_id) { + /* Use dummy codec if codec id not specified */ + links[i].codecs = dummy_codec; + links[i].num_codecs = ARRAY_SIZE(dummy_codec); + } + if (drv_data->amp_codec_id == MAX98360A) { + links[i].codecs = max98360a; + links[i].num_codecs = ARRAY_SIZE(max98360a); + links[i].ops = &acp_card_maxim_ops; + links[i].init = acp_card_maxim_init; + } + if (drv_data->amp_codec_id == RT1019) { + links[i].codecs = rt1019; + links[i].num_codecs = ARRAY_SIZE(rt1019); + links[i].ops = &acp_card_rt1019_ops; + links[i].init = acp_card_rt1019_init; + card->codec_conf = rt1019_conf; + card->num_configs = ARRAY_SIZE(rt1019_conf); + } + i++; + } + if (drv_data->dmic_cpu_id == DMIC) { links[i].name = "acp-dmic-codec"; links[i].id = DMIC_BE_ID; @@ -817,8 +894,13 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card) } links[i].cpus = pdm_dmic; links[i].num_cpus = ARRAY_SIZE(pdm_dmic); - links[i].platforms = platform_component; - links[i].num_platforms = ARRAY_SIZE(platform_component); + if (drv_data->platform == REMBRANDT) { + links[i].platforms = platform_rmb_component; + links[i].num_platforms = ARRAY_SIZE(platform_rmb_component); + } else { + links[i].platforms = platform_component; + links[i].num_platforms = ARRAY_SIZE(platform_component); + } links[i].ops = &acp_card_dmic_ops; links[i].dpcm_capture = 1; } diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h index c95ee1c52eb1b..20583ef902df7 100644 --- a/sound/soc/amd/acp/acp-mach.h +++ b/sound/soc/amd/acp/acp-mach.h @@ -41,6 +41,11 @@ enum codec_endpoints { NAU8825, }; +enum platform_end_point { + RENOIR = 0, + REMBRANDT, +}; + struct acp_card_drvdata { unsigned int hs_cpu_id; unsigned int amp_cpu_id; @@ -49,6 +54,7 @@ struct acp_card_drvdata { unsigned int amp_codec_id; unsigned int dmic_codec_id; unsigned int dai_fmt; + unsigned int platform; struct clk *wclk; struct clk *bclk; bool soc_mclk; diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c index c893963ee2d06..c03bcd31fc950 100644 --- a/sound/soc/amd/acp/acp-pci.c +++ b/sound/soc/amd/acp/acp-pci.c @@ -82,6 +82,12 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id chip->name = "acp_asoc_renoir"; chip->acp_rev = ACP3X_DEV; break; + case 0x6f: + res_acp = acp3x_res; + num_res = ARRAY_SIZE(acp3x_res); + chip->name = "acp_asoc_rembrandt"; + chip->acp_rev = ACP6X_DEV; + break; default: dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision); return -EINVAL; diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index e93c9e478cfac..327e17736dbd3 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -94,11 +94,14 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) struct acp_resource *rsrc = adata->rsrc; struct acp_stream *stream; u16 i2s_flag = 0; - u32 val, i; + u32 val, val1, i; if (!adata) return IRQ_NONE; + if (adata->rsrc->no_of_ctrls == 2) + val1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1))); + val = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); for (i = 0; i < ACP_MAX_STREAM; i++) { @@ -110,8 +113,16 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) i2s_flag = 1; break; } + if (adata->rsrc->no_of_ctrls == 2) { + if (stream && (val1 & stream->irq_bit)) { + writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata, + (rsrc->irqp_used - 1))); + snd_pcm_period_elapsed(stream->substream); + i2s_flag = 1; + break; + } + } } - if (i2s_flag) return IRQ_HANDLED; @@ -132,6 +143,7 @@ static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream reg_val = rsrc->sram_pte_offset; writel(reg_val | BIT(31), adata->acp_base + pte_reg); writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size); + writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); } static void config_acp_dma(struct acp_dev_data *adata, int cpu_id, int size) diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c new file mode 100644 index 0000000000000..2b57c0ca4e998 --- /dev/null +++ b/sound/soc/amd/acp/acp-rembrandt.c @@ -0,0 +1,401 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2022 Advanced Micro Devices, Inc. +// +// Authors: Ajit Kumar Pandey +// V sujith kumar Reddy +/* + * Hardware interface for Renoir ACP block + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "amd.h" + +#define DRV_NAME "acp_asoc_rembrandt" + +#define ACP6X_PGFSM_CONTROL 0x1024 +#define ACP6X_PGFSM_STATUS 0x1028 + +#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001 + +#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01 +#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00 +#define ACP_PGFSM_STATUS_MASK 0x03 +#define ACP_POWERED_ON 0x00 +#define ACP_POWER_ON_IN_PROGRESS 0x01 +#define ACP_POWERED_OFF 0x02 +#define ACP_POWER_OFF_IN_PROGRESS 0x03 + +#define ACP_ERROR_MASK 0x20000000 +#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF + + +static int rmb_acp_init(void __iomem *base); +static int rmb_acp_deinit(void __iomem *base); + +static struct acp_resource rsrc = { + .offset = 0, + .no_of_ctrls = 2, + .irqp_used = 1, + .soc_mclk = true, + .irq_reg_offset = 0x1a00, + .i2s_pin_cfg_offset = 0x1440, + .i2s_mode = 0x0a, + .scratch_reg_offset = 0x12800, + .sram_pte_offset = 0x03802800, +}; + +static struct snd_soc_acpi_codecs amp_rt1019 = { + .num_codecs = 1, + .codecs = {"10EC1019"} +}; + +static struct snd_soc_acpi_codecs amp_max = { + .num_codecs = 1, + .codecs = {"MX98360A"} +}; + +static struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_acp_machines[] = { + { + .id = "10508825", + .drv_name = "rmb-nau8825-max", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max, + }, + { + .id = "AMDI0007", + .drv_name = "rembrandt-acp", + }, + { + .id = "RTL5682", + .drv_name = "rmb-rt5682s-rt1019", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_rt1019, + }, + {}, +}; + +static struct snd_soc_dai_driver acp_rmb_dai[] = { +{ + .name = "acp-i2s-sp", + .id = I2S_SP_INSTANCE, + .playback = { + .stream_name = "I2S SP Playback", + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 96000, + }, + .capture = { + .stream_name = "I2S SP Capture", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &asoc_acp_cpu_dai_ops, + .probe = &asoc_acp_i2s_probe, +}, +{ + .name = "acp-i2s-bt", + .id = I2S_BT_INSTANCE, + .playback = { + .stream_name = "I2S BT Playback", + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 96000, + }, + .capture = { + .stream_name = "I2S BT Capture", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &asoc_acp_cpu_dai_ops, + .probe = &asoc_acp_i2s_probe, +}, +{ + .name = "acp-i2s-hs", + .id = I2S_HS_INSTANCE, + .playback = { + .stream_name = "I2S HS Playback", + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 96000, + }, + .capture = { + .stream_name = "I2S HS Capture", + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &asoc_acp_cpu_dai_ops, + .probe = &asoc_acp_i2s_probe, +}, +{ + .name = "acp-pdm-dmic", + .id = DMIC_INSTANCE, + .capture = { + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + }, + .ops = &acp_dmic_dai_ops, +}, +}; + +static int acp6x_power_on(void __iomem *base) +{ + u32 val; + int timeout; + + val = readl(base + ACP6X_PGFSM_STATUS); + + if (val == ACP_POWERED_ON) + return 0; + + if ((val & ACP_PGFSM_STATUS_MASK) != + ACP_POWER_ON_IN_PROGRESS) + writel(ACP_PGFSM_CNTL_POWER_ON_MASK, + base + ACP6X_PGFSM_CONTROL); + timeout = 0; + while (++timeout < 500) { + val = readl(base + ACP6X_PGFSM_STATUS); + if (!val) + return 0; + udelay(1); + } + return -ETIMEDOUT; +} + +static int acp6x_power_off(void __iomem *base) +{ + u32 val; + int timeout; + + writel(ACP_PGFSM_CNTL_POWER_OFF_MASK, + base + ACP6X_PGFSM_CONTROL); + timeout = 0; + while (++timeout < 500) { + val = readl(base + ACP6X_PGFSM_STATUS); + if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF) + return 0; + udelay(1); + } + return -ETIMEDOUT; +} + +static int acp6x_reset(void __iomem *base) +{ + u32 val; + int timeout; + + writel(1, base + ACP_SOFT_RESET); + timeout = 0; + while (++timeout < 500) { + val = readl(base + ACP_SOFT_RESET); + if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK) + break; + cpu_relax(); + } + writel(0, base + ACP_SOFT_RESET); + timeout = 0; + while (++timeout < 500) { + val = readl(base + ACP_SOFT_RESET); + if (!val) + return 0; + cpu_relax(); + } + return -ETIMEDOUT; +} + +static void acp6x_enable_interrupts(struct acp_dev_data *adata) +{ + struct acp_resource *rsrc = adata->rsrc; + u32 ext_intr_ctrl; + + writel(0x01, ACP_EXTERNAL_INTR_ENB(adata)); + ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); + ext_intr_ctrl |= ACP_ERROR_MASK; + writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used)); +} + +static void acp6x_disable_interrupts(struct acp_dev_data *adata) +{ + struct acp_resource *rsrc = adata->rsrc; + + writel(ACP_EXT_INTR_STAT_CLEAR_MASK, + ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); + writel(0x00, ACP_EXTERNAL_INTR_ENB(adata)); +} + +static int rmb_acp_init(void __iomem *base) +{ + int ret; + + /* power on */ + ret = acp6x_power_on(base); + if (ret) { + pr_err("ACP power on failed\n"); + return ret; + } + writel(0x01, base + ACP_CONTROL); + + /* Reset */ + ret = acp6x_reset(base); + if (ret) { + pr_err("ACP reset failed\n"); + return ret; + } + + return 0; +} + +static int rmb_acp_deinit(void __iomem *base) +{ + int ret = 0; + + /* Reset */ + ret = acp6x_reset(base); + if (ret) { + pr_err("ACP reset failed\n"); + return ret; + } + + writel(0x00, base + ACP_CONTROL); + + /* power off */ + ret = acp6x_power_off(base); + if (ret) { + pr_err("ACP power off failed\n"); + return ret; + } + + return 0; +} + +static int rembrandt_audio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct acp_chip_info *chip; + struct acp_dev_data *adata; + struct resource *res; + + chip = dev_get_platdata(&pdev->dev); + if (!chip || !chip->base) { + dev_err(&pdev->dev, "ACP chip data is NULL\n"); + return -ENODEV; + } + + if (chip->acp_rev != ACP6X_DEV) { + dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev); + return -ENODEV; + } + + rmb_acp_init(chip->base); + + adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL); + if (!adata) + return -ENOMEM; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem"); + if (!res) { + dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n"); + return -ENODEV; + } + + adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!adata->acp_base) + return -ENOMEM; + + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq"); + if (!res) { + dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); + return -ENODEV; + } + + adata->i2s_irq = res->start; + adata->dev = dev; + adata->dai_driver = acp_rmb_dai; + adata->num_dai = ARRAY_SIZE(acp_rmb_dai); + adata->rsrc = &rsrc; + + adata->machines = snd_soc_acpi_amd_rmb_acp_machines; + acp_machine_select(adata); + + dev_set_drvdata(dev, adata); + acp6x_enable_interrupts(adata); + acp_platform_register(dev); + + return 0; +} + +static int rembrandt_audio_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip; + + chip = dev_get_platdata(&pdev->dev); + if (!chip || !chip->base) { + dev_err(&pdev->dev, "ACP chip data is NULL\n"); + return -ENODEV; + } + + rmb_acp_deinit(chip->base); + + acp6x_disable_interrupts(adata); + acp_platform_unregister(dev); + return 0; +} + +static struct platform_driver rembrandt_driver = { + .probe = rembrandt_audio_probe, + .remove = rembrandt_audio_remove, + .driver = { + .name = "acp_asoc_rembrandt", + }, +}; + +module_platform_driver(rembrandt_driver); + +MODULE_DESCRIPTION("AMD ACP Rembrandt Driver"); +MODULE_IMPORT_NS(SND_SOC_ACP_COMMON); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h index 186cb8b261754..af9603724a68c 100644 --- a/sound/soc/amd/acp/amd.h +++ b/sound/soc/amd/acp/amd.h @@ -19,10 +19,12 @@ #include "chip_offset_byte.h" #define ACP3X_DEV 3 +#define ACP6X_DEV 6 #define I2S_SP_INSTANCE 0x00 #define I2S_BT_INSTANCE 0x01 #define DMIC_INSTANCE 0x02 +#define I2S_HS_INSTANCE 0x03 #define MEM_WINDOW_START 0x4080000 @@ -38,23 +40,31 @@ #define I2S_TX_THRESHOLD(base) THRESHOLD(8, base) #define BT_TX_THRESHOLD(base) THRESHOLD(6, base) #define BT_RX_THRESHOLD(base) THRESHOLD(5, base) +#define HS_TX_THRESHOLD(base) THRESHOLD(4, base) +#define HS_RX_THRESHOLD(base) THRESHOLD(3, base) #define ACP_SRAM_SP_PB_PTE_OFFSET 0x0 #define ACP_SRAM_SP_CP_PTE_OFFSET 0x100 #define ACP_SRAM_BT_PB_PTE_OFFSET 0x200 #define ACP_SRAM_BT_CP_PTE_OFFSET 0x300 #define ACP_SRAM_PDM_PTE_OFFSET 0x400 +#define ACP_SRAM_HS_PB_PTE_OFFSET 0x500 +#define ACP_SRAM_HS_CP_PTE_OFFSET 0x600 #define PAGE_SIZE_4K_ENABLE 0x2 #define I2S_SP_TX_MEM_WINDOW_START 0x4000000 #define I2S_SP_RX_MEM_WINDOW_START 0x4020000 #define I2S_BT_TX_MEM_WINDOW_START 0x4040000 #define I2S_BT_RX_MEM_WINDOW_START 0x4060000 +#define I2S_HS_TX_MEM_WINDOW_START 0x40A0000 +#define I2S_HS_RX_MEM_WINDOW_START 0x40C0000 #define SP_PB_FIFO_ADDR_OFFSET 0x500 #define SP_CAPT_FIFO_ADDR_OFFSET 0x700 #define BT_PB_FIFO_ADDR_OFFSET 0x900 #define BT_CAPT_FIFO_ADDR_OFFSET 0xB00 +#define HS_PB_FIFO_ADDR_OFFSET 0xD00 +#define HS_CAPT_FIFO_ADDR_OFFSET 0xF00 #define PLAYBACK_MIN_NUM_PERIODS 2 #define PLAYBACK_MAX_NUM_PERIODS 8 #define PLAYBACK_MAX_PERIOD_SIZE 8192 @@ -72,7 +82,7 @@ #define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38 -#define ACP_MAX_STREAM 6 +#define ACP_MAX_STREAM 8 struct acp_chip_info { char *name; /* Platform name */ @@ -95,6 +105,7 @@ struct acp_resource { int offset; int no_of_ctrls; int irqp_used; + bool soc_mclk; u32 irq_reg_offset; u32 i2s_pin_cfg_offset; int i2s_mode; @@ -117,9 +128,23 @@ struct acp_dev_data { struct snd_soc_acpi_mach *machines; struct platform_device *mach_dev; + u32 bclk_div; + u32 lrclk_div; + struct acp_resource *rsrc; }; +union acp_i2stdm_mstrclkgen { + struct { + u32 i2stdm_master_mode : 1; + u32 i2stdm_format_mode : 1; + u32 i2stdm_lrclk_div_val : 9; + u32 i2stdm_bclk_div_val : 11; + u32:10; + } bitfields, bits; + u32 u32_all; +}; + extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops; extern const struct snd_soc_dai_ops acp_dmic_dai_ops; @@ -146,6 +171,10 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH); low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW); break; + case I2S_HS_INSTANCE: + high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH); + low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW); + break; default: dev_err(adata->dev, "Invalid dai id %x\n", dai_id); return -EINVAL; @@ -160,6 +189,10 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH); low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW); break; + case I2S_HS_INSTANCE: + high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH); + low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW); + break; case DMIC_INSTANCE: high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH); low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW); @@ -175,4 +208,31 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int return byte_count; } +static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id) +{ + union acp_i2stdm_mstrclkgen mclkgen; + u32 master_reg; + + switch (dai_id) { + case I2S_SP_INSTANCE: + master_reg = ACP_I2STDM0_MSTRCLKGEN; + break; + case I2S_BT_INSTANCE: + master_reg = ACP_I2STDM1_MSTRCLKGEN; + break; + case I2S_HS_INSTANCE: + master_reg = ACP_I2STDM2_MSTRCLKGEN; + break; + default: + master_reg = ACP_I2STDM0_MSTRCLKGEN; + break; + } + + mclkgen.bits.i2stdm_master_mode = 0x1; + mclkgen.bits.i2stdm_format_mode = 0x00; + + mclkgen.bits.i2stdm_bclk_div_val = adata->bclk_div; + mclkgen.bits.i2stdm_lrclk_div_val = adata->lrclk_div; + writel(mclkgen.u32_all, adata->acp_base + master_reg); +} #endif diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h index fff7e80475ba1..ce3948e0679c5 100644 --- a/sound/soc/amd/acp/chip_offset_byte.h +++ b/sound/soc/amd/acp/chip_offset_byte.h @@ -66,6 +66,24 @@ #define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x2084 #define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x2088 #define ACP_BT_TX_INTR_WATERMARK_SIZE 0x208C +#define ACP_HS_RX_RINGBUFADDR 0x3A90 +#define ACP_HS_RX_RINGBUFSIZE 0x3A94 +#define ACP_HS_RX_LINKPOSITIONCNTR 0x3A98 +#define ACP_HS_RX_FIFOADDR 0x3A9C +#define ACP_HS_RX_FIFOSIZE 0x3AA0 +#define ACP_HS_RX_DMA_SIZE 0x3AA4 +#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x3AA8 +#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x3AAC +#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x3AB0 +#define ACP_HS_TX_RINGBUFADDR 0x3AB4 +#define ACP_HS_TX_RINGBUFSIZE 0x3AB8 +#define ACP_HS_TX_LINKPOSITIONCNTR 0x3ABC +#define ACP_HS_TX_FIFOADDR 0x3AC0 +#define ACP_HS_TX_FIFOSIZE 0x3AC4 +#define ACP_HS_TX_DMA_SIZE 0x3AC8 +#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x3ACC +#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x3AD0 +#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x3AD4 #define ACP_I2STDM_IER 0x2400 #define ACP_I2STDM_IRER 0x2404 @@ -81,6 +99,13 @@ #define ACP_BTTDM_ITER 0x280C #define ACP_BTTDM_TXFRMT 0x2810 +/* Registers from ACP_HS_TDM block */ +#define ACP_HSTDM_IER 0x2814 +#define ACP_HSTDM_IRER 0x2818 +#define ACP_HSTDM_RXFRMT 0x281C +#define ACP_HSTDM_ITER 0x2820 +#define ACP_HSTDM_TXFRMT 0x2824 + /* Registers from ACP_WOV_PDM block */ #define ACP_WOV_PDM_ENABLE 0x2C04 @@ -101,4 +126,7 @@ #define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x2C64 #define ACP_WOV_ERROR_STATUS_REGISTER 0x2C68 +#define ACP_I2STDM0_MSTRCLKGEN 0x2414 +#define ACP_I2STDM1_MSTRCLKGEN 0x2418 +#define ACP_I2STDM2_MSTRCLKGEN 0x241C #endif -- GitLab From c50cea054e04769471d2f17a57fafd7c5dfe8df8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:42 +0200 Subject: [PATCH 841/942] ASoC: Intel: avs: Register HDAudio ext-bus operations With ASoC representation of HDAudio codec added, update bus initiazation to complete it. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 2 +- sound/soc/intel/avs/core.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index e5107a3ce16a5..ded903f95b67c 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -216,7 +216,7 @@ config SND_SOC_INTEL_AVS depends on COMMON_CLK select SND_SOC_ACPI if ACPI select SND_SOC_TOPOLOGY - select SND_HDA + select SND_SOC_HDA select SND_HDA_EXT_CORE select SND_HDA_DSP_LOADER select SND_INTEL_DSP_CONFIG diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 3a0997c3af2b9..664f87c33e9d1 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -23,6 +23,7 @@ #include #include #include +#include "../../codecs/hda.h" #include "avs.h" #include "cldma.h" @@ -356,7 +357,7 @@ static int avs_bus_init(struct avs_dev *adev, struct pci_dev *pci, const struct struct device *dev = &pci->dev; int ret; - ret = snd_hdac_ext_bus_init(&bus->core, dev, NULL, NULL); + ret = snd_hdac_ext_bus_init(&bus->core, dev, NULL, &soc_hda_ext_bus_ops); if (ret < 0) return ret; -- GitLab From 5f267aa4adad13f764e0b00926c349f8728fce77 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:43 +0200 Subject: [PATCH 842/942] ASoC: Intel: avs: Assign I2S gateway when parsing topology For formatted port - ssp%d - descriptions to have an effect, copier module templates need to be updated with specified port value. This value is later propagated to the firmware when module instances are being instantiated. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/topology.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 6a06fe387d13b..8a9f9fc48938e 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -808,6 +808,30 @@ static const struct avs_tplg_token_parser pin_format_parsers[] = { }, }; +static void +assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcfg_ext *cfg) +{ + struct snd_soc_acpi_mach *mach; + + if (!guid_equal(&cfg->type, &AVS_COPIER_MOD_UUID)) + return; + + /* Only I2S boards assign port instance in ->i2s_link_mask. */ + switch (cfg->copier.dma_type) { + case AVS_DMA_I2S_LINK_OUTPUT: + case AVS_DMA_I2S_LINK_INPUT: + break; + default: + return; + } + + mach = dev_get_platdata(comp->card->dev); + + /* Automatic assignment only when board describes single SSP. */ + if (hweight_long(mach->mach_params.i2s_link_mask) == 1 && !cfg->copier.vindex.i2s.instance) + cfg->copier.vindex.i2s.instance = __ffs(mach->mach_params.i2s_link_mask); +} + static int avs_tplg_parse_modcfg_ext(struct snd_soc_component *comp, struct avs_tplg_modcfg_ext *cfg, struct snd_soc_tplg_vendor_array *tuples, @@ -827,6 +851,9 @@ static int avs_tplg_parse_modcfg_ext(struct snd_soc_component *comp, if (ret) return ret; + /* Update copier gateway based on board's i2s_link_mask. */ + assign_copier_gtw_instance(comp, cfg); + block_size -= esize; /* Parse trailing in/out pin formats if any. */ if (block_size) { -- GitLab From 8192d24cccfbd93dadefd2b7553ff15e41d0e680 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:44 +0200 Subject: [PATCH 843/942] ASoC: Intel: avs: Relax DSP core transition timings To avoid any false positives when checking CPA after setting SPA, do a short wait. For stall operation, give HW more time to propagate the change before moving on. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/dsp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c index 06d2f7af520fe..b881100d3e02a 100644 --- a/sound/soc/intel/avs/dsp.c +++ b/sound/soc/intel/avs/dsp.c @@ -13,6 +13,7 @@ #define AVS_ADSPCS_INTERVAL_US 500 #define AVS_ADSPCS_TIMEOUT_US 50000 +#define AVS_ADSPCS_DELAY_US 1000 int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power) { @@ -26,6 +27,8 @@ int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power) value = power ? mask : 0; snd_hdac_adsp_updatel(adev, AVS_ADSP_REG_ADSPCS, mask, value); + /* Delay the polling to avoid false positives. */ + usleep_range(AVS_ADSPCS_DELAY_US, 2 * AVS_ADSPCS_DELAY_US); mask = AVS_ADSPCS_CPA_MASK(core_mask); value = power ? mask : 0; @@ -82,11 +85,15 @@ int avs_dsp_core_stall(struct avs_dev *adev, u32 core_mask, bool stall) reg, (reg & mask) == value, AVS_ADSPCS_INTERVAL_US, AVS_ADSPCS_TIMEOUT_US); - if (ret) + if (ret) { dev_err(adev->dev, "core_mask %d %sstall failed: %d\n", core_mask, stall ? "" : "un", ret); + return ret; + } - return ret; + /* Give HW time to propagate the change. */ + usleep_range(AVS_ADSPCS_DELAY_US, 2 * AVS_ADSPCS_DELAY_US); + return 0; } int avs_dsp_core_enable(struct avs_dev *adev, u32 core_mask) -- GitLab From 3c1923a119a61534f8ce221766041ddf470c9307 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:45 +0200 Subject: [PATCH 844/942] ASoC: Intel: avs: Copy only as many RX bytes as necessary There is no need to copy number of bytes specified by IPC message caller if DSP firmware returned lower number. In consequence, LARGE_CONFIG_GET handler is simplified. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/ipc.c | 1 + sound/soc/intel/avs/messages.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index d755ba8b85188..020d85c7520de 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -480,6 +480,7 @@ static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request ret = ipc->rx.rsp.status; if (reply) { reply->header = ipc->rx.header; + reply->size = ipc->rx.size; if (reply->data && ipc->rx.size) memcpy(reply->data, ipc->rx.data, reply->size); } diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 6404fce8cde45..3559fb496e0bf 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -378,7 +378,6 @@ int avs_ipc_get_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id union avs_module_msg msg = AVS_MODULE_REQUEST(LARGE_CONFIG_GET); struct avs_ipc_msg request; struct avs_ipc_msg reply = {{0}}; - size_t size; void *buf; int ret; @@ -406,15 +405,14 @@ int avs_ipc_get_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id return ret; } - size = reply.rsp.ext.large_config.data_off_size; - buf = krealloc(reply.data, size, GFP_KERNEL); + buf = krealloc(reply.data, reply.size, GFP_KERNEL); if (!buf) { kfree(reply.data); return -ENOMEM; } *reply_data = buf; - *reply_size = size; + *reply_size = reply.size; return 0; } -- GitLab From 00566ad4ce9d394c6ebaacde12eda06eef4e5279 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:46 +0200 Subject: [PATCH 845/942] ASoC: Intel: avs: Shield LARGE_CONFIG_GETs against zero payload_size Some LARGE_CONFIG_GETs are never expected to return payload of size 0. Check for such situation and collapse if met. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 3559fb496e0bf..9cf621eaec5aa 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -474,6 +474,9 @@ int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg) &payload, &payload_size); if (ret) return ret; + /* Non-zero payload expected for FIRMWARE_CONFIG. */ + if (!payload_size) + return -EREMOTEIO; while (offset < payload_size) { tlv = (struct avs_tlv *)(payload + offset); @@ -587,6 +590,9 @@ int avs_ipc_get_hw_config(struct avs_dev *adev, struct avs_hw_cfg *cfg) &payload, &payload_size); if (ret) return ret; + /* Non-zero payload expected for HARDWARE_CONFIG. */ + if (!payload_size) + return -EREMOTEIO; while (offset < payload_size) { tlv = (struct avs_tlv *)(payload + offset); @@ -670,6 +676,9 @@ int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info) &payload, &payload_size); if (ret) return ret; + /* Non-zero payload expected for MODULES_INFO. */ + if (!payload_size) + return -EREMOTEIO; *info = (struct avs_mods_info *)payload; return 0; -- GitLab From daa36bbcd78bca24db84e273bcafec9a8f81c767 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:47 +0200 Subject: [PATCH 846/942] ASoC: Intel: avs: Block IPC channel on suspend To allow for driver's filesystem interfaces e.g.: debugfs, to be touched even when the device is asleep, mark IPC-channel as blocked when the device is suspended. This causes any invocation of said interfaces that do not toggle PM themselves to gracefully fail with "Operation not permitted" message. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 664f87c33e9d1..4234adeb3d1c4 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -556,6 +556,7 @@ static int __maybe_unused avs_suspend_common(struct avs_dev *adev) return AVS_IPC_RET(ret); } + avs_ipc_block(adev->ipc); avs_dsp_op(adev, int_control, false); snd_hdac_ext_bus_ppcap_int_enable(bus, false); -- GitLab From 8544eebc78c96f1834a46b26ade3e7ebe785d10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:41:48 +0200 Subject: [PATCH 847/942] ASoC: Intel: avs: Set max DMA segment size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently it is possible for code to allocate large buffers which may cause warnings as reported in [1]. This was fixed for HDA, SOF and skylake in patchset [2], fix it also for avs driver. [1] https://github.com/thesofproject/linux/issues/3430 [2] https://lore.kernel.org/all/20220215132756.31236-1-tiwai@suse.de/ Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 4234adeb3d1c4..6a35bf45efcb5 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -446,6 +446,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) dma_set_mask(dev, DMA_BIT_MASK(32)); dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); } + dma_set_max_seg_size(dev, UINT_MAX); ret = avs_hdac_bus_init_streams(bus); if (ret < 0) { -- GitLab From a5bbbde2b81e41cea7fa1b38911e88da5febc2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:41:49 +0200 Subject: [PATCH 848/942] ASoC: Intel: avs: Use helper function to set up DMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dma_set_mask() and dma_set_coherent_mask() can be performed with one call to dma_set_mask_and_coherent(), which slightly reduces amount of code on our side. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 6a35bf45efcb5..c50c20fd681a1 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -440,12 +440,8 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) if (bus->mlcap) snd_hdac_ext_bus_get_ml_capabilities(bus); - if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { - dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); - } else { - dma_set_mask(dev, DMA_BIT_MASK(32)); - dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - } + if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) + dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); dma_set_max_seg_size(dev, UINT_MAX); ret = avs_hdac_bus_init_streams(bus); -- GitLab From 79c351fb50e7e37eacf93f55f1e7056148d0d814 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:50 +0200 Subject: [PATCH 849/942] ASoC: Intel: avs: Recognize FW_CFG_RESERVED If exposed by firmware, count RESERVED parameter as known one to avoid dumping noise in kernel logs. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 9cf621eaec5aa..28a948cf790f0 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -562,6 +562,7 @@ int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg) case AVS_FW_CFG_DMA_BUFFER_CONFIG: case AVS_FW_CFG_SCHEDULER_CONFIG: case AVS_FW_CFG_CLOCKS_CONFIG: + case AVS_FW_CFG_RESERVED: break; default: -- GitLab From 4b38bd16ca6d8b16c1dc2cc4aa61663193b0b893 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:51 +0200 Subject: [PATCH 850/942] ASoC: Intel: avs: Replace hardcodes with SD_CTL_STREAM_RESET Improve readability of CLDMA reset operation by making use of already defined SD_CTL_STREAM_RESET. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/cldma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/intel/avs/cldma.c b/sound/soc/intel/avs/cldma.c index d100c6ba4d8aa..d7a9390b5e483 100644 --- a/sound/soc/intel/avs/cldma.c +++ b/sound/soc/intel/avs/cldma.c @@ -176,17 +176,17 @@ int hda_cldma_reset(struct hda_cldma *cl) return ret; } - snd_hdac_stream_updateb(cl, SD_CTL, 1, 1); - ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, (reg & 1), AVS_CL_OP_INTERVAL_US, - AVS_CL_OP_TIMEOUT_US); + snd_hdac_stream_updateb(cl, SD_CTL, SD_CTL_STREAM_RESET, SD_CTL_STREAM_RESET); + ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, (reg & SD_CTL_STREAM_RESET), + AVS_CL_OP_INTERVAL_US, AVS_CL_OP_TIMEOUT_US); if (ret < 0) { dev_err(cl->dev, "cldma set SRST failed: %d\n", ret); return ret; } - snd_hdac_stream_updateb(cl, SD_CTL, 1, 0); - ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, !(reg & 1), AVS_CL_OP_INTERVAL_US, - AVS_CL_OP_TIMEOUT_US); + snd_hdac_stream_updateb(cl, SD_CTL, SD_CTL_STREAM_RESET, 0); + ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, !(reg & SD_CTL_STREAM_RESET), + AVS_CL_OP_INTERVAL_US, AVS_CL_OP_TIMEOUT_US); if (ret < 0) { dev_err(cl->dev, "cldma unset SRST failed: %d\n", ret); return ret; -- GitLab From 8758ae88f0f4ade16e6a1b709eb5ea7271f62320 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:52 +0200 Subject: [PATCH 851/942] ASoC: Intel: avs: Lower UNLOAD_MULTIPLE_MODULES IPC timeout Module unloading operation performs memory unmapping and the weight of the opration does not different from any other standard IPC. There is no dependency on secondary task like in module loading scenario where larger message timeout is recommended. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 28a948cf790f0..d4bcee1aabcf2 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -59,7 +59,7 @@ int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids) request.data = mod_ids; request.size = sizeof(*mod_ids) * num_mod_ids; - ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS); + ret = avs_dsp_send_msg(adev, &request, NULL); if (ret) avs_ipc_err(adev, &request, "unload multiple modules", ret); -- GitLab From f1eea11523e4394d6670f10a51356e9b7c8567a8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 7 Jul 2022 14:41:53 +0200 Subject: [PATCH 852/942] ASoC: Intel: avs: Update AVS_FW_INIT_TIMEOUT_US declaration To reduce the number of places to update if timeouts would have to change, modify the constant declaration. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707124153.1858249-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index 542fd44aa501e..9e3f8ff33a87a 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -27,8 +27,8 @@ #define APL_ROM_INIT_RETRIES 3 #define AVS_FW_INIT_POLLING_US 500 -#define AVS_FW_INIT_TIMEOUT_US 3000000 #define AVS_FW_INIT_TIMEOUT_MS 3000 +#define AVS_FW_INIT_TIMEOUT_US (AVS_FW_INIT_TIMEOUT_MS * 1000) #define AVS_CLDMA_START_DELAY_MS 100 -- GitLab From b737fd8cf196bc96e471304007c3cd9b78672069 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Fri, 8 Jul 2022 15:05:15 -0500 Subject: [PATCH 853/942] ASoC: SOF: ipc4-topology: check dai->private in ipc_free() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the swidget->private or dai->private to NULL after kfree in the error handling in ipc_setup(). The private needs to be set NULL because if ipc_setup() returns error, ipc_free() will be called later. ipc_free() will judge the private is NULL or not to do the clearing. For dai widget, dai->private is allocated and set in dai widget ipc_setup(). So we need to check dai->private is NULL or not in the ipc_free(). Fixes: 2cabd02b6090 ("ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets") Fixes: abfb536bd116 ("ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets") Fixes: 4f838ab20812 ("ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets") Fixes: 4d4ba014ac4b ("ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets") Reviewed-by: Péter Ujfalusi Signed-off-by: Libin Yang Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220708200516.26853-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 34f805431f2eb..2d157ea79db5e 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -394,6 +394,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) kfree(available_fmt->dma_buffer_size); free_copier: kfree(ipc4_copier); + swidget->private = NULL; return ret; } @@ -541,6 +542,8 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) kfree(available_fmt->dma_buffer_size); free_copier: kfree(ipc4_copier); + dai->private = NULL; + dai->scomp = NULL; return ret; } @@ -553,6 +556,12 @@ static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget) if (!dai) return; + if (!dai->private) { + kfree(dai); + swidget->private = NULL; + return; + } + ipc4_copier = dai->private; available_fmt = &ipc4_copier->available_fmt; @@ -669,6 +678,7 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) return 0; err: kfree(gain); + swidget->private = NULL; return ret; } @@ -698,6 +708,7 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) return 0; err: kfree(mixer); + swidget->private = NULL; return ret; } -- GitLab From dc4fc0ae94cf87f1017f158b6fa2b7536ef29b4e Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Fri, 8 Jul 2022 15:05:16 -0500 Subject: [PATCH 854/942] ASoC: SOF: ipc4-topology: free memories allocated in sof_ipc4_get_audio_fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Free the memories allocated in sof_ipc4_get_audio_fmt in error handling and ipc_free() Fixes: 2cabd02b6090 ("ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets") Fixes: abfb536bd116 ("ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets") Fixes: 4f838ab20812 ("ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets") Fixes: 4d4ba014ac4b ("ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets") Reviewed-by: Péter Ujfalusi Signed-off-by: Libin Yang Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220708200516.26853-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc4-topology.c | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 2d157ea79db5e..22ea628d78d07 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -263,6 +263,16 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, return ret; } +/* release the memory allocated in sof_ipc4_get_audio_fmt */ +static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt) + +{ + kfree(available_fmt->base_config); + available_fmt->base_config = NULL; + kfree(available_fmt->out_audio_fmt); + available_fmt->out_audio_fmt = NULL; +} + static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget) { kfree(swidget->private); @@ -341,7 +351,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) GFP_KERNEL); if (!available_fmt->dma_buffer_size) { ret = -ENOMEM; - goto free_copier; + goto free_available_fmt; } ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, @@ -392,6 +402,8 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) kfree(ipc4_copier->gtw_attr); err: kfree(available_fmt->dma_buffer_size); +free_available_fmt: + sof_ipc4_free_audio_fmt(available_fmt); free_copier: kfree(ipc4_copier); swidget->private = NULL; @@ -440,7 +452,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) GFP_KERNEL); if (!available_fmt->dma_buffer_size) { ret = -ENOMEM; - goto free_copier; + goto free_available_fmt; } ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, @@ -540,6 +552,8 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) kfree(ipc4_copier->copier_config); err: kfree(available_fmt->dma_buffer_size); +free_available_fmt: + sof_ipc4_free_audio_fmt(available_fmt); free_copier: kfree(ipc4_copier); dai->private = NULL; @@ -677,11 +691,24 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) return 0; err: + sof_ipc4_free_audio_fmt(&gain->available_fmt); kfree(gain); swidget->private = NULL; return ret; } +static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_gain *gain = swidget->private; + + if (!gain) + return; + + sof_ipc4_free_audio_fmt(&gain->available_fmt); + kfree(swidget->private); + swidget->private = NULL; +} + static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) { struct snd_soc_component *scomp = swidget->scomp; @@ -707,11 +734,24 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) return 0; err: + sof_ipc4_free_audio_fmt(&mixer->available_fmt); kfree(mixer); swidget->private = NULL; return ret; } +static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget) +{ + struct sof_ipc4_mixer *mixer = swidget->private; + + if (!mixer) + return; + + sof_ipc4_free_audio_fmt(&mixer->available_fmt); + kfree(swidget->private); + swidget->private = NULL; +} + static void sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, struct sof_ipc4_base_module_cfg *base_config) @@ -1746,11 +1786,11 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp, pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, NULL, NULL}, - [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp, + [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga, pga_token_list, ARRAY_SIZE(pga_token_list), NULL, sof_ipc4_prepare_gain_module, sof_ipc4_unprepare_generic_module}, - [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp, + [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer, mixer_token_list, ARRAY_SIZE(mixer_token_list), NULL, sof_ipc4_prepare_mixer_module, sof_ipc4_unprepare_generic_module}, -- GitLab From 0fcc43e2e159f2f609686a5339093177f019ae26 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 14:02:23 +0200 Subject: [PATCH 855/942] ALSA: hda: Fix null-ptr-deref when i915 fails and hdmi is denylisted If snd_hda_hdmi_codec module is denylisted and any event causes i915 enumeration to fail, is_likely_hdmi_codec() ends in null-ptr-deref. As snd_soc_hda is an ASoC-based driver, its initialization is delayed until all the necessary components appear in the system - allowing actual sound card to enumerate. snd_hda_codec_configure() gets called by the avs-driver core during probe_codecs() but the snd_hda_codec_device_new(), necessary to complete codecs initialization, happens only when codec-component of hda sound card is being probed. Denylisting snd_hda_codec_hdmi module causes snd_hda_codec_configure() to reach: codec_bind_generic() -> is_likely_hdmi_codec() which makes use of ->wcaps and at this point the it isn't initialized yet - again, requires completion of snd_hda_codec_device_new(). Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-3-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_bind.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index c572fb5886d5d..cae9a975cbcca 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -248,6 +248,13 @@ static bool is_likely_hdmi_codec(struct hda_codec *codec) { hda_nid_t nid; + /* + * For ASoC users, if snd_hda_hdmi_codec module is denylisted and any + * event causes i915 enumeration to fail, ->wcaps remains uninitialized. + */ + if (!codec->wcaps) + return true; + for_each_hda_codec_node(nid, codec) { unsigned int wcaps = get_wcaps(codec, nid); switch (get_wcaps_type(wcaps)) { -- GitLab From 9c76958b396a1342f08f205c350447b4bb54b26a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 14:02:24 +0200 Subject: [PATCH 856/942] ALSA: hda: Make device usage_count consistent across subsequent probing AVS HDAudio bus driver does not tie with codec drivers tighly and snd_hda_codec_device_new() can be called after codec's module reload. In such case, rpm is forbidden and invoking pm_runtime_forbid() unconditionally causes device's usage_count to become unbalanced. This is later caught by WARN_ON() found in sound/soc/hda.c. Detect such circumstance and bump the usage_count instead. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-4-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7579a6982f471..018067addd86d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1045,8 +1045,14 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, goto error; } +#ifdef CONFIG_PM /* PM runtime needs to be enabled later after binding codec */ - pm_runtime_forbid(&codec->core.dev); + if (codec->core.dev.power.runtime_auto) + pm_runtime_forbid(&codec->core.dev); + else + /* Keep the usage_count consistent across subsequent probing */ + pm_runtime_get_noresume(&codec->core.dev); +#endif return 0; -- GitLab From ebe043a3dfcade2756a41a3956365e1bfe4198cf Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 14:02:25 +0200 Subject: [PATCH 857/942] ALSA: hda: Fix put_device() inconsistency in error path AVS HDAudio bus driver does not tie with codec drivers tighly. Codec device and its respective driver cleanup procedures are split and may not occur one after the other. Device cleanup is performed only on snd_hdac_ext_bus_device_remove() i.e. it's the bus driver's responsibility. If codec component probing fails, put_device() found in snd_hda_codec_device_new() may lead to page fault. Relocate it to snd_hda_codec_new() to address the problem on ASoC side while keeping status quo for snd_hda_intel. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-5-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 018067addd86d..e8a5d0e4105b4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -950,6 +950,7 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, unsigned int codec_addr, struct hda_codec **codecp) { struct hda_codec *codec; + int ret; codec = snd_hda_codec_device_init(bus, codec_addr, "hdaudioC%dD%d", card->number, codec_addr); @@ -957,7 +958,11 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, return PTR_ERR(codec); *codecp = codec; - return snd_hda_codec_device_new(bus, card, codec_addr, *codecp, true); + ret = snd_hda_codec_device_new(bus, card, codec_addr, *codecp, true); + if (ret) + put_device(hda_codec_dev(*codecp)); + + return ret; } EXPORT_SYMBOL_GPL(snd_hda_codec_new); @@ -1012,19 +1017,17 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, if (codec->bus->modelname) { codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); - if (!codec->modelname) { - err = -ENOMEM; - goto error; - } + if (!codec->modelname) + return -ENOMEM; } fg = codec->core.afg ? codec->core.afg : codec->core.mfg; err = read_widget_caps(codec, fg); if (err < 0) - goto error; + return err; err = read_pin_defaults(codec); if (err < 0) - goto error; + return err; /* power-up all before initialization */ hda_set_power_state(codec, AC_PWRST_D0); @@ -1042,7 +1045,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, /* ASoC features component management instead */ err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops); if (err < 0) - goto error; + return err; } #ifdef CONFIG_PM @@ -1055,10 +1058,6 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, #endif return 0; - - error: - put_device(hda_codec_dev(codec)); - return err; } EXPORT_SYMBOL_GPL(snd_hda_codec_device_new); -- GitLab From 980b3a8790b402e959a6d773b38b771019682be1 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 14:02:27 +0200 Subject: [PATCH 858/942] ALSA: hda: Fix page fault in snd_hda_codec_shutdown() If early probe of HDAudio bus driver fails e.g.: due to missing firmware file, snd_hda_codec_shutdown() ends in manipulating uninitialized codec->pcm_list_head causing page fault. Iinitialization of HDAudio codec in ASoC is split in two: - snd_hda_codec_device_init() - snd_hda_codec_device_new() snd_hda_codec_device_init() is called during probe_codecs() by HDAudio bus driver while snd_hda_codec_device_new() is called by codec-component's ->probe(). The second call will not happen until all components required by related sound card are present within the ASoC framework. With firmware failing to load during the PCI's deferred initialization i.e.: probe_work(), no platform components are ever registered. HDAudio codec enumeration is done at that point though, so the codec components became registered to ASoC framework, calling snd_hda_codec_device_init() in the process. Now, during platform reboot snd_hda_codec_shutdown() is called for every codec found on the HDAudio bus causing oops if any of them has not completed both of their initialization steps. Relocating field initialization fixes the issue. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-7-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 41 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e8a5d0e4105b4..b1921f9205132 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -931,8 +931,28 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr, } codec->bus = bus; + codec->depop_delay = -1; + codec->fixup_id = HDA_FIXUP_ID_NOT_SET; + codec->core.dev.release = snd_hda_codec_dev_release; + codec->core.exec_verb = codec_exec_verb; codec->core.type = HDA_DEV_LEGACY; + mutex_init(&codec->spdif_mutex); + mutex_init(&codec->control_mutex); + snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); + snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); + snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); + snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); + snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); + snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); + snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); + snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); + INIT_LIST_HEAD(&codec->conn_list); + INIT_LIST_HEAD(&codec->pcm_list_head); + INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); + refcount_set(&codec->pcm_ref, 1); + init_waitqueue_head(&codec->remove_sleep); + return codec; } EXPORT_SYMBOL_GPL(snd_hda_codec_device_init); @@ -985,29 +1005,8 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) return -EINVAL; - codec->core.dev.release = snd_hda_codec_dev_release; - codec->core.exec_verb = codec_exec_verb; - codec->card = card; codec->addr = codec_addr; - mutex_init(&codec->spdif_mutex); - mutex_init(&codec->control_mutex); - snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); - snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); - snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); - snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); - snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); - snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); - snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); - snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); - INIT_LIST_HEAD(&codec->conn_list); - INIT_LIST_HEAD(&codec->pcm_list_head); - refcount_set(&codec->pcm_ref, 1); - init_waitqueue_head(&codec->remove_sleep); - - INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); - codec->depop_delay = -1; - codec->fixup_id = HDA_FIXUP_ID_NOT_SET; #ifdef CONFIG_PM codec->power_jiffies = jiffies; -- GitLab From 856282f166d7b95004e70859ca87cf33eb7f9a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 6 Jul 2022 14:02:28 +0200 Subject: [PATCH 859/942] ALSA: hda: Reset all SIE bits in INTCTL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Old code resets SIE for up to 8 streams using byte accessor, but register is laid out in following way: 31 GIE 30 CIE 29:x Reserved x-1:0 SIE If there is more than 8 streams, some of them may and up with enabled interrupts. To fix this just clear whole INTCTL register when disabling interrupts. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-8-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/hda/hdac_controller.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index f7bd6e2db085b..9a60bfdb39bac 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -474,11 +474,8 @@ static void azx_int_disable(struct hdac_bus *bus) list_for_each_entry(azx_dev, &bus->stream_list, list) snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0); - /* disable SIE for all streams */ - snd_hdac_chip_writeb(bus, INTCTL, 0); - - /* disable controller CIE and GIE */ - snd_hdac_chip_updatel(bus, INTCTL, AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN, 0); + /* disable SIE for all streams & disable controller CIE and GIE */ + snd_hdac_chip_writel(bus, INTCTL, 0); } /* clear interrupts */ -- GitLab From 0440741254ed27bd695d994f00358647c92ed832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 6 Jul 2022 14:02:29 +0200 Subject: [PATCH 860/942] ALSA: hda: Remove unused macro definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not used anywhere in the file, so there is no need to keep it. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-9-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- sound/hda/ext/hdac_ext_controller.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index b072392725c74..a42f66f561f57 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -14,13 +14,6 @@ #include #include -/* - * maximum HDAC capablities we should parse to avoid endless looping: - * currently we have 4 extended caps, so this is future proof for now. - * extend when this limit is seen meeting in real HW - */ -#define HDAC_MAX_CAPS 10 - /* * processing pipe helpers - these helpers are useful for dealing with HDA * new capability of processing pipelines -- GitLab From 19bb587f3ffcb9c166bac2debdc3b08fb362c0b7 Mon Sep 17 00:00:00 2001 From: Zhongjun Tan Date: Fri, 8 Jul 2022 10:46:51 +0800 Subject: [PATCH 861/942] ASoC: mediatek: mt8186: Remove condition with no effect Remove condition with no effect Signed-off-by: Zhongjun Tan Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220708024651.42999-1-hbut_tan@163.com Signed-off-by: Mark Brown --- sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c index db71b032770dd..6be6d4f3b5850 100644 --- a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c @@ -295,8 +295,6 @@ static int mtk_adda_pad_top_event(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_PRE_PMU: if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x39); - else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) - regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); else regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); break; -- GitLab From eaa27e7fe43f16fe587c3e93fd5c25ce86be3c43 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 11 Jul 2022 10:39:50 +0800 Subject: [PATCH 862/942] ASoC: fsl_utils: Drop usage of __clk_get_name() Avoid build errors when CONFIG_COMMON_CLK is not set/enabled. ERROR: modpost: "__clk_get_name" [sound/soc/fsl/snd-soc-fsl-utils.ko] undefined! Fixes: 7bad8125549c ("ASoC: fsl_utils: Add function to handle PLL clock source") Reported-by: kernel test robot Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1657507190-14546-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c index 3e969c7bc1c52..d0fc430f7033d 100644 --- a/sound/soc/fsl/fsl_utils.c +++ b/sound/soc/fsl/fsl_utils.c @@ -147,7 +147,7 @@ void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk, if (reparent) { ret = clk_set_parent(p, npll); if (ret < 0) - dev_warn(dev, "failed to set parent %s: %d\n", __clk_get_name(npll), ret); + dev_warn(dev, "failed to set parent:%d\n", ret); } } EXPORT_SYMBOL(fsl_asoc_reparent_pll_clocks); -- GitLab From 9b6803ec1fe0f10942b9297d2d60ec46f2999323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:56:57 +0200 Subject: [PATCH 863/942] ASoC: codecs: rt298: Fix NULL jack in interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set rt298->jack to passed value in mic_detect, otherwise when jack is set to NULL on next interrupt call, we may use freed pointer. Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707125701.3518263-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 266a2cc55b8d6..6a615943f9835 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -335,6 +335,8 @@ static int rt298_mic_detect(struct snd_soc_component *component, bool mic = false; int status = 0; + rt298->jack = jack; + /* If jack in NULL, disable HS jack */ if (!jack) { regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0); @@ -344,7 +346,6 @@ static int rt298_mic_detect(struct snd_soc_component *component, return 0; } - rt298->jack = jack; regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); rt298_jack_detect(rt298, &hp, &mic); -- GitLab From c0c5a242bba878b4d34f7c9612fd6cd6c404d414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:56:58 +0200 Subject: [PATCH 864/942] ASoC: codecs: rt298: Fix jack detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On our RVP platforms using rt298 with combojack we've seen issues with controls being in incorrect state after suspend/resume cycle. This is caused by codec driver not setting pins to correct state and causing codec suspend method to not be called. Which on resume caused codec registers to be in undefined state. Fix this by setting pins correctly in jack detect function. Above problem is caused by the fact that when jack == NULL code doesn't reach rt298_jack_detect() function which sets pins. Alternatively problem could be fixed by just moving rt298_jack_detect, but as rt298 codec is similar to rt286, align the code by setting pins explicitly. Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707125701.3518263-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index 6a615943f9835..e1d94f128fd94 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -329,34 +329,31 @@ static void rt298_jack_detect_work(struct work_struct *work) static int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack, void *data) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm; - bool hp = false; - bool mic = false; - int status = 0; rt298->jack = jack; - /* If jack in NULL, disable HS jack */ - if (!jack) { + if (jack) { + /* Enable IRQ */ + if (rt298->jack->status & SND_JACK_HEADPHONE) + snd_soc_dapm_force_enable_pin(dapm, "LDO1"); + if (rt298->jack->status & SND_JACK_MICROPHONE) { + snd_soc_dapm_force_enable_pin(dapm, "HV"); + snd_soc_dapm_force_enable_pin(dapm, "VREF"); + } + regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); + /* Send an initial empty report */ + snd_soc_jack_report(rt298->jack, rt298->jack->status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + } else { + /* Disable IRQ */ regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0); - dapm = snd_soc_component_get_dapm(component); + snd_soc_dapm_disable_pin(dapm, "HV"); + snd_soc_dapm_disable_pin(dapm, "VREF"); snd_soc_dapm_disable_pin(dapm, "LDO1"); - snd_soc_dapm_sync(dapm); - return 0; } - - regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); - - rt298_jack_detect(rt298, &hp, &mic); - if (hp) - status |= SND_JACK_HEADPHONE; - - if (mic) - status |= SND_JACK_MICROPHONE; - - snd_soc_jack_report(rt298->jack, status, - SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + snd_soc_dapm_sync(dapm); return 0; } -- GitLab From c1d7ebda11aae4659b665af61d7277dd351659b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:56:59 +0200 Subject: [PATCH 865/942] ASoC: codecs: rt286: Set component to NULL on remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that component is set to proper value, otherwise we may dereference freed component in interrupt. Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707125701.3518263-4-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt286.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index b2b0b2b1e4d06..c4f7c4c2d7939 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -960,6 +960,7 @@ static void rt286_remove(struct snd_soc_component *component) struct rt286_priv *rt286 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt286->jack_detect_work); + rt286->component = NULL; } #ifdef CONFIG_PM -- GitLab From af3b33b9707d453a12e0cf5ac35d7b97b3524ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:57:00 +0200 Subject: [PATCH 866/942] ASoC: codecs: rt298: Set component to NULL on remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that component is set to proper value, otherwise we may dereference freed component in interrupt. Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707125701.3518263-5-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt298.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index e1d94f128fd94..b0b53d4f07df9 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1022,6 +1022,7 @@ static void rt298_remove(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt298->jack_detect_work); + rt298->component = NULL; } #ifdef CONFIG_PM -- GitLab From b9f098aa7ae2a022dee06a8ca363e3e0e077f05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Thu, 7 Jul 2022 14:57:01 +0200 Subject: [PATCH 867/942] ASoC: codecs: rt274: Set component to NULL on remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that component is set to proper value, otherwise we may dereference freed component in interrupt. Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220707125701.3518263-6-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt274.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c index 6b208f9eb5035..f2c50b11e4d0c 100644 --- a/sound/soc/codecs/rt274.c +++ b/sound/soc/codecs/rt274.c @@ -993,6 +993,7 @@ static void rt274_remove(struct snd_soc_component *component) struct rt274_priv *rt274 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt274->jack_detect_work); + rt274->component = NULL; } #ifdef CONFIG_PM -- GitLab From 375f53566cf04324825b7a0f545aeb4405963bd0 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 11 Jul 2022 14:22:12 +0300 Subject: [PATCH 868/942] ASoC: atmel: mchp-pdmc: remove space in front of mchp_pdmc_dt_init() Remove extra space in front of mchp_pdmc_dt_init(). Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220711112212.888895-1-claudiu.beznea@microchip.com Signed-off-by: Mark Brown --- sound/soc/atmel/mchp-pdmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index aba7c5cde62c6..44aefbd5b62c7 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -985,7 +985,7 @@ static int mchp_pdmc_probe(struct platform_device *pdev) return -ENOMEM; dd->dev = &pdev->dev; - ret = mchp_pdmc_dt_init(dd); + ret = mchp_pdmc_dt_init(dd); if (ret < 0) return ret; -- GitLab From fd1c769d33872d6c7ec474c199f6a910d3555927 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 8 Jul 2022 15:07:19 -0500 Subject: [PATCH 869/942] ASoC: SOF: remove warning on ABI checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should only have an error when enforcing strict mapping between kernel and firmware versions. In all other cases, there is no reason to throw a warning. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220708200719.26961-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 13 ++++--------- sound/soc/sof/ipc3.c | 11 ++++------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 99b62fe7a95cd..9448d5338423a 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -2348,15 +2348,10 @@ static int sof_ipc3_parse_manifest(struct snd_soc_component *scomp, int index, return -EINVAL; } - if (SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { - dev_warn(scomp->dev, "%s: Topology ABI is more recent than kernel\n", - __func__); - } else { - dev_err(scomp->dev, "%s: Topology ABI is more recent than kernel\n", - __func__); - return -EINVAL; - } + if (IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS) && + SOF_ABI_VERSION_MINOR(abi_version) > SOF_ABI_MINOR) { + dev_err(scomp->dev, "%s: Topology ABI is more recent than kernel\n", __func__); + return -EINVAL; } return 0; diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c index 1fb132b477bf2..82fa320253bef 100644 --- a/sound/soc/sof/ipc3.c +++ b/sound/soc/sof/ipc3.c @@ -758,13 +758,10 @@ int sof_ipc3_validate_fw_version(struct snd_sof_dev *sdev) return -EINVAL; } - if (SOF_ABI_VERSION_MINOR(v->abi_version) > SOF_ABI_MINOR) { - if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) { - dev_warn(sdev->dev, "FW ABI is more recent than kernel\n"); - } else { - dev_err(sdev->dev, "FW ABI is more recent than kernel\n"); - return -EINVAL; - } + if (IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS) && + SOF_ABI_VERSION_MINOR(v->abi_version) > SOF_ABI_MINOR) { + dev_err(sdev->dev, "FW ABI is more recent than kernel\n"); + return -EINVAL; } if (ready->flags & SOF_IPC_INFO_BUILD) { -- GitLab From 2551b6e89936f98406bce9c1d50110e3ff443f81 Mon Sep 17 00:00:00 2001 From: Seven Lee Date: Mon, 27 Jun 2022 11:29:59 +0800 Subject: [PATCH 870/942] ASoC: nau8821: Add headset button detection This patch adds the function of headphone button detection, Button detection will be enabled if the device tree has a key_enable property. Signed-off-by: Seven Lee Link: https://lore.kernel.org/r/20220627032959.3442064-1-wtli@nuvoton.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/nau8821.txt | 2 +- sound/soc/codecs/nau8821.c | 35 +++++++++++++++++++ sound/soc/codecs/nau8821.h | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/sound/nau8821.txt b/Documentation/devicetree/bindings/sound/nau8821.txt index 6c3baf7a5f21d..7c84e7c7327a7 100644 --- a/Documentation/devicetree/bindings/sound/nau8821.txt +++ b/Documentation/devicetree/bindings/sound/nau8821.txt @@ -34,7 +34,7 @@ Optional properties: - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms - nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock. - + - nuvoton,key_enable: Headset button detection switch. Example: diff --git a/sound/soc/codecs/nau8821.c b/sound/soc/codecs/nau8821.c index 6453e93678d22..2600be250a3c6 100644 --- a/sound/soc/codecs/nau8821.c +++ b/sound/soc/codecs/nau8821.c @@ -29,6 +29,8 @@ #define NAU_FVCO_MAX 100000000 #define NAU_FVCO_MIN 90000000 +#define NAU8821_BUTTON SND_JACK_BTN_0 + /* the maximum frequency of CLK_ADC and CLK_DAC */ #define CLK_DA_AD_MAX 6144000 @@ -911,6 +913,20 @@ static void nau8821_eject_jack(struct nau8821 *nau8821) /* Recover to normal channel input */ regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, NAU8821_ADC_R_SRC_EN, 0); + if (nau8821->key_enable) { + regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN); + regmap_update_bits(regmap, + NAU8821_R12_INTERRUPT_DIS_CTRL, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS); + } + } static void nau8821_jdet_work(struct work_struct *work) @@ -940,6 +956,15 @@ static void nau8821_jdet_work(struct work_struct *work) */ regmap_update_bits(regmap, NAU8821_R2B_ADC_RATE, NAU8821_ADC_R_SRC_EN, NAU8821_ADC_R_SRC_EN); + if (nau8821->key_enable) { + regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK, + NAU8821_IRQ_KEY_RELEASE_EN | + NAU8821_IRQ_KEY_PRESS_EN, 0); + regmap_update_bits(regmap, + NAU8821_R12_INTERRUPT_DIS_CTRL, + NAU8821_IRQ_KEY_RELEASE_DIS | + NAU8821_IRQ_KEY_PRESS_DIS, 0); + } } else { dev_dbg(nau8821->dev, "Headphone connected\n"); event |= SND_JACK_HEADPHONE; @@ -999,6 +1024,13 @@ static irqreturn_t nau8821_interrupt(int irq, void *data) nau8821_eject_jack(nau8821); event_mask |= SND_JACK_HEADSET; clear_irq = NAU8821_JACK_EJECT_IRQ_MASK; + } else if (active_irq & NAU8821_KEY_SHORT_PRESS_IRQ) { + event |= NAU8821_BUTTON; + event_mask |= NAU8821_BUTTON; + clear_irq = NAU8821_KEY_SHORT_PRESS_IRQ; + } else if (active_irq & NAU8821_KEY_RELEASE_IRQ) { + event_mask = NAU8821_BUTTON; + clear_irq = NAU8821_KEY_RELEASE_IRQ; } else if ((active_irq & NAU8821_JACK_INSERT_IRQ_MASK) == NAU8821_JACK_INSERT_DETECTED) { regmap_update_bits(regmap, NAU8821_R71_ANALOG_ADC_1, @@ -1489,6 +1521,7 @@ static void nau8821_print_device_properties(struct nau8821 *nau8821) nau8821->jack_eject_debounce); dev_dbg(dev, "dmic-clk-threshold: %d\n", nau8821->dmic_clk_threshold); + dev_dbg(dev, "key_enable: %d\n", nau8821->key_enable); } static int nau8821_read_device_properties(struct device *dev, @@ -1502,6 +1535,8 @@ static int nau8821_read_device_properties(struct device *dev, "nuvoton,jkdet-pull-enable"); nau8821->jkdet_pull_up = device_property_read_bool(dev, "nuvoton,jkdet-pull-up"); + nau8821->key_enable = device_property_read_bool(dev, + "nuvoton,key-enable"); ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity", &nau8821->jkdet_polarity); if (ret) diff --git a/sound/soc/codecs/nau8821.h b/sound/soc/codecs/nau8821.h index a92edfeb9d3aa..c44251f54d481 100644 --- a/sound/soc/codecs/nau8821.h +++ b/sound/soc/codecs/nau8821.h @@ -525,6 +525,7 @@ struct nau8821 { int jack_eject_debounce; int fs; int dmic_clk_threshold; + int key_enable; }; int nau8821_enable_jack_detect(struct snd_soc_component *component, -- GitLab From 642999365da3b7cd5552ec758d6e1bb6f2f465d8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 11 Jul 2022 13:01:29 +0300 Subject: [PATCH 871/942] ALSA: hda: cs35l41: Fix comments wrt serial-multi-instantiate reference The comments are inconsistent and point to the wrong driver name. The initially named i2c-multi-instantiate it was renamed to the serial-multi-instantiate exactly due to support of the platforms with multiple CS35L41 codecs. Fix comments accordingly. While at it, drop file names from the files. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220711100129.37326-1-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 4 ++-- sound/pci/hda/cs35l41_hda_i2c.c | 7 ++++--- sound/pci/hda/cs35l41_hda_spi.c | 7 ++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index cce27a86267f6..a9923a8818a20 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -415,8 +415,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i no_acpi_dsd: /* * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. - * And devices created by i2c-multi-instantiate don't have their device struct pointing to - * the correct fwnode, so acpi_dev must be used here. + * And devices created by serial-multi-instantiate don't have their device struct + * pointing to the correct fwnode, so acpi_dev must be used here. * And devm functions expect that the device requesting the resource has the correct * fwnode. */ diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index e810b278fb91d..ec626e0fbedc7 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// cs35l41.c -- CS35l41 HDA I2C driver +// CS35l41 HDA I2C driver // // Copyright 2021 Cirrus Logic, Inc. // @@ -16,8 +16,9 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device { const char *device_name; - /* Compare against the device name so it works for I2C, normal ACPI - * and for ACPI by i2c-multi-instantiate matching cases + /* + * Compare against the device name so it works for SPI, normal ACPI + * and for ACPI by serial-multi-instantiate matching cases. */ if (strstr(dev_name(&clt->dev), "CLSA0100")) device_name = "CLSA0100"; diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index 22e088f28438e..3a1472e1bc244 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// cs35l41.c -- CS35l41 HDA SPI driver +// CS35l41 HDA SPI driver // // Copyright 2021 Cirrus Logic, Inc. // @@ -16,8 +16,9 @@ static int cs35l41_hda_spi_probe(struct spi_device *spi) { const char *device_name; - /* Compare against the device name so it works for SPI, normal ACPI - * and for ACPI by spi-multi-instantiate matching cases + /* + * Compare against the device name so it works for SPI, normal ACPI + * and for ACPI by serial-multi-instantiate matching cases. */ if (strstr(dev_name(&spi->dev), "CSC3551")) device_name = "CSC3551"; -- GitLab From e35cd6881dd56d5ad7711d23faab668268e17555 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 11 Jul 2022 12:52:16 +0300 Subject: [PATCH 872/942] ALSA: hda: cs35l41: Improve dev_err_probe() messaging Drop duplicate print of returned value in the messages and use pattern return dev_err_probe(...) where it's possible. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220711095219.36915-1-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index a9923a8818a20..49b25432a9f56 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -460,10 +460,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i dev_set_drvdata(dev, cs35l41); ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); - if (ret) { - dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(cs35l41->dev, ret, "Platform not supported\n"); if (IS_ERR(cs35l41->reset_gpio)) { ret = PTR_ERR(cs35l41->reset_gpio); @@ -471,7 +469,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (ret == -EBUSY) { dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); } else { - dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO: %d\n", ret); + dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO\n"); goto err; } } -- GitLab From acacd9eefd0def5a83244d88e5483b5f38ee7287 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 15:23:55 +0300 Subject: [PATCH 873/942] ASoC: SOF: Intel: cnl: Do not process IPC reply before firmware boot It is not yet clear, but it is possible to create a firmware so broken that it will send a reply message before a FW_READY message (it is not yet clear if FW_READY will arrive later). Since the reply_data is allocated only after the FW_READY message, this will lead to a NULL pointer dereference if not filtered out. The issue was reported with IPC4 firmware but the same condition is present for IPC3. Reported-by: Kai Vehmanen Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220712122357.31282-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/cnl.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index ccf46fcd6c9ab..a064453f0bc3e 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -60,17 +60,23 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context) if (primary & SOF_IPC4_MSG_DIR_MASK) { /* Reply received */ - struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; + if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { + struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; - data->primary = primary; - data->extension = extension; + data->primary = primary; + data->extension = extension; - spin_lock_irq(&sdev->ipc_lock); + spin_lock_irq(&sdev->ipc_lock); - snd_sof_ipc_get_reply(sdev); - snd_sof_ipc_reply(sdev, data->primary); + snd_sof_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, data->primary); - spin_unlock_irq(&sdev->ipc_lock); + spin_unlock_irq(&sdev->ipc_lock); + } else { + dev_dbg_ratelimited(sdev->dev, + "IPC reply before FW_READY: %#x|%#x\n", + primary, extension); + } } else { /* Notification received */ notification_data.primary = primary; @@ -124,15 +130,20 @@ irqreturn_t cnl_ipc_irq_thread(int irq, void *context) CNL_DSP_REG_HIPCCTL, CNL_DSP_REG_HIPCCTL_DONE, 0); - spin_lock_irq(&sdev->ipc_lock); + if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { + spin_lock_irq(&sdev->ipc_lock); - /* handle immediate reply from DSP core */ - hda_dsp_ipc_get_reply(sdev); - snd_sof_ipc_reply(sdev, msg); + /* handle immediate reply from DSP core */ + hda_dsp_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, msg); - cnl_ipc_dsp_done(sdev); + cnl_ipc_dsp_done(sdev); - spin_unlock_irq(&sdev->ipc_lock); + spin_unlock_irq(&sdev->ipc_lock); + } else { + dev_dbg_ratelimited(sdev->dev, "IPC reply before FW_READY: %#x\n", + msg); + } ipc_irq = true; } -- GitLab From 499cc881b09c8283ab5e75b0d6d21cb427722161 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 15:23:56 +0300 Subject: [PATCH 874/942] ASoC: SOF: Intel: hda-ipc: Do not process IPC reply before firmware boot It is not yet clear, but it is possible to create a firmware so broken that it will send a reply message before a FW_READY message (it is not yet clear if FW_READY will arrive later). Since the reply_data is allocated only after the FW_READY message, this will lead to a NULL pointer dereference if not filtered out. The issue was reported with IPC4 firmware but the same condition is present for IPC3. Reported-by: Kai Vehmanen Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220712122357.31282-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-ipc.c | 39 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c index f080112499552..65e688f749eaf 100644 --- a/sound/soc/sof/intel/hda-ipc.c +++ b/sound/soc/sof/intel/hda-ipc.c @@ -148,17 +148,23 @@ irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context) if (primary & SOF_IPC4_MSG_DIR_MASK) { /* Reply received */ - struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; + if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { + struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; - data->primary = primary; - data->extension = extension; + data->primary = primary; + data->extension = extension; - spin_lock_irq(&sdev->ipc_lock); + spin_lock_irq(&sdev->ipc_lock); - snd_sof_ipc_get_reply(sdev); - snd_sof_ipc_reply(sdev, data->primary); + snd_sof_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, data->primary); - spin_unlock_irq(&sdev->ipc_lock); + spin_unlock_irq(&sdev->ipc_lock); + } else { + dev_dbg_ratelimited(sdev->dev, + "IPC reply before FW_READY: %#x|%#x\n", + primary, extension); + } } else { /* Notification received */ @@ -225,16 +231,21 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context) * place, the message might not yet be marked as expecting a * reply. */ - spin_lock_irq(&sdev->ipc_lock); + if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { + spin_lock_irq(&sdev->ipc_lock); - /* handle immediate reply from DSP core */ - hda_dsp_ipc_get_reply(sdev); - snd_sof_ipc_reply(sdev, msg); + /* handle immediate reply from DSP core */ + hda_dsp_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, msg); - /* set the done bit */ - hda_dsp_ipc_dsp_done(sdev); + /* set the done bit */ + hda_dsp_ipc_dsp_done(sdev); - spin_unlock_irq(&sdev->ipc_lock); + spin_unlock_irq(&sdev->ipc_lock); + } else { + dev_dbg_ratelimited(sdev->dev, "IPC reply before FW_READY: %#x\n", + msg); + } ipc_irq = true; } -- GitLab From 1549a69b89b7e5b1b830da897529344766728a4b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 15:23:57 +0300 Subject: [PATCH 875/942] ASoC: SOF: Intel: mtl: Do not process IPC reply before firmware boot It is not yet clear, but it is possible to create a firmware so broken that it will send a reply message before a FW_READY message (it is not yet clear if FW_READY will arrive later). Since the reply_data is allocated only after the FW_READY message, this will lead to a NULL pointer dereference if not filtered out. Reported-by: Kai Vehmanen Signed-off-by: Peter Ujfalusi Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220712122357.31282-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/mtl.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 3a043589c12bb..a5e244ea06886 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -512,17 +512,23 @@ static irqreturn_t mtl_ipc_irq_thread(int irq, void *context) */ if (primary & SOF_IPC4_MSG_DIR_MASK) { /* Reply received */ - struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; + if (likely(sdev->fw_state == SOF_FW_BOOT_COMPLETE)) { + struct sof_ipc4_msg *data = sdev->ipc->msg.reply_data; - data->primary = primary; - data->extension = extension; + data->primary = primary; + data->extension = extension; - spin_lock_irq(&sdev->ipc_lock); + spin_lock_irq(&sdev->ipc_lock); - snd_sof_ipc_get_reply(sdev); - snd_sof_ipc_reply(sdev, data->primary); + snd_sof_ipc_get_reply(sdev); + snd_sof_ipc_reply(sdev, data->primary); - spin_unlock_irq(&sdev->ipc_lock); + spin_unlock_irq(&sdev->ipc_lock); + } else { + dev_dbg_ratelimited(sdev->dev, + "IPC reply before FW_READY: %#x|%#x\n", + primary, extension); + } } else { /* Notification received */ notification_data.primary = primary; -- GitLab From 57724db17a946476f11c1b1be9750bc0cf877adc Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 15:09:35 +0300 Subject: [PATCH 876/942] ASoC: SOF: Intel: hda: Introduce skip_imr_boot flag Use a dedicated flag instead of directly checking the sdev->system_suspend_target to decide if we need to skip IMR boot due to too deep sleep state where the memory used for IMR booting will not retain its content. The skip_imr_boot flag will be set true during suspend if the target state is deeper than S3 and reset back to false on successful boot to re-enable IMR booting in shallower sleep states. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220712120936.28072-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 7 +++++++ sound/soc/sof/intel/hda-loader.c | 10 ++++++---- sound/soc/sof/intel/hda.h | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 2afaee91b982a..eddfd77ad90f4 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -617,6 +617,13 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) #endif int ret, j; + /* + * The memory used for IMR boot loses its content in deeper than S3 state + * We must not try IMR boot on next power up (as it will fail). + */ + if (sdev->system_suspend_target > SOF_SUSPEND_S3) + hda->skip_imr_boot = true; + hda_sdw_int_enable(sdev, false); /* disable IPC interrupts */ diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 819b3b08c6557..eb22eb3f6fee1 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -395,8 +395,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) struct snd_dma_buffer dmab; int ret, ret1, i; - if (sdev->system_suspend_target < SOF_SUSPEND_S4 && - hda->imrboot_supported && !sdev->first_boot) { + if (hda->imrboot_supported && !sdev->first_boot && !hda->skip_imr_boot) { dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n"); hda->boot_iteration = 0; ret = hda_dsp_boot_imr(sdev); @@ -480,11 +479,14 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) */ hda->boot_iteration = HDA_FW_BOOT_ATTEMPTS; ret = hda_cl_copy_fw(sdev, hext_stream); - if (!ret) + if (!ret) { dev_dbg(sdev->dev, "Firmware download successful, booting...\n"); - else + hda->skip_imr_boot = false; + } else { snd_sof_dsp_dbg_dump(sdev, "Firmware download failed", SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX); + hda->skip_imr_boot = true; + } cleanup: /* diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index dc713c20ba1d9..2b4d23af6054e 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -419,6 +419,7 @@ enum sof_hda_D0_substate { /* represents DSP HDA controller frontend - i.e. host facing control */ struct sof_intel_hda_dev { bool imrboot_supported; + bool skip_imr_boot; int boot_iteration; -- GitLab From 4ccf0949cd364811217a0e61754ff7e52cb4f0e4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 8 Jul 2022 15:06:41 -0500 Subject: [PATCH 877/942] ASoC: soc-pcm: demote warnings on non-atomic BE connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an FE, typically non-atomic, is connected to an atomic BE, we force the BE as non-atomic. There's no reason to throw a warning, this is a perfectly fine configuration and a conversion that's required by-design. This removes the unconditional warnings such as [ 12.054213] iDisp1: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic [ 12.074693] iDisp2: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic [ 12.096612] iDisp3: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic [ 12.118637] iDisp4: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic [ 12.140660] dmic01: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic [ 12.147521] dmic16k: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic and demotes them to dev_dbg(), as suggested in review comments. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Péter Ujfalusi Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220708200641.26923-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a827cc3c158ae..5b99bf2dbd085 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1209,8 +1209,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, return -EINVAL; } if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) { - dev_warn(be->dev, "%s: FE is nonatomic but BE is not, forcing BE as nonatomic\n", - __func__); + dev_dbg(be->dev, "FE is nonatomic but BE is not, forcing BE as nonatomic\n"); be_substream->pcm->nonatomic = 1; } -- GitLab From 98418a08a20d3a72e14d88ccb3a48d0bf961ab6a Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 12 Jul 2022 15:39:02 +0300 Subject: [PATCH 878/942] ASoC: SOF: topology: remove unused variable 'ret' is never used. Remove it and return 0 instead. Signed-off-by: Ranjani Sridharan Reviewed-by: Bard Liao Reviewed-by: Pierre-Louis Bossart Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20220712123902.14696-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/topology.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 7e54eb1bf77b3..9273a70fec25c 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1419,7 +1419,6 @@ static int sof_widget_unload(struct snd_soc_component *scomp, struct soc_bytes_ext *sbe; struct snd_sof_dai *dai; struct soc_enum *se; - int ret = 0; int i; swidget = dobj->private; @@ -1480,7 +1479,7 @@ static int sof_widget_unload(struct snd_soc_component *scomp, list_del(&swidget->list); kfree(swidget); - return ret; + return 0; } /* -- GitLab From 15d8370cf6d5b3316ad58954086433301363be67 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 15:57:32 +0300 Subject: [PATCH 879/942] ASoC: SOF: Intel: hda: Correct the ROM/FW state reporting code The FSR (Firmware State Register) can be found at offset 0 in the SRAM and it is holding information about the state of the ROM/FW. In case of a boot failure it can be used to get the state where the boot process got stuck, it does not itself contains error codes as such. The error code (or the firmware state information) is stored in the next soft register at offset 0x4. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220712125734.30512-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda.c | 147 ++++++++++++++++++++++++++++++++------ sound/soc/sof/intel/hda.h | 63 ++++++++++++++++ 2 files changed, 190 insertions(+), 20 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index bc07df1fc39f0..d519b9802b3bc 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -353,7 +353,7 @@ static inline bool hda_sdw_check_wakeen_irq(struct snd_sof_dev *sdev) struct hda_dsp_msg_code { u32 code; - const char *msg; + const char *text; }; #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG) @@ -382,10 +382,7 @@ module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); #endif -static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { - {HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"}, - {HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"}, - {HDA_DSP_ROM_FW_ENTERED, "status: fw entered"}, +static const struct hda_dsp_msg_code hda_dsp_rom_fw_error_texts[] = { {HDA_DSP_ROM_CSE_ERROR, "error: cse error"}, {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"}, {HDA_DSP_ROM_IMR_TO_SMALL, "error: IMR too small"}, @@ -404,26 +401,136 @@ static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = { {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"}, }; -static void hda_dsp_get_status(struct snd_sof_dev *sdev, const char *level) +#define FSR_ROM_STATE_ENTRY(state) {FSR_STATE_ROM_##state, #state} +static const struct hda_dsp_msg_code fsr_rom_state_names[] = { + FSR_ROM_STATE_ENTRY(INIT), + FSR_ROM_STATE_ENTRY(INIT_DONE), + FSR_ROM_STATE_ENTRY(CSE_MANIFEST_LOADED), + FSR_ROM_STATE_ENTRY(FW_MANIFEST_LOADED), + FSR_ROM_STATE_ENTRY(FW_FW_LOADED), + FSR_ROM_STATE_ENTRY(FW_ENTERED), + FSR_ROM_STATE_ENTRY(VERIFY_FEATURE_MASK), + FSR_ROM_STATE_ENTRY(GET_LOAD_OFFSET), + FSR_ROM_STATE_ENTRY(FETCH_ROM_EXT), + FSR_ROM_STATE_ENTRY(FETCH_ROM_EXT_DONE), + /* CSE states */ + FSR_ROM_STATE_ENTRY(CSE_IMR_REQUEST), + FSR_ROM_STATE_ENTRY(CSE_IMR_GRANTED), + FSR_ROM_STATE_ENTRY(CSE_VALIDATE_IMAGE_REQUEST), + FSR_ROM_STATE_ENTRY(CSE_IMAGE_VALIDATED), + FSR_ROM_STATE_ENTRY(CSE_IPC_IFACE_INIT), + FSR_ROM_STATE_ENTRY(CSE_IPC_RESET_PHASE_1), + FSR_ROM_STATE_ENTRY(CSE_IPC_OPERATIONAL_ENTRY), + FSR_ROM_STATE_ENTRY(CSE_IPC_OPERATIONAL), + FSR_ROM_STATE_ENTRY(CSE_IPC_DOWN), +}; + +#define FSR_BRINGUP_STATE_ENTRY(state) {FSR_STATE_BRINGUP_##state, #state} +static const struct hda_dsp_msg_code fsr_bringup_state_names[] = { + FSR_BRINGUP_STATE_ENTRY(INIT), + FSR_BRINGUP_STATE_ENTRY(INIT_DONE), + FSR_BRINGUP_STATE_ENTRY(HPSRAM_LOAD), + FSR_BRINGUP_STATE_ENTRY(UNPACK_START), + FSR_BRINGUP_STATE_ENTRY(IMR_RESTORE), + FSR_BRINGUP_STATE_ENTRY(FW_ENTERED), +}; + +#define FSR_WAIT_STATE_ENTRY(state) {FSR_WAIT_FOR_##state, #state} +static const struct hda_dsp_msg_code fsr_wait_state_names[] = { + FSR_WAIT_STATE_ENTRY(IPC_BUSY), + FSR_WAIT_STATE_ENTRY(IPC_DONE), + FSR_WAIT_STATE_ENTRY(CACHE_INVALIDATION), + FSR_WAIT_STATE_ENTRY(LP_SRAM_OFF), + FSR_WAIT_STATE_ENTRY(DMA_BUFFER_FULL), + FSR_WAIT_STATE_ENTRY(CSE_CSR), +}; + +#define FSR_MODULE_NAME_ENTRY(mod) [FSR_MOD_##mod] = #mod +static const char * const fsr_module_names[] = { + FSR_MODULE_NAME_ENTRY(ROM), + FSR_MODULE_NAME_ENTRY(ROM_BYP), + FSR_MODULE_NAME_ENTRY(BASE_FW), + FSR_MODULE_NAME_ENTRY(LP_BOOT), + FSR_MODULE_NAME_ENTRY(BRNGUP), + FSR_MODULE_NAME_ENTRY(ROM_EXT), +}; + +static const char * +hda_dsp_get_state_text(u32 code, const struct hda_dsp_msg_code *msg_code, + size_t array_size) { - const struct sof_intel_dsp_desc *chip; - u32 status; int i; - chip = get_chip_info(sdev->pdata); - status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, - chip->rom_status_reg); - - for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) { - if (status == hda_dsp_rom_msg[i].code) { - dev_printk(level, sdev->dev, "%s - code %8.8x\n", - hda_dsp_rom_msg[i].msg, status); - return; - } + for (i = 0; i < array_size; i++) { + if (code == msg_code[i].code) + return msg_code[i].text; } + return NULL; +} + +static void hda_dsp_get_state(struct snd_sof_dev *sdev, const char *level) +{ + const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata); + const char *state_text, *error_text, *module_text; + u32 fsr, state, wait_state, module, error_code; + + fsr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->rom_status_reg); + state = FSR_TO_STATE_CODE(fsr); + wait_state = FSR_TO_WAIT_STATE_CODE(fsr); + module = FSR_TO_MODULE_CODE(fsr); + + if (module > FSR_MOD_ROM_EXT) + module_text = "unknown"; + else + module_text = fsr_module_names[module]; + + if (module == FSR_MOD_BRNGUP) + state_text = hda_dsp_get_state_text(state, fsr_bringup_state_names, + ARRAY_SIZE(fsr_bringup_state_names)); + else + state_text = hda_dsp_get_state_text(state, fsr_rom_state_names, + ARRAY_SIZE(fsr_rom_state_names)); + /* not for us, must be generic sof message */ - dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); + if (!state_text) { + dev_printk(level, sdev->dev, "%#010x: unknown ROM status value\n", fsr); + return; + } + + if (wait_state) { + const char *wait_state_text; + + wait_state_text = hda_dsp_get_state_text(wait_state, fsr_wait_state_names, + ARRAY_SIZE(fsr_wait_state_names)); + if (!wait_state_text) + wait_state_text = "unknown"; + + dev_printk(level, sdev->dev, + "%#010x: module: %s, state: %s, waiting for: %s, %s\n", + fsr, module_text, state_text, wait_state_text, + fsr & FSR_HALTED ? "not running" : "running"); + } else { + dev_printk(level, sdev->dev, "%#010x: module: %s, state: %s, %s\n", + fsr, module_text, state_text, + fsr & FSR_HALTED ? "not running" : "running"); + } + + error_code = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->rom_status_reg + 4); + if (!error_code) + return; + + error_text = hda_dsp_get_state_text(error_code, hda_dsp_rom_fw_error_texts, + ARRAY_SIZE(hda_dsp_rom_fw_error_texts)); + if (!error_text) + error_text = "unknown"; + + if (state == FSR_STATE_FW_ENTERED) + dev_printk(level, sdev->dev, "status code: %#x (%s)\n", error_code, + error_text); + else + dev_printk(level, sdev->dev, "error code: %#x (%s)\n", error_code, + error_text); } static void hda_dsp_get_registers(struct snd_sof_dev *sdev, @@ -482,7 +589,7 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) u32 stack[HDA_DSP_STACK_DUMP_SIZE]; /* print ROM/FW status */ - hda_dsp_get_status(sdev, level); + hda_dsp_get_state(sdev, level); if (flags & SOF_DBG_DUMP_REGS) { u32 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_STATUS); diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index dc713c20ba1d9..77c74e3c09b10 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -187,6 +187,69 @@ #define HDA_DSP_STACK_DUMP_SIZE 32 +/* ROM/FW status register */ +#define FSR_STATE_MASK GENMASK(23, 0) +#define FSR_WAIT_STATE_MASK GENMASK(27, 24) +#define FSR_MODULE_MASK GENMASK(30, 28) +#define FSR_HALTED BIT(31) +#define FSR_TO_STATE_CODE(x) ((x) & FSR_STATE_MASK) +#define FSR_TO_WAIT_STATE_CODE(x) (((x) & FSR_WAIT_STATE_MASK) >> 24) +#define FSR_TO_MODULE_CODE(x) (((x) & FSR_MODULE_MASK) >> 28) + +/* Wait states */ +#define FSR_WAIT_FOR_IPC_BUSY 0x1 +#define FSR_WAIT_FOR_IPC_DONE 0x2 +#define FSR_WAIT_FOR_CACHE_INVALIDATION 0x3 +#define FSR_WAIT_FOR_LP_SRAM_OFF 0x4 +#define FSR_WAIT_FOR_DMA_BUFFER_FULL 0x5 +#define FSR_WAIT_FOR_CSE_CSR 0x6 + +/* Module codes */ +#define FSR_MOD_ROM 0x0 +#define FSR_MOD_ROM_BYP 0x1 +#define FSR_MOD_BASE_FW 0x2 +#define FSR_MOD_LP_BOOT 0x3 +#define FSR_MOD_BRNGUP 0x4 +#define FSR_MOD_ROM_EXT 0x5 + +/* State codes (module dependent) */ +/* Module independent states */ +#define FSR_STATE_INIT 0x0 +#define FSR_STATE_INIT_DONE 0x1 +#define FSR_STATE_FW_ENTERED 0x5 + +/* ROM states */ +#define FSR_STATE_ROM_INIT FSR_STATE_INIT +#define FSR_STATE_ROM_INIT_DONE FSR_STATE_INIT_DONE +#define FSR_STATE_ROM_CSE_MANIFEST_LOADED 0x2 +#define FSR_STATE_ROM_FW_MANIFEST_LOADED 0x3 +#define FSR_STATE_ROM_FW_FW_LOADED 0x4 +#define FSR_STATE_ROM_FW_ENTERED FSR_STATE_FW_ENTERED +#define FSR_STATE_ROM_VERIFY_FEATURE_MASK 0x6 +#define FSR_STATE_ROM_GET_LOAD_OFFSET 0x7 +#define FSR_STATE_ROM_FETCH_ROM_EXT 0x8 +#define FSR_STATE_ROM_FETCH_ROM_EXT_DONE 0x9 + +/* (ROM) CSE states */ +#define FSR_STATE_ROM_CSE_IMR_REQUEST 0x10 +#define FSR_STATE_ROM_CSE_IMR_GRANTED 0x11 +#define FSR_STATE_ROM_CSE_VALIDATE_IMAGE_REQUEST 0x12 +#define FSR_STATE_ROM_CSE_IMAGE_VALIDATED 0x13 + +#define FSR_STATE_ROM_CSE_IPC_IFACE_INIT 0x20 +#define FSR_STATE_ROM_CSE_IPC_RESET_PHASE_1 0x21 +#define FSR_STATE_ROM_CSE_IPC_OPERATIONAL_ENTRY 0x22 +#define FSR_STATE_ROM_CSE_IPC_OPERATIONAL 0x23 +#define FSR_STATE_ROM_CSE_IPC_DOWN 0x24 + +/* BRINGUP (or BRNGUP) states */ +#define FSR_STATE_BRINGUP_INIT FSR_STATE_INIT +#define FSR_STATE_BRINGUP_INIT_DONE FSR_STATE_INIT_DONE +#define FSR_STATE_BRINGUP_HPSRAM_LOAD 0x2 +#define FSR_STATE_BRINGUP_UNPACK_START 0X3 +#define FSR_STATE_BRINGUP_IMR_RESTORE 0x4 +#define FSR_STATE_BRINGUP_FW_ENTERED FSR_STATE_FW_ENTERED + /* ROM status/error values */ #define HDA_DSP_ROM_STS_MASK GENMASK(23, 0) #define HDA_DSP_ROM_INIT 0x1 -- GitLab From 402355e6cdbebf15f2c40cd9469b924c97b94b32 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 16:16:19 +0300 Subject: [PATCH 880/942] ASoC: SOF: Intel: hda-dai: Drop misleading comment regarding dma_data The comment in hda_link_dma_hw_params() is no longer valid as the dma_data is set to NULL at system suspend as well. Instead of rewording the comment to state the obvious: try to take the hext_stream from the dma_data and if it is not set then assign a new one and store it as dma_data. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220712131620.13365-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index ed74a1f264e86..9015ca2024bcc 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -221,7 +221,6 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, struct hdac_bus *bus = hstream->bus; struct hdac_ext_link *link; - /* get stored dma data if resuming from system suspend */ hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); if (!hext_stream) { hext_stream = hda_link_stream_assign(bus, substream); -- GitLab From fbabebfb26a8130c10fd91cca687bac87944580d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 16:16:20 +0300 Subject: [PATCH 881/942] ASoC: SOF: Intel: hda-dai: Do snd_hdac_ext_stream_decouple() only once Call snd_hdac_ext_stream_decouple_locked() unconditionally in hda_link_stream_assign(), the snd_hdac_ext_stream_decouple_locked() have internal checks to avoid re-configuring. There is no need to call snd_hdac_ext_stream_decouple() via hda_link_dma_params() as the stream must have been set to decoupled when it got assigned (even if it used local condition to call snd_hdac_ext_stream_decouple_locked()). Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220712131620.13365-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 9015ca2024bcc..c5b65e4a06be4 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -126,12 +126,8 @@ hda_link_stream_assign(struct hdac_bus *bus, } if (res) { - /* - * Decouple host and link DMA. The decoupled flag - * is updated in snd_hdac_ext_stream_decouple(). - */ - if (!res->decoupled) - snd_hdac_ext_stream_decouple_locked(bus, res, true); + /* Make sure that host and link DMA is decoupled. */ + snd_hdac_ext_stream_decouple_locked(bus, res, true); res->link_locked = 1; res->link_substream = substream; @@ -184,7 +180,6 @@ static int hda_link_dma_params(struct hdac_ext_stream *hext_stream, struct hdac_ext_link *link; unsigned int format_val; - snd_hdac_ext_stream_decouple(bus, hext_stream, true); snd_hdac_ext_link_stream_reset(hext_stream); format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, -- GitLab From d5770daef62d2e4d33015089bab392ef867fd35a Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 12 Jul 2022 17:15:28 +0300 Subject: [PATCH 882/942] ASoC: SOF: compress: Dynamically allocate pcm params struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to extend sof_ipc_pcm_parmas with additional data in order to send compress_params to SOF FW. The extensions will be done at runtime so we need to dynamically allocate pcm object of type struct sof_ipc_pcm_params. Signed-off-by: Daniel Baluta Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220712141531.14599-2-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 53 ++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 47639b6344c80..45c2ff61ee4d0 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -168,7 +168,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct snd_compr_runtime *crtd = cstream->runtime; struct sof_ipc_pcm_params_reply ipc_params_reply; struct snd_compr_tstamp *tstamp; - struct sof_ipc_pcm_params pcm; + struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; int ret; @@ -179,40 +179,42 @@ static int sof_compr_set_params(struct snd_soc_component *component, if (!spcm) return -EINVAL; + pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + if (!pcm) + return -ENOMEM; + cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG; cstream->dma_buffer.dev.dev = sdev->dev; ret = snd_compr_malloc_pages(cstream, crtd->buffer_size); if (ret < 0) - return ret; + goto out; ret = create_page_table(component, cstream, crtd->dma_area, crtd->dma_bytes); if (ret < 0) - return ret; - - memset(&pcm, 0, sizeof(pcm)); - - pcm.params.buffer.pages = PFN_UP(crtd->dma_bytes); - pcm.hdr.size = sizeof(pcm); - pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; - - pcm.comp_id = spcm->stream[cstream->direction].comp_id; - pcm.params.hdr.size = sizeof(pcm.params); - pcm.params.buffer.phy_addr = spcm->stream[cstream->direction].page_table.addr; - pcm.params.buffer.size = crtd->dma_bytes; - pcm.params.direction = cstream->direction; - pcm.params.channels = params->codec.ch_out; - pcm.params.rate = params->codec.sample_rate; - pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; - pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE; - pcm.params.sample_container_bytes = + goto out; + + pcm->params.buffer.pages = PFN_UP(crtd->dma_bytes); + pcm->hdr.size = sizeof(*pcm); + pcm->hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; + + pcm->comp_id = spcm->stream[cstream->direction].comp_id; + pcm->params.hdr.size = sizeof(pcm->params); + pcm->params.buffer.phy_addr = spcm->stream[cstream->direction].page_table.addr; + pcm->params.buffer.size = crtd->dma_bytes; + pcm->params.direction = cstream->direction; + pcm->params.channels = params->codec.ch_out; + pcm->params.rate = params->codec.sample_rate; + pcm->params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED; + pcm->params.frame_fmt = SOF_IPC_FRAME_S32_LE; + pcm->params.sample_container_bytes = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32) >> 3; - pcm.params.host_period_bytes = params->buffer.fragment_size; + pcm->params.host_period_bytes = params->buffer.fragment_size; - ret = sof_ipc_tx_message(sdev->ipc, &pcm, sizeof(pcm), + ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm), &ipc_params_reply, sizeof(ipc_params_reply)); if (ret < 0) { dev_err(component->dev, "error ipc failed\n"); - return ret; + goto out; } tstamp->byte_offset = sdev->stream_box.offset + ipc_params_reply.posn_offset; @@ -220,7 +222,10 @@ static int sof_compr_set_params(struct snd_soc_component *component, spcm->prepared[cstream->direction] = true; - return 0; +out: + kfree(pcm); + + return ret; } static int sof_compr_get_params(struct snd_soc_component *component, -- GitLab From 3f70c360d484466da7420f395d4675ca02436e32 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 12 Jul 2022 17:15:29 +0300 Subject: [PATCH 883/942] ASoC: SOF: Copy compress parameters into extended data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allocate memory at the end of sof_ipc_stream_params to store snd_compr_params in order to be sent them to SOF firmware. This will help firmware correctly configure codecs parameters. Notice, that we use 2 bytes from the reserved pool in order to store the extended data length. This is compatible with older FWs where there was no extended data. Signed-off-by: Daniel Baluta Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220712141531.14599-3-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- include/sound/sof/stream.h | 6 ++++-- sound/soc/sof/compress.c | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/sound/sof/stream.h b/include/sound/sof/stream.h index 1db3bbc3e65d4..9377113f13e49 100644 --- a/include/sound/sof/stream.h +++ b/include/sound/sof/stream.h @@ -86,9 +86,11 @@ struct sof_ipc_stream_params { uint32_t host_period_bytes; uint16_t no_stream_position; /**< 1 means don't send stream position */ uint8_t cont_update_posn; /**< 1 means continuous update stream position */ - - uint8_t reserved[5]; + uint8_t reserved0; + int16_t ext_data_length; /**< 0, means no extended data */ + uint8_t reserved[2]; uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ + uint8_t ext_data[]; /**< extended data */ } __packed; /* PCM params info - SOF_IPC_STREAM_PCM_PARAMS */ diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 45c2ff61ee4d0..1204dce29ef94 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -170,6 +170,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct snd_compr_tstamp *tstamp; struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; + size_t ext_data_size; int ret; tstamp = crtd->private_data; @@ -179,7 +180,12 @@ static int sof_compr_set_params(struct snd_soc_component *component, if (!spcm) return -EINVAL; - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + ext_data_size = sizeof(params->codec); + + if (sizeof(*pcm) + ext_data_size > sdev->ipc->max_payload_size) + return -EINVAL; + + pcm = kzalloc(sizeof(*pcm) + ext_data_size, GFP_KERNEL); if (!pcm) return -ENOMEM; @@ -194,11 +200,11 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; pcm->params.buffer.pages = PFN_UP(crtd->dma_bytes); - pcm->hdr.size = sizeof(*pcm); + pcm->hdr.size = sizeof(*pcm) + ext_data_size; pcm->hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS; pcm->comp_id = spcm->stream[cstream->direction].comp_id; - pcm->params.hdr.size = sizeof(pcm->params); + pcm->params.hdr.size = sizeof(pcm->params) + ext_data_size; pcm->params.buffer.phy_addr = spcm->stream[cstream->direction].page_table.addr; pcm->params.buffer.size = crtd->dma_bytes; pcm->params.direction = cstream->direction; @@ -209,8 +215,11 @@ static int sof_compr_set_params(struct snd_soc_component *component, pcm->params.sample_container_bytes = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32) >> 3; pcm->params.host_period_bytes = params->buffer.fragment_size; + pcm->params.ext_data_length = ext_data_size; + + memcpy((u8 *)pcm->params.ext_data, ¶ms->codec, ext_data_size); - ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm), + ret = sof_ipc_tx_message(sdev->ipc, pcm, sizeof(*pcm) + ext_data_size, &ipc_params_reply, sizeof(ipc_params_reply)); if (ret < 0) { dev_err(component->dev, "error ipc failed\n"); -- GitLab From 246b135fcdba57a4e77a702580391ae1942c1e3b Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 12 Jul 2022 17:15:30 +0300 Subject: [PATCH 884/942] ASoC: SOF: compress: Prevent current kernel running with older FW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After introducing extended parameters we need to forbid older firmware versions to run with the current and future kernel versions. Although in theory the communication protocol will still work the semantics at application level are undefined. So, prevent this by disallowing older firmwares to run with newer kernels. Signed-off-by: Daniel Baluta Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220712141531.14599-4-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- sound/soc/sof/compress.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 1204dce29ef94..67139e15f862a 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -167,12 +167,23 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_compr_runtime *crtd = cstream->runtime; struct sof_ipc_pcm_params_reply ipc_params_reply; + struct sof_ipc_fw_ready *ready = &sdev->fw_ready; + struct sof_ipc_fw_version *v = &ready->version; struct snd_compr_tstamp *tstamp; struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; size_t ext_data_size; int ret; + if (v->abi_version < SOF_ABI_VER(3, 22, 0)) { + dev_err(component->dev, + "Compress params not supported with FW ABI version %d:%d:%d\n", + SOF_ABI_VERSION_MAJOR(v->abi_version), + SOF_ABI_VERSION_MINOR(v->abi_version), + SOF_ABI_VERSION_PATCH(v->abi_version)); + return -EINVAL; + } + tstamp = crtd->private_data; spcm = snd_sof_find_spcm_dai(component, rtd); -- GitLab From 75b5b7a1ccf606281c4afe365a57ccca486641a2 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 12 Jul 2022 17:15:31 +0300 Subject: [PATCH 885/942] uapi: sof: abi: Bump SOF ABI for ext_data_length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new field to sof_ipc_stream_params in order to extend stream params struct with extended data to store compress parameters. Older kernel will still work this as they ext_data_length will always be zero. Signed-off-by: Daniel Baluta Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220712141531.14599-5-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown --- include/uapi/sound/sof/abi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/sound/sof/abi.h b/include/uapi/sound/sof/abi.h index c88f467374aec..b7dce4df7ecd7 100644 --- a/include/uapi/sound/sof/abi.h +++ b/include/uapi/sound/sof/abi.h @@ -28,7 +28,7 @@ /* SOF ABI version major, minor and patch numbers */ #define SOF_ABI_MAJOR 3 -#define SOF_ABI_MINOR 21 +#define SOF_ABI_MINOR 22 #define SOF_ABI_PATCH 0 /* SOF ABI version number. Format within 32bit word is MMmmmppp */ -- GitLab From 9b93eda355089b36482f7a2f134bdd24be70f907 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 16:10:22 +0300 Subject: [PATCH 886/942] ASoC: SOF: sof-client-probes: Only load the driver if IPC3 is used The current implementation of probes only supports IPC3 and should not be loaded for other IPC implementation. Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220712131022.1124-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-client-probes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-probes.c index 1f1ea93a7fbf3..e7e78d1a8ec31 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -694,6 +694,10 @@ static int sof_probes_client_probe(struct auxiliary_device *auxdev, if (!sof_probes_enabled) return -ENXIO; + /* only ipc3 is supported */ + if (sof_client_get_ipc_type(cdev) != SOF_IPC) + return -ENXIO; + if (!dev->platform_data) { dev_err(dev, "missing platform data\n"); return -ENODEV; -- GitLab From d5bd47f3ca124058a8e87eae4508afeda2132611 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 12 Jul 2022 16:01:03 +0300 Subject: [PATCH 887/942] ASoC: SOF: ipc3-topology: Prevent double freeing of ipc_control_data via load_bytes We have sanity checks for byte controls and if any of the fail the locally allocated scontrol->ipc_control_data is freed up, but not set to NULL. On a rollback path of the error the higher level code will also try to free the scontrol->ipc_control_data which will eventually going to lead to memory corruption as double freeing memory is not a good thing. Fixes: b5cee8feb1d4 ("ASoC: SOF: topology: Make control parsing IPC agnostic") Reported-by: Seppo Ingalsuo Signed-off-by: Peter Ujfalusi Reviewed-by: Seppo Ingalsuo Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220712130103.31514-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 9448d5338423a..b2cc046b9f606 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1644,6 +1644,7 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ return 0; err: kfree(scontrol->ipc_control_data); + scontrol->ipc_control_data = NULL; return ret; } -- GitLab From 20bcf721068f6418607283cdb0c16cf0b606cfc1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 12 Jul 2022 18:35:16 +0300 Subject: [PATCH 888/942] ALSA: hda: cs35l41: Don't dereference fwnode handle Use acpi_fwnode_handle() instead of dereferencing an fwnode handle directly, which is a better coding practice. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220712153519.35692-1-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 49b25432a9f56..1a1afa0725e02 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -347,7 +347,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i /* To use the same release code for all laptop variants we can't use devm_ version of * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node */ - cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, + cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(adev), "reset", cs35l41->index, GPIOD_OUT_LOW, "cs35l41-reset"); property = "cirrus,speaker-position"; -- GitLab From d60b05b4c7802b45c4f2ac003827384618a17bb4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 12 Jul 2022 18:35:17 +0300 Subject: [PATCH 889/942] ALSA: hda: cs35l41: Allow compilation test on non-ACPI configurations ACPI is needed only for functioning of this codec on some platforms, there is no compilation dependency, so make it optional Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220712153519.35692-2-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 79ade4787d95b..e86cf80bdf96d 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -97,7 +97,7 @@ config SND_HDA_SCODEC_CS35L41 config SND_HDA_SCODEC_CS35L41_I2C tristate "Build CS35L41 HD-audio side codec support for I2C Bus" depends on I2C - depends on ACPI + depends on ACPI || COMPILE_TEST depends on SND_SOC select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB @@ -113,7 +113,7 @@ comment "Set to Y if you want auto-loading the side codec driver" config SND_HDA_SCODEC_CS35L41_SPI tristate "Build CS35L41 HD-audio codec support for SPI Bus" depends on SPI_MASTER - depends on ACPI + depends on ACPI || COMPILE_TEST depends on SND_SOC select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB -- GitLab From 931c940fc5d96e5ef7a2188abfb14e7c3ab1290e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 12 Jul 2022 18:35:18 +0300 Subject: [PATCH 890/942] ALSA: hda: cs35l41: Drop wrong use of ACPI_PTR() ACPI_PTR() is more harmful than helpful. For example, in this case if CONFIG_ACPI=n, the ID table left unused which is not what we want. Instead of adding ifdeffery or attribute here and there, drop ACPI_PTR(). Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220712153519.35692-3-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda_i2c.c | 8 +++----- sound/pci/hda/cs35l41_hda_spi.c | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index ec626e0fbedc7..df39fc76e6be6 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -6,9 +6,9 @@ // // Author: Lucas Tanure +#include #include #include -#include #include "cs35l41_hda.h" @@ -43,19 +43,17 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = { {} }; -#ifdef CONFIG_ACPI static const struct acpi_device_id cs35l41_acpi_hda_match[] = { {"CLSA0100", 0 }, {"CSC3551", 0 }, - { }, + {} }; MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); -#endif static struct i2c_driver cs35l41_i2c_driver = { .driver = { .name = "cs35l41-hda", - .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), + .acpi_match_table = cs35l41_acpi_hda_match, }, .id_table = cs35l41_hda_i2c_id, .probe = cs35l41_hda_i2c_probe, diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index 3a1472e1bc244..2f5afad3719e7 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -6,7 +6,7 @@ // // Author: Lucas Tanure -#include +#include #include #include @@ -39,18 +39,16 @@ static const struct spi_device_id cs35l41_hda_spi_id[] = { {} }; -#ifdef CONFIG_ACPI static const struct acpi_device_id cs35l41_acpi_hda_match[] = { { "CSC3551", 0 }, - {}, + {} }; MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_hda_match); -#endif static struct spi_driver cs35l41_spi_driver = { .driver = { .name = "cs35l41-hda", - .acpi_match_table = ACPI_PTR(cs35l41_acpi_hda_match), + .acpi_match_table = cs35l41_acpi_hda_match, }, .id_table = cs35l41_hda_spi_id, .probe = cs35l41_hda_spi_probe, -- GitLab From 33c1f401939c66858157c0665dc07ad9596cd1bd Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 12 Jul 2022 18:35:19 +0300 Subject: [PATCH 891/942] ALSA: hda: cs35l41: Consolidate selections under SND_HDA_SCODEC_CS35L41 Selections can be propagated via selections, while dependencies are not. Hence, consolidate selections under the SND_HDA_SCODEC_CS35L41 option. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220712153519.35692-4-andriy.shevchenko@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index e86cf80bdf96d..8b73a12d356f0 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -93,16 +93,16 @@ config SND_HDA_PATCH_LOADER config SND_HDA_SCODEC_CS35L41 tristate + select SND_HDA_GENERIC + select REGMAP_IRQ config SND_HDA_SCODEC_CS35L41_I2C tristate "Build CS35L41 HD-audio side codec support for I2C Bus" depends on I2C depends on ACPI || COMPILE_TEST depends on SND_SOC - select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 - select REGMAP_IRQ help Say Y or M here to include CS35L41 I2C HD-audio side codec support in snd-hda-intel driver, such as ALC287. @@ -115,10 +115,8 @@ config SND_HDA_SCODEC_CS35L41_SPI depends on SPI_MASTER depends on ACPI || COMPILE_TEST depends on SND_SOC - select SND_HDA_GENERIC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 - select REGMAP_IRQ help Say Y or M here to include CS35L41 SPI HD-audio side codec support in snd-hda-intel driver, such as ALC287. -- GitLab From 539311aa61a144088779f1354492bbf9ae1ac458 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:53 +0200 Subject: [PATCH 892/942] ALSA: compress: Enable kernel doc markers for some functions The exported functions snd_compress_new() and snd_compr_stop_error() had already kernel-doc-style comments but they were not processed as they weren't marked properly. Let's enable them. This patch also fixes the missing argument id for snd_compress_new comments, too. Reported-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/3cd6b93b36b32ad6ae160931aaa00b20688e241a.1656759989.git.mchehab@kernel.org Link: https://lore.kernel.org/r/20220713104759.4365-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/compress_offload.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index de514ec8c83d5..cf415fe231edf 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -810,7 +810,7 @@ static void error_delayed_work(struct work_struct *work) mutex_unlock(&stream->device->lock); } -/* +/** * snd_compr_stop_error: Report a fatal error on a stream * @stream: pointer to stream * @state: state to transition the stream to @@ -1157,11 +1157,12 @@ static int snd_compress_dev_free(struct snd_device *device) return 0; } -/* +/** * snd_compress_new: create new compress device * @card: sound card pointer * @device: device number * @dirn: device direction, should be of type enum snd_compr_direction + * @id: ID string * @compr: compress device pointer */ int snd_compress_new(struct snd_card *card, int device, -- GitLab From 4e2b70673f2b93ab8e037a2b89c15f146c1ae9b0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:54 +0200 Subject: [PATCH 893/942] ALSA: pcm: Fix missing return value comments for kernel docs Each kernel doc comment expects the definition of the return value in a proper format. This patch adds or fixes the missing entries for PCM API. Link: https://lore.kernel.org/r/20220713104759.4365-3-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 50 +++++++++++++++++++++++++++++++++++++++-- sound/core/pcm.c | 4 ++++ sound/core/pcm_memory.c | 4 ++++ sound/core/pcm_native.c | 6 +++++ 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 6b99310b5b889..08cf4a5801f36 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -607,7 +607,7 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) * snd_pcm_stream_linked - Check whether the substream is linked with others * @substream: substream to check * - * Returns true if the given substream is being linked with others. + * Return: true if the given substream is being linked with others */ static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream) { @@ -673,7 +673,7 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, * snd_pcm_running - Check whether the substream is in a running state * @substream: substream to check * - * Returns true if the given substream is in the state RUNNING, or in the + * Return: true if the given substream is in the state RUNNING, or in the * state DRAINING for playback. */ static inline int snd_pcm_running(struct snd_pcm_substream *substream) @@ -687,6 +687,8 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) * bytes_to_samples - Unit conversion of the size from bytes to samples * @runtime: PCM runtime instance * @size: size in bytes + * + * Return: the size in samples */ static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size) { @@ -697,6 +699,8 @@ static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t * bytes_to_frames - Unit conversion of the size from bytes to frames * @runtime: PCM runtime instance * @size: size in bytes + * + * Return: the size in frames */ static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size) { @@ -707,6 +711,8 @@ static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, * samples_to_bytes - Unit conversion of the size from samples to bytes * @runtime: PCM runtime instance * @size: size in samples + * + * Return: the byte size */ static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size) { @@ -717,6 +723,8 @@ static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t * frames_to_bytes - Unit conversion of the size from frames to bytes * @runtime: PCM runtime instance * @size: size in frames + * + * Return: the byte size */ static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size) { @@ -727,6 +735,8 @@ static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_s * frame_aligned - Check whether the byte size is aligned to frames * @runtime: PCM runtime instance * @bytes: size in bytes + * + * Return: true if aligned, or false if not */ static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) { @@ -736,6 +746,8 @@ static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) /** * snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes * @substream: PCM substream + * + * Return: buffer byte size */ static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream) { @@ -746,6 +758,8 @@ static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substrea /** * snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes * @substream: PCM substream + * + * Return: period byte size */ static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream) { @@ -758,6 +772,8 @@ static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substrea * @runtime: PCM runtime instance * * Result is between 0 ... (boundary - 1) + * + * Return: available frame size */ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) { @@ -774,6 +790,8 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r * @runtime: PCM runtime instance * * Result is between 0 ... (boundary - 1) + * + * Return: available frame size */ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime) { @@ -786,6 +804,8 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru /** * snd_pcm_playback_hw_avail - Get the queued space for playback * @runtime: PCM runtime instance + * + * Return: available frame size */ static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime) { @@ -795,6 +815,8 @@ static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime /** * snd_pcm_capture_hw_avail - Get the free space for capture * @runtime: PCM runtime instance + * + * Return: available frame size */ static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime) { @@ -934,6 +956,8 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc /** * params_channels - Get the number of channels from the hw params * @p: hw params + * + * Return: the number of channels */ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) { @@ -943,6 +967,8 @@ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) /** * params_rate - Get the sample rate from the hw params * @p: hw params + * + * Return: the sample rate */ static inline unsigned int params_rate(const struct snd_pcm_hw_params *p) { @@ -952,6 +978,8 @@ static inline unsigned int params_rate(const struct snd_pcm_hw_params *p) /** * params_period_size - Get the period size (in frames) from the hw params * @p: hw params + * + * Return: the period size in frames */ static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p) { @@ -961,6 +989,8 @@ static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p) /** * params_periods - Get the number of periods from the hw params * @p: hw params + * + * Return: the number of periods */ static inline unsigned int params_periods(const struct snd_pcm_hw_params *p) { @@ -970,6 +1000,8 @@ static inline unsigned int params_periods(const struct snd_pcm_hw_params *p) /** * params_buffer_size - Get the buffer size (in frames) from the hw params * @p: hw params + * + * Return: the buffer size in frames */ static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p) { @@ -979,6 +1011,8 @@ static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p) /** * params_buffer_bytes - Get the buffer size (in bytes) from the hw params * @p: hw params + * + * Return: the buffer size in bytes */ static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p) { @@ -1241,6 +1275,8 @@ int snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type, * only the given sized buffer and doesn't allow re-allocation nor dynamic * allocation of a larger buffer unlike the standard one. * The function may return -ENOMEM error, hence the caller must check it. + * + * Return: zero if successful, or a negative error code */ static inline int __must_check snd_pcm_set_fixed_buffer(struct snd_pcm_substream *substream, int type, @@ -1259,6 +1295,8 @@ snd_pcm_set_fixed_buffer(struct snd_pcm_substream *substream, int type, * Apply the set up of the fixed buffer via snd_pcm_set_fixed_buffer() for * all substream. If any of allocation fails, it returns -ENOMEM, hence the * caller must check the return value. + * + * Return: zero if successful, or a negative error code */ static inline int __must_check snd_pcm_set_fixed_buffer_all(struct snd_pcm *pcm, int type, @@ -1315,6 +1353,8 @@ static inline int snd_pcm_lib_alloc_vmalloc_32_buffer * snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset * @substream: PCM substream * @ofs: byte offset + * + * Return: DMA address */ static inline dma_addr_t snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) @@ -1328,6 +1368,8 @@ snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) * @substream: PCM substream * @ofs: byte offset * @size: byte size to examine + * + * Return: chunk size */ static inline unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, @@ -1430,6 +1472,8 @@ struct snd_pcm_chmap { * snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info * @info: chmap information * @idx: the substream number index + * + * Return: the matched PCM substream, or NULL if not found */ static inline struct snd_pcm_substream * snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) @@ -1460,6 +1504,8 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, /** * pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise * @pcm_format: PCM format + * + * Return: 64bit mask corresponding to the given PCM format */ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) { diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 977d54320a5ca..03fc5fa5813ef 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -216,6 +216,8 @@ static const char * const snd_pcm_format_names[] = { /** * snd_pcm_format_name - Return a name string for the given PCM format * @format: PCM format + * + * Return: the format name string */ const char *snd_pcm_format_name(snd_pcm_format_t format) { @@ -1138,6 +1140,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) * This adds the given notifier to the global list so that the callback is * called for each registered PCM devices. This exists only for PCM OSS * emulation, so far. + * + * Return: zero if successful, or a negative error code */ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) { diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index b8296b6eb2c19..7bde7fb64011e 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -350,6 +350,8 @@ EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); * SNDRV_DMA_TYPE_VMALLOC type. * * Upon successful buffer allocation and setup, the function returns 0. + * + * Return: zero if successful, or a negative error code */ int snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type, struct device *data, size_t size, size_t max) @@ -369,6 +371,8 @@ EXPORT_SYMBOL(snd_pcm_set_managed_buffer); * * Do pre-allocation to all substreams of the given pcm for the specified DMA * type and size, and set the managed_buffer_alloc flag to each substream. + * + * Return: zero if successful, or a negative error code */ int snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type, struct device *data, diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 4adaee62ef333..aa0453e515956 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3412,6 +3412,8 @@ static long snd_pcm_ioctl(struct file *file, unsigned int cmd, * The function is provided primarily for OSS layer and USB gadget drivers, * and it allows only the limited set of ioctls (hw_params, sw_params, * prepare, start, drain, drop, forward). + * + * Return: zero if successful, or a negative error code */ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) @@ -3810,6 +3812,8 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { * * This is the default mmap handler for PCM data. When mmap pcm_ops is NULL, * this function is invoked implicitly. + * + * Return: zero if successful, or a negative error code */ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *area) @@ -3836,6 +3840,8 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); * When your hardware uses the iomapped pages as the hardware buffer and * wants to mmap it, pass this function as mmap pcm_ops. Note that this * is supposed to work only on limited architectures. + * + * Return: zero if successful, or a negative error code */ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area) -- GitLab From 5c121d6362d60198d9e37429f87e87d5477e3555 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:55 +0200 Subject: [PATCH 894/942] ALSA: dmaengine: Fix missing return value comments for kernel docs Each kernel doc comment expects the definition of the return value in a proper format. This patch adds or fixes the missing entries for PCM dmaengine API. Link: https://lore.kernel.org/r/20220713104759.4365-4-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/dmaengine_pcm.h | 2 ++ sound/core/pcm_dmaengine.c | 30 ++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index 38ea046e653c5..2df54cf02cb33 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -15,6 +15,8 @@ * snd_pcm_substream_to_dma_direction - Get dma_transfer_direction for a PCM * substream * @substream: PCM substream + * + * Return: DMA transfer direction */ static inline enum dma_transfer_direction snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream) diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index af6f717e1e7e6..5b2ca028f5aab 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -48,6 +48,8 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_chan); * * This function can be used to initialize a dma_slave_config from a substream * and hw_params in a dmaengine based PCM driver implementation. + * + * Return: zero if successful, or a negative error code */ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_params *params, @@ -175,10 +177,10 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) * @substream: PCM substream * @cmd: Trigger command * - * Returns 0 on success, a negative error code otherwise. - * * This function can be used as the PCM trigger callback for dmaengine based PCM * driver implementations. + * + * Return: 0 on success, a negative error code otherwise */ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { @@ -223,6 +225,8 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); * * This function is deprecated and should not be used by new drivers, as its * results may be unreliable. + * + * Return: PCM position in frames */ snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream) { @@ -237,6 +241,8 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue); * * This function can be used as the PCM pointer callback for dmaengine based PCM * driver implementations. + * + * Return: PCM position in frames */ snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) { @@ -266,9 +272,9 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); * @filter_fn: Filter function used to request the DMA channel * @filter_data: Data passed to the DMA filter function * - * Returns NULL or the requested DMA channel. - * * This function request a DMA channel for usage with dmaengine PCM. + * + * Return: NULL or the requested DMA channel */ struct dma_chan *snd_dmaengine_pcm_request_channel(dma_filter_fn filter_fn, void *filter_data) @@ -288,11 +294,11 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_request_channel); * @substream: PCM substream * @chan: DMA channel to use for data transfers * - * Returns 0 on success, a negative error code otherwise. - * * The function should usually be called from the pcm open callback. Note that * this function will use private_data field of the substream's runtime. So it * is not available to your pcm driver implementation. + * + * Return: 0 on success, a negative error code otherwise */ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, struct dma_chan *chan) @@ -326,12 +332,12 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); * @filter_fn: Filter function used to request the DMA channel * @filter_data: Data passed to the DMA filter function * - * Returns 0 on success, a negative error code otherwise. - * * This function will request a DMA channel using the passed filter function and * data. The function should usually be called from the pcm open callback. Note * that this function will use private_data field of the substream's runtime. So * it is not available to your pcm driver implementation. + * + * Return: 0 on success, a negative error code otherwise */ int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, dma_filter_fn filter_fn, void *filter_data) @@ -344,6 +350,8 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan); /** * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream * @substream: PCM substream + * + * Return: 0 on success, a negative error code otherwise */ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) { @@ -362,6 +370,8 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); * @substream: PCM substream * * Releases the DMA channel associated with the PCM substream. + * + * Return: zero if successful, or a negative error code */ int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) { @@ -382,10 +392,10 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); * @hw: PCM hw params * @chan: DMA channel to use for data transfers * - * Returns 0 on success, a negative error code otherwise. - * * This function will query DMA capability, then refine the pcm hardware * parameters. + * + * Return: 0 on success, a negative error code otherwise */ int snd_dmaengine_pcm_refine_runtime_hwparams( struct snd_pcm_substream *substream, -- GitLab From b05d834ef8f8fbd90b1bacca909c1eeec02e3625 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:56 +0200 Subject: [PATCH 895/942] ALSA: compress: Fix kernel doc warnings Each kernel doc comment expects the definition of the return value and the summary for each struct / enum in a proper format. This patch adds or fixes the missing entries for compress-offload API. Link: https://lore.kernel.org/r/20220713104759.4365-5-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/uapi/sound/compress_offload.h | 2 +- include/uapi/sound/compress_params.h | 6 +++--- sound/core/compress_offload.c | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/compress_offload.h index 9555f31c8425c..3aef123dbd7f6 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -123,7 +123,7 @@ struct snd_compr_codec_caps { } __attribute__((packed, aligned(4))); /** - * enum sndrv_compress_encoder + * enum sndrv_compress_encoder - encoder metadata key * @SNDRV_COMPRESS_ENCODER_PADDING: no of samples appended by the encoder at the * end of the track * @SNDRV_COMPRESS_ENCODER_DELAY: no of samples inserted by the encoder at the diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h index 79b14389ae411..7263617169195 100644 --- a/include/uapi/sound/compress_params.h +++ b/include/uapi/sound/compress_params.h @@ -250,7 +250,7 @@ struct snd_enc_wma { /** - * struct snd_enc_vorbis + * struct snd_enc_vorbis - Vorbis encoder parameters * @quality: Sets encoding quality to n, between -1 (low) and 10 (high). * In the default mode of operation, the quality level is 3. * Normal quality range is 0 - 10. @@ -279,7 +279,7 @@ struct snd_enc_vorbis { /** - * struct snd_enc_real + * struct snd_enc_real - RealAudio encoder parameters * @quant_bits: number of coupling quantization bits in the stream * @start_region: coupling start region in the stream * @num_regions: number of regions value @@ -294,7 +294,7 @@ struct snd_enc_real { } __attribute__((packed, aligned(4))); /** - * struct snd_enc_flac + * struct snd_enc_flac - FLAC encoder parameters * @num: serial number, valid only for OGG formats * needs to be set by application * @gain: Add replay gain tags diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index cf415fe231edf..243acad89fd3b 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -818,6 +818,8 @@ static void error_delayed_work(struct work_struct *work) * Stop the stream and set its state. * * Should be called with compressed device lock held. + * + * Return: zero if successful, or a negative error code */ int snd_compr_stop_error(struct snd_compr_stream *stream, snd_pcm_state_t state) @@ -1164,6 +1166,8 @@ static int snd_compress_dev_free(struct snd_device *device) * @dirn: device direction, should be of type enum snd_compr_direction * @id: ID string * @compr: compress device pointer + * + * Return: zero if successful, or a negative error code */ int snd_compress_new(struct snd_card *card, int device, int dirn, const char *id, struct snd_compr *compr) -- GitLab From e8406ebc37d2efb7e473e469152f977235a742e1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:57 +0200 Subject: [PATCH 896/942] ALSA: control: Fix missing return value comments for kernel docs Each kernel doc comment expects the definition of the return value in proper format. This patch adds or fixes the missing entries for control API. Link: https://lore.kernel.org/r/20220713104759.4365-6-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/control.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index fa04a92331554..4dba3a342458f 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -2054,6 +2054,8 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * * @fcn: ioctl callback function * * called from each device manager like pcm.c, hwdep.c, etc. + * + * Return: zero if successful, or a negative error code */ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) { @@ -2066,6 +2068,8 @@ EXPORT_SYMBOL(snd_ctl_register_ioctl); * snd_ctl_register_ioctl_compat - register the device-specific 32bit compat * control-ioctls * @fcn: ioctl callback function + * + * Return: zero if successful, or a negative error code */ int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) { @@ -2101,6 +2105,8 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, /** * snd_ctl_unregister_ioctl - de-register the device-specific control-ioctls * @fcn: ioctl callback function to unregister + * + * Return: zero if successful, or a negative error code */ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) { @@ -2113,6 +2119,8 @@ EXPORT_SYMBOL(snd_ctl_unregister_ioctl); * snd_ctl_unregister_ioctl_compat - de-register the device-specific compat * 32bit control-ioctls * @fcn: ioctl callback function to unregister + * + * Return: zero if successful, or a negative error code */ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) { @@ -2168,7 +2176,7 @@ EXPORT_SYMBOL_GPL(snd_ctl_get_preferred_subdevice); * snd_ctl_request_layer - request to use the layer * @module_name: Name of the kernel module (NULL == build-in) * - * Return an error code when the module cannot be loaded. + * Return: zero if successful, or an error code when the module cannot be loaded */ int snd_ctl_request_layer(const char *module_name) { @@ -2370,6 +2378,8 @@ int snd_ctl_create(struct snd_card *card) * * This is a function that can be used as info callback for a standard * boolean control with a single mono channel. + * + * Return: Zero (always successful) */ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -2390,6 +2400,8 @@ EXPORT_SYMBOL(snd_ctl_boolean_mono_info); * * This is a function that can be used as info callback for a standard * boolean control with stereo two channels. + * + * Return: Zero (always successful) */ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -2413,7 +2425,7 @@ EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); * If the control's accessibility is not the default (readable and writable), * the caller has to fill @info->access. * - * Return: Zero. + * Return: Zero (always successful) */ int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels, unsigned int items, const char *const names[]) -- GitLab From 6eba99d4ce2487f2050b8787029cabfcfb748ee4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:58 +0200 Subject: [PATCH 897/942] ALSA: memalloc: Fix missing return value comments for kernel docs Each kernel doc comment expects the definition of the return value in a proper format. This patch adds or fixes the missing entries for memory allocation helpers. Link: https://lore.kernel.org/r/20220713104759.4365-7-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/memalloc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 8cfdaee779050..d3885cb02270e 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -147,7 +147,7 @@ static void __snd_release_pages(struct device *dev, void *res) * hence it can't work with SNDRV_DMA_TYPE_CONTINUOUS or * SNDRV_DMA_TYPE_VMALLOC type. * - * The function returns the snd_dma_buffer object at success, or NULL if failed. + * Return: the snd_dma_buffer object at success, or NULL if failed */ struct snd_dma_buffer * snd_devm_alloc_dir_pages(struct device *dev, int type, @@ -179,6 +179,8 @@ EXPORT_SYMBOL_GPL(snd_devm_alloc_dir_pages); * snd_dma_buffer_mmap - perform mmap of the given DMA buffer * @dmab: buffer allocation information * @area: VM area information + * + * Return: zero if successful, or a negative error code */ int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab, struct vm_area_struct *area) @@ -219,6 +221,8 @@ EXPORT_SYMBOL_GPL(snd_dma_buffer_sync); * snd_sgbuf_get_addr - return the physical address at the corresponding offset * @dmab: buffer allocation information * @offset: offset in the ring buffer + * + * Return: the physical address */ dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset) { @@ -235,6 +239,8 @@ EXPORT_SYMBOL(snd_sgbuf_get_addr); * snd_sgbuf_get_page - return the physical page at the corresponding offset * @dmab: buffer allocation information * @offset: offset in the ring buffer + * + * Return: the page pointer */ struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset) { @@ -253,6 +259,8 @@ EXPORT_SYMBOL(snd_sgbuf_get_page); * @dmab: buffer allocation information * @ofs: offset in the ring buffer * @size: the requested size + * + * Return: the chunk size */ unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab, unsigned int ofs, unsigned int size) -- GitLab From 281dee6707a869e0f40cac81b6b65c703192aa9d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jul 2022 12:47:59 +0200 Subject: [PATCH 898/942] ALSA: core: Fix missing return value comments for kernel docs Each kernel doc comment expects the definition of the return value in a proper format. This patch adds or fixes the missing entries for the remaining ALSA core API functions. Link: https://lore.kernel.org/r/20220713104759.4365-8-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/device.c | 2 ++ sound/core/info.c | 2 ++ sound/core/init.c | 10 ++++++++++ sound/core/isadma.c | 3 ++- sound/core/vmaster.c | 3 ++- 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sound/core/device.c b/sound/core/device.c index bf0b04a7ee797..b57d80a170522 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -247,6 +247,8 @@ void snd_device_free_all(struct snd_card *card) * device, either @SNDRV_DEV_BUILD, @SNDRV_DEV_REGISTERED or * @SNDRV_DEV_DISCONNECTED is returned. * Or for a non-existing device, -1 is returned as an error. + * + * Return: the current state, or -1 if not found */ int snd_device_get_state(struct snd_card *card, void *device_data) { diff --git a/sound/core/info.c b/sound/core/info.c index 782fba87cc043..b8058b3411783 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -868,6 +868,8 @@ EXPORT_SYMBOL(snd_info_register); * * This proc file entry will be registered via snd_card_register() call, and * it will be removed automatically at the card removal, too. + * + * Return: zero if successful, or a negative error code */ int snd_card_rw_proc_new(struct snd_card *card, const char *name, void *private_data, diff --git a/sound/core/init.c b/sound/core/init.c index 1870aee7b64f6..3ac95c66a4b5b 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -215,6 +215,8 @@ static void __snd_card_release(struct device *dev, void *data) * via snd_card_free() call in the error; otherwise it may lead to UAF due to * devres call orders. You can use snd_card_free_on_error() helper for * handling it more easily. + * + * Return: zero if successful, or a negative error code */ int snd_devm_card_new(struct device *parent, int idx, const char *xid, struct module *module, size_t extra_size, @@ -249,6 +251,8 @@ EXPORT_SYMBOL_GPL(snd_devm_card_new); * This function handles the explicit snd_card_free() call at the error from * the probe callback. It's just a small helper for simplifying the error * handling with the managed devices. + * + * Return: zero if successful, or a negative error code */ int snd_card_free_on_error(struct device *dev, int ret) { @@ -370,6 +374,8 @@ static int snd_card_init(struct snd_card *card, struct device *parent, * * Returns a card object corresponding to the given index or NULL if not found. * Release the object via snd_card_unref(). + * + * Return: a card object or NULL */ struct snd_card *snd_card_ref(int idx) { @@ -608,6 +614,8 @@ static int snd_card_do_free(struct snd_card *card) * resource immediately, but tries to disconnect at first. When the card * is still in use, the function returns before freeing the resources. * The card resources will be freed when the refcount gets to zero. + * + * Return: zero if successful, or a negative error code */ int snd_card_free_when_closed(struct snd_card *card) { @@ -833,6 +841,8 @@ static const struct attribute_group card_dev_attr_group = { * snd_card_add_dev_attr - Append a new sysfs attribute group to card * @card: card instance * @group: attribute group to append + * + * Return: zero if successful, or a negative error code */ int snd_card_add_dev_attr(struct snd_card *card, const struct attribute_group *group) diff --git a/sound/core/isadma.c b/sound/core/isadma.c index 1f45ede023b44..2602246bd5a09 100644 --- a/sound/core/isadma.c +++ b/sound/core/isadma.c @@ -116,8 +116,9 @@ static void __snd_release_dma(struct device *dev, void *data) * @dma: the dma number * @name: the name string of the requester * - * Returns zero on success, or a negative error code. * The requested DMA will be automatically released at unbinding via devres. + * + * Return: zero on success, or a negative error code */ int snd_devm_request_dma(struct device *dev, int dma, const char *name) { diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index ab36f9898711a..d0f11f37889b5 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -494,7 +494,8 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); * @arg: optional function argument * * Apply the function @func to each follower kctl of the given vmaster kctl. - * Returns 0 if successful, or a negative error code. + * + * Return: 0 if successful, or a negative error code */ int snd_ctl_apply_vmaster_followers(struct snd_kcontrol *kctl, int (*func)(struct snd_kcontrol *vfollower, -- GitLab From 73acfba792b06156b7c805162fcd89fdb71646f9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 12 Jul 2022 17:42:12 +0300 Subject: [PATCH 899/942] ASoC: amd: Fix error pointer dereference The "gpio_pa" pointer is an error pointer, there is no need to try put it. Calling gpiod_put() on it will lead to an error pointer dereference. Fixes: 02527c3f2300 ("ASoC: amd: add Machine driver for Jadeite platform") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/Ys2IRPHWGIwuVs21@kili Signed-off-by: Mark Brown --- sound/soc/amd/acp-es8336.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index d501618b78f6e..2fe8df86053ae 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -212,7 +212,6 @@ static int st_es8336_late_probe(struct snd_soc_card *card) if (IS_ERR(gpio_pa)) { ret = dev_err_probe(card->dev, PTR_ERR(gpio_pa), "could not get pa-enable GPIO\n"); - gpiod_put(gpio_pa); put_device(codec_dev); return ret; } -- GitLab From eda26893dabfc6da7a1e1ff5f8628ed9faab3ab9 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 13 Jul 2022 15:12:00 +0800 Subject: [PATCH 900/942] ASoc: audio-graph-card2: Fix refcount leak bug in __graph_get_type() We should call of_node_put() for the reference before its replacement as it returned by of_get_parent() which has increased the refcount. Besides, we should also call of_node_put() before return. Fixes: c8c74939f791 ("ASoC: audio-graph-card2: add Multi CPU/Codec support") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220713071200.366729-1-windhl@126.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 35 +++++++++++++++++++-------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 19e31d53422ab..18d053a0d05c7 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -229,7 +229,8 @@ enum graph_type { static enum graph_type __graph_get_type(struct device_node *lnk) { - struct device_node *np; + struct device_node *np, *parent_np; + enum graph_type ret; /* * target { @@ -240,19 +241,33 @@ static enum graph_type __graph_get_type(struct device_node *lnk) * }; */ np = of_get_parent(lnk); - if (of_node_name_eq(np, "ports")) - np = of_get_parent(np); + if (of_node_name_eq(np, "ports")) { + parent_np = of_get_parent(np); + of_node_put(np); + np = parent_np; + } - if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) - return GRAPH_MULTI; + if (of_node_name_eq(np, GRAPH_NODENAME_MULTI)) { + ret = GRAPH_MULTI; + goto out_put; + } - if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) - return GRAPH_DPCM; + if (of_node_name_eq(np, GRAPH_NODENAME_DPCM)) { + ret = GRAPH_DPCM; + goto out_put; + } - if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) - return GRAPH_C2C; + if (of_node_name_eq(np, GRAPH_NODENAME_C2C)) { + ret = GRAPH_C2C; + goto out_put; + } + + ret = GRAPH_NORMAL; + +out_put: + of_node_put(np); + return ret; - return GRAPH_NORMAL; } static enum graph_type graph_get_type(struct asoc_simple_priv *priv, -- GitLab From 1795c16a436057f95fef5b622d808885dd772d0e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 12 Jul 2022 11:33:48 -0700 Subject: [PATCH 901/942] ASoC: amd: fix Jadeite kconfig warning and build errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since SND_SOC_ES8316 has a hard dependency on I2C and since 'select' does not follow any dependency chains, SND_SOC_AMD_ST_ES8336_MACH also needs to have a hard dependency on I2C. Fixes a kconfig warning and subsequent build errors: WARNING: unmet direct dependencies detected for SND_SOC_ES8316 Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=n] Selected by [y]: - SND_SOC_AMD_ST_ES8336_MACH [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && SND_SOC_AMD_ACP [=y] && ACPI [=y] && (I2C [=n] || COMPILE_TEST [=y]) sound/soc/codecs/es8316.c:866:1: warning: data definition has no type or storage class 866 | module_i2c_driver(es8316_i2c_driver); sound/soc/codecs/es8316.c:866:1: error: type defaults to ‘int’ in declaration of ‘module_i2c_driver’ [-Werror=implicit-int] sound/soc/codecs/es8316.c:866:1: warning: parameter names (without types) in function declaration sound/soc/codecs/es8316.c:857:26: warning: ‘es8316_i2c_driver’ defined but not used [-Wunused-variable] 857 | static struct i2c_driver es8316_i2c_driver = { Fixes: f94fa8405801 ("ASoC: amd: enable machine driver build for Jadeite platform") Signed-off-by: Randy Dunlap Cc: Vijendar Mukunda Cc: Mark Brown Cc: alsa-devel@alsa-project.org Cc: Jaroslav Kysela Cc: Takashi Iwai Link: https://lore.kernel.org/r/20220712183348.31046-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- sound/soc/amd/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 9629328c419ea..9c2fef2ce89fd 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -28,7 +28,7 @@ config SND_SOC_AMD_ST_ES8336_MACH select SND_SOC_ACPI if ACPI select SND_SOC_ES8316 depends on SND_SOC_AMD_ACP && ACPI - depends on I2C || COMPILE_TEST + depends on I2C help This option enables machine driver for Jadeite platform using es8336 codec. -- GitLab From a8d5df69e2ec702d979f7d04ed519caf8691a032 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 13 Jul 2022 18:20:13 +0800 Subject: [PATCH 902/942] ASoC: mt6359: Fix refcount leak bug In mt6359_parse_dt() and mt6359_accdet_parse_dt(), we should call of_node_put() for the reference returned by of_get_child_by_name() which has increased the refcount. Fixes: 683530285316 ("ASoC: mt6359: fix failed to parse DT properties") Fixes: eef07b9e0925 ("ASoC: mediatek: mt6359: add MT6359 accdet jack driver") Signed-off-by: Liang He Link: https://lore.kernel.org/r/20220713102013.367336-1-windhl@126.com Signed-off-by: Mark Brown --- sound/soc/codecs/mt6359-accdet.c | 1 + sound/soc/codecs/mt6359.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c index 6d3d170144a0a..c190628e29056 100644 --- a/sound/soc/codecs/mt6359-accdet.c +++ b/sound/soc/codecs/mt6359-accdet.c @@ -675,6 +675,7 @@ static int mt6359_accdet_parse_dt(struct mt6359_accdet *priv) sizeof(struct three_key_threshold)); } + of_node_put(node); dev_warn(priv->dev, "accdet caps=%x\n", priv->caps); return 0; diff --git a/sound/soc/codecs/mt6359.c b/sound/soc/codecs/mt6359.c index 23709b180409c..c9a453ce8a2a8 100644 --- a/sound/soc/codecs/mt6359.c +++ b/sound/soc/codecs/mt6359.c @@ -2778,6 +2778,7 @@ static int mt6359_parse_dt(struct mt6359_priv *priv) ret = of_property_read_u32(np, "mediatek,mic-type-2", &priv->mux_select[MUX_MIC_TYPE_2]); + of_node_put(np); if (ret) { dev_info(priv->dev, "%s() failed to read mic-type-2, use default (%d)\n", -- GitLab From 6d1c1a73e1126572de0a8b063fe62fe43786ed59 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 8 Jul 2022 14:13:11 +0800 Subject: [PATCH 903/942] soundwire: Intel: add trigger callback When a pipeline is split into FE and BE parts, the BE pipeline may need to be triggered separately in the BE trigger op. So add the trigger callback in the link_res ops that will be invoked during BE DAI trigger. Signed-off-by: Bard Liao Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Acked-by: Vinod Koul Link: https://lore.kernel.org/r/20220708061312.25878-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- drivers/soundwire/intel.c | 9 +++++++++ include/linux/soundwire/sdw_intel.h | 1 + 2 files changed, 10 insertions(+) diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 0268fa527c0c0..fed6418d6375e 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -1004,9 +1004,18 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn { struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); struct sdw_intel *sdw = cdns_to_intel(cdns); + struct sdw_intel_link_res *res = sdw->link_res; struct sdw_cdns_dma_data *dma; int ret = 0; + /* + * The .trigger callback is used to send required IPC to audio + * firmware. The .free_stream callback will still be called + * by intel_free_stream() in the TRIGGER_SUSPEND case. + */ + if (res->ops && res->ops->trigger) + res->ops->trigger(dai, cmd, substream->stream); + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) { dev_err(dai->dev, "failed to get dma data in %s\n", diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index b5b489ea1aefe..ec16ae49e6a43 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -121,6 +121,7 @@ struct sdw_intel_ops { struct sdw_intel_stream_params_data *params_data); int (*free_stream)(struct device *dev, struct sdw_intel_stream_free_data *free_data); + int (*trigger)(struct snd_soc_dai *dai, int cmd, int stream); }; /** -- GitLab From 2a1be12c4d77d4f7b122568383382e006a60381b Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 8 Jul 2022 14:13:12 +0800 Subject: [PATCH 904/942] ASoC: SOF: Intel: add trigger callback into sdw_callback For IPC4, we need to set pipeline state in BE DAI trigger. Signed-off-by: Bard Liao Reviewed-by: Rander Wang Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220708061312.25878-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dai.c | 14 +++++++++++--- sound/soc/sof/intel/hda.c | 2 +- sound/soc/sof/intel/hda.h | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index c5b65e4a06be4..556e883a32edb 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -708,8 +708,7 @@ static const struct snd_soc_dai_ops ipc3_ssp_dai_ops = { .shutdown = ssp_dai_shutdown, }; -static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) +static int ipc4_be_dai_common_trigger(struct snd_soc_dai *dai, int cmd, int stream) { struct snd_sof_widget *pipe_widget; struct sof_ipc4_pipeline *pipeline; @@ -718,7 +717,7 @@ static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev; int ret; - w = snd_soc_dai_get_widget(dai, substream->stream); + w = snd_soc_dai_get_widget(dai, stream); swidget = w->dobj.private; pipe_widget = swidget->pipe_widget; pipeline = pipe_widget->private; @@ -753,6 +752,12 @@ static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, return 0; } +static int ipc4_be_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + return ipc4_be_dai_common_trigger(dai, cmd, substream->stream); +} + static const struct snd_soc_dai_ops ipc4_dmic_dai_ops = { .trigger = ipc4_be_dai_trigger, }; @@ -804,6 +809,9 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) if (!hda_use_tplg_nhlt) ipc4_data->nhlt = intel_nhlt_init(sdev->dev); + if (IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)) + sdw_callback.trigger = ipc4_be_dai_common_trigger; + break; } default: diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index d519b9802b3bc..b7fa95ea1090b 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -147,7 +147,7 @@ static int sdw_free_stream(struct device *dev, return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, &data); } -static const struct sdw_intel_ops sdw_callback = { +struct sdw_intel_ops sdw_callback = { .params_stream = sdw_params_stream, .free_stream = sdw_free_stream, }; diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index d684908e9a53a..5ef3e8775e364 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -842,5 +842,6 @@ irqreturn_t cnl_ipc4_irq_thread(int irq, void *context); int cnl_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); irqreturn_t hda_dsp_ipc4_irq_thread(int irq, void *context); int hda_dsp_ipc4_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg); +extern struct sdw_intel_ops sdw_callback; #endif -- GitLab From 89422df9548002adfffb73799cebe4909cfc8902 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 13 Jul 2022 17:19:46 +0200 Subject: [PATCH 905/942] ALSA: usb-audio: Use atomic_try_cmpxchg in ep_state_update Use atomic_try_cmpxchg instead of atomic_cmpxchg (*ptr, old, new) == old in ep_state_update. x86 CMPXCHG instruction returns success in ZF flag, so this change saves a compare after cmpxchg (and related move instruction in front of cmpxchg). No functional change intended. Signed-off-by: Uros Bizjak Link: https://lore.kernel.org/r/20220713151946.4743-1-ubizjak@gmail.com Signed-off-by: Takashi Iwai --- sound/usb/endpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index f9c921683948d..0d7b73bf79450 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -133,7 +133,7 @@ static inline bool ep_state_running(struct snd_usb_endpoint *ep) static inline bool ep_state_update(struct snd_usb_endpoint *ep, int old, int new) { - return atomic_cmpxchg(&ep->state, old, new) == old; + return atomic_try_cmpxchg(&ep->state, &old, new); } /** -- GitLab From 3233b978af23f11b4ad4f7f11a9a64bd05702b1f Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:22 +0100 Subject: [PATCH 906/942] ALSA: hda: hda_cs_dsp_ctl: Add Library to support CS_DSP ALSA controls The cs35l41 part contains a DSP which is able to run firmware. The cs_dsp library can be used to control the DSP. These controls can be exposed to userspace using ALSA controls. This library adds apis to be able to interface between cs_dsp and hda drivers and expose the relevant controls as ALSA controls. [ Note: the dependency of CONFIG_SND_HDA_CS_DSP_CONTROLS Kconfig is corrected. Also, this Kconfig isn't enabled now but will be actually enabled in a later patch -- tiwai ] Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-2-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- MAINTAINERS | 1 + sound/pci/hda/Kconfig | 4 + sound/pci/hda/Makefile | 2 + sound/pci/hda/hda_cs_dsp_ctl.c | 193 +++++++++++++++++++++++++++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 33 ++++++ 5 files changed, 233 insertions(+) create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.c create mode 100644 sound/pci/hda/hda_cs_dsp_ctl.h diff --git a/MAINTAINERS b/MAINTAINERS index 5582019bb0f02..e0fb3e3f6fdef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4755,6 +4755,7 @@ S: Maintained F: Documentation/devicetree/bindings/sound/cirrus,cs* F: include/dt-bindings/sound/cs* F: sound/pci/hda/cs* +F: sound/pci/hda/hda_cs_dsp_ctl.* F: sound/soc/codecs/cs* CIRRUS LOGIC DSP FIRMWARE DRIVER diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 8b73a12d356f0..a17803953222e 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -96,6 +96,10 @@ config SND_HDA_SCODEC_CS35L41 select SND_HDA_GENERIC select REGMAP_IRQ +config SND_HDA_CS_DSP_CONTROLS + tristate + select CS_DSP + config SND_HDA_SCODEC_CS35L41_I2C tristate "Build CS35L41 HD-audio side codec support for I2C Bus" depends on I2C diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 3e7bc608d45f2..00d3061044842 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -31,6 +31,7 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o snd-hda-scodec-cs35l41-objs := cs35l41_hda.o snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o +snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o # common driver obj-$(CONFIG_SND_HDA) := snd-hda-codec.o @@ -54,6 +55,7 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o +obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o # this must be the last entry after codec drivers; # otherwise the codec patches won't be hooked before the PCI probe diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c new file mode 100644 index 0000000000000..74e2c5bd1b08a --- /dev/null +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// HDA DSP ALSA Control Driver +// +// Copyright 2022 Cirrus Logic, Inc. +// +// Author: Stefan Binding + +#include +#include +#include +#include +#include "hda_cs_dsp_ctl.h" + +#define ADSP_MAX_STD_CTRL_SIZE 512 + +struct hda_cs_dsp_coeff_ctl { + struct cs_dsp_coeff_ctl *cs_ctl; + struct snd_card *card; + struct snd_kcontrol *kctl; +}; + +static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { + [HDA_CS_DSP_FW_SPK_PROT] = "Prot", + [HDA_CS_DSP_FW_SPK_CALI] = "Cali", + [HDA_CS_DSP_FW_SPK_DIAG] = "Diag", + [HDA_CS_DSP_FW_MISC] = "Misc", +}; + +static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = cs_ctl->len; + + return 0; +} + +static int hda_cs_dsp_coeff_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret = 0; + + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +} + +static int hda_cs_dsp_coeff_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + char *p = ucontrol->value.bytes.data; + int ret; + + mutex_lock(&cs_ctl->dsp->pwr_lock); + ret = cs_dsp_coeff_read_ctrl(cs_ctl, 0, p, cs_ctl->len); + mutex_unlock(&cs_ctl->dsp->pwr_lock); + + return ret; +} + +static unsigned int wmfw_convert_flags(unsigned int in) +{ + unsigned int out, rd, wr, vol; + + rd = SNDRV_CTL_ELEM_ACCESS_READ; + wr = SNDRV_CTL_ELEM_ACCESS_WRITE; + vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; + + out = 0; + + if (in) { + out |= rd; + if (in & WMFW_CTL_FLAG_WRITEABLE) + out |= wr; + if (in & WMFW_CTL_FLAG_VOLATILE) + out |= vol; + } else { + out |= rd | wr | vol; + } + + return out; +} + +static int hda_cs_dsp_add_kcontrol(struct hda_cs_dsp_coeff_ctl *ctl, const char *name) +{ + struct cs_dsp_coeff_ctl *cs_ctl = ctl->cs_ctl; + struct snd_kcontrol_new kcontrol = {0}; + struct snd_kcontrol *kctl; + int ret = 0; + + if (cs_ctl->len > ADSP_MAX_STD_CTRL_SIZE) { + dev_err(cs_ctl->dsp->dev, "KControl %s: length %zu exceeds maximum %d\n", name, + cs_ctl->len, ADSP_MAX_STD_CTRL_SIZE); + return -EINVAL; + } + + kcontrol.name = name; + kcontrol.info = hda_cs_dsp_coeff_info; + kcontrol.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kcontrol.access = wmfw_convert_flags(cs_ctl->flags); + kcontrol.get = hda_cs_dsp_coeff_get; + kcontrol.put = hda_cs_dsp_coeff_put; + + /* Save ctl inside private_data, ctl is owned by cs_dsp, + * and will be freed when cs_dsp removes the control */ + kctl = snd_ctl_new1(&kcontrol, (void *)ctl); + if (!kctl) { + ret = -ENOMEM; + return ret; + } + + ret = snd_ctl_add(ctl->card, kctl); + if (ret) { + dev_err(cs_ctl->dsp->dev, "Failed to add KControl %s = %d\n", kcontrol.name, ret); + return ret; + } + + dev_dbg(cs_ctl->dsp->dev, "Added KControl: %s\n", kcontrol.name); + ctl->kctl = kctl; + + return 0; +} + +int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info) +{ + struct cs_dsp *cs_dsp = cs_ctl->dsp; + char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + struct hda_cs_dsp_coeff_ctl *ctl; + const char *region_name; + int ret; + + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + + region_name = cs_dsp_mem_region_name(cs_ctl->alg_region.type); + if (!region_name) { + dev_err(cs_dsp->dev, "Unknown region type: %d\n", cs_ctl->alg_region.type); + return -EINVAL; + } + + ret = scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %.12s %x", info->device_name, + cs_dsp->name, hda_cs_dsp_fw_text[info->fw_type], cs_ctl->alg_region.alg); + + if (cs_ctl->subname) { + int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; + int skip = 0; + + /* Truncate the subname from the start if it is too long */ + if (cs_ctl->subname_len > avail) + skip = cs_ctl->subname_len - avail; + + snprintf(name + ret, SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, + " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); + } + + ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + if (!ctl) + return -ENOMEM; + + ctl->cs_ctl = cs_ctl; + ctl->card = info->card; + cs_ctl->priv = ctl; + + ret = hda_cs_dsp_add_kcontrol(ctl, name); + if (ret) { + dev_err(cs_dsp->dev, "Error (%d) adding control %s\n", ret, name); + kfree(ctl); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_add, SND_HDA_CS_DSP_CONTROLS); + +void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) +{ + struct hda_cs_dsp_coeff_ctl *ctl = cs_ctl->priv; + + kfree(ctl); +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); + +MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); +MODULE_AUTHOR("Stefan Binding, "); +MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h new file mode 100644 index 0000000000000..1c6d0fc9a2cc5 --- /dev/null +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * HDA DSP ALSA Control Driver + * + * Copyright 2022 Cirrus Logic, Inc. + * + * Author: Stefan Binding + */ + +#ifndef __HDA_CS_DSP_CTL_H__ +#define __HDA_CS_DSP_CTL_H__ + +#include +#include + +enum hda_cs_dsp_fw_id { + HDA_CS_DSP_FW_SPK_PROT, + HDA_CS_DSP_FW_SPK_CALI, + HDA_CS_DSP_FW_SPK_DIAG, + HDA_CS_DSP_FW_MISC, + HDA_CS_DSP_NUM_FW +}; + +struct hda_cs_dsp_ctl_info { + struct snd_card *card; + enum hda_cs_dsp_fw_id fw_type; + const char *device_name; +}; + +int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); +void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); + +#endif /*__HDA_CS_DSP_CTL_H__*/ -- GitLab From e414b05e724f5fbae6e86d074d7668287a603b24 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:23 +0100 Subject: [PATCH 907/942] ALSA: hda: hda_cs_dsp_ctl: Add apis to write the controls directly DSP controls are exposed as ALSA controls, however, some of these controls are required to be accessed by the driver. Add apis which allow read/write of these controls. The write api will also notify the ALSA control on value change. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-3-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_cs_dsp_ctl.c | 39 ++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 4 ++++ 2 files changed, 43 insertions(+) diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c index 74e2c5bd1b08a..2351476c9ee6b 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.c +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -188,6 +188,45 @@ void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl) } EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_control_remove, SND_HDA_CS_DSP_CONTROLS); +int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len) +{ + struct cs_dsp_coeff_ctl *cs_ctl; + struct hda_cs_dsp_coeff_ctl *ctl; + int ret; + + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + + ctl = cs_ctl->priv; + + ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, buf, len); + if (ret) + return ret; + + if (cs_ctl->flags & WMFW_CTL_FLAG_SYS) + return 0; + + snd_ctl_notify(ctl->card, SNDRV_CTL_EVENT_MASK_VALUE, &ctl->kctl->id); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_write_ctl, SND_HDA_CS_DSP_CONTROLS); + +int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len) +{ + struct cs_dsp_coeff_ctl *cs_ctl; + + cs_ctl = cs_dsp_get_ctl(dsp, name, type, alg); + if (!cs_ctl) + return -EINVAL; + + return cs_dsp_coeff_read_ctrl(cs_ctl, 0, buf, len); +} +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_read_ctl, SND_HDA_CS_DSP_CONTROLS); + MODULE_DESCRIPTION("CS_DSP ALSA Control HDA Library"); MODULE_AUTHOR("Stefan Binding, "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h index 1c6d0fc9a2cc5..c65bfd6878fde 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.h +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -29,5 +29,9 @@ struct hda_cs_dsp_ctl_info { int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); +int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, const void *buf, size_t len); +int hda_cs_dsp_read_ctl(struct cs_dsp *dsp, const char *name, int type, + unsigned int alg, void *buf, size_t len); #endif /*__HDA_CS_DSP_CTL_H__*/ -- GitLab From 22d5cbd273a2ca90ba026ec82f0b9c3e984b0c1c Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:24 +0100 Subject: [PATCH 908/942] ALSA: hda: cs35l41: Save codec object inside component struct This is required for ALSA control support. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-4-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 1 + sound/pci/hda/cs35l41_hda.h | 1 + sound/pci/hda/hda_component.h | 1 + sound/pci/hda/patch_realtek.c | 1 + 4 files changed, 4 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 1a1afa0725e02..20d3ce8773dd4 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -117,6 +117,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas return -EBUSY; comps->dev = dev; + cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index a52ffd1f79994..aaf9e16684c26 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -32,6 +32,7 @@ struct cs35l41_hda { struct regmap *regmap; struct gpio_desc *reset_gpio; struct cs35l41_hw_cfg hw_cfg; + struct hda_codec *codec; int irq; int index; diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h index e26c896a13f34..534e845b9cd1d 100644 --- a/sound/pci/hda/hda_component.h +++ b/sound/pci/hda/hda_component.h @@ -14,5 +14,6 @@ struct hda_component { struct device *dev; char name[HDA_MAX_NAME_SIZE]; + struct hda_codec *codec; void (*playback_hook)(struct device *dev, int action); }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 007dd8b5e1f2f..44744d5684048 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6654,6 +6654,7 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char "%s-%s:00-cs35l41-hda.%d", bus, hid, i); if (!name) return; + spec->comps[i].codec = cdc; component_match_add(dev, &spec->match, component_compare_dev_name, name); } ret = component_master_add_with_match(dev, &comp_master_ops, spec->match); -- GitLab From 2e81e1fffd53ba108481f2f14388b628884efe61 Mon Sep 17 00:00:00 2001 From: Vitaly Rodionov Date: Thu, 30 Jun 2022 01:23:25 +0100 Subject: [PATCH 909/942] ALSA: hda: cs35l41: Add initial DSP support and firmware loading This patch adds support for the CS35L41 DSP. The DSP allows for extra features, such as running speaker protection algorithms and hibernations. To utilize these features, the driver must load firmware into the DSP, as well as various tuning files which allow for customization for specific models. [ Slightly simplified Kconfig changes by tiwai ] Signed-off-by: Vitaly Rodionov Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-5-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- include/sound/cs35l41.h | 4 + sound/pci/hda/Kconfig | 2 + sound/pci/hda/cs35l41_hda.c | 251 +++++++++++++++++++++++++++++++++++- sound/pci/hda/cs35l41_hda.h | 13 ++ 4 files changed, 269 insertions(+), 1 deletion(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 8972fa6976227..8887087815a75 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -665,6 +665,10 @@ #define CS35L41_BST_EN_DEFAULT 0x2 #define CS35L41_AMP_EN_SHIFT 0 #define CS35L41_AMP_EN_MASK 1 +#define CS35L41_VMON_EN_MASK 0x1000 +#define CS35L41_VMON_EN_SHIFT 12 +#define CS35L41_IMON_EN_MASK 0x2000 +#define CS35L41_IMON_EN_SHIFT 13 #define CS35L41_PDN_DONE_MASK 0x00800000 #define CS35L41_PDN_DONE_SHIFT 23 diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index a17803953222e..44c33bc0740e0 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -107,6 +107,7 @@ config SND_HDA_SCODEC_CS35L41_I2C depends on SND_SOC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 + select SND_HDA_CS_DSP_CONTROLS help Say Y or M here to include CS35L41 I2C HD-audio side codec support in snd-hda-intel driver, such as ALC287. @@ -121,6 +122,7 @@ config SND_HDA_SCODEC_CS35L41_SPI depends on SND_SOC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 + select SND_HDA_CS_DSP_CONTROLS help Say Y or M here to include CS35L41 SPI HD-audio side codec support in snd-hda-intel driver, such as ALC287. diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 20d3ce8773dd4..d68d951c434ed 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -9,12 +9,22 @@ #include #include #include +#include #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" #include "hda_generic.h" #include "hda_component.h" #include "cs35l41_hda.h" +#include "hda_cs_dsp_ctl.h" + +#define CS35L41_FIRMWARE_ROOT "cirrus/" +#define CS35L41_PART "cs35l41" +#define FW_NAME "CSPL" + +#define HALO_STATE_DSP_CTL_NAME "HALO_STATE" +#define HALO_STATE_DSP_CTL_TYPE 5 +#define HALO_STATE_DSP_CTL_ALG 262308 static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 @@ -27,11 +37,172 @@ static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB }; +static const struct reg_sequence cs35l41_hda_config_dsp[] = { + { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz + { CS35L41_SP_ENABLES, 0x00010001 }, // ASP_RX1_EN = 1, ASP_TX1_EN = 1 + { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz + { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer + { CS35L41_SP_HIZ_CTRL, 0x00000003 }, // Hi-Z unused/disabled + { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_DAC_PCM1_SRC, 0x00000032 }, // DACPCM1_SRC = ERR_VOL + { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON + { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON + { CS35L41_ASP_TX3_SRC, 0x00000028 }, // ASPTX3 SRC = VPMON + { CS35L41_ASP_TX4_SRC, 0x00000029 }, // ASPTX4 SRC = VBSTMON + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 + { CS35L41_DSP1_RX2_SRC, 0x00000008 }, // DSP1RX2 SRC = ASPRX1 + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON + { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON + { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB + { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB +}; + static const struct reg_sequence cs35l41_hda_mute[] = { { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute }; +static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) +{ + struct cs35l41_hda *cs35l41 = container_of(cs_ctl->dsp, struct cs35l41_hda, cs_dsp); + struct hda_cs_dsp_ctl_info info; + + info.device_name = cs35l41->amp_name; + info.fw_type = HDA_CS_DSP_FW_SPK_PROT; + info.card = cs35l41->codec->card; + + return hda_cs_dsp_control_add(cs_ctl, &info); +} + +static const struct cs_dsp_client_ops client_ops = { + .control_add = cs35l41_control_add, + .control_remove = hda_cs_dsp_control_remove, +}; + +static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, + const struct firmware **firmware, char **filename, + const char *dir, const char *filetype) +{ + const char * const dsp_name = cs35l41->cs_dsp.name; + char *s, c; + int ret = 0; + + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", + filetype); + + if (*filename == NULL) + return -ENOMEM; + + /* + * Make sure that filename is lower-case and any non alpha-numeric + * characters except full stop and '/' are replaced with hyphens. + */ + s = *filename; + while (*s) { + c = *s; + if (isalnum(c)) + *s = tolower(c); + else if (c != '.' && c != '/') + *s = '-'; + s++; + } + + ret = firmware_request_nowarn(firmware, *filename, cs35l41->dev); + if (ret != 0) { + dev_dbg(cs35l41->dev, "Failed to request '%s'\n", *filename); + kfree(*filename); + *filename = NULL; + } + + return ret; +} + +static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) +{ + int ret; + + /* cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, "wmfw"); + if (!ret) { + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, "bin"); + return 0; + } + + dev_warn(cs35l41->dev, "Failed to request firmware\n"); + + return ret; +} + +static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) +{ + const struct firmware *coeff_firmware = NULL; + const struct firmware *wmfw_firmware = NULL; + struct cs_dsp *dsp = &cs35l41->cs_dsp; + char *coeff_filename = NULL; + char *wmfw_filename = NULL; + int ret; + + if (!cs35l41->halo_initialized) { + cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, dsp); + dsp->client_ops = &client_ops; + + ret = cs_dsp_halo_init(&cs35l41->cs_dsp); + if (ret) + return ret; + cs35l41->halo_initialized = true; + } + + ret = cs35l41_request_firmware_files(cs35l41, &wmfw_firmware, &wmfw_filename, + &coeff_firmware, &coeff_filename); + if (ret < 0) + return ret; + + dev_dbg(cs35l41->dev, "Loading WMFW Firmware: %s\n", wmfw_filename); + if (coeff_filename) + dev_dbg(cs35l41->dev, "Loading Coefficient File: %s\n", coeff_filename); + else + dev_warn(cs35l41->dev, "No Coefficient File available.\n"); + + ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, + FW_NAME); + + release_firmware(wmfw_firmware); + release_firmware(coeff_firmware); + kfree(wmfw_filename); + kfree(coeff_filename); + + return ret; +} + +static void cs35l41_shutdown_dsp(struct cs35l41_hda *cs35l41) +{ + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cs_dsp_stop(dsp); + cs_dsp_power_down(dsp); + cs35l41->firmware_running = false; + dev_dbg(cs35l41->dev, "Unloaded Firmware\n"); +} + +static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) +{ + struct cs_dsp *dsp = &cs35l41->cs_dsp; + + cs35l41_shutdown_dsp(cs35l41); + cs_dsp_remove(dsp); + cs35l41->halo_initialized = false; +} + /* Protection release cycle to get the speaker out of Safe-Mode */ static void cs35l41_error_release(struct device *dev, struct regmap *regmap, unsigned int mask) { @@ -53,9 +224,22 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) struct regmap *reg = cs35l41->regmap; int ret = 0; + mutex_lock(&cs35l41->fw_mutex); + switch (action) { case HDA_GEN_PCM_ACT_OPEN: - regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); + if (cs35l41->firmware_running) { + regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, + ARRAY_SIZE(cs35l41_hda_config_dsp)); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, + 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT); + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_RESUME); + } else { + regmap_multi_reg_write(reg, cs35l41_hda_config, + ARRAY_SIZE(cs35l41_hda_config)); + } ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) @@ -73,6 +257,13 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); + if (cs35l41->firmware_running) { + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_PAUSE); + regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, + CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK, + 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); + } cs35l41_irq_release(cs35l41); break; default: @@ -80,6 +271,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) break; } + mutex_unlock(&cs35l41->fw_mutex); + if (ret) dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); } @@ -104,6 +297,51 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi rx_slot); } +static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) +{ + int halo_sts; + int ret; + + ret = cs35l41_init_dsp(cs35l41); + if (ret) { + dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); + goto clean_dsp; + } + + ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write FS Errata: %d\n", ret); + goto clean_dsp; + } + + ret = cs_dsp_run(&cs35l41->cs_dsp); + if (ret) { + dev_err(cs35l41->dev, "Fail to start dsp: %d\n", ret); + goto clean_dsp; + } + + ret = read_poll_timeout(hda_cs_dsp_read_ctl, ret, + be32_to_cpu(halo_sts) == HALO_STATE_CODE_RUN, + 1000, 15000, false, &cs35l41->cs_dsp, HALO_STATE_DSP_CTL_NAME, + HALO_STATE_DSP_CTL_TYPE, HALO_STATE_DSP_CTL_ALG, + &halo_sts, sizeof(halo_sts)); + + if (ret) { + dev_err(cs35l41->dev, "Timeout waiting for HALO Core to start. State: %d\n", + halo_sts); + goto clean_dsp; + } + + cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE); + cs35l41->firmware_running = true; + + return 0; + +clean_dsp: + cs35l41_shutdown_dsp(cs35l41); + return ret; +} + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); @@ -121,6 +359,11 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + return 0; } @@ -535,6 +778,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (ret) goto err; + mutex_init(&cs35l41->fw_mutex); + ret = cs35l41_hda_apply_properties(cs35l41); if (ret) goto err; @@ -562,6 +807,9 @@ void cs35l41_hda_remove(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + if (cs35l41->halo_initialized) + cs35l41_remove_dsp(cs35l41); + component_del(cs35l41->dev, &cs35l41_hda_comp_ops); if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) @@ -571,5 +819,6 @@ void cs35l41_hda_remove(struct device *dev) EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); MODULE_DESCRIPTION("CS35L41 HDA Driver"); +MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index aaf9e16684c26..5814af0509447 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -15,6 +15,9 @@ #include #include +#include +#include + enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, @@ -39,7 +42,17 @@ struct cs35l41_hda { int channel_index; unsigned volatile long irq_errors; const char *amp_name; + struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; + bool firmware_running; + bool halo_initialized; + struct cs_dsp cs_dsp; +}; + +enum halo_state { + HALO_STATE_CODE_INIT_DOWNLOAD = 0, + HALO_STATE_CODE_START, + HALO_STATE_CODE_RUN }; int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, -- GitLab From e99f3c7e3250dd895d2da506d0d910d641136d2c Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:26 +0100 Subject: [PATCH 910/942] ALSA: hda: cs35l41: Save Subsystem ID inside CS35L41 Driver The Subsystem ID is read from the HDA driver, and will be used by the CS35L41 driver to be able to uniquely identify the laptop, which is required to be able to define firmware to be used by specific models. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-6-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 3 +++ sound/pci/hda/cs35l41_hda.h | 1 + 2 files changed, 4 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index d68d951c434ed..25cb76437ba52 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -355,6 +355,9 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas return -EBUSY; comps->dev = dev; + if (!cs35l41->acpi_subsystem_id) + cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", + comps->codec->core.subsystem_id); cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); comps->playback_hook = cs35l41_hda_playback_hook; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 5814af0509447..b57f59a1ba49e 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -42,6 +42,7 @@ struct cs35l41_hda { int channel_index; unsigned volatile long irq_errors; const char *amp_name; + const char *acpi_subsystem_id; struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; bool firmware_running; -- GitLab From eef375960210fdc1ec2786bddc91ff100444ffb8 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:27 +0100 Subject: [PATCH 911/942] ALSA: hda: cs35l41: Support reading subsystem id from ACPI On some laptop models, the ACPI contains the unique Subsystem ID, and this value should be preferred over the value from the HDA driver. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-7-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 25cb76437ba52..effb3ce95c00c 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -544,6 +544,36 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); } +static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *adev, + const char **subsysid) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + int ret = 0; + + status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); + if (ACPI_SUCCESS(status)) { + obj = buffer.pointer; + if (obj->type == ACPI_TYPE_STRING) { + *subsysid = devm_kstrdup(dev, obj->string.pointer, GFP_KERNEL); + if (*subsysid == NULL) { + dev_err(dev, "Cannot allocate Subsystem ID"); + ret = -ENOMEM; + } + } else { + dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); + ret = -ENODEV; + } + acpi_os_free(buffer.pointer); + } else { + dev_dbg(dev, "Warning ACPI _SUB failed: %#x\n", status); + ret = -ENODEV; + } + + return ret; +} + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) { struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; @@ -563,6 +593,12 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i physdev = get_device(acpi_get_first_physical_node(adev)); acpi_dev_put(adev); + ret = cs35l41_get_acpi_sub_string(cs35l41->dev, adev, &cs35l41->acpi_subsystem_id); + if (ret) + dev_info(cs35l41->dev, "No Subsystem ID found in ACPI: %d", ret); + else + dev_dbg(cs35l41->dev, "Subsystem ID %s found", cs35l41->acpi_subsystem_id); + property = "cirrus,dev-index"; ret = device_property_count_u32(physdev, property); if (ret <= 0) -- GitLab From bb6eb621f522d1f76ee4593966d2863401892407 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:28 +0100 Subject: [PATCH 912/942] ALSA: hda: cs35l41: Support multiple load paths for firmware To be able to support different firmwares and tuning for different models, the driver needs to be able to load a different firmware and coefficient file based on its Subsystem ID. The driver attempts to load the firmware in the following order: /lib/firmware/cirrus/cs35l41-dsp1---dev<#>.wmfw /lib/firmware/cirrus/cs35l41-dsp1--.wmfw /lib/firmware/cirrus/cs35l41-dsp1-.wmfw Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-8-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 52 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index effb3ce95c00c..d356c1a55ad5f 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -85,14 +85,23 @@ static const struct cs_dsp_client_ops client_ops = { static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, const struct firmware **firmware, char **filename, - const char *dir, const char *filetype) + const char *dir, const char *ssid, const char *amp_name, + const char *filetype) { const char * const dsp_name = cs35l41->cs_dsp.name; char *s, c; int ret = 0; - *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", - filetype); + if (ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, amp_name, + filetype); + else if (ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, filetype); + else + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", filetype); if (*filename == NULL) return -ENOMEM; @@ -129,12 +138,43 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, { int ret; - /* cirrus/part-dspN-fwtype.wmfw */ + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, NULL, "bin"); + return 0; + } + + /* fallback try cirrus/part-dspN-fwtype.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, - CS35L41_FIRMWARE_ROOT, "wmfw"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); if (!ret) { + /* fallback try cirrus/part-dspN-fwtype.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, - CS35L41_FIRMWARE_ROOT, "bin"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); return 0; } -- GitLab From 63f4b99f0089a9719aa4441015fe30ff4b6f10e5 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:29 +0100 Subject: [PATCH 913/942] ALSA: hda: cs35l41: Support Speaker ID for laptops Some Laptops use a number of gpios to define which vendor is used for a particular laptop. Different coefficient files are used for different vendors. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-9-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 174 ++++++++++++++++++++++++++++++++++-- sound/pci/hda/cs35l41_hda.h | 1 + 2 files changed, 166 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index d356c1a55ad5f..d5d2323cc8c73 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -86,13 +86,19 @@ static const struct cs_dsp_client_ops client_ops = { static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, const struct firmware **firmware, char **filename, const char *dir, const char *ssid, const char *amp_name, - const char *filetype) + int spkid, const char *filetype) { const char * const dsp_name = cs35l41->cs_dsp.name; char *s, c; int ret = 0; - if (ssid && amp_name) + if (spkid > -1 && ssid && amp_name) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); + else if (spkid > -1 && ssid) + *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, + dsp_name, "spk-prot", ssid, spkid, filetype); + else if (ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, dsp_name, "spk-prot", ssid, amp_name, filetype); @@ -130,6 +136,93 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, return ret; } +static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41, + const struct firmware **wmfw_firmware, + char **wmfw_filename, + const struct firmware **coeff_firmware, + char **coeff_filename) +{ + int ret; + + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, cs35l41->amp_name, + cs35l41->speaker_id, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, cs35l41->amp_name, + cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "bin"); + return 0; + } + + /* try cirrus/part-dspN-fwtype-sub.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, + NULL, -1, "wmfw"); + if (!ret) { + /* try cirrus/part-dspN-fwtype-sub<-spkidN><-ampname>.bin */ + ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + cs35l41->amp_name, cs35l41->speaker_id, "bin"); + if (ret) + /* try cirrus/part-dspN-fwtype-sub<-spkidN>.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, + cs35l41->acpi_subsystem_id, + NULL, cs35l41->speaker_id, "bin"); + return 0; + } + + /* fallback try cirrus/part-dspN-fwtype.wmfw */ + ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); + if (!ret) { + /* fallback try cirrus/part-dspN-fwtype.bin */ + cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); + return 0; + } + + dev_warn(cs35l41->dev, "Failed to request firmware\n"); + + return ret; +} + static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, const struct firmware **wmfw_firmware, char **wmfw_filename, @@ -138,43 +231,48 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, { int ret; + if (cs35l41->speaker_id > -1) + return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename, + coeff_firmware, coeff_filename); + /* try cirrus/part-dspN-fwtype-sub<-ampname>.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "wmfw"); + cs35l41->amp_name, -1, "wmfw"); if (!ret) { /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "bin"); + cs35l41->amp_name, -1, "bin"); return 0; } /* try cirrus/part-dspN-fwtype-sub.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - NULL, "wmfw"); + NULL, -1, "wmfw"); if (!ret) { /* try cirrus/part-dspN-fwtype-sub<-ampname>.bin */ ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, - cs35l41->amp_name, "bin"); + cs35l41->amp_name, -1, "bin"); if (ret) /* try cirrus/part-dspN-fwtype-sub.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, CS35L41_FIRMWARE_ROOT, - cs35l41->acpi_subsystem_id, NULL, "bin"); + cs35l41->acpi_subsystem_id, + NULL, -1, "bin"); return 0; } /* fallback try cirrus/part-dspN-fwtype.wmfw */ ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, - CS35L41_FIRMWARE_ROOT, NULL, NULL, "wmfw"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "wmfw"); if (!ret) { /* fallback try cirrus/part-dspN-fwtype.bin */ cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, - CS35L41_FIRMWARE_ROOT, NULL, NULL, "bin"); + CS35L41_FIRMWARE_ROOT, NULL, NULL, -1, "bin"); return 0; } @@ -614,6 +712,61 @@ static int cs35l41_get_acpi_sub_string(struct device *dev, struct acpi_device *a return ret; } +static int cs35l41_get_speaker_id(struct device *dev, int amp_index, + int num_amps, int fixed_gpio_id) +{ + struct gpio_desc *speaker_id_desc; + int speaker_id = -ENODEV; + + if (fixed_gpio_id >= 0) { + dev_dbg(dev, "Found Fixed Speaker ID GPIO (index = %d)\n", fixed_gpio_id); + speaker_id_desc = gpiod_get_index(dev, NULL, fixed_gpio_id, GPIOD_IN); + if (IS_ERR(speaker_id_desc)) { + speaker_id = PTR_ERR(speaker_id_desc); + return speaker_id; + } + speaker_id = gpiod_get_value_cansleep(speaker_id_desc); + gpiod_put(speaker_id_desc); + dev_dbg(dev, "Speaker ID = %d\n", speaker_id); + } else { + int base_index; + int gpios_per_amp; + int count; + int tmp; + int i; + + count = gpiod_count(dev, "spk-id"); + if (count > 0) { + speaker_id = 0; + gpios_per_amp = count / num_amps; + base_index = gpios_per_amp * amp_index; + + if (count % num_amps) + return -EINVAL; + + dev_dbg(dev, "Found %d Speaker ID GPIOs per Amp\n", gpios_per_amp); + + for (i = 0; i < gpios_per_amp; i++) { + speaker_id_desc = gpiod_get_index(dev, "spk-id", i + base_index, + GPIOD_IN); + if (IS_ERR(speaker_id_desc)) { + speaker_id = PTR_ERR(speaker_id_desc); + break; + } + tmp = gpiod_get_value_cansleep(speaker_id_desc); + gpiod_put(speaker_id_desc); + if (tmp < 0) { + speaker_id = tmp; + break; + } + speaker_id |= tmp << i; + } + dev_dbg(dev, "Speaker ID = %d\n", speaker_id); + } + } + return speaker_id; +} + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) { struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; @@ -719,6 +872,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i else hw_cfg->bst_cap = -1; + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1); + if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) hw_cfg->bst_type = CS35L41_INT_BOOST; else @@ -752,6 +907,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i cs35l41->channel_index = 0; cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; hw_cfg->gpio2.valid = true; cs35l41->hw_cfg.valid = true; diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index b57f59a1ba49e..a9dbc1c192486 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -43,6 +43,7 @@ struct cs35l41_hda { unsigned volatile long irq_errors; const char *amp_name; const char *acpi_subsystem_id; + int speaker_id; struct mutex fw_mutex; struct regmap_irq_chip_data *irq_data; bool firmware_running; -- GitLab From fa9b878ff86f4adccddf62492a5894fbdb04f97d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 8 Jul 2022 16:48:36 +0300 Subject: [PATCH 914/942] ASoC: SOF: ipc-msg-injector: fix copy in sof_msg_inject_ipc4_dfs_write() There are two bugs that have to do with when we copy the payload: size = simple_write_to_buffer(ipc4_msg->data_ptr, priv->max_msg_size, ppos, buffer, count); The value of "*ppos" was supposed to be zero but it is sizeof(ipc4_msg->header_u64) so it will copy the data into the middle of the "ipc4_msg->data_ptr" buffer instead of to the start. The second problem is "buffer" should be "buffer + sizeof(ipc4_msg->header_u64)". This function is used for fuzz testing so the data is normally random and this bug likely does not affect anyone very much. In this context, it's simpler and more appropriate to use copy_from_user() instead of simple_write_to_buffer() so I have re-written the function. Fixes: 066c67624d8c ("ASoC: SOF: ipc-msg-injector: Add support for IPC4 messages") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/Ysg1tB2FKLnRMsel@kili Signed-off-by: Mark Brown --- sound/soc/sof/sof-client-ipc-msg-injector.c | 29 +++++++++------------ 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/sound/soc/sof/sof-client-ipc-msg-injector.c b/sound/soc/sof/sof-client-ipc-msg-injector.c index 6bdfa527b7f76..752d5320680f1 100644 --- a/sound/soc/sof/sof-client-ipc-msg-injector.c +++ b/sound/soc/sof/sof-client-ipc-msg-injector.c @@ -181,7 +181,7 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, struct sof_client_dev *cdev = file->private_data; struct sof_msg_inject_priv *priv = cdev->data; struct sof_ipc4_msg *ipc4_msg = priv->tx_buffer; - ssize_t size; + size_t data_size; int ret; if (*ppos) @@ -191,25 +191,20 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, return -EINVAL; /* copy the header first */ - size = simple_write_to_buffer(&ipc4_msg->header_u64, - sizeof(ipc4_msg->header_u64), - ppos, buffer, count); - if (size < 0) - return size; - if (size != sizeof(ipc4_msg->header_u64)) + if (copy_from_user(&ipc4_msg->header_u64, buffer, + sizeof(ipc4_msg->header_u64))) return -EFAULT; - count -= size; + data_size = count - sizeof(ipc4_msg->header_u64); + if (data_size > priv->max_msg_size) + return -EINVAL; + /* Copy the payload */ - size = simple_write_to_buffer(ipc4_msg->data_ptr, - priv->max_msg_size, ppos, buffer, - count); - if (size < 0) - return size; - if (size != count) + if (copy_from_user(ipc4_msg->data_ptr, + buffer + sizeof(ipc4_msg->header_u64), data_size)) return -EFAULT; - ipc4_msg->data_size = count; + ipc4_msg->data_size = data_size; /* Initialize the reply storage */ ipc4_msg = priv->rx_buffer; @@ -221,9 +216,9 @@ static ssize_t sof_msg_inject_ipc4_dfs_write(struct file *file, /* return the error code if test failed */ if (ret < 0) - size = ret; + return ret; - return size; + return count; }; static int sof_msg_inject_dfs_release(struct inode *inode, struct file *file) -- GitLab From ef30911d3c39fd57884c348c29b9cbff88def155 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 14 Jul 2022 06:28:15 +0000 Subject: [PATCH 915/942] ASoC: rsnd: care default case on rsnd_ssiu_busif_err_irq_ctrl() Before, ssiu.c didn't care SSI5-8, thus, commit b1384d4c95088d0 ("ASoC: rsnd: care default case on rsnd_ssiu_busif_err_status_clear()") cares it for status clear. But we should care it for error irq handling, too. This patch cares it. Reported-by: Nguyen Bao Nguyen Reported-by: Nishiyama Kunihiko Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/871quocio1.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/sh/rcar/ssiu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 4b8a63e336c77..d7f4646ee029c 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -67,6 +67,8 @@ static void rsnd_ssiu_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable) shift = 1; offset = 1; break; + default: + return; } for (i = 0; i < 4; i++) { -- GitLab From ffb2759df7efbc00187bfd9d1072434a13a54139 Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Fri, 15 Jul 2022 09:05:15 +0800 Subject: [PATCH 916/942] ALSA: bcd2000: Fix a UAF bug on the error path of probing When the driver fails in snd_card_register() at probe time, it will free the 'bcd2k->midi_out_urb' before killing it, which may cause a UAF bug. The following log can reveal it: [ 50.727020] BUG: KASAN: use-after-free in bcd2000_input_complete+0x1f1/0x2e0 [snd_bcd2000] [ 50.727623] Read of size 8 at addr ffff88810fab0e88 by task swapper/4/0 [ 50.729530] Call Trace: [ 50.732899] bcd2000_input_complete+0x1f1/0x2e0 [snd_bcd2000] Fix this by adding usb_kill_urb() before usb_free_urb(). Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device") Signed-off-by: Zheyu Ma Cc: Link: https://lore.kernel.org/r/20220715010515.2087925-1-zheyuma97@gmail.com Signed-off-by: Takashi Iwai --- sound/usb/bcd2000/bcd2000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c index cd4a0bc6d278f..7aec0a95c609a 100644 --- a/sound/usb/bcd2000/bcd2000.c +++ b/sound/usb/bcd2000/bcd2000.c @@ -348,7 +348,8 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k) static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k, struct usb_interface *interface) { - /* usb_kill_urb not necessary, urb is aborted automatically */ + usb_kill_urb(bcd2k->midi_out_urb); + usb_kill_urb(bcd2k->midi_in_urb); usb_free_urb(bcd2k->midi_out_urb); usb_free_urb(bcd2k->midi_in_urb); -- GitLab From 1873ebd30cc818eefd151e40a4bd05fd8f83b85a Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:30 +0100 Subject: [PATCH 917/942] ALSA: hda: cs35l41: Support Hibernation during Suspend CS35L41 supports hibernation during suspend when using DSP firmware. When the driver suspends it will hibernate the part, if firmware is running, and resume will wake from hibernation. CS35L41 driver will suspend/resume when requested by hda driver. Note that suspend/resume and hibernation is only supported when firmware is running. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-10-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 109 +++++++++++++++++++++++++++++++- sound/pci/hda/cs35l41_hda.h | 2 + sound/pci/hda/cs35l41_hda_i2c.c | 1 + sound/pci/hda/cs35l41_hda_spi.c | 1 + sound/pci/hda/hda_component.h | 2 + sound/pci/hda/patch_realtek.c | 25 +++++++- 6 files changed, 136 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index d5d2323cc8c73..61441bfc9fa9a 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" @@ -435,6 +436,75 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi rx_slot); } +static int cs35l41_runtime_suspend(struct device *dev) +{ + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + + dev_dbg(cs35l41->dev, "Suspend\n"); + + if (!cs35l41->firmware_running) + return 0; + + if (cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type) < 0) + return 0; + + regcache_cache_only(cs35l41->regmap, true); + regcache_mark_dirty(cs35l41->regmap); + + return 0; +} + +static int cs35l41_runtime_resume(struct device *dev) +{ + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + int ret; + + dev_dbg(cs35l41->dev, "Resume.\n"); + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { + dev_dbg(cs35l41->dev, "System does not support Resume\n"); + return 0; + } + + if (!cs35l41->firmware_running) + return 0; + + regcache_cache_only(cs35l41->regmap, false); + + ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); + if (ret) { + regcache_cache_only(cs35l41->regmap, true); + return ret; + } + + /* Test key needs to be unlocked to allow the OTP settings to re-apply */ + cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); + ret = regcache_sync(cs35l41->regmap); + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); + if (ret) { + dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); + return ret; + } + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) + cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); + + return 0; +} + +static int cs35l41_hda_suspend_hook(struct device *dev) +{ + dev_dbg(dev, "Request Suspend\n"); + pm_runtime_mark_last_busy(dev); + return pm_runtime_put_autosuspend(dev); +} + +static int cs35l41_hda_resume_hook(struct device *dev) +{ + dev_dbg(dev, "Request Resume\n"); + return pm_runtime_get_sync(dev); +} + static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) { int halo_sts; @@ -492,19 +562,27 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas if (comps->dev) return -EBUSY; + pm_runtime_get_sync(dev); + comps->dev = dev; if (!cs35l41->acpi_subsystem_id) cs35l41->acpi_subsystem_id = devm_kasprintf(dev, GFP_KERNEL, "%.8x", comps->codec->core.subsystem_id); cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); - comps->playback_hook = cs35l41_hda_playback_hook; mutex_lock(&cs35l41->fw_mutex); if (cs35l41_smart_amp(cs35l41) < 0) dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); mutex_unlock(&cs35l41->fw_mutex); + comps->playback_hook = cs35l41_hda_playback_hook; + comps->suspend_hook = cs35l41_hda_suspend_hook; + comps->resume_hook = cs35l41_hda_resume_hook; + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } @@ -600,7 +678,7 @@ static const struct regmap_irq cs35l41_reg_irqs[] = { CS35L41_REG_IRQ(IRQ1_STATUS1, AMP_SHORT_ERR), }; -static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { +static struct regmap_irq_chip cs35l41_regmap_irq_chip = { .name = "cs35l41 IRQ1 Controller", .status_base = CS35L41_IRQ1_STATUS1, .mask_base = CS35L41_IRQ1_MASK1, @@ -608,6 +686,7 @@ static const struct regmap_irq_chip cs35l41_regmap_irq_chip = { .num_regs = 4, .irqs = cs35l41_reg_irqs, .num_irqs = ARRAY_SIZE(cs35l41_reg_irqs), + .runtime_pm = true, }; static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) @@ -1015,13 +1094,23 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i mutex_init(&cs35l41->fw_mutex); + pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); + pm_runtime_use_autosuspend(cs35l41->dev); + pm_runtime_mark_last_busy(cs35l41->dev); + pm_runtime_set_active(cs35l41->dev); + pm_runtime_get_noresume(cs35l41->dev); + pm_runtime_enable(cs35l41->dev); + ret = cs35l41_hda_apply_properties(cs35l41); if (ret) - goto err; + goto err_pm; + + pm_runtime_put_autosuspend(cs35l41->dev); ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); if (ret) { dev_err(cs35l41->dev, "Register component failed: %d\n", ret); + pm_runtime_disable(cs35l41->dev); goto err; } @@ -1029,6 +1118,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i return 0; +err_pm: + pm_runtime_disable(cs35l41->dev); + pm_runtime_put_noidle(cs35l41->dev); + err: if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); @@ -1042,17 +1135,27 @@ void cs35l41_hda_remove(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + pm_runtime_get_sync(cs35l41->dev); + pm_runtime_disable(cs35l41->dev); + if (cs35l41->halo_initialized) cs35l41_remove_dsp(cs35l41); component_del(cs35l41->dev, &cs35l41_hda_comp_ops); + pm_runtime_put_noidle(cs35l41->dev); + if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_put(cs35l41->reset_gpio); } EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); +const struct dev_pm_ops cs35l41_hda_pm_ops = { + SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) +}; +EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); + MODULE_DESCRIPTION("CS35L41 HDA Driver"); MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, "); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index a9dbc1c192486..439c4b7053282 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -57,6 +57,8 @@ enum halo_state { HALO_STATE_CODE_RUN }; +extern const struct dev_pm_ops cs35l41_hda_pm_ops; + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, struct regmap *regmap); void cs35l41_hda_remove(struct device *dev); diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index df39fc76e6be6..9c08fa08c4211 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -54,6 +54,7 @@ static struct i2c_driver cs35l41_i2c_driver = { .driver = { .name = "cs35l41-hda", .acpi_match_table = cs35l41_acpi_hda_match, + .pm = &cs35l41_hda_pm_ops, }, .id_table = cs35l41_hda_i2c_id, .probe = cs35l41_hda_i2c_probe, diff --git a/sound/pci/hda/cs35l41_hda_spi.c b/sound/pci/hda/cs35l41_hda_spi.c index 2f5afad3719e7..71979cfb4d7ed 100644 --- a/sound/pci/hda/cs35l41_hda_spi.c +++ b/sound/pci/hda/cs35l41_hda_spi.c @@ -49,6 +49,7 @@ static struct spi_driver cs35l41_spi_driver = { .driver = { .name = "cs35l41-hda", .acpi_match_table = cs35l41_acpi_hda_match, + .pm = &cs35l41_hda_pm_ops, }, .id_table = cs35l41_hda_spi_id, .probe = cs35l41_hda_spi_probe, diff --git a/sound/pci/hda/hda_component.h b/sound/pci/hda/hda_component.h index 534e845b9cd1d..1223621bd62ca 100644 --- a/sound/pci/hda/hda_component.h +++ b/sound/pci/hda/hda_component.h @@ -16,4 +16,6 @@ struct hda_component { char name[HDA_MAX_NAME_SIZE]; struct hda_codec *codec; void (*playback_hook)(struct device *dev, int action); + int (*suspend_hook)(struct device *dev); + int (*resume_hook)(struct device *dev); }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 44744d5684048..7c21bc439c466 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4021,15 +4021,22 @@ static void alc5505_dsp_init(struct hda_codec *codec) static int alc269_suspend(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + int i; if (spec->has_alc5505_dsp) alc5505_dsp_suspend(codec); + + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].suspend_hook) + spec->comps[i].suspend_hook(spec->comps[i].dev); + return alc_suspend(codec); } static int alc269_resume(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + int i; if (spec->codec_variant == ALC269_TYPE_ALC269VB) alc269vb_toggle_power_output(codec, 0); @@ -4060,6 +4067,10 @@ static int alc269_resume(struct hda_codec *codec) if (spec->has_alc5505_dsp) alc5505_dsp_resume(codec); + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].resume_hook) + spec->comps[i].resume_hook(spec->comps[i].dev); + return 0; } #endif /* CONFIG_PM */ @@ -6610,8 +6621,20 @@ static int comp_bind(struct device *dev) { struct hda_codec *cdc = dev_to_hda_codec(dev); struct alc_spec *spec = cdc->spec; + int ret, i; + + ret = component_bind_all(dev, spec->comps); + if (ret) + return ret; - return component_bind_all(dev, spec->comps); + if (snd_hdac_is_power_on(&cdc->core)) { + codec_dbg(cdc, "Resuming after bind.\n"); + for (i = 0; i < HDA_MAX_COMPONENTS; i++) + if (spec->comps[i].resume_hook) + spec->comps[i].resume_hook(spec->comps[i].dev); + } + + return 0; } static void comp_unbind(struct device *dev) -- GitLab From 3e34e2ae29591f0fd84dca905d296da1e127160c Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:31 +0100 Subject: [PATCH 918/942] ALSA: hda: cs35l41: Read Speaker Calibration data from UEFI variables Speaker Calibration data, specific to an individual speaker is stored inside UEFI variables during calibration, and can be used by the DSP. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-11-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 101 ++++++++++++++++++++++++++++++++++++ sound/pci/hda/cs35l41_hda.h | 15 ++++++ 2 files changed, 116 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 61441bfc9fa9a..75edaffb568a1 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -26,6 +26,12 @@ #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" #define HALO_STATE_DSP_CTL_TYPE 5 #define HALO_STATE_DSP_CTL_ALG 262308 +#define CAL_R_DSP_CTL_NAME "CAL_R" +#define CAL_STATUS_DSP_CTL_NAME "CAL_STATUS" +#define CAL_CHECKSUM_DSP_CTL_NAME "CAL_CHECKSUM" +#define CAL_AMBIENT_DSP_CTL_NAME "CAL_AMBIENT" +#define CAL_DSP_CTL_TYPE 5 +#define CAL_DSP_CTL_ALG 205 static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 @@ -282,6 +288,96 @@ static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, return ret; } +#if IS_ENABLED(CONFIG_EFI) +static int cs35l41_apply_calibration(struct cs35l41_hda *cs35l41, unsigned int ambient, + unsigned int r0, unsigned int status, unsigned int checksum) +{ + int ret; + + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_AMBIENT_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &ambient, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_AMBIENT_DSP_CTL_NAME, + ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_R_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &r0, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_R_DSP_CTL_NAME, ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_STATUS_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &status, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_STATUS_DSP_CTL_NAME, + ret); + return ret; + } + ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_CHECKSUM_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, + CAL_DSP_CTL_ALG, &checksum, 4); + if (ret) { + dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_CHECKSUM_DSP_CTL_NAME, + ret); + return ret; + } + + return 0; +} + +static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) +{ + static efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d, 0x93, 0xfe, + 0x5a, 0xa3, 0x5d, 0xb3); + static efi_char16_t efi_name[] = L"CirrusSmartAmpCalibrationData"; + const struct cs35l41_amp_efi_data *efi_data; + const struct cs35l41_amp_cal_data *cl; + unsigned long data_size = 0; + efi_status_t status; + int ret = 0; + u8 *data = NULL; + u32 attr; + + /* Get real size of UEFI variable */ + status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); + if (status == EFI_BUFFER_TOO_SMALL) { + ret = -ENODEV; + /* Allocate data buffer of data_size bytes */ + data = vmalloc(data_size); + if (!data) + return -ENOMEM; + /* Get variable contents into buffer */ + status = efi.get_variable(efi_name, &efi_guid, &attr, &data_size, data); + if (status == EFI_SUCCESS) { + efi_data = (struct cs35l41_amp_efi_data *)data; + dev_dbg(cs35l41->dev, "Calibration: Size=%d, Amp Count=%d\n", + efi_data->size, efi_data->count); + if (efi_data->count > cs35l41->index) { + cl = &efi_data->data[cs35l41->index]; + dev_dbg(cs35l41->dev, + "Calibration: Ambient=%02x, Status=%02x, R0=%d\n", + cl->calAmbient, cl->calStatus, cl->calR); + + /* Calibration can only be applied whilst the DSP is not running */ + ret = cs35l41_apply_calibration(cs35l41, + cpu_to_be32(cl->calAmbient), + cpu_to_be32(cl->calR), + cpu_to_be32(cl->calStatus), + cpu_to_be32(cl->calR + 1)); + } + } + vfree(data); + } + return ret; +} +#else +static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) +{ + dev_warn(cs35l41->dev, "Calibration not supported without EFI support.\n"); + return 0; +} +#endif + static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) { const struct firmware *coeff_firmware = NULL; @@ -314,7 +410,12 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, FW_NAME); + if (ret) + goto err_release; + + ret = cs35l41_save_calibration(cs35l41); +err_release: release_firmware(wmfw_firmware); release_firmware(coeff_firmware); kfree(wmfw_filename); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 439c4b7053282..59a9461d04448 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -10,6 +10,7 @@ #ifndef __CS35L41_HDA_H__ #define __CS35L41_HDA_H__ +#include #include #include #include @@ -18,6 +19,20 @@ #include #include +struct cs35l41_amp_cal_data { + u32 calTarget[2]; + u32 calTime[2]; + s8 calAmbient; + u8 calStatus; + u16 calR; +} __packed; + +struct cs35l41_amp_efi_data { + u32 size; + u32 count; + struct cs35l41_amp_cal_data data[]; +} __packed; + enum cs35l41_hda_spk_pos { CS35l41_LEFT, CS35l41_RIGHT, -- GitLab From 291e7c220b82b28d4c128dfb2abaa51d29969dd5 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:32 +0100 Subject: [PATCH 919/942] ALSA: hda: hda_cs_dsp_ctl: Add fw id strings This will be used to define the firmware names. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-12-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_cs_dsp_ctl.c | 8 ++++++++ sound/pci/hda/hda_cs_dsp_ctl.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/sound/pci/hda/hda_cs_dsp_ctl.c b/sound/pci/hda/hda_cs_dsp_ctl.c index 2351476c9ee6b..89ee549cb7d50 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.c +++ b/sound/pci/hda/hda_cs_dsp_ctl.c @@ -27,6 +27,14 @@ static const char * const hda_cs_dsp_fw_text[HDA_CS_DSP_NUM_FW] = { [HDA_CS_DSP_FW_MISC] = "Misc", }; +const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW] = { + [HDA_CS_DSP_FW_SPK_PROT] = "spk-prot", + [HDA_CS_DSP_FW_SPK_CALI] = "spk-cali", + [HDA_CS_DSP_FW_SPK_DIAG] = "spk-diag", + [HDA_CS_DSP_FW_MISC] = "misc", +}; +EXPORT_SYMBOL_NS_GPL(hda_cs_dsp_fw_ids, SND_HDA_CS_DSP_CONTROLS); + static int hda_cs_dsp_coeff_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo) { struct hda_cs_dsp_coeff_ctl *ctl = (struct hda_cs_dsp_coeff_ctl *)snd_kcontrol_chip(kctl); diff --git a/sound/pci/hda/hda_cs_dsp_ctl.h b/sound/pci/hda/hda_cs_dsp_ctl.h index c65bfd6878fde..4babc69cf2f0c 100644 --- a/sound/pci/hda/hda_cs_dsp_ctl.h +++ b/sound/pci/hda/hda_cs_dsp_ctl.h @@ -27,6 +27,8 @@ struct hda_cs_dsp_ctl_info { const char *device_name; }; +extern const char * const hda_cs_dsp_fw_ids[HDA_CS_DSP_NUM_FW]; + int hda_cs_dsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl, struct hda_cs_dsp_ctl_info *info); void hda_cs_dsp_control_remove(struct cs_dsp_coeff_ctl *cs_ctl); int hda_cs_dsp_write_ctl(struct cs_dsp *dsp, const char *name, int type, -- GitLab From 4fa58b1d7ec714581bfb1d12370746d29518cd3a Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:33 +0100 Subject: [PATCH 920/942] ALSA: hda: cs35l41: Add defaulted values into dsp bypass config sequence The config sequences for running with and without firmware and DSP are different. The original behavior assumed that we would only run without DSP only in the case where firmware load failed. This meant the non-firmware sequence was written with the assumtion that various registers would be set to their default value. However, to support the ability to unload the firmware, the non-firmware register sequence must be updated to update all required registers, including values that would be defaulted, in case the firmware sequence, which could have already run, has changed their value. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-13-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 75edaffb568a1..a02a74f68c2d1 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -35,11 +35,24 @@ static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 + { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer + { CS35L41_SP_HIZ_CTRL, 0x00000002 }, // Hi-Z unused + { CS35L41_SP_TX_WL, 0x00000018 }, // 24 cycles/slot + { CS35L41_SP_RX_WL, 0x00000018 }, // 24 cycles/slot { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 + { CS35L41_ASP_TX1_SRC, 0x00000018 }, // ASPTX1 SRC = VMON + { CS35L41_ASP_TX2_SRC, 0x00000019 }, // ASPTX2 SRC = IMON + { CS35L41_ASP_TX3_SRC, 0x00000032 }, // ASPTX3 SRC = ERRVOL + { CS35L41_ASP_TX4_SRC, 0x00000033 }, // ASPTX4 SRC = CLASSH_TGT + { CS35L41_DSP1_RX1_SRC, 0x00000008 }, // DSP1RX1 SRC = ASPRX1 + { CS35L41_DSP1_RX2_SRC, 0x00000009 }, // DSP1RX2 SRC = ASPRX2 + { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON + { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON + { CS35L41_DSP1_RX5_SRC, 0x00000020 }, // DSP1RX5 SRC = ERRVOL { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB }; -- GitLab From 47ceabd99a28399f8971f4ca0a37ebc0a21dd2a8 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:34 +0100 Subject: [PATCH 921/942] ALSA: hda: cs35l41: Support Firmware switching and reloading This is required to support CS35L41 calibration. By default, speaker protection firmware will be loaded, if available. However, different firmware is required to run the calibration sequence, so it is necessary to add support to be able to unload, switch and reload firmware. This patch adds 2 ALSA Controls for each amp: "DSP1 Firmware Load" "DSP1 Firmware Type" "DSP1 Firmware Load" can be used to unload and load the firmware. "DSP1 Firmware Type" can be used to switch the target firmware to be loaded by "DSP1 Firmware Load" Since loading firmware can add new ALSA controls, it is necessary to ensure the firmware loading is run asynchronously from the ALSA control itself to prevent deadlocks. Note: When switching between firmwares, an ALSA control is only added if it has not previously existed. If it had existed previously, it will be re-enabled instead. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-14-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 182 ++++++++++++++++++++++++++++++++++-- sound/pci/hda/cs35l41_hda.h | 6 ++ 2 files changed, 178 insertions(+), 10 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index a02a74f68c2d1..4252c0ac69b76 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -21,7 +21,6 @@ #define CS35L41_FIRMWARE_ROOT "cirrus/" #define CS35L41_PART "cs35l41" -#define FW_NAME "CSPL" #define HALO_STATE_DSP_CTL_NAME "HALO_STATE" #define HALO_STATE_DSP_CTL_TYPE 5 @@ -92,7 +91,7 @@ static int cs35l41_control_add(struct cs_dsp_coeff_ctl *cs_ctl) struct hda_cs_dsp_ctl_info info; info.device_name = cs35l41->amp_name; - info.fw_type = HDA_CS_DSP_FW_SPK_PROT; + info.fw_type = cs35l41->firmware_type; info.card = cs35l41->codec->card; return hda_cs_dsp_control_add(cs_ctl, &info); @@ -114,20 +113,24 @@ static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, if (spkid > -1 && ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, spkid, amp_name, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, spkid, amp_name, filetype); else if (spkid > -1 && ssid) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-spkid%d.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, spkid, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, spkid, filetype); else if (ssid && amp_name) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, amp_name, - filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, amp_name, filetype); else if (ssid) *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", ssid, filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + ssid, filetype); else *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, CS35L41_PART, - dsp_name, "spk-prot", filetype); + dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], + filetype); if (*filename == NULL) return -ENOMEM; @@ -422,7 +425,7 @@ static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) dev_warn(cs35l41->dev, "No Coefficient File available.\n"); ret = cs_dsp_power_up(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, - FW_NAME); + hda_cs_dsp_fw_ids[cs35l41->firmware_type]); if (ret) goto err_release; @@ -451,6 +454,7 @@ static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) { struct cs_dsp *dsp = &cs35l41->cs_dsp; + cancel_work_sync(&cs35l41->fw_load_work); cs35l41_shutdown_dsp(cs35l41); cs_dsp_remove(dsp); cs35l41->halo_initialized = false; @@ -481,6 +485,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) switch (action) { case HDA_GEN_PCM_ACT_OPEN: + cs35l41->playback_started = true; if (cs35l41->firmware_running) { regmap_multi_reg_write(reg, cs35l41_hda_config_dsp, ARRAY_SIZE(cs35l41_hda_config_dsp)); @@ -518,6 +523,7 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT); } cs35l41_irq_release(cs35l41); + cs35l41->playback_started = false; break; default: dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); @@ -664,10 +670,160 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) return ret; } +static void cs35l41_load_firmware(struct cs35l41_hda *cs35l41, bool load) +{ + pm_runtime_get_sync(cs35l41->dev); + + if (cs35l41->firmware_running && !load) { + dev_dbg(cs35l41->dev, "Unloading Firmware\n"); + cs35l41_shutdown_dsp(cs35l41); + } else if (!cs35l41->firmware_running && load) { + dev_dbg(cs35l41->dev, "Loading Firmware\n"); + cs35l41_smart_amp(cs35l41); + } else { + dev_dbg(cs35l41->dev, "Unable to Load firmware.\n"); + } + + pm_runtime_mark_last_busy(cs35l41->dev); + pm_runtime_put_autosuspend(cs35l41->dev); +} + +static int cs35l41_fw_load_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = cs35l41->request_fw_load; + return 0; +} + +static void cs35l41_fw_load_work(struct work_struct *work) +{ + struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work); + + mutex_lock(&cs35l41->fw_mutex); + + /* Recheck if playback is ongoing, mutex will block playback during firmware loading */ + if (cs35l41->playback_started) + dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); + else + cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); + + cs35l41->fw_request_ongoing = false; + mutex_unlock(&cs35l41->fw_mutex); +} + +static int cs35l41_fw_load_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + unsigned int ret = 0; + + mutex_lock(&cs35l41->fw_mutex); + + if (cs35l41->request_fw_load == ucontrol->value.integer.value[0]) + goto err; + + if (cs35l41->fw_request_ongoing) { + dev_dbg(cs35l41->dev, "Existing request not complete\n"); + ret = -EBUSY; + goto err; + } + + /* Check if playback is ongoing when initial request is made */ + if (cs35l41->playback_started) { + dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); + ret = -EBUSY; + goto err; + } + + cs35l41->fw_request_ongoing = true; + cs35l41->request_fw_load = ucontrol->value.integer.value[0]; + schedule_work(&cs35l41->fw_load_work); + +err: + mutex_unlock(&cs35l41->fw_mutex); + + return ret; +} + +static int cs35l41_fw_type_ctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = cs35l41->firmware_type; + + return 0; +} + +static int cs35l41_fw_type_ctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); + + if (ucontrol->value.enumerated.item[0] < HDA_CS_DSP_NUM_FW) { + cs35l41->firmware_type = ucontrol->value.enumerated.item[0]; + return 0; + } + + return -EINVAL; +} + +static int cs35l41_fw_type_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(hda_cs_dsp_fw_ids), hda_cs_dsp_fw_ids); +} + +static int cs35l41_create_controls(struct cs35l41_hda *cs35l41) +{ + char fw_type_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + char fw_load_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; + struct snd_kcontrol_new fw_type_ctl = { + .name = fw_type_ctl_name, + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = cs35l41_fw_type_ctl_info, + .get = cs35l41_fw_type_ctl_get, + .put = cs35l41_fw_type_ctl_put, + }; + struct snd_kcontrol_new fw_load_ctl = { + .name = fw_load_ctl_name, + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .info = snd_ctl_boolean_mono_info, + .get = cs35l41_fw_load_ctl_get, + .put = cs35l41_fw_load_ctl_put, + }; + int ret; + + scnprintf(fw_type_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Type", + cs35l41->amp_name); + scnprintf(fw_load_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s DSP1 Firmware Load", + cs35l41->amp_name); + + ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41)); + if (ret) { + dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_type_ctl.name, ret); + return ret; + } + + dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name); + + ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_load_ctl, cs35l41)); + if (ret) { + dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_load_ctl.name, ret); + return ret; + } + + dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name); + + return 0; +} + static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); struct hda_component *comps = master_data; + int ret = 0; if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) return -EINVAL; @@ -685,11 +841,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas cs35l41->codec = comps->codec; strscpy(comps->name, dev_name(dev), sizeof(comps->name)); + cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; + + cs35l41->request_fw_load = true; mutex_lock(&cs35l41->fw_mutex); if (cs35l41_smart_amp(cs35l41) < 0) dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); mutex_unlock(&cs35l41->fw_mutex); + ret = cs35l41_create_controls(cs35l41); + comps->playback_hook = cs35l41_hda_playback_hook; comps->suspend_hook = cs35l41_hda_suspend_hook; comps->resume_hook = cs35l41_hda_resume_hook; @@ -697,7 +858,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); - return 0; + return ret; } static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) @@ -1206,6 +1367,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i if (ret) goto err; + INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work); mutex_init(&cs35l41->fw_mutex); pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h index 59a9461d04448..bdb35f3be68a6 100644 --- a/sound/pci/hda/cs35l41_hda.h +++ b/sound/pci/hda/cs35l41_hda.h @@ -58,11 +58,17 @@ struct cs35l41_hda { unsigned volatile long irq_errors; const char *amp_name; const char *acpi_subsystem_id; + int firmware_type; int speaker_id; struct mutex fw_mutex; + struct work_struct fw_load_work; + struct regmap_irq_chip_data *irq_data; bool firmware_running; + bool request_fw_load; + bool fw_request_ongoing; bool halo_initialized; + bool playback_started; struct cs_dsp cs_dsp; }; -- GitLab From 622f21994506e1dac7b8e4e362c8951426e032c5 Mon Sep 17 00:00:00 2001 From: Stefan Binding Date: Thu, 30 Jun 2022 01:23:35 +0100 Subject: [PATCH 922/942] ALSA: hda: cs35l41: Add module parameter to control firmware load By default, the driver will automatically load DSP firmware for the amps, if available. Adding this option allows the autoload to be optional, which allows for different configurations. Signed-off-by: Stefan Binding Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20220630002335.366545-15-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 4252c0ac69b76..28798d5c1cf1c 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,11 @@ #define CAL_DSP_CTL_TYPE 5 #define CAL_DSP_CTL_ALG 205 +static bool firmware_autostart = 1; +module_param(firmware_autostart, bool, 0444); +MODULE_PARM_DESC(firmware_autostart, "Allow automatic firmware download on boot" + "(0=Disable, 1=Enable) (default=1); "); + static const struct reg_sequence cs35l41_hda_config[] = { { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 { CS35L41_DSP_CLK_CTRL, 0x00000003 }, // DSP CLK EN @@ -843,11 +849,16 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; - cs35l41->request_fw_load = true; - mutex_lock(&cs35l41->fw_mutex); - if (cs35l41_smart_amp(cs35l41) < 0) - dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); - mutex_unlock(&cs35l41->fw_mutex); + if (firmware_autostart) { + dev_dbg(cs35l41->dev, "Firmware Autostart.\n"); + cs35l41->request_fw_load = true; + mutex_lock(&cs35l41->fw_mutex); + if (cs35l41_smart_amp(cs35l41) < 0) + dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); + mutex_unlock(&cs35l41->fw_mutex); + } else { + dev_dbg(cs35l41->dev, "Firmware Autostart is disabled.\n"); + } ret = cs35l41_create_controls(cs35l41); -- GitLab From e7255c00b10e5e570dd8eb24f59e964eeec38d3b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 6 Jul 2022 14:02:26 +0200 Subject: [PATCH 923/942] ALSA: hda: Skip event processing for unregistered codecs When codec is unbound but not yet removed, in the eyes of snd_hdac_bus_process_unsol_events() it is still a valid target to delegate work to. Such behaviour may lead to use-after-free errors. Address by verifying if codec is actually registered. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220706120230.427296-6-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai --- include/sound/hda_codec.h | 1 - include/sound/hdaudio.h | 1 + sound/hda/hdac_bus.c | 2 +- sound/pci/hda/hda_codec.c | 10 +++++----- sound/soc/codecs/hda.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h index b7be300b6b18c..6d3c82c4b6acd 100644 --- a/include/sound/hda_codec.h +++ b/include/sound/hda_codec.h @@ -231,7 +231,6 @@ struct hda_codec { /* misc flags */ unsigned int configured:1; /* codec was configured */ unsigned int in_freeing:1; /* being released */ - unsigned int registered:1; /* codec was registered */ unsigned int display_power_control:1; /* needs display power */ unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each * status change diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 15f15075238d0..797bf67a164db 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -93,6 +93,7 @@ struct hdac_device { bool lazy_cache:1; /* don't wake up for writes */ bool caps_overwriting:1; /* caps overwrite being in process */ bool cache_coef:1; /* cache COEF read/write too */ + unsigned int registered:1; /* codec was registered */ }; /* device/driver type used for matching */ diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 71db8592b33db..d497414a5538f 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c @@ -183,7 +183,7 @@ static void snd_hdac_bus_process_unsol_events(struct work_struct *work) if (!(caddr & (1 << 4))) /* no unsolicited event? */ continue; codec = bus->caddr_tbl[caddr & 0x0f]; - if (!codec || !codec->dev.driver) + if (!codec || !codec->registered) continue; spin_unlock_irq(&bus->reg_lock); drv = drv_to_hdac_driver(codec->dev.driver); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b1921f9205132..7be74227bf19b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -772,11 +772,11 @@ static void codec_release_pcms(struct hda_codec *codec) */ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) { - if (codec->registered) { + if (codec->core.registered) { /* pm_runtime_put() is called in snd_hdac_device_exit() */ pm_runtime_get_noresume(hda_codec_dev(codec)); pm_runtime_disable(hda_codec_dev(codec)); - codec->registered = 0; + codec->core.registered = 0; } snd_hda_codec_disconnect_pcms(codec); @@ -825,14 +825,14 @@ void snd_hda_codec_display_power(struct hda_codec *codec, bool enable) */ void snd_hda_codec_register(struct hda_codec *codec) { - if (codec->registered) + if (codec->core.registered) return; if (device_is_registered(hda_codec_dev(codec))) { snd_hda_codec_display_power(codec, true); pm_runtime_enable(hda_codec_dev(codec)); /* it was powered up in snd_hda_codec_new(), now all done */ snd_hda_power_down(codec); - codec->registered = 1; + codec->core.registered = 1; } } EXPORT_SYMBOL_GPL(snd_hda_codec_register); @@ -3047,7 +3047,7 @@ void snd_hda_codec_shutdown(struct hda_codec *codec) struct hda_pcm *cpcm; /* Skip the shutdown if codec is not registered */ - if (!codec->registered) + if (!codec->core.registered) return; cancel_delayed_work_sync(&codec->jackpoll_work); diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index edcb8bc6806bd..ad20a3dff9b7e 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -274,7 +274,7 @@ static void hda_codec_remove(struct snd_soc_component *component) struct hdac_device *hdev = &codec->core; struct hdac_bus *bus = hdev->bus; struct hdac_ext_link *hlink; - bool was_registered = codec->registered; + bool was_registered = codec->core.registered; /* Don't allow any more runtime suspends */ pm_runtime_forbid(&hdev->dev); @@ -376,7 +376,7 @@ static int hda_hdev_detach(struct hdac_device *hdev) { struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); - if (codec->registered) + if (codec->core.registered) cancel_delayed_work_sync(&codec->jackpoll_work); snd_soc_unregister_component(&hdev->dev); -- GitLab From d59d2277febbad93e42137a50673dd1c16199813 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jul 2022 20:24:27 +0200 Subject: [PATCH 924/942] Revert "ALSA: hda: cs35l41: Allow compilation test on non-ACPI configurations" Since the recent change in CS35L41 codec requires the reference of acpi_dev handle, the current Kconfig may lead to a build breakage. Revert the Kconfig change and re-introduce the hard dependency on CONFIG_ACPI again as a temporary workaround. Fixes: eef375960210 ("ALSA: hda: cs35l41: Support reading subsystem id from ACPI") Link: https://lore.kernel.org/r/20220715182427.18891-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 44c33bc0740e0..a8e8cf98befa1 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -103,7 +103,7 @@ config SND_HDA_CS_DSP_CONTROLS config SND_HDA_SCODEC_CS35L41_I2C tristate "Build CS35L41 HD-audio side codec support for I2C Bus" depends on I2C - depends on ACPI || COMPILE_TEST + depends on ACPI depends on SND_SOC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 @@ -118,7 +118,7 @@ comment "Set to Y if you want auto-loading the side codec driver" config SND_HDA_SCODEC_CS35L41_SPI tristate "Build CS35L41 HD-audio codec support for SPI Bus" depends on SPI_MASTER - depends on ACPI || COMPILE_TEST + depends on ACPI depends on SND_SOC select SND_SOC_CS35L41_LIB select SND_HDA_SCODEC_CS35L41 -- GitLab From 53f07e9b010b966017e32be1ca1bbcbcc4cee73d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 15 Jul 2022 20:29:03 +0200 Subject: [PATCH 925/942] Revert "ALSA: hda: Fix page fault in snd_hda_codec_shutdown()" This reverts commit 980b3a8790b402e959a6d773b38b771019682be1. The commit didn't consider the fact that ASoC hdac-hda driver initializes the HD-audio stuff without calling snd_hda_codec_device_init(). Hence this caused a regression leading to Oops. Revert the commit to restore the behavior. Fixes: 980b3a8790b4 ("ALSA: hda: Fix page fault in snd_hda_codec_shutdown()") Link: https://lore.kernel.org/r/3c40df55-3aee-1e08-493b-7b30cd84dc00@linux.intel.com Link: https://lore.kernel.org/r/20220715182903.19594-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 41 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7be74227bf19b..7b2e62fa82d55 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -931,28 +931,8 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr, } codec->bus = bus; - codec->depop_delay = -1; - codec->fixup_id = HDA_FIXUP_ID_NOT_SET; - codec->core.dev.release = snd_hda_codec_dev_release; - codec->core.exec_verb = codec_exec_verb; codec->core.type = HDA_DEV_LEGACY; - mutex_init(&codec->spdif_mutex); - mutex_init(&codec->control_mutex); - snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); - snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); - snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); - snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); - snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); - snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); - snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); - snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); - INIT_LIST_HEAD(&codec->conn_list); - INIT_LIST_HEAD(&codec->pcm_list_head); - INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); - refcount_set(&codec->pcm_ref, 1); - init_waitqueue_head(&codec->remove_sleep); - return codec; } EXPORT_SYMBOL_GPL(snd_hda_codec_device_init); @@ -1005,8 +985,29 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) return -EINVAL; + codec->core.dev.release = snd_hda_codec_dev_release; + codec->core.exec_verb = codec_exec_verb; + codec->card = card; codec->addr = codec_addr; + mutex_init(&codec->spdif_mutex); + mutex_init(&codec->control_mutex); + snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); + snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); + snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); + snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); + snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); + snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16); + snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16); + snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); + INIT_LIST_HEAD(&codec->conn_list); + INIT_LIST_HEAD(&codec->pcm_list_head); + refcount_set(&codec->pcm_ref, 1); + init_waitqueue_head(&codec->remove_sleep); + + INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); + codec->depop_delay = -1; + codec->fixup_id = HDA_FIXUP_ID_NOT_SET; #ifdef CONFIG_PM codec->power_jiffies = jiffies; -- GitLab From 48d8bd769fb7e2272beb92a75518d4d6f98b4ccc Mon Sep 17 00:00:00 2001 From: shaomin Deng Date: Thu, 21 Jul 2022 11:05:28 -0400 Subject: [PATCH 926/942] ALSA: emu10k1: Fix typo in comments Remove the rebundant word "in" in comments. Signed-off-by: shaomin Deng Link: https://lore.kernel.org/r/20220721150528.22099-1-dengshaomin@cdjrlc.com Signed-off-by: Takashi Iwai --- sound/pci/emu10k1/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 9d26535f3fa34..edb3f17637192 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -324,7 +324,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst return NULL; } /* fill buffer addresses but pointers are not stored so that - * snd_free_pci_page() is not called in in synth_free() + * snd_free_pci_page() is not called in synth_free() */ idx = 0; for (page = blk->first_page; page <= blk->last_page; page++, idx++) { -- GitLab From 84f2a3c182d545261c36f94510134f5e9fb918f5 Mon Sep 17 00:00:00 2001 From: shaomin Deng Date: Thu, 21 Jul 2022 11:55:17 -0400 Subject: [PATCH 927/942] ALSA: asihpi: Fix typo in comments Delete the repeated word "in" in comments. Signed-off-by: shaomin Deng Link: https://lore.kernel.org/r/20220721155517.2438-1-dengshaomin@cdjrlc.com Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpi6205.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 3d6914c64c4a8..27e11b5f70b97 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -445,7 +445,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) /* SUBSYSTEM */ /** Create an adapter object and initialise it based on resource information - * passed in in the message + * passed in the message * *** NOTE - you cannot use this function AND the FindAdapters function at the * same time, the application must use only one of them to get the adapters *** */ -- GitLab From e086c37f876fd1f551e2b4f9be97d4a1923cd219 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 22 Jul 2022 16:39:48 +0200 Subject: [PATCH 928/942] ALSA: usb-audio: Add quirk for Behringer UMC202HD Just like other Behringer models, UMC202HD (USB ID 1397:0507) requires the quirk for the stable streaming, too. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215934 Cc: Link: https://lore.kernel.org/r/20220722143948.29804-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 968d90caeefa0..168fd802d70bd 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1843,6 +1843,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */ + QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */ QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */ -- GitLab From ccc86a0a02139321df943313a99efa11745bd273 Mon Sep 17 00:00:00 2001 From: wangjianli Date: Sun, 24 Jul 2022 15:14:13 +0800 Subject: [PATCH 929/942] ALSA: asihpi: fix repeated words in comments Delete the redundant word 'in'. Signed-off-by: wangjianli Link: https://lore.kernel.org/r/20220724071413.10085-1-wangjianli@cdjrlc.com Signed-off-by: Takashi Iwai --- sound/pci/asihpi/hpi6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index aa4d063531260..88d902997b749 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -388,7 +388,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) /* SUBSYSTEM */ /* create an adapter object and initialise it based on resource information - * passed in in the message + * passed in the message * NOTE - you cannot use this function AND the FindAdapters function at the * same time, the application must use only one of them to get the adapters */ -- GitLab From 614b9febdc144c56b087dacc7c1268c25ef6d684 Mon Sep 17 00:00:00 2001 From: wangjianli Date: Sun, 24 Jul 2022 15:16:44 +0800 Subject: [PATCH 930/942] ALSA: usb/6fire: fix repeated words in comments Delete the redundant word 'in'. Signed-off-by: wangjianli Link: https://lore.kernel.org/r/20220724071644.10630-1-wangjianli@cdjrlc.com Signed-off-by: Takashi Iwai --- sound/usb/6fire/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 7168f1c6a37aa..32c39d8bd2e55 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -175,7 +175,7 @@ static int usb6fire_pcm_stream_start(struct pcm_runtime *rt) } } - /* wait for first out urb to return (sent in in urb handler) */ + /* wait for first out urb to return (sent in urb handler) */ wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond, HZ); if (rt->stream_wait_cond) -- GitLab From 4e3b86509f9204f65842561ad8d37cf83c297550 Mon Sep 17 00:00:00 2001 From: wangjianli Date: Sun, 24 Jul 2022 15:18:29 +0800 Subject: [PATCH 931/942] ALSA: hiface: fix repeated words in comments Delete the redundant word 'in'. Signed-off-by: wangjianli Link: https://lore.kernel.org/r/20220724071829.11117-1-wangjianli@cdjrlc.com Signed-off-by: Takashi Iwai --- sound/usb/hiface/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index 71f17f02f3418..cf650fab54d7e 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -225,7 +225,7 @@ static int hiface_pcm_stream_start(struct pcm_runtime *rt) } } - /* wait for first out urb to return (sent in in urb handler) */ + /* wait for first out urb to return (sent in urb handler) */ wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond, HZ); if (rt->stream_wait_cond) { -- GitLab From 26ae150bbb6d19767f10800e17ad0fd81f3da67e Mon Sep 17 00:00:00 2001 From: Ren Zhijie Date: Mon, 25 Jul 2022 10:36:11 +0800 Subject: [PATCH 932/942] ALSA: hda: cs35l41: Fix build error unused-function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CONFIG_PM_SLEEP is not set, make ARCH=x86_64 CROSS_COMPILE=x86_64-linux-gnu-, will be failed, like this: sound/pci/hda/cs35l41_hda.c:583:12: error: ‘cs35l41_runtime_resume’ defined but not used [-Werror=unused-function] static int cs35l41_runtime_resume(struct device *dev) ^~~~~~~~~~~~~~~~~~~~~~ sound/pci/hda/cs35l41_hda.c:565:12: error: ‘cs35l41_runtime_suspend’ defined but not used [-Werror=unused-function] static int cs35l41_runtime_suspend(struct device *dev) ^~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[3]: *** [sound/pci/hda/cs35l41_hda.o] Error 1 commit 1a3c7bb08826 ("PM: core: Add new *_PM_OPS macros, deprecate old ones"), add new marco RUNTIME_PM_OPS to fix this unused-function problem. Fixes: 1873ebd30cc8 ("ALSA: hda: cs35l41: Support Hibernation during Suspend") Signed-off-by: Ren Zhijie Link: https://lore.kernel.org/r/20220725023611.57055-1-renzhijie2@huawei.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 28798d5c1cf1c..93cf039abb024 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -1439,7 +1439,7 @@ void cs35l41_hda_remove(struct device *dev) EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); const struct dev_pm_ops cs35l41_hda_pm_ops = { - SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) + RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) }; EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); -- GitLab From c578d5da10dc429c6676ab09f3fec0b79b31633a Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 19 Jul 2022 22:20:14 +0800 Subject: [PATCH 933/942] ALSA: hda/realtek: Enable speaker and mute LEDs for HP laptops Two more HP laptops that use cs35l41 AMP for speaker and GPIO for mute LEDs. So use the existing quirk to enable them accordingly. [ Sort the entries at the SSID order by tiwai ] Signed-off-by: Kai-Heng Feng Reviewed-by: Lucas Tanure Link: https://lore.kernel.org/r/20220719142015.244426-1-kai.heng.feng@canonical.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0e340c0934db8..06bb553995646 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9138,6 +9138,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), -- GitLab From f81ee579c0898201eb2b5105718bedf34c0401f9 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Wed, 27 Jul 2022 10:59:21 +0100 Subject: [PATCH 934/942] ALSA: hda: cs35l41: Use the CS35L41 HDA internal define Follow GPIO1 pattern, use cs35l41 HDA internal define for IRQ and then translate to ASoC cs35l41 define. Signed-off-by: Lucas Tanure Link: https://lore.kernel.org/r/20220727095924.80884-2-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 93cf039abb024..9af5e2e9be55f 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -1014,6 +1014,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) break; case CS35L41_INTERRUPT: using_irq = true; + hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; break; default: dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); @@ -1273,7 +1274,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); - hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; + hw_cfg->gpio2.func = CS35L41_INTERRUPT; hw_cfg->gpio2.valid = true; cs35l41->hw_cfg.valid = true; put_device(physdev); -- GitLab From 1e24881d8b2a7c198a67fe9e5179e9efb2140df7 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Wed, 27 Jul 2022 10:59:22 +0100 Subject: [PATCH 935/942] ALSA: hda: cs35l41: Support CLSA0101 Add support for Intel version of Legion 7 laptop. Signed-off-by: Lucas Tanure Link: https://lore.kernel.org/r/20220727095924.80884-3-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/pci/hda/cs35l41_hda.c | 66 ++++++++++++++++++++------------- sound/pci/hda/cs35l41_hda_i2c.c | 3 ++ sound/pci/hda/patch_realtek.c | 12 ++++++ 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 9af5e2e9be55f..129bffb431c22 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -1133,6 +1133,45 @@ static int cs35l41_get_speaker_id(struct device *dev, int amp_index, return speaker_id; } +/* + * Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work. + * And devices created by serial-multi-instantiate don't have their device struct + * pointing to the correct fwnode, so acpi_dev must be used here. + * And devm functions expect that the device requesting the resource has the correct + * fwnode. + */ +static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id, + const char *hid) +{ + struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; + + /* check I2C address to assign the index */ + cs35l41->index = id == 0x40 ? 0 : 1; + cs35l41->channel_index = 0; + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); + cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); + hw_cfg->spk_pos = cs35l41->index; + hw_cfg->gpio2.func = CS35L41_INTERRUPT; + hw_cfg->gpio2.valid = true; + hw_cfg->valid = true; + put_device(physdev); + + if (strncmp(hid, "CLSA0100", 8) == 0) { + hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; + } else if (strncmp(hid, "CLSA0101", 8) == 0) { + hw_cfg->bst_type = CS35L41_EXT_BOOST; + hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH; + hw_cfg->gpio1.valid = true; + } else { + hw_cfg->valid = false; + hw_cfg->gpio1.valid = false; + hw_cfg->gpio2.valid = false; + return -EINVAL; + } + + return 0; +} + static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) { struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; @@ -1161,7 +1200,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i property = "cirrus,dev-index"; ret = device_property_count_u32(physdev, property); if (ret <= 0) - goto no_acpi_dsd; + return cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid); if (ret > ARRAY_SIZE(values)) { ret = -EINVAL; @@ -1255,31 +1294,6 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); return ret; - -no_acpi_dsd: - /* - * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. - * And devices created by serial-multi-instantiate don't have their device struct - * pointing to the correct fwnode, so acpi_dev must be used here. - * And devm functions expect that the device requesting the resource has the correct - * fwnode. - */ - if (strncmp(hid, "CLSA0100", 8) != 0) - return -EINVAL; - - /* check I2C address to assign the index */ - cs35l41->index = id == 0x40 ? 0 : 1; - cs35l41->hw_cfg.spk_pos = cs35l41->index; - cs35l41->channel_index = 0; - cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); - cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; - cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); - hw_cfg->gpio2.func = CS35L41_INTERRUPT; - hw_cfg->gpio2.valid = true; - cs35l41->hw_cfg.valid = true; - put_device(physdev); - - return 0; } int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, diff --git a/sound/pci/hda/cs35l41_hda_i2c.c b/sound/pci/hda/cs35l41_hda_i2c.c index 9c08fa08c4211..5baacfde4f16b 100644 --- a/sound/pci/hda/cs35l41_hda_i2c.c +++ b/sound/pci/hda/cs35l41_hda_i2c.c @@ -22,6 +22,8 @@ static int cs35l41_hda_i2c_probe(struct i2c_client *clt, const struct i2c_device */ if (strstr(dev_name(&clt->dev), "CLSA0100")) device_name = "CLSA0100"; + else if (strstr(dev_name(&clt->dev), "CLSA0101")) + device_name = "CLSA0101"; else if (strstr(dev_name(&clt->dev), "CSC3551")) device_name = "CSC3551"; else @@ -45,6 +47,7 @@ static const struct i2c_device_id cs35l41_hda_i2c_id[] = { static const struct acpi_device_id cs35l41_acpi_hda_match[] = { {"CLSA0100", 0 }, + {"CLSA0101", 0 }, {"CSC3551", 0 }, {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 06bb553995646..e1fbda2159756 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6710,6 +6710,12 @@ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const st cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0100", 2); } +static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix, + int action) +{ + cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2); +} + /* for alc295_fixup_hp_top_speakers */ #include "hp_x360_helper.c" @@ -7047,6 +7053,7 @@ enum { ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED, ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, + ALC287_FIXUP_LEGION_16ITHG6, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -8889,6 +8896,10 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC }, + [ALC287_FIXUP_LEGION_16ITHG6] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc287_fixup_legion_16ithg6_speakers, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -9355,6 +9366,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x384a, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3852, "Lenovo Yoga 7 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), -- GitLab From 87eb04bb87fbdf1d53f0fc64e6fc56ba2b504762 Mon Sep 17 00:00:00 2001 From: Lucas Tanure Date: Wed, 27 Jul 2022 10:59:23 +0100 Subject: [PATCH 936/942] ACPI: scan: Add CLSA0101 Laptop Support Add CLSA0101 id to the ignore_serial_bus_ids so serial-multi-instantiate can correctly instantiate the driver. Signed-off-by: Lucas Tanure Link: https://lore.kernel.org/r/20220727095924.80884-4-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai --- drivers/acpi/scan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 762b61f67e6c6..834d6a2da7805 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1737,6 +1737,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) {"INT3515", }, /* Non-conforming _HID for Cirrus Logic already released */ {"CLSA0100", }, + {"CLSA0101", }, /* * Some ACPI devs contain SerialBus resources even though they are not * attached to a serial bus at all. -- GitLab From ef34a0ae7a2654bc9e58675e36898217fb2799d8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Jul 2022 14:59:42 +0200 Subject: [PATCH 937/942] ALSA: core: Add async signal helpers Currently the call of kill_fasync() from an interrupt handler might lead to potential spin deadlocks, as spotted by syzkaller. Unfortunately, it's not so trivial to fix this lock chain as it's involved with the tasklist_lock that is touched in allover places. As a temporary workaround, this patch provides the way to defer the async signal notification in a work. The new helper functions, snd_fasync_helper() and snd_kill_faync() are replacements for fasync_helper() and kill_fasync(), respectively. In addition, snd_fasync_free() needs to be called at the destructor of the relevant file object. Link: https://lore.kernel.org/r/20220728125945.29533-2-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/core.h | 8 ++++ sound/core/misc.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/include/sound/core.h b/include/sound/core.h index dd28de2343b80..4365c35d038b4 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -507,4 +507,12 @@ snd_pci_quirk_lookup_id(u16 vendor, u16 device, } #endif +/* async signal helpers */ +struct snd_fasync; + +int snd_fasync_helper(int fd, struct file *file, int on, + struct snd_fasync **fasyncp); +void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll); +void snd_fasync_free(struct snd_fasync *fasync); + #endif /* __SOUND_CORE_H */ diff --git a/sound/core/misc.c b/sound/core/misc.c index 50e4aaa6270d1..d32a19976a2b9 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #ifdef CONFIG_SND_DEBUG @@ -145,3 +146,96 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list) } EXPORT_SYMBOL(snd_pci_quirk_lookup); #endif + +/* + * Deferred async signal helpers + * + * Below are a few helper functions to wrap the async signal handling + * in the deferred work. The main purpose is to avoid the messy deadlock + * around tasklist_lock and co at the kill_fasync() invocation. + * fasync_helper() and kill_fasync() are replaced with snd_fasync_helper() + * and snd_kill_fasync(), respectively. In addition, snd_fasync_free() has + * to be called at releasing the relevant file object. + */ +struct snd_fasync { + struct fasync_struct *fasync; + int signal; + int poll; + int on; + struct list_head list; +}; + +static DEFINE_SPINLOCK(snd_fasync_lock); +static LIST_HEAD(snd_fasync_list); + +static void snd_fasync_work_fn(struct work_struct *work) +{ + struct snd_fasync *fasync; + + spin_lock_irq(&snd_fasync_lock); + while (!list_empty(&snd_fasync_list)) { + fasync = list_first_entry(&snd_fasync_list, struct snd_fasync, list); + list_del_init(&fasync->list); + spin_unlock_irq(&snd_fasync_lock); + if (fasync->on) + kill_fasync(&fasync->fasync, fasync->signal, fasync->poll); + spin_lock_irq(&snd_fasync_lock); + } + spin_unlock_irq(&snd_fasync_lock); +} + +static DECLARE_WORK(snd_fasync_work, snd_fasync_work_fn); + +int snd_fasync_helper(int fd, struct file *file, int on, + struct snd_fasync **fasyncp) +{ + struct snd_fasync *fasync = NULL; + + if (on) { + fasync = kzalloc(sizeof(*fasync), GFP_KERNEL); + if (!fasync) + return -ENOMEM; + INIT_LIST_HEAD(&fasync->list); + } + + spin_lock_irq(&snd_fasync_lock); + if (*fasyncp) { + kfree(fasync); + fasync = *fasyncp; + } else { + if (!fasync) { + spin_unlock_irq(&snd_fasync_lock); + return 0; + } + *fasyncp = fasync; + } + fasync->on = on; + spin_unlock_irq(&snd_fasync_lock); + return fasync_helper(fd, file, on, &fasync->fasync); +} +EXPORT_SYMBOL_GPL(snd_fasync_helper); + +void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll) +{ + unsigned long flags; + + if (!fasync || !fasync->on) + return; + spin_lock_irqsave(&snd_fasync_lock, flags); + fasync->signal = signal; + fasync->poll = poll; + list_move(&fasync->list, &snd_fasync_list); + schedule_work(&snd_fasync_work); + spin_unlock_irqrestore(&snd_fasync_lock, flags); +} +EXPORT_SYMBOL_GPL(snd_kill_fasync); + +void snd_fasync_free(struct snd_fasync *fasync) +{ + if (!fasync) + return; + fasync->on = 0; + flush_work(&snd_fasync_work); + kfree(fasync); +} +EXPORT_SYMBOL_GPL(snd_fasync_free); -- GitLab From 95cc637c1afd83fb7dd3d7c8a53710488f4caf9c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Jul 2022 14:59:43 +0200 Subject: [PATCH 938/942] ALSA: timer: Use deferred fasync helper For avoiding the potential deadlock via kill_fasync() call, use the new fasync helpers to defer the invocation from PCI API. Note that it's merely a workaround. Reported-by: syzbot+1ee0910eca9c94f71f25@syzkaller.appspotmail.com Reported-by: syzbot+49b10793b867871ee26f@syzkaller.appspotmail.com Reported-by: syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20220728125945.29533-3-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/core/timer.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index b3214baa89193..e08a37c23add8 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -83,7 +83,7 @@ struct snd_timer_user { unsigned int filter; struct timespec64 tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; - struct fasync_struct *fasync; + struct snd_fasync *fasync; struct mutex ioctl_lock; }; @@ -1345,7 +1345,7 @@ static void snd_timer_user_interrupt(struct snd_timer_instance *timeri, } __wake: spin_unlock(&tu->qlock); - kill_fasync(&tu->fasync, SIGIO, POLL_IN); + snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); wake_up(&tu->qchange_sleep); } @@ -1383,7 +1383,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, spin_lock_irqsave(&tu->qlock, flags); snd_timer_user_append_to_tqueue(tu, &r1); spin_unlock_irqrestore(&tu->qlock, flags); - kill_fasync(&tu->fasync, SIGIO, POLL_IN); + snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); wake_up(&tu->qchange_sleep); } @@ -1453,7 +1453,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, spin_unlock(&tu->qlock); if (append == 0) return; - kill_fasync(&tu->fasync, SIGIO, POLL_IN); + snd_kill_fasync(tu->fasync, SIGIO, POLL_IN); wake_up(&tu->qchange_sleep); } @@ -1521,6 +1521,7 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) snd_timer_instance_free(tu->timeri); } mutex_unlock(&tu->ioctl_lock); + snd_fasync_free(tu->fasync); kfree(tu->queue); kfree(tu->tqueue); kfree(tu); @@ -2135,7 +2136,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) struct snd_timer_user *tu; tu = file->private_data; - return fasync_helper(fd, file, on, &tu->fasync); + return snd_fasync_helper(fd, file, on, &tu->fasync); } static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, -- GitLab From 96b097091c66df4f6fbf5cbff21df6cc02a2f055 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Jul 2022 14:59:44 +0200 Subject: [PATCH 939/942] ALSA: pcm: Use deferred fasync helper For avoiding the potential deadlock via kill_fasync() call, use the new fasync helpers to defer the invocation from timer API. Note that it's merely a workaround. Reported-by: syzbot+8285e973a41b5aa68902@syzkaller.appspotmail.com Reported-by: syzbot+669c9abf11a6a011dd09@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20220728125945.29533-4-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 2 +- sound/core/pcm.c | 1 + sound/core/pcm_lib.c | 2 +- sound/core/pcm_native.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 2d03c10f6a360..8c48a5bce88c1 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -399,7 +399,7 @@ struct snd_pcm_runtime { snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */ wait_queue_head_t sleep; /* poll sleep */ wait_queue_head_t tsleep; /* transfer sleep */ - struct fasync_struct *fasync; + struct snd_fasync *fasync; bool stop_operating; /* sync_stop will be called */ struct mutex buffer_mutex; /* protect for buffer changes */ atomic_t buffer_accessing; /* >0: in r/w operation, <0: blocked */ diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 03fc5fa5813ef..2ac742035310d 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -1007,6 +1007,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) substream->runtime = NULL; } mutex_destroy(&runtime->buffer_mutex); + snd_fasync_free(runtime->fasync); kfree(runtime); put_pid(substream->pid); substream->pid = NULL; diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1fc7c50ffa625..40751e5aff09f 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1822,7 +1822,7 @@ void snd_pcm_period_elapsed_under_stream_lock(struct snd_pcm_substream *substrea snd_timer_interrupt(substream->timer, 1); #endif _end: - kill_fasync(&runtime->fasync, SIGIO, POLL_IN); + snd_kill_fasync(runtime->fasync, SIGIO, POLL_IN); } EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index aa0453e515956..ad0541e9e8880 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3951,7 +3951,7 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) runtime = substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED) return -EBADFD; - return fasync_helper(fd, file, on, &runtime->fasync); + return snd_fasync_helper(fd, file, on, &runtime->fasync); } /* -- GitLab From 4a971e84a7ae10a38d875cd2d4e487c8d1682ca3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 28 Jul 2022 14:59:45 +0200 Subject: [PATCH 940/942] ALSA: control: Use deferred fasync helper For avoiding the potential deadlock via kill_fasync() call, use the new fasync helpers to defer the invocation from the control API. Note that it's merely a workaround. Another note: although we haven't received reports about the deadlock with the control API, the deadlock is still potentially possible, and it's better to align the behavior with other core APIs (PCM and timer); so let's move altogether. Link: https://lore.kernel.org/r/20220728125945.29533-5-tiwai@suse.de Signed-off-by: Takashi Iwai --- include/sound/control.h | 2 +- sound/core/control.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/sound/control.h b/include/sound/control.h index fcd3cce673ec3..eae443ba79ba5 100644 --- a/include/sound/control.h +++ b/include/sound/control.h @@ -109,7 +109,7 @@ struct snd_ctl_file { int preferred_subdevice[SND_CTL_SUBDEV_ITEMS]; wait_queue_head_t change_sleep; spinlock_t read_lock; - struct fasync_struct *fasync; + struct snd_fasync *fasync; int subscribed; /* read interface is activated */ struct list_head events; /* waiting events for read */ }; diff --git a/sound/core/control.c b/sound/core/control.c index 4dba3a342458f..f3e893715369f 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -127,6 +127,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file) if (control->vd[idx].owner == ctl) control->vd[idx].owner = NULL; up_write(&card->controls_rwsem); + snd_fasync_free(ctl->fasync); snd_ctl_empty_read_queue(ctl); put_pid(ctl->pid); kfree(ctl); @@ -181,7 +182,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, _found: wake_up(&ctl->change_sleep); spin_unlock(&ctl->read_lock); - kill_fasync(&ctl->fasync, SIGIO, POLL_IN); + snd_kill_fasync(ctl->fasync, SIGIO, POLL_IN); } read_unlock_irqrestore(&card->ctl_files_rwlock, flags); } @@ -2134,7 +2135,7 @@ static int snd_ctl_fasync(int fd, struct file * file, int on) struct snd_ctl_file *ctl; ctl = file->private_data; - return fasync_helper(fd, file, on, &ctl->fasync); + return snd_fasync_helper(fd, file, on, &ctl->fasync); } /* return the preferred subdevice number if already assigned; @@ -2302,7 +2303,7 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) read_lock_irqsave(&card->ctl_files_rwlock, flags); list_for_each_entry(ctl, &card->ctl_files, list) { wake_up(&ctl->change_sleep); - kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); + snd_kill_fasync(ctl->fasync, SIGIO, POLL_ERR); } read_unlock_irqrestore(&card->ctl_files_rwlock, flags); -- GitLab From 3790a3d6dbbc48e30586e9c3fc752a00e2e11946 Mon Sep 17 00:00:00 2001 From: Philipp Jungkamp Date: Fri, 29 Jul 2022 18:21:03 +0200 Subject: [PATCH 941/942] ALSA: hda/realtek: Add quirk for Lenovo Yoga9 14IAP7 The Lenovo Yoga 9 14IAP7 is set up similarly to the Thinkpad X1 7th and 8th Gen. It also has the speakers attached to NID 0x14 and the bass speakers to NID 0x17, but here the codec misreports the NID 0x17 as unconnected. The pincfg and hda verbs connect and activate the bass speaker amplifiers, but the generic driver will connect them to NID 0x06 which has no volume control. Set connection list/preferred connections is required to gain volume control. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208555 Signed-off-by: Philipp Jungkamp Cc: Link: https://lore.kernel.org/r/20220729162103.6062-1-p.jungkamp@gmx.net Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e1fbda2159756..cca093cb643ee 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6817,6 +6817,43 @@ static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec, } } +static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + /* + * The Pin Complex 0x17 for the bass speakers is wrongly reported as + * unconnected. + */ + static const struct hda_pintbl pincfgs[] = { + { 0x17, 0x90170121 }, + { } + }; + /* + * Avoid DAC 0x06 and 0x08, as they have no volume controls. + * DAC 0x02 and 0x03 would be fine. + */ + static const hda_nid_t conn[] = { 0x02, 0x03 }; + /* + * Prefer both speakerbar (0x14) and bass speakers (0x17) connected to DAC 0x02. + * Headphones (0x21) are connected to DAC 0x03. + */ + static const hda_nid_t preferred_pairs[] = { + 0x14, 0x02, + 0x17, 0x02, + 0x21, 0x03, + 0 + }; + struct alc_spec *spec = codec->spec; + + switch (action) { + case HDA_FIXUP_ACT_PRE_PROBE: + snd_hda_apply_pincfgs(codec, pincfgs); + snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn); + spec->gen.preferred_dacs = preferred_pairs; + break; + } +} + enum { ALC269_FIXUP_GPIO2, ALC269_FIXUP_SONY_VAIO, @@ -7054,6 +7091,8 @@ enum { ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED, ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE, ALC287_FIXUP_LEGION_16ITHG6, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, + ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -8900,6 +8939,74 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc287_fixup_legion_16ithg6_speakers, }, + [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + // enable left speaker + { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x41 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xc }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x1a }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xf }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x42 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x10 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x40 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + // enable right speaker + { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x46 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xc }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2a }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xf }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x46 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x10 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x44 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x2 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, + + { }, + }, + }, + [ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc287_fixup_yoga9_14iap7_bass_spk_pin, + .chained = true, + .chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -9352,6 +9459,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x31af, "ThinkCentre Station", ALC623_FIXUP_LENOVO_THINKSTATION_P340), + SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS), SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7), @@ -9598,6 +9706,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC285_FIXUP_HP_SPECTRE_X360_EB1, .name = "alc285-hp-spectre-x360-eb1"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, + {.id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN, .name = "alc287-yoga9-bass-spk-pin"}, {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"}, -- GitLab From be561ffad708f0cee18aee4231f80ffafaf7a419 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Sat, 30 Jul 2022 21:22:43 -0600 Subject: [PATCH 942/942] ALSA: hda/realtek: Add quirk for Clevo NV45PZ Fixes headset detection on Clevo NV45PZ. Signed-off-by: Tim Crawford Cc: Link: https://lore.kernel.org/r/20220731032243.4300-1-tcrawford@system76.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cca093cb643ee..105468acde905 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9347,6 +9347,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1558, 0x4018, "Clevo NV40M[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x4019, "Clevo NV40MZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x4020, "Clevo NV40MB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x4041, "Clevo NV4[15]PZ", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40a1, "Clevo NL40GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40c1, "Clevo NL40[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40d1, "Clevo NL41DU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), -- GitLab