162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// This file is provided under a dual BSD/GPLv2 license. When using or 462306a36Sopenharmony_ci// redistributing this file, you may do so under either license. 562306a36Sopenharmony_ci// 662306a36Sopenharmony_ci// Copyright(c) 2018-2021 Intel Corporation. All rights reserved. 762306a36Sopenharmony_ci// 862306a36Sopenharmony_ci// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 962306a36Sopenharmony_ci// 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * Hardware interface for audio DSP on Atom devices 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <sound/sof.h> 1762306a36Sopenharmony_ci#include <sound/sof/xtensa.h> 1862306a36Sopenharmony_ci#include <sound/soc-acpi.h> 1962306a36Sopenharmony_ci#include <sound/soc-acpi-intel-match.h> 2062306a36Sopenharmony_ci#include <sound/intel-dsp-config.h> 2162306a36Sopenharmony_ci#include "../ops.h" 2262306a36Sopenharmony_ci#include "shim.h" 2362306a36Sopenharmony_ci#include "atom.h" 2462306a36Sopenharmony_ci#include "../sof-acpi-dev.h" 2562306a36Sopenharmony_ci#include "../sof-audio.h" 2662306a36Sopenharmony_ci#include "../../intel/common/soc-intel-quirks.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void atom_host_done(struct snd_sof_dev *sdev); 2962306a36Sopenharmony_cistatic void atom_dsp_done(struct snd_sof_dev *sdev); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * Debug 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic void atom_get_registers(struct snd_sof_dev *sdev, 3662306a36Sopenharmony_ci struct sof_ipc_dsp_oops_xtensa *xoops, 3762306a36Sopenharmony_ci struct sof_ipc_panic_info *panic_info, 3862306a36Sopenharmony_ci u32 *stack, size_t stack_words) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci u32 offset = sdev->dsp_oops_offset; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* first read regsisters */ 4362306a36Sopenharmony_ci sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci /* note: variable AR register array is not read */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* then get panic info */ 4862306a36Sopenharmony_ci if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { 4962306a36Sopenharmony_ci dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", 5062306a36Sopenharmony_ci xoops->arch_hdr.totalsize); 5162306a36Sopenharmony_ci return; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci offset += xoops->arch_hdr.totalsize; 5462306a36Sopenharmony_ci sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* then get the stack */ 5762306a36Sopenharmony_ci offset += sizeof(*panic_info); 5862306a36Sopenharmony_ci sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_civoid atom_dump(struct snd_sof_dev *sdev, u32 flags) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci struct sof_ipc_dsp_oops_xtensa xoops; 6462306a36Sopenharmony_ci struct sof_ipc_panic_info panic_info; 6562306a36Sopenharmony_ci u32 stack[STACK_DUMP_SIZE]; 6662306a36Sopenharmony_ci u64 status, panic, imrd, imrx; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci /* now try generic SOF status messages */ 6962306a36Sopenharmony_ci status = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 7062306a36Sopenharmony_ci panic = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 7162306a36Sopenharmony_ci atom_get_registers(sdev, &xoops, &panic_info, stack, 7262306a36Sopenharmony_ci STACK_DUMP_SIZE); 7362306a36Sopenharmony_ci sof_print_oops_and_stack(sdev, KERN_ERR, status, panic, &xoops, 7462306a36Sopenharmony_ci &panic_info, stack, STACK_DUMP_SIZE); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci /* provide some context for firmware debug */ 7762306a36Sopenharmony_ci imrx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRX); 7862306a36Sopenharmony_ci imrd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRD); 7962306a36Sopenharmony_ci dev_err(sdev->dev, 8062306a36Sopenharmony_ci "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n", 8162306a36Sopenharmony_ci (panic & SHIM_IPCX_BUSY) ? "yes" : "no", 8262306a36Sopenharmony_ci (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic); 8362306a36Sopenharmony_ci dev_err(sdev->dev, 8462306a36Sopenharmony_ci "error: mask host: pending %s complete %s raw 0x%llx\n", 8562306a36Sopenharmony_ci (imrx & SHIM_IMRX_BUSY) ? "yes" : "no", 8662306a36Sopenharmony_ci (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx); 8762306a36Sopenharmony_ci dev_err(sdev->dev, 8862306a36Sopenharmony_ci "error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n", 8962306a36Sopenharmony_ci (status & SHIM_IPCD_BUSY) ? "yes" : "no", 9062306a36Sopenharmony_ci (status & SHIM_IPCD_DONE) ? "yes" : "no", status); 9162306a36Sopenharmony_ci dev_err(sdev->dev, 9262306a36Sopenharmony_ci "error: mask DSP: pending %s complete %s raw 0x%llx\n", 9362306a36Sopenharmony_ci (imrd & SHIM_IMRD_BUSY) ? "yes" : "no", 9462306a36Sopenharmony_ci (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_dump, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* 10062306a36Sopenharmony_ci * IPC Doorbell IRQ handler and thread. 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ciirqreturn_t atom_irq_handler(int irq, void *context) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci struct snd_sof_dev *sdev = context; 10662306a36Sopenharmony_ci u64 ipcx, ipcd; 10762306a36Sopenharmony_ci int ret = IRQ_NONE; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 11062306a36Sopenharmony_ci ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci if (ipcx & SHIM_BYT_IPCX_DONE) { 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /* reply message from DSP, Mask Done interrupt first */ 11562306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, 11662306a36Sopenharmony_ci SHIM_IMRX, 11762306a36Sopenharmony_ci SHIM_IMRX_DONE, 11862306a36Sopenharmony_ci SHIM_IMRX_DONE); 11962306a36Sopenharmony_ci ret = IRQ_WAKE_THREAD; 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (ipcd & SHIM_BYT_IPCD_BUSY) { 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci /* new message from DSP, Mask Busy interrupt first */ 12562306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, 12662306a36Sopenharmony_ci SHIM_IMRX, 12762306a36Sopenharmony_ci SHIM_IMRX_BUSY, 12862306a36Sopenharmony_ci SHIM_IMRX_BUSY); 12962306a36Sopenharmony_ci ret = IRQ_WAKE_THREAD; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci return ret; 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_irq_handler, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ciirqreturn_t atom_irq_thread(int irq, void *context) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci struct snd_sof_dev *sdev = context; 13962306a36Sopenharmony_ci u64 ipcx, ipcd; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 14262306a36Sopenharmony_ci ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci /* reply message from DSP */ 14562306a36Sopenharmony_ci if (ipcx & SHIM_BYT_IPCX_DONE) { 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci spin_lock_irq(&sdev->ipc_lock); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci /* 15062306a36Sopenharmony_ci * handle immediate reply from DSP core. If the msg is 15162306a36Sopenharmony_ci * found, set done bit in cmd_done which is called at the 15262306a36Sopenharmony_ci * end of message processing function, else set it here 15362306a36Sopenharmony_ci * because the done bit can't be set in cmd_done function 15462306a36Sopenharmony_ci * which is triggered by msg 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_ci snd_sof_ipc_process_reply(sdev, ipcx); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci atom_dsp_done(sdev); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci spin_unlock_irq(&sdev->ipc_lock); 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* new message from DSP */ 16462306a36Sopenharmony_ci if (ipcd & SHIM_BYT_IPCD_BUSY) { 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* Handle messages from DSP Core */ 16762306a36Sopenharmony_ci if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { 16862306a36Sopenharmony_ci snd_sof_dsp_panic(sdev, PANIC_OFFSET(ipcd) + MBOX_OFFSET, 16962306a36Sopenharmony_ci true); 17062306a36Sopenharmony_ci } else { 17162306a36Sopenharmony_ci snd_sof_ipc_msgs_rx(sdev); 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci atom_host_done(sdev); 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci return IRQ_HANDLED; 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_irq_thread, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciint atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci /* unmask and prepare to receive Done interrupt */ 18462306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX, 18562306a36Sopenharmony_ci SHIM_IMRX_DONE, 0); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci /* send the message */ 18862306a36Sopenharmony_ci sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 18962306a36Sopenharmony_ci msg->msg_size); 19062306a36Sopenharmony_ci snd_sof_dsp_write64(sdev, DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_send_msg, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ciint atom_get_mailbox_offset(struct snd_sof_dev *sdev) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci return MBOX_OFFSET; 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_get_mailbox_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ciint atom_get_window_offset(struct snd_sof_dev *sdev, u32 id) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci return MBOX_OFFSET; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_get_window_offset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic void atom_host_done(struct snd_sof_dev *sdev) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci /* clear BUSY bit and set DONE bit - accept new messages */ 21162306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCD, 21262306a36Sopenharmony_ci SHIM_BYT_IPCD_BUSY | 21362306a36Sopenharmony_ci SHIM_BYT_IPCD_DONE, 21462306a36Sopenharmony_ci SHIM_BYT_IPCD_DONE); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* unmask and prepare to receive next new message */ 21762306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX, 21862306a36Sopenharmony_ci SHIM_IMRX_BUSY, 0); 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic void atom_dsp_done(struct snd_sof_dev *sdev) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci /* clear DONE bit - tell DSP we have completed */ 22462306a36Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCX, 22562306a36Sopenharmony_ci SHIM_BYT_IPCX_DONE, 0); 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/* 22962306a36Sopenharmony_ci * DSP control. 23062306a36Sopenharmony_ci */ 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ciint atom_run(struct snd_sof_dev *sdev) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci int tries = 10; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci /* release stall and wait to unstall */ 23762306a36Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 23862306a36Sopenharmony_ci SHIM_BYT_CSR_STALL, 0x0); 23962306a36Sopenharmony_ci while (tries--) { 24062306a36Sopenharmony_ci if (!(snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_CSR) & 24162306a36Sopenharmony_ci SHIM_BYT_CSR_PWAITMODE)) 24262306a36Sopenharmony_ci break; 24362306a36Sopenharmony_ci msleep(100); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci if (tries < 0) 24662306a36Sopenharmony_ci return -ENODEV; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci /* return init core mask */ 24962306a36Sopenharmony_ci return 1; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_run, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint atom_reset(struct snd_sof_dev *sdev) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci /* put DSP into reset, set reset vector and stall */ 25662306a36Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 25762306a36Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 25862306a36Sopenharmony_ci SHIM_BYT_CSR_STALL, 25962306a36Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 26062306a36Sopenharmony_ci SHIM_BYT_CSR_STALL); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci usleep_range(10, 15); 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci /* take DSP out of reset and keep stalled for FW loading */ 26562306a36Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 26662306a36Sopenharmony_ci SHIM_BYT_CSR_RST, 0); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci return 0; 26962306a36Sopenharmony_ci} 27062306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_reset, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_cistatic const char *fixup_tplg_name(struct snd_sof_dev *sdev, 27362306a36Sopenharmony_ci const char *sof_tplg_filename, 27462306a36Sopenharmony_ci const char *ssp_str) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci const char *tplg_filename = NULL; 27762306a36Sopenharmony_ci const char *split_ext; 27862306a36Sopenharmony_ci char *filename, *tmp; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci filename = kstrdup(sof_tplg_filename, GFP_KERNEL); 28162306a36Sopenharmony_ci if (!filename) 28262306a36Sopenharmony_ci return NULL; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* this assumes a .tplg extension */ 28562306a36Sopenharmony_ci tmp = filename; 28662306a36Sopenharmony_ci split_ext = strsep(&tmp, "."); 28762306a36Sopenharmony_ci if (split_ext) 28862306a36Sopenharmony_ci tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 28962306a36Sopenharmony_ci "%s-%s.tplg", 29062306a36Sopenharmony_ci split_ext, ssp_str); 29162306a36Sopenharmony_ci kfree(filename); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci return tplg_filename; 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistruct snd_soc_acpi_mach *atom_machine_select(struct snd_sof_dev *sdev) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci struct snd_sof_pdata *sof_pdata = sdev->pdata; 29962306a36Sopenharmony_ci const struct sof_dev_desc *desc = sof_pdata->desc; 30062306a36Sopenharmony_ci struct snd_soc_acpi_mach *mach; 30162306a36Sopenharmony_ci struct platform_device *pdev; 30262306a36Sopenharmony_ci const char *tplg_filename; 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci mach = snd_soc_acpi_find_machine(desc->machines); 30562306a36Sopenharmony_ci if (!mach) { 30662306a36Sopenharmony_ci dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); 30762306a36Sopenharmony_ci return NULL; 30862306a36Sopenharmony_ci } 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci pdev = to_platform_device(sdev->dev); 31162306a36Sopenharmony_ci if (soc_intel_is_byt_cr(pdev)) { 31262306a36Sopenharmony_ci dev_dbg(sdev->dev, 31362306a36Sopenharmony_ci "BYT-CR detected, SSP0 used instead of SSP2\n"); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci tplg_filename = fixup_tplg_name(sdev, 31662306a36Sopenharmony_ci mach->sof_tplg_filename, 31762306a36Sopenharmony_ci "ssp0"); 31862306a36Sopenharmony_ci } else { 31962306a36Sopenharmony_ci tplg_filename = mach->sof_tplg_filename; 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci if (!tplg_filename) { 32362306a36Sopenharmony_ci dev_dbg(sdev->dev, 32462306a36Sopenharmony_ci "error: no topology filename\n"); 32562306a36Sopenharmony_ci return NULL; 32662306a36Sopenharmony_ci } 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci sof_pdata->tplg_filename = tplg_filename; 32962306a36Sopenharmony_ci mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci return mach; 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_machine_select, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* Atom DAIs */ 33662306a36Sopenharmony_cistruct snd_soc_dai_driver atom_dai[] = { 33762306a36Sopenharmony_ci{ 33862306a36Sopenharmony_ci .name = "ssp0-port", 33962306a36Sopenharmony_ci .playback = { 34062306a36Sopenharmony_ci .channels_min = 1, 34162306a36Sopenharmony_ci .channels_max = 8, 34262306a36Sopenharmony_ci }, 34362306a36Sopenharmony_ci .capture = { 34462306a36Sopenharmony_ci .channels_min = 1, 34562306a36Sopenharmony_ci .channels_max = 8, 34662306a36Sopenharmony_ci }, 34762306a36Sopenharmony_ci}, 34862306a36Sopenharmony_ci{ 34962306a36Sopenharmony_ci .name = "ssp1-port", 35062306a36Sopenharmony_ci .playback = { 35162306a36Sopenharmony_ci .channels_min = 1, 35262306a36Sopenharmony_ci .channels_max = 8, 35362306a36Sopenharmony_ci }, 35462306a36Sopenharmony_ci .capture = { 35562306a36Sopenharmony_ci .channels_min = 1, 35662306a36Sopenharmony_ci .channels_max = 8, 35762306a36Sopenharmony_ci }, 35862306a36Sopenharmony_ci}, 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci .name = "ssp2-port", 36162306a36Sopenharmony_ci .playback = { 36262306a36Sopenharmony_ci .channels_min = 1, 36362306a36Sopenharmony_ci .channels_max = 8, 36462306a36Sopenharmony_ci }, 36562306a36Sopenharmony_ci .capture = { 36662306a36Sopenharmony_ci .channels_min = 1, 36762306a36Sopenharmony_ci .channels_max = 8, 36862306a36Sopenharmony_ci } 36962306a36Sopenharmony_ci}, 37062306a36Sopenharmony_ci{ 37162306a36Sopenharmony_ci .name = "ssp3-port", 37262306a36Sopenharmony_ci .playback = { 37362306a36Sopenharmony_ci .channels_min = 1, 37462306a36Sopenharmony_ci .channels_max = 8, 37562306a36Sopenharmony_ci }, 37662306a36Sopenharmony_ci .capture = { 37762306a36Sopenharmony_ci .channels_min = 1, 37862306a36Sopenharmony_ci .channels_max = 8, 37962306a36Sopenharmony_ci }, 38062306a36Sopenharmony_ci}, 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci .name = "ssp4-port", 38362306a36Sopenharmony_ci .playback = { 38462306a36Sopenharmony_ci .channels_min = 1, 38562306a36Sopenharmony_ci .channels_max = 8, 38662306a36Sopenharmony_ci }, 38762306a36Sopenharmony_ci .capture = { 38862306a36Sopenharmony_ci .channels_min = 1, 38962306a36Sopenharmony_ci .channels_max = 8, 39062306a36Sopenharmony_ci }, 39162306a36Sopenharmony_ci}, 39262306a36Sopenharmony_ci{ 39362306a36Sopenharmony_ci .name = "ssp5-port", 39462306a36Sopenharmony_ci .playback = { 39562306a36Sopenharmony_ci .channels_min = 1, 39662306a36Sopenharmony_ci .channels_max = 8, 39762306a36Sopenharmony_ci }, 39862306a36Sopenharmony_ci .capture = { 39962306a36Sopenharmony_ci .channels_min = 1, 40062306a36Sopenharmony_ci .channels_max = 8, 40162306a36Sopenharmony_ci }, 40262306a36Sopenharmony_ci}, 40362306a36Sopenharmony_ci}; 40462306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_dai, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_civoid atom_set_mach_params(struct snd_soc_acpi_mach *mach, 40762306a36Sopenharmony_ci struct snd_sof_dev *sdev) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci struct snd_sof_pdata *pdata = sdev->pdata; 41062306a36Sopenharmony_ci const struct sof_dev_desc *desc = pdata->desc; 41162306a36Sopenharmony_ci struct snd_soc_acpi_mach_params *mach_params; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci mach_params = &mach->mach_params; 41462306a36Sopenharmony_ci mach_params->platform = dev_name(sdev->dev); 41562306a36Sopenharmony_ci mach_params->num_dai_drivers = desc->ops->num_drv; 41662306a36Sopenharmony_ci mach_params->dai_drivers = desc->ops->drv; 41762306a36Sopenharmony_ci} 41862306a36Sopenharmony_ciEXPORT_SYMBOL_NS(atom_set_mach_params, SND_SOC_SOF_INTEL_ATOM_HIFI_EP); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 421