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 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 Baytrail, Braswell and Cherrytrail.
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 "atom.h"
2362306a36Sopenharmony_ci#include "shim.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 const struct snd_sof_debugfs_map byt_debugfs[] = {
2962306a36Sopenharmony_ci	{"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
3062306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
3162306a36Sopenharmony_ci	{"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
3262306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
3362306a36Sopenharmony_ci	{"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
3462306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
3562306a36Sopenharmony_ci	{"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
3662306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
3762306a36Sopenharmony_ci	{"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
3862306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
3962306a36Sopenharmony_ci	{"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
4062306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_D0_ONLY},
4162306a36Sopenharmony_ci	{"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
4262306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_D0_ONLY},
4362306a36Sopenharmony_ci	{"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
4462306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic const struct snd_sof_debugfs_map cht_debugfs[] = {
4862306a36Sopenharmony_ci	{"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
4962306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
5062306a36Sopenharmony_ci	{"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
5162306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
5262306a36Sopenharmony_ci	{"dmac2", DSP_BAR, DMAC2_OFFSET, DMAC_SIZE,
5362306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
5462306a36Sopenharmony_ci	{"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
5562306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
5662306a36Sopenharmony_ci	{"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
5762306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
5862306a36Sopenharmony_ci	{"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
5962306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
6062306a36Sopenharmony_ci	{"ssp3", DSP_BAR, SSP3_OFFSET, SSP_SIZE,
6162306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
6262306a36Sopenharmony_ci	{"ssp4", DSP_BAR, SSP4_OFFSET, SSP_SIZE,
6362306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
6462306a36Sopenharmony_ci	{"ssp5", DSP_BAR, SSP5_OFFSET, SSP_SIZE,
6562306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
6662306a36Sopenharmony_ci	{"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
6762306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_D0_ONLY},
6862306a36Sopenharmony_ci	{"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
6962306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_D0_ONLY},
7062306a36Sopenharmony_ci	{"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
7162306a36Sopenharmony_ci	 SOF_DEBUGFS_ACCESS_ALWAYS},
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	/* Disable Interrupt from both sides */
7762306a36Sopenharmony_ci	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 0x3, 0x3);
7862306a36Sopenharmony_ci	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRD, 0x3, 0x3);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	/* Put DSP into reset, set reset vector */
8162306a36Sopenharmony_ci	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
8262306a36Sopenharmony_ci				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL,
8362306a36Sopenharmony_ci				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL);
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic int byt_suspend(struct snd_sof_dev *sdev, u32 target_state)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci	byt_reset_dsp_disable_int(sdev);
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	return 0;
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic int byt_resume(struct snd_sof_dev *sdev)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	/* enable BUSY and disable DONE Interrupt by default */
9662306a36Sopenharmony_ci	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
9762306a36Sopenharmony_ci				  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
9862306a36Sopenharmony_ci				  SHIM_IMRX_DONE);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	return 0;
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistatic int byt_remove(struct snd_sof_dev *sdev)
10462306a36Sopenharmony_ci{
10562306a36Sopenharmony_ci	byt_reset_dsp_disable_int(sdev);
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	return 0;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistatic int byt_acpi_probe(struct snd_sof_dev *sdev)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	struct snd_sof_pdata *pdata = sdev->pdata;
11362306a36Sopenharmony_ci	const struct sof_dev_desc *desc = pdata->desc;
11462306a36Sopenharmony_ci	struct platform_device *pdev =
11562306a36Sopenharmony_ci		container_of(sdev->dev, struct platform_device, dev);
11662306a36Sopenharmony_ci	const struct sof_intel_dsp_desc *chip;
11762306a36Sopenharmony_ci	struct resource *mmio;
11862306a36Sopenharmony_ci	u32 base, size;
11962306a36Sopenharmony_ci	int ret;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	chip = get_chip_info(sdev->pdata);
12262306a36Sopenharmony_ci	if (!chip) {
12362306a36Sopenharmony_ci		dev_err(sdev->dev, "error: no such device supported\n");
12462306a36Sopenharmony_ci		return -EIO;
12562306a36Sopenharmony_ci	}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	sdev->num_cores = chip->cores_num;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* DSP DMA can only access low 31 bits of host memory */
13062306a36Sopenharmony_ci	ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
13162306a36Sopenharmony_ci	if (ret < 0) {
13262306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
13362306a36Sopenharmony_ci		return ret;
13462306a36Sopenharmony_ci	}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	/* LPE base */
13762306a36Sopenharmony_ci	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
13862306a36Sopenharmony_ci				     desc->resindex_lpe_base);
13962306a36Sopenharmony_ci	if (mmio) {
14062306a36Sopenharmony_ci		base = mmio->start;
14162306a36Sopenharmony_ci		size = resource_size(mmio);
14262306a36Sopenharmony_ci	} else {
14362306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
14462306a36Sopenharmony_ci			desc->resindex_lpe_base);
14562306a36Sopenharmony_ci		return -EINVAL;
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
14962306a36Sopenharmony_ci	sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
15062306a36Sopenharmony_ci	if (!sdev->bar[DSP_BAR]) {
15162306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
15262306a36Sopenharmony_ci			base, size);
15362306a36Sopenharmony_ci		return -ENODEV;
15462306a36Sopenharmony_ci	}
15562306a36Sopenharmony_ci	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* TODO: add offsets */
15862306a36Sopenharmony_ci	sdev->mmio_bar = DSP_BAR;
15962306a36Sopenharmony_ci	sdev->mailbox_bar = DSP_BAR;
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	/* IMR base - optional */
16262306a36Sopenharmony_ci	if (desc->resindex_imr_base == -1)
16362306a36Sopenharmony_ci		goto irq;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
16662306a36Sopenharmony_ci				     desc->resindex_imr_base);
16762306a36Sopenharmony_ci	if (mmio) {
16862306a36Sopenharmony_ci		base = mmio->start;
16962306a36Sopenharmony_ci		size = resource_size(mmio);
17062306a36Sopenharmony_ci	} else {
17162306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
17262306a36Sopenharmony_ci			desc->resindex_imr_base);
17362306a36Sopenharmony_ci		return -ENODEV;
17462306a36Sopenharmony_ci	}
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	/* some BIOSes don't map IMR */
17762306a36Sopenharmony_ci	if (base == 0x55aa55aa || base == 0x0) {
17862306a36Sopenharmony_ci		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
17962306a36Sopenharmony_ci		goto irq;
18062306a36Sopenharmony_ci	}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
18362306a36Sopenharmony_ci	sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size);
18462306a36Sopenharmony_ci	if (!sdev->bar[IMR_BAR]) {
18562306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
18662306a36Sopenharmony_ci			base, size);
18762306a36Sopenharmony_ci		return -ENODEV;
18862306a36Sopenharmony_ci	}
18962306a36Sopenharmony_ci	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciirq:
19262306a36Sopenharmony_ci	/* register our IRQ */
19362306a36Sopenharmony_ci	sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
19462306a36Sopenharmony_ci	if (sdev->ipc_irq < 0)
19562306a36Sopenharmony_ci		return sdev->ipc_irq;
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
19862306a36Sopenharmony_ci	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
19962306a36Sopenharmony_ci					atom_irq_handler, atom_irq_thread,
20062306a36Sopenharmony_ci					IRQF_SHARED, "AudioDSP", sdev);
20162306a36Sopenharmony_ci	if (ret < 0) {
20262306a36Sopenharmony_ci		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
20362306a36Sopenharmony_ci			sdev->ipc_irq);
20462306a36Sopenharmony_ci		return ret;
20562306a36Sopenharmony_ci	}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	/* enable BUSY and disable DONE Interrupt by default */
20862306a36Sopenharmony_ci	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
20962306a36Sopenharmony_ci				  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
21062306a36Sopenharmony_ci				  SHIM_IMRX_DONE);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* set default mailbox offset for FW ready message */
21362306a36Sopenharmony_ci	sdev->dsp_box.offset = MBOX_OFFSET;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	return ret;
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/* baytrail ops */
21962306a36Sopenharmony_cistatic struct snd_sof_dsp_ops sof_byt_ops = {
22062306a36Sopenharmony_ci	/* device init */
22162306a36Sopenharmony_ci	.probe		= byt_acpi_probe,
22262306a36Sopenharmony_ci	.remove		= byt_remove,
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	/* DSP core boot / reset */
22562306a36Sopenharmony_ci	.run		= atom_run,
22662306a36Sopenharmony_ci	.reset		= atom_reset,
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	/* Register IO uses direct mmio */
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	/* Block IO */
23162306a36Sopenharmony_ci	.block_read	= sof_block_read,
23262306a36Sopenharmony_ci	.block_write	= sof_block_write,
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	/* Mailbox IO */
23562306a36Sopenharmony_ci	.mailbox_read	= sof_mailbox_read,
23662306a36Sopenharmony_ci	.mailbox_write	= sof_mailbox_write,
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	/* doorbell */
23962306a36Sopenharmony_ci	.irq_handler	= atom_irq_handler,
24062306a36Sopenharmony_ci	.irq_thread	= atom_irq_thread,
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	/* ipc */
24362306a36Sopenharmony_ci	.send_msg	= atom_send_msg,
24462306a36Sopenharmony_ci	.get_mailbox_offset = atom_get_mailbox_offset,
24562306a36Sopenharmony_ci	.get_window_offset = atom_get_window_offset,
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	.ipc_msg_data	= sof_ipc_msg_data,
24862306a36Sopenharmony_ci	.set_stream_data_offset = sof_set_stream_data_offset,
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	/* machine driver */
25162306a36Sopenharmony_ci	.machine_select = atom_machine_select,
25262306a36Sopenharmony_ci	.machine_register = sof_machine_register,
25362306a36Sopenharmony_ci	.machine_unregister = sof_machine_unregister,
25462306a36Sopenharmony_ci	.set_mach_params = atom_set_mach_params,
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	/* debug */
25762306a36Sopenharmony_ci	.debug_map	= byt_debugfs,
25862306a36Sopenharmony_ci	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
25962306a36Sopenharmony_ci	.dbg_dump	= atom_dump,
26062306a36Sopenharmony_ci	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci	/* stream callbacks */
26362306a36Sopenharmony_ci	.pcm_open	= sof_stream_pcm_open,
26462306a36Sopenharmony_ci	.pcm_close	= sof_stream_pcm_close,
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	/*Firmware loading */
26762306a36Sopenharmony_ci	.load_firmware	= snd_sof_load_firmware_memcpy,
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	/* PM */
27062306a36Sopenharmony_ci	.suspend = byt_suspend,
27162306a36Sopenharmony_ci	.resume = byt_resume,
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	/* DAI drivers */
27462306a36Sopenharmony_ci	.drv = atom_dai,
27562306a36Sopenharmony_ci	.num_drv = 3, /* we have only 3 SSPs on byt*/
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	/* ALSA HW info flags */
27862306a36Sopenharmony_ci	.hw_info =	SNDRV_PCM_INFO_MMAP |
27962306a36Sopenharmony_ci			SNDRV_PCM_INFO_MMAP_VALID |
28062306a36Sopenharmony_ci			SNDRV_PCM_INFO_INTERLEAVED |
28162306a36Sopenharmony_ci			SNDRV_PCM_INFO_PAUSE |
28262306a36Sopenharmony_ci			SNDRV_PCM_INFO_BATCH,
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	.dsp_arch_ops = &sof_xtensa_arch_ops,
28562306a36Sopenharmony_ci};
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_cistatic const struct sof_intel_dsp_desc byt_chip_info = {
28862306a36Sopenharmony_ci	.cores_num = 1,
28962306a36Sopenharmony_ci	.host_managed_cores_mask = 1,
29062306a36Sopenharmony_ci	.hw_ip_version = SOF_INTEL_BAYTRAIL,
29162306a36Sopenharmony_ci};
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci/* cherrytrail and braswell ops */
29462306a36Sopenharmony_cistatic struct snd_sof_dsp_ops sof_cht_ops = {
29562306a36Sopenharmony_ci	/* device init */
29662306a36Sopenharmony_ci	.probe		= byt_acpi_probe,
29762306a36Sopenharmony_ci	.remove		= byt_remove,
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/* DSP core boot / reset */
30062306a36Sopenharmony_ci	.run		= atom_run,
30162306a36Sopenharmony_ci	.reset		= atom_reset,
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	/* Register IO uses direct mmio */
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	/* Block IO */
30662306a36Sopenharmony_ci	.block_read	= sof_block_read,
30762306a36Sopenharmony_ci	.block_write	= sof_block_write,
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	/* Mailbox IO */
31062306a36Sopenharmony_ci	.mailbox_read	= sof_mailbox_read,
31162306a36Sopenharmony_ci	.mailbox_write	= sof_mailbox_write,
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	/* doorbell */
31462306a36Sopenharmony_ci	.irq_handler	= atom_irq_handler,
31562306a36Sopenharmony_ci	.irq_thread	= atom_irq_thread,
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	/* ipc */
31862306a36Sopenharmony_ci	.send_msg	= atom_send_msg,
31962306a36Sopenharmony_ci	.get_mailbox_offset = atom_get_mailbox_offset,
32062306a36Sopenharmony_ci	.get_window_offset = atom_get_window_offset,
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	.ipc_msg_data	= sof_ipc_msg_data,
32362306a36Sopenharmony_ci	.set_stream_data_offset = sof_set_stream_data_offset,
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	/* machine driver */
32662306a36Sopenharmony_ci	.machine_select = atom_machine_select,
32762306a36Sopenharmony_ci	.machine_register = sof_machine_register,
32862306a36Sopenharmony_ci	.machine_unregister = sof_machine_unregister,
32962306a36Sopenharmony_ci	.set_mach_params = atom_set_mach_params,
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	/* debug */
33262306a36Sopenharmony_ci	.debug_map	= cht_debugfs,
33362306a36Sopenharmony_ci	.debug_map_count	= ARRAY_SIZE(cht_debugfs),
33462306a36Sopenharmony_ci	.dbg_dump	= atom_dump,
33562306a36Sopenharmony_ci	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	/* stream callbacks */
33862306a36Sopenharmony_ci	.pcm_open	= sof_stream_pcm_open,
33962306a36Sopenharmony_ci	.pcm_close	= sof_stream_pcm_close,
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	/*Firmware loading */
34262306a36Sopenharmony_ci	.load_firmware	= snd_sof_load_firmware_memcpy,
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	/* PM */
34562306a36Sopenharmony_ci	.suspend = byt_suspend,
34662306a36Sopenharmony_ci	.resume = byt_resume,
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	/* DAI drivers */
34962306a36Sopenharmony_ci	.drv = atom_dai,
35062306a36Sopenharmony_ci	/* all 6 SSPs may be available for cherrytrail */
35162306a36Sopenharmony_ci	.num_drv = 6,
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	/* ALSA HW info flags */
35462306a36Sopenharmony_ci	.hw_info =	SNDRV_PCM_INFO_MMAP |
35562306a36Sopenharmony_ci			SNDRV_PCM_INFO_MMAP_VALID |
35662306a36Sopenharmony_ci			SNDRV_PCM_INFO_INTERLEAVED |
35762306a36Sopenharmony_ci			SNDRV_PCM_INFO_PAUSE |
35862306a36Sopenharmony_ci			SNDRV_PCM_INFO_BATCH,
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	.dsp_arch_ops = &sof_xtensa_arch_ops,
36162306a36Sopenharmony_ci};
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_cistatic const struct sof_intel_dsp_desc cht_chip_info = {
36462306a36Sopenharmony_ci	.cores_num = 1,
36562306a36Sopenharmony_ci	.host_managed_cores_mask = 1,
36662306a36Sopenharmony_ci	.hw_ip_version = SOF_INTEL_BAYTRAIL,
36762306a36Sopenharmony_ci};
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci/* BYTCR uses different IRQ index */
37062306a36Sopenharmony_cistatic const struct sof_dev_desc sof_acpi_baytrailcr_desc = {
37162306a36Sopenharmony_ci	.machines = snd_soc_acpi_intel_baytrail_machines,
37262306a36Sopenharmony_ci	.resindex_lpe_base = 0,
37362306a36Sopenharmony_ci	.resindex_pcicfg_base = 1,
37462306a36Sopenharmony_ci	.resindex_imr_base = 2,
37562306a36Sopenharmony_ci	.irqindex_host_ipc = 0,
37662306a36Sopenharmony_ci	.chip_info = &byt_chip_info,
37762306a36Sopenharmony_ci	.ipc_supported_mask = BIT(SOF_IPC),
37862306a36Sopenharmony_ci	.ipc_default = SOF_IPC,
37962306a36Sopenharmony_ci	.default_fw_path = {
38062306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof",
38162306a36Sopenharmony_ci	},
38262306a36Sopenharmony_ci	.default_tplg_path = {
38362306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof-tplg",
38462306a36Sopenharmony_ci	},
38562306a36Sopenharmony_ci	.default_fw_filename = {
38662306a36Sopenharmony_ci		[SOF_IPC] = "sof-byt.ri",
38762306a36Sopenharmony_ci	},
38862306a36Sopenharmony_ci	.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
38962306a36Sopenharmony_ci	.ops = &sof_byt_ops,
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistatic const struct sof_dev_desc sof_acpi_baytrail_desc = {
39362306a36Sopenharmony_ci	.machines = snd_soc_acpi_intel_baytrail_machines,
39462306a36Sopenharmony_ci	.resindex_lpe_base = 0,
39562306a36Sopenharmony_ci	.resindex_pcicfg_base = 1,
39662306a36Sopenharmony_ci	.resindex_imr_base = 2,
39762306a36Sopenharmony_ci	.irqindex_host_ipc = 5,
39862306a36Sopenharmony_ci	.chip_info = &byt_chip_info,
39962306a36Sopenharmony_ci	.ipc_supported_mask = BIT(SOF_IPC),
40062306a36Sopenharmony_ci	.ipc_default = SOF_IPC,
40162306a36Sopenharmony_ci	.default_fw_path = {
40262306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof",
40362306a36Sopenharmony_ci	},
40462306a36Sopenharmony_ci	.default_tplg_path = {
40562306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof-tplg",
40662306a36Sopenharmony_ci	},
40762306a36Sopenharmony_ci	.default_fw_filename = {
40862306a36Sopenharmony_ci		[SOF_IPC] = "sof-byt.ri",
40962306a36Sopenharmony_ci	},
41062306a36Sopenharmony_ci	.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
41162306a36Sopenharmony_ci	.ops = &sof_byt_ops,
41262306a36Sopenharmony_ci};
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
41562306a36Sopenharmony_ci	.machines = snd_soc_acpi_intel_cherrytrail_machines,
41662306a36Sopenharmony_ci	.resindex_lpe_base = 0,
41762306a36Sopenharmony_ci	.resindex_pcicfg_base = 1,
41862306a36Sopenharmony_ci	.resindex_imr_base = 2,
41962306a36Sopenharmony_ci	.irqindex_host_ipc = 5,
42062306a36Sopenharmony_ci	.chip_info = &cht_chip_info,
42162306a36Sopenharmony_ci	.ipc_supported_mask = BIT(SOF_IPC),
42262306a36Sopenharmony_ci	.ipc_default = SOF_IPC,
42362306a36Sopenharmony_ci	.default_fw_path = {
42462306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof",
42562306a36Sopenharmony_ci	},
42662306a36Sopenharmony_ci	.default_tplg_path = {
42762306a36Sopenharmony_ci		[SOF_IPC] = "intel/sof-tplg",
42862306a36Sopenharmony_ci	},
42962306a36Sopenharmony_ci	.default_fw_filename = {
43062306a36Sopenharmony_ci		[SOF_IPC] = "sof-cht.ri",
43162306a36Sopenharmony_ci	},
43262306a36Sopenharmony_ci	.nocodec_tplg_filename = "sof-cht-nocodec.tplg",
43362306a36Sopenharmony_ci	.ops = &sof_cht_ops,
43462306a36Sopenharmony_ci};
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic const struct acpi_device_id sof_baytrail_match[] = {
43762306a36Sopenharmony_ci	{ "80860F28", (unsigned long)&sof_acpi_baytrail_desc },
43862306a36Sopenharmony_ci	{ "808622A8", (unsigned long)&sof_acpi_cherrytrail_desc },
43962306a36Sopenharmony_ci	{ }
44062306a36Sopenharmony_ci};
44162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, sof_baytrail_match);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_cistatic int sof_baytrail_probe(struct platform_device *pdev)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
44662306a36Sopenharmony_ci	const struct sof_dev_desc *desc;
44762306a36Sopenharmony_ci	const struct acpi_device_id *id;
44862306a36Sopenharmony_ci	int ret;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	id = acpi_match_device(dev->driver->acpi_match_table, dev);
45162306a36Sopenharmony_ci	if (!id)
45262306a36Sopenharmony_ci		return -ENODEV;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
45562306a36Sopenharmony_ci	if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
45662306a36Sopenharmony_ci		dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
45762306a36Sopenharmony_ci		return -ENODEV;
45862306a36Sopenharmony_ci	}
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci	desc = (const struct sof_dev_desc *)id->driver_data;
46162306a36Sopenharmony_ci	if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev))
46262306a36Sopenharmony_ci		desc = &sof_acpi_baytrailcr_desc;
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	return sof_acpi_probe(pdev, desc);
46562306a36Sopenharmony_ci}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci/* acpi_driver definition */
46862306a36Sopenharmony_cistatic struct platform_driver snd_sof_acpi_intel_byt_driver = {
46962306a36Sopenharmony_ci	.probe = sof_baytrail_probe,
47062306a36Sopenharmony_ci	.remove = sof_acpi_remove,
47162306a36Sopenharmony_ci	.driver = {
47262306a36Sopenharmony_ci		.name = "sof-audio-acpi-intel-byt",
47362306a36Sopenharmony_ci		.pm = &sof_acpi_pm,
47462306a36Sopenharmony_ci		.acpi_match_table = sof_baytrail_match,
47562306a36Sopenharmony_ci	},
47662306a36Sopenharmony_ci};
47762306a36Sopenharmony_cimodule_platform_driver(snd_sof_acpi_intel_byt_driver);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
48062306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
48162306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
48262306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);
48362306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP);
484