[alsa-devel] [PATCH v2 0/5] ASoC: Intel: ACPI support and machines
This is second rev of patch series which fixes the modules split as discussed in ML. The core part is now module along with PCI and ACPI one. Added fix reported by Dan as well. Also added the BYTCR machine driver
Subhransu S. Prusty (1): ASoC: Intel: add BYTCR machine driver with RT5640
Vinod Koul (4): ASoC: Intel: mrfld - remove unnecessary check for pointer ASoC: Intel: mrfld - create separate module for pci part ASoC: Intel: mrfld - add shim save restore ASoC: Intel: mrfld- add ACPI module
sound/soc/intel/Kconfig | 22 ++- sound/soc/intel/Makefile | 2 + sound/soc/intel/bytcr_dpcm_rt5640.c | 258 +++++++++++++++++++++++ sound/soc/intel/sst-atom-controls.c | 2 +- sound/soc/intel/sst/Makefile | 8 +- sound/soc/intel/sst/sst.c | 243 +++++----------------- sound/soc/intel/sst/sst.h | 9 +- sound/soc/intel/sst/sst_acpi.c | 386 +++++++++++++++++++++++++++++++++++ sound/soc/intel/sst/sst_pci.c | 225 ++++++++++++++++++++ sound/soc/intel/sst/sst_pvt.c | 2 + 10 files changed, 958 insertions(+), 199 deletions(-) create mode 100644 sound/soc/intel/bytcr_dpcm_rt5640.c create mode 100644 sound/soc/intel/sst/sst_acpi.c create mode 100644 sound/soc/intel/sst/sst_pci.c
the 'platform' pointer in sst_map_modules_to_pipe() is deref in caller function so we need to check for it in this function
Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/sst-atom-controls.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c index 309a8f3..90aa5c0 100644 --- a/sound/soc/intel/sst-atom-controls.c +++ b/sound/soc/intel/sst-atom-controls.c @@ -1351,7 +1351,7 @@ static int sst_map_modules_to_pipe(struct snd_soc_platform *platform) int ret = 0;
list_for_each_entry(w, &platform->component.card->widgets, list) { - if (platform && is_sst_dapm_widget(w) && (w->priv)) { + if (is_sst_dapm_widget(w) && (w->priv)) { struct sst_ids *ids = w->priv;
dev_dbg(platform->dev, "widget type=%d name=%s\n",
Now the SST_IPC will support both ACPI and PCI, separate into core module and PCI module. This also move probe function into PCI module and exports the required symbols from core module
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/Kconfig | 6 +- sound/soc/intel/sst/Makefile | 8 +- sound/soc/intel/sst/sst.c | 201 +----------------------------------- sound/soc/intel/sst/sst.h | 6 + sound/soc/intel/sst/sst_pci.c | 225 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+), 199 deletions(-) create mode 100644 sound/soc/intel/sst/sst_pci.c
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index ae7f872..c963a5d 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -3,7 +3,7 @@ config SND_MFLD_MACHINE depends on INTEL_SCU_IPC select SND_SOC_SN95031 select SND_SST_MFLD_PLATFORM - select SND_SST_IPC + select SND_SST_IPC_PCI help This adds support for ASoC machine driver for Intel(R) MID Medfield platform used as alsa device in audio substem in Intel(R) MID devices @@ -16,6 +16,10 @@ config SND_SST_MFLD_PLATFORM config SND_SST_IPC tristate
+config SND_SST_IPC_PCI + tristate + select SND_SST_IPC + config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/sst/Makefile index 4d0e79b..b8aa1d3 100644 --- a/sound/soc/intel/sst/Makefile +++ b/sound/soc/intel/sst/Makefile @@ -1,3 +1,7 @@ -snd-intel-sst-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o +snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o +snd-intel-sst-pci-objs += sst_pci.o + + +obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst-core.o +obj-$(CONFIG_SND_SST_IPC_PCI) += snd-intel-sst-pci.o
-obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst.o diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 2bfb404..1e9eda2 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -20,20 +20,14 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/module.h> -#include <linux/pci.h> #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/firmware.h> #include <linux/pm_runtime.h> #include <linux/pm_qos.h> #include <linux/async.h> -#include <linux/delay.h> -#include <linux/acpi.h> #include <sound/core.h> -#include <sound/pcm.h> #include <sound/soc.h> -#include <sound/compress_driver.h> -#include <asm/intel-mid.h> #include <asm/platform_sst_audio.h> #include "../sst-mfld-platform.h" #include "sst.h" @@ -242,6 +236,7 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx,
return 0; } +EXPORT_SYMBOL_GPL(sst_alloc_drv_context);
int sst_context_init(struct intel_sst_drv *ctx) { @@ -313,6 +308,7 @@ do_free_mem: destroy_workqueue(ctx->post_msg_wq); return ret; } +EXPORT_SYMBOL_GPL(sst_context_init);
void sst_context_cleanup(struct intel_sst_drv *ctx) { @@ -331,6 +327,7 @@ void sst_context_cleanup(struct intel_sst_drv *ctx) sst_memcpy_free_resources(ctx); ctx = NULL; } +EXPORT_SYMBOL_GPL(sst_context_cleanup);
void sst_configure_runtime_pm(struct intel_sst_drv *ctx) { @@ -339,175 +336,7 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) pm_runtime_allow(ctx->dev); pm_runtime_put_noidle(ctx->dev); } - -static int sst_platform_get_resources(struct intel_sst_drv *ctx) -{ - int ddr_base, ret = 0; - struct pci_dev *pci = ctx->pci; - ret = pci_request_regions(pci, SST_DRV_NAME); - if (ret) - return ret; - - /* map registers */ - /* DDR base */ - if (ctx->dev_id == SST_MRFLD_PCI_ID) { - ctx->ddr_base = pci_resource_start(pci, 0); - /* check that the relocated IMR base matches with FW Binary */ - ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base); - if (!ctx->pdata->lib_info) { - dev_err(ctx->dev, "lib_info pointer NULL\n"); - ret = -EINVAL; - goto do_release_regions; - } - if (ddr_base != ctx->pdata->lib_info->mod_base) { - dev_err(ctx->dev, - "FW LSP DDR BASE does not match with IFWI\n"); - ret = -EINVAL; - goto do_release_regions; - } - ctx->ddr_end = pci_resource_end(pci, 0); - - ctx->ddr = pcim_iomap(pci, 0, - pci_resource_len(pci, 0)); - if (!ctx->ddr) { - ret = -EINVAL; - goto do_release_regions; - } - dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr); - } else { - ctx->ddr = NULL; - } - /* SHIM */ - ctx->shim_phy_add = pci_resource_start(pci, 1); - ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); - if (!ctx->shim) { - ret = -EINVAL; - goto do_release_regions; - } - dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim); - - /* Shared SRAM */ - ctx->mailbox_add = pci_resource_start(pci, 2); - ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); - if (!ctx->mailbox) { - ret = -EINVAL; - goto do_release_regions; - } - dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox); - - /* IRAM */ - ctx->iram_end = pci_resource_end(pci, 3); - ctx->iram_base = pci_resource_start(pci, 3); - ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); - if (!ctx->iram) { - ret = -EINVAL; - goto do_release_regions; - } - dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram); - - /* DRAM */ - ctx->dram_end = pci_resource_end(pci, 4); - ctx->dram_base = pci_resource_start(pci, 4); - ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); - if (!ctx->dram) { - ret = -EINVAL; - goto do_release_regions; - } - dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); -do_release_regions: - pci_release_regions(pci); - return 0; -} -/* -* intel_sst_probe - PCI probe function -* -* @pci: PCI device structure -* @pci_id: PCI device ID structure -* -*/ -static int intel_sst_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - int ret = 0; - struct intel_sst_drv *sst_drv_ctx; - struct sst_platform_info *sst_pdata = pci->dev.platform_data; - - dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); - - ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); - if (ret < 0) - return ret; - - sst_drv_ctx->pdata = sst_pdata; - sst_drv_ctx->irq_num = pci->irq; - - ret = sst_context_init(sst_drv_ctx); - if (ret < 0) - goto do_free_drv_ctx; - - - /* Init the device */ - ret = pcim_enable_device(pci); - if (ret) { - dev_err(sst_drv_ctx->dev, - "device can't be enabled. Returned err: %d\n", ret); - goto do_destroy_wq; - } - sst_drv_ctx->pci = pci_dev_get(pci); - - ret = sst_platform_get_resources(sst_drv_ctx); - if (ret < 0) - goto do_destroy_wq; - - sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); - snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), - "%s%04x%s", "fw_sst_", - sst_drv_ctx->dev_id, ".bin"); - dev_dbg(sst_drv_ctx->dev, - "Requesting FW %s now...\n", sst_drv_ctx->firmware_name); - ret = request_firmware_nowait(THIS_MODULE, 1, - sst_drv_ctx->firmware_name, sst_drv_ctx->dev, - GFP_KERNEL, sst_drv_ctx, sst_firmware_load_cb); - - if (ret) { - dev_err(sst_drv_ctx->dev, - "Firmware load failed with error: %d\n", ret); - goto do_release_regions; - } - - - pci_set_drvdata(pci, sst_drv_ctx); - sst_configure_runtime_pm(sst_drv_ctx); - sst_register(sst_drv_ctx->dev); - - return ret; - -do_release_regions: - pci_release_regions(pci); -do_destroy_wq: - destroy_workqueue(sst_drv_ctx->post_msg_wq); -do_free_drv_ctx: - dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); - return ret; -} - -/** -* intel_sst_remove - PCI remove function -* -* @pci: PCI device structure -* -* This function is called by OS when a device is unloaded -* This frees the interrupt etc -*/ -static void intel_sst_remove(struct pci_dev *pci) -{ - struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); - - sst_context_cleanup(sst_drv_ctx); - pci_dev_put(sst_drv_ctx->pci); - pci_release_regions(pci); - pci_set_drvdata(pci, NULL); -} +EXPORT_SYMBOL_GPL(sst_configure_runtime_pm);
static int intel_sst_runtime_suspend(struct device *dev) { @@ -546,27 +375,7 @@ static int intel_sst_runtime_resume(struct device *dev) return ret; }
-static const struct dev_pm_ops intel_sst_pm = { +const struct dev_pm_ops intel_sst_pm = { .runtime_suspend = intel_sst_runtime_suspend, .runtime_resume = intel_sst_runtime_resume, }; - -/* PCI Routines */ -static struct pci_device_id intel_sst_ids[] = { - { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, - { 0, } -}; - -static struct pci_driver sst_driver = { - .name = SST_DRV_NAME, - .id_table = intel_sst_ids, - .probe = intel_sst_probe, - .remove = intel_sst_remove, -#ifdef CONFIG_PM - .driver = { - .pm = &intel_sst_pm, - }, -#endif -}; - -module_pci_driver(sst_driver); diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index b65b9c0..3ee555e 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h @@ -40,6 +40,7 @@ #define MRFLD_FW_FEATURE_BASE_OFFSET 0x4 #define MRFLD_FW_BSS_RESET_BIT 0
+extern const struct dev_pm_ops intel_sst_pm; enum sst_states { SST_FW_LOADING = 1, SST_FW_RUNNING, @@ -537,4 +538,9 @@ void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg, int sst_register(struct device *); int sst_unregister(struct device *);
+int sst_alloc_drv_context(struct intel_sst_drv **ctx, + struct device *dev, unsigned int dev_id); +int sst_context_init(struct intel_sst_drv *ctx); +void sst_context_cleanup(struct intel_sst_drv *ctx); +void sst_configure_runtime_pm(struct intel_sst_drv *ctx); #endif diff --git a/sound/soc/intel/sst/sst_pci.c b/sound/soc/intel/sst/sst_pci.c new file mode 100644 index 0000000..c7eb28b --- /dev/null +++ b/sound/soc/intel/sst/sst_pci.c @@ -0,0 +1,225 @@ +/* + * sst_pci.c - SST (LPE) driver init file for pci enumeration. + * + * Copyright (C) 2008-14 Intel Corp + * Authors: Vinod Koul vinod.koul@intel.com + * Harsha Priya priya.harsha@intel.com + * Dharageswari R dharageswari.r@intel.com + * KP Jeeja jeeja.kp@intel.com + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/fs.h> +#include <linux/firmware.h> +#include <linux/pm_runtime.h> +#include <sound/core.h> +#include <sound/soc.h> +#include <asm/platform_sst_audio.h> +#include "../sst-mfld-platform.h" +#include "sst.h" + +static int sst_platform_get_resources(struct intel_sst_drv *ctx) +{ + int ddr_base, ret = 0; + struct pci_dev *pci = ctx->pci; + + ret = pci_request_regions(pci, SST_DRV_NAME); + if (ret) + return ret; + + /* map registers */ + /* DDR base */ + if (ctx->dev_id == SST_MRFLD_PCI_ID) { + ctx->ddr_base = pci_resource_start(pci, 0); + /* check that the relocated IMR base matches with FW Binary */ + ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base); + if (!ctx->pdata->lib_info) { + dev_err(ctx->dev, "lib_info pointer NULL\n"); + ret = -EINVAL; + goto do_release_regions; + } + if (ddr_base != ctx->pdata->lib_info->mod_base) { + dev_err(ctx->dev, + "FW LSP DDR BASE does not match with IFWI\n"); + ret = -EINVAL; + goto do_release_regions; + } + ctx->ddr_end = pci_resource_end(pci, 0); + + ctx->ddr = pcim_iomap(pci, 0, + pci_resource_len(pci, 0)); + if (!ctx->ddr) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr); + } else { + ctx->ddr = NULL; + } + /* SHIM */ + ctx->shim_phy_add = pci_resource_start(pci, 1); + ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); + if (!ctx->shim) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim); + + /* Shared SRAM */ + ctx->mailbox_add = pci_resource_start(pci, 2); + ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); + if (!ctx->mailbox) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox); + + /* IRAM */ + ctx->iram_end = pci_resource_end(pci, 3); + ctx->iram_base = pci_resource_start(pci, 3); + ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); + if (!ctx->iram) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram); + + /* DRAM */ + ctx->dram_end = pci_resource_end(pci, 4); + ctx->dram_base = pci_resource_start(pci, 4); + ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); + if (!ctx->dram) { + ret = -EINVAL; + goto do_release_regions; + } + dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); +do_release_regions: + pci_release_regions(pci); + return 0; +} + +/* + * intel_sst_probe - PCI probe function + * + * @pci: PCI device structure + * @pci_id: PCI device ID structure + * + */ +static int intel_sst_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + int ret = 0; + struct intel_sst_drv *sst_drv_ctx; + struct sst_platform_info *sst_pdata = pci->dev.platform_data; + + dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); + ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); + if (ret < 0) + return ret; + + sst_drv_ctx->pdata = sst_pdata; + sst_drv_ctx->irq_num = pci->irq; + ret = sst_context_init(sst_drv_ctx); + if (ret < 0) + goto do_free_drv_ctx; + + /* Init the device */ + ret = pcim_enable_device(pci); + if (ret) { + dev_err(sst_drv_ctx->dev, + "device can't be enabled. Returned err: %d\n", ret); + goto do_destroy_wq; + } + sst_drv_ctx->pci = pci_dev_get(pci); + ret = sst_platform_get_resources(sst_drv_ctx); + if (ret < 0) + goto do_destroy_wq; + + sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); + snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), + "%s%04x%s", "fw_sst_", + sst_drv_ctx->dev_id, ".bin"); + dev_dbg(sst_drv_ctx->dev, + "Requesting FW %s now...\n", sst_drv_ctx->firmware_name); + ret = request_firmware_nowait(THIS_MODULE, 1, + sst_drv_ctx->firmware_name, sst_drv_ctx->dev, + GFP_KERNEL, sst_drv_ctx, sst_firmware_load_cb); + + if (ret) { + dev_err(sst_drv_ctx->dev, + "Firmware load failed with error: %d\n", ret); + goto do_release_regions; + } + + pci_set_drvdata(pci, sst_drv_ctx); + sst_configure_runtime_pm(sst_drv_ctx); + sst_register(sst_drv_ctx->dev); + + return ret; + +do_release_regions: + pci_release_regions(pci); +do_destroy_wq: + destroy_workqueue(sst_drv_ctx->post_msg_wq); +do_free_drv_ctx: + dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); + return ret; +} + +/** + * intel_sst_remove - PCI remove function + * + * @pci: PCI device structure + * + * This function is called by OS when a device is unloaded + * This frees the interrupt etc + */ +static void intel_sst_remove(struct pci_dev *pci) +{ + struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); + + sst_context_cleanup(sst_drv_ctx); + pci_dev_put(sst_drv_ctx->pci); + pci_release_regions(pci); + pci_set_drvdata(pci, NULL); +} + +/* PCI Routines */ +static struct pci_device_id intel_sst_ids[] = { + { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, + { 0, } +}; + +static struct pci_driver sst_driver = { + .name = SST_DRV_NAME, + .id_table = intel_sst_ids, + .probe = intel_sst_probe, + .remove = intel_sst_remove, +#ifdef CONFIG_PM + .driver = { + .pm = &intel_sst_pm, + }, +#endif +}; + +module_pci_driver(sst_driver); + +MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver"); +MODULE_AUTHOR("Vinod Koul vinod.koul@intel.com"); +MODULE_AUTHOR("Harsha Priya priya.harsha@intel.com"); +MODULE_AUTHOR("Dharageswari R dharageswari.r@intel.com"); +MODULE_AUTHOR("KP Jeeja jeeja.kp@intel.com"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("sst");
In ACPI platform we need to save few registers of Shim on suspend and restore them on resume, so add handlers to do this
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/sst/sst.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 1e9eda2..67c7c29 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -329,6 +329,34 @@ void sst_context_cleanup(struct intel_sst_drv *ctx) } EXPORT_SYMBOL_GPL(sst_context_cleanup);
+static inline void sst_save_shim64(struct intel_sst_drv *ctx, + void __iomem *shim, + struct sst_shim_regs64 *shim_regs) +{ + unsigned long irq_flags; + + spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); + + shim_regs->imrx = sst_shim_read64(shim, SST_IMRX), + + spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); +} + +static inline void sst_restore_shim64(struct intel_sst_drv *ctx, + void __iomem *shim, + struct sst_shim_regs64 *shim_regs) +{ + unsigned long irq_flags; + + /* + * we only need to restore IMRX for this case, rest will be + * initialize by FW or driver when firmware is loaded + */ + spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags); + sst_shim_write64(shim, SST_IMRX, shim_regs->imrx), + spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags); +} + void sst_configure_runtime_pm(struct intel_sst_drv *ctx) { pm_runtime_set_autosuspend_delay(ctx->dev, SST_SUSPEND_DELAY);
Add the last ACPI module support which also uses core module like the PCI part
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/Kconfig | 4 + sound/soc/intel/sst/Makefile | 4 +- sound/soc/intel/sst/sst.c | 20 ++ sound/soc/intel/sst/sst.h | 3 +- sound/soc/intel/sst/sst_acpi.c | 386 ++++++++++++++++++++++++++++++++++++++++ sound/soc/intel/sst/sst_pvt.c | 2 + 6 files changed, 415 insertions(+), 4 deletions(-) create mode 100644 sound/soc/intel/sst/sst_acpi.c
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index c963a5d..edff4a3 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -20,6 +20,10 @@ config SND_SST_IPC_PCI tristate select SND_SST_IPC
+config SND_SST_IPC_ACPI + tristate + select SND_SST_IPC + config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/sst/Makefile index b8aa1d3..fd21726 100644 --- a/sound/soc/intel/sst/Makefile +++ b/sound/soc/intel/sst/Makefile @@ -1,7 +1,7 @@ snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o snd-intel-sst-pci-objs += sst_pci.o - +snd-intel-sst-acpi-objs += sst_acpi.o
obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst-core.o obj-$(CONFIG_SND_SST_IPC_PCI) += snd-intel-sst-pci.o - +obj-$(CONFIG_SND_SST_IPC_ACPI) += snd-intel-sst-acpi.o diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c index 67c7c29..f180f1d 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c @@ -181,6 +181,7 @@ int sst_driver_ops(struct intel_sst_drv *sst)
switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: sst->tstamp = SST_TIME_STAMP_MRFLD; sst->ops = &mrfld_ops; return 0; @@ -313,7 +314,11 @@ EXPORT_SYMBOL_GPL(sst_context_init); void sst_context_cleanup(struct intel_sst_drv *ctx) { pm_runtime_get_noresume(ctx->dev); +#if IS_ENABLED(CONFIG_ACPI) + pm_runtime_disable(ctx->dev); +#else pm_runtime_forbid(ctx->dev); +#endif sst_unregister(ctx->dev); sst_set_fw_state_locked(ctx, SST_SHUTDOWN); flush_scheduled_work(); @@ -361,8 +366,19 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) { pm_runtime_set_autosuspend_delay(ctx->dev, SST_SUSPEND_DELAY); pm_runtime_use_autosuspend(ctx->dev); +#if IS_ENABLED(CONFIG_ACPI) + /* + * For acpi devices, the actual physical device state is + * initially active. So change the state to active before + * enabling the pm + */ + pm_runtime_set_active(ctx->dev); + pm_runtime_enable(ctx->dev); + sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); +#else pm_runtime_allow(ctx->dev); pm_runtime_put_noidle(ctx->dev); +#endif } EXPORT_SYMBOL_GPL(sst_configure_runtime_pm);
@@ -385,6 +401,10 @@ static int intel_sst_runtime_suspend(struct device *dev) synchronize_irq(ctx->irq_num); flush_workqueue(ctx->post_msg_wq);
+ /* save the shim registers because PMC doesn't save state */ + if (ctx->dev_id == SST_BYT_ACPI_ID) + sst_save_shim64(ctx, ctx->shim, ctx->shim_regs64); + return ret; }
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index 3ee555e..683dc71 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h @@ -29,6 +29,7 @@ /* driver names */ #define SST_DRV_NAME "intel_sst_driver" #define SST_MRFLD_PCI_ID 0x119A +#define SST_BYT_ACPI_ID 0x80860F28
#define SST_SUSPEND_DELAY 2000 #define FW_CONTEXT_MEM (64*1024) @@ -508,8 +509,6 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst, size_t mbox_data_len, const void *mbox_data, void **data, bool large, bool fill_dsp, bool sync, bool response);
-void sst_save_shim64(struct intel_sst_drv *ctx, void __iomem *shim, - struct sst_shim_regs64 *shim_regs); void sst_process_pending_msg(struct work_struct *work); int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx); void sst_init_stream(struct stream_info *stream, diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/sst/sst_acpi.c new file mode 100644 index 0000000..3bd7c8e --- /dev/null +++ b/sound/soc/intel/sst/sst_acpi.c @@ -0,0 +1,386 @@ +/* + * sst_acpi.c - SST (LPE) driver init file for ACPI enumeration. + * + * Copyright (c) 2013, Intel Corporation. + * + * Authors: Ramesh Babu K V Ramesh.Babu@intel.com + * Authors: Omair Mohammed Abdullah omair.m.abdullah@intel.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/miscdevice.h> +#include <linux/platform_device.h> +#include <linux/firmware.h> +#include <linux/pm_runtime.h> +#include <linux/pm_qos.h> +#include <linux/acpi.h> +#include <asm/platform_sst_audio.h> +#include <sound/core.h> +#include <sound/soc.h> +#include <sound/compress_driver.h> +#include <acpi/acbuffer.h> +#include <acpi/platform/acenv.h> +#include <acpi/platform/aclinux.h> +#include <acpi/actypes.h> +#include <acpi/acpi_bus.h> +#include "../sst-mfld-platform.h" +#include "../sst-dsp.h" +#include "sst.h" + +struct sst_machines { + char codec_id[32]; + char board[32]; + char machine[32]; + void (*machine_quirk)(void); + char firmware[32]; + struct sst_platform_info *pdata; + +}; + +/* LPE viewpoint addresses */ +#define SST_BYT_IRAM_PHY_START 0xff2c0000 +#define SST_BYT_IRAM_PHY_END 0xff2d4000 +#define SST_BYT_DRAM_PHY_START 0xff300000 +#define SST_BYT_DRAM_PHY_END 0xff320000 +#define SST_BYT_IMR_VIRT_START 0xc0000000 /* virtual addr in LPE */ +#define SST_BYT_IMR_VIRT_END 0xc01fffff +#define SST_BYT_SHIM_PHY_ADDR 0xff340000 +#define SST_BYT_MBOX_PHY_ADDR 0xff344000 +#define SST_BYT_DMA0_PHY_ADDR 0xff298000 +#define SST_BYT_DMA1_PHY_ADDR 0xff29c000 +#define SST_BYT_SSP0_PHY_ADDR 0xff2a0000 +#define SST_BYT_SSP2_PHY_ADDR 0xff2a2000 + +#define BYT_FW_MOD_TABLE_OFFSET 0x80000 +#define BYT_FW_MOD_TABLE_SIZE 0x100 +#define BYT_FW_MOD_OFFSET (BYT_FW_MOD_TABLE_OFFSET + BYT_FW_MOD_TABLE_SIZE) + +static const struct sst_info byt_fwparse_info = { + .use_elf = false, + .max_streams = 25, + .iram_start = SST_BYT_IRAM_PHY_START, + .iram_end = SST_BYT_IRAM_PHY_END, + .iram_use = true, + .dram_start = SST_BYT_DRAM_PHY_START, + .dram_end = SST_BYT_DRAM_PHY_END, + .dram_use = true, + .imr_start = SST_BYT_IMR_VIRT_START, + .imr_end = SST_BYT_IMR_VIRT_END, + .imr_use = true, + .mailbox_start = SST_BYT_MBOX_PHY_ADDR, + .num_probes = 0, + .lpe_viewpt_rqd = true, +}; + +static const struct sst_ipc_info byt_ipc_info = { + .ipc_offset = 0, + .mbox_recv_off = 0x400, +}; + +static const struct sst_lib_dnld_info byt_lib_dnld_info = { + .mod_base = SST_BYT_IMR_VIRT_START, + .mod_end = SST_BYT_IMR_VIRT_END, + .mod_table_offset = BYT_FW_MOD_TABLE_OFFSET, + .mod_table_size = BYT_FW_MOD_TABLE_SIZE, + .mod_ddr_dnld = false, +}; + +static const struct sst_res_info byt_rvp_res_info = { + .shim_offset = 0x140000, + .shim_size = 0x000100, + .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, + .ssp0_offset = 0xa0000, + .ssp0_size = 0x1000, + .dma0_offset = 0x98000, + .dma0_size = 0x4000, + .dma1_offset = 0x9c000, + .dma1_size = 0x4000, + .iram_offset = 0x0c0000, + .iram_size = 0x14000, + .dram_offset = 0x100000, + .dram_size = 0x28000, + .mbox_offset = 0x144000, + .mbox_size = 0x1000, + .acpi_lpe_res_index = 0, + .acpi_ddr_index = 2, + .acpi_ipc_irq_index = 5, +}; + +struct sst_platform_info byt_rvp_platform_data = { + .probe_data = &byt_fwparse_info, + .ipc_info = &byt_ipc_info, + .lib_info = &byt_lib_dnld_info, + .res_info = &byt_rvp_res_info, + .platform = "sst-mfld-platform", +}; + +#if IS_ENABLED(CONFIG_ACPI) +static int sst_platform_get_resources(struct intel_sst_drv *ctx) +{ + struct resource *rsrc; + struct platform_device *pdev = to_platform_device(ctx->dev); + + /* All ACPI resource request here */ + /* Get Shim addr */ + rsrc = platform_get_resource(pdev, IORESOURCE_MEM, + ctx->pdata->res_info->acpi_lpe_res_index); + if (!rsrc) { + dev_err(ctx->dev, "Invalid SHIM base from IFWI"); + return -EIO; + } + dev_info(ctx->dev, "LPE base: %#x size:%#x", (unsigned int) rsrc->start, + (unsigned int)resource_size(rsrc)); + + ctx->iram_base = rsrc->start + ctx->pdata->res_info->iram_offset; + ctx->iram_end = ctx->iram_base + ctx->pdata->res_info->iram_size - 1; + dev_info(ctx->dev, "IRAM base: %#x", ctx->iram_base); + ctx->iram = devm_ioremap_nocache(ctx->dev, ctx->iram_base, + ctx->pdata->res_info->iram_size); + if (!ctx->iram) { + dev_err(ctx->dev, "unable to map IRAM"); + return -EIO; + } + + ctx->dram_base = rsrc->start + ctx->pdata->res_info->dram_offset; + ctx->dram_end = ctx->dram_base + ctx->pdata->res_info->dram_size - 1; + dev_info(ctx->dev, "DRAM base: %#x", ctx->dram_base); + ctx->dram = devm_ioremap_nocache(ctx->dev, ctx->dram_base, + ctx->pdata->res_info->dram_size); + if (!ctx->dram) { + dev_err(ctx->dev, "unable to map DRAM"); + return -EIO; + } + + ctx->shim_phy_add = rsrc->start + ctx->pdata->res_info->shim_offset; + dev_info(ctx->dev, "SHIM base: %#x", ctx->shim_phy_add); + ctx->shim = devm_ioremap_nocache(ctx->dev, ctx->shim_phy_add, + ctx->pdata->res_info->shim_size); + if (!ctx->shim) { + dev_err(ctx->dev, "unable to map SHIM"); + return -EIO; + } + + /* reassign physical address to LPE viewpoint address */ + ctx->shim_phy_add = ctx->pdata->res_info->shim_phy_addr; + + /* Get mailbox addr */ + ctx->mailbox_add = rsrc->start + ctx->pdata->res_info->mbox_offset; + dev_info(ctx->dev, "Mailbox base: %#x", ctx->mailbox_add); + ctx->mailbox = devm_ioremap_nocache(ctx->dev, ctx->mailbox_add, + ctx->pdata->res_info->mbox_size); + if (!ctx->mailbox) { + dev_err(ctx->dev, "unable to map mailbox"); + return -EIO; + } + + /* reassign physical address to LPE viewpoint address */ + ctx->mailbox_add = ctx->info.mailbox_start; + + rsrc = platform_get_resource(pdev, IORESOURCE_MEM, + ctx->pdata->res_info->acpi_ddr_index); + if (!rsrc) { + dev_err(ctx->dev, "Invalid DDR base from IFWI"); + return -EIO; + } + ctx->ddr_base = rsrc->start; + ctx->ddr_end = rsrc->end; + dev_info(ctx->dev, "DDR base: %#x", ctx->ddr_base); + ctx->ddr = devm_ioremap_nocache(ctx->dev, ctx->ddr_base, + resource_size(rsrc)); + if (!ctx->ddr) { + dev_err(ctx->dev, "unable to map DDR"); + return -EIO; + } + + /* Find the IRQ */ + ctx->irq_num = platform_get_irq(pdev, + ctx->pdata->res_info->acpi_ipc_irq_index); + return 0; +} + +static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level, + void *context, void **ret) +{ + *(bool *)context = true; + return AE_OK; +} + +static struct sst_machines *sst_acpi_find_machine( + struct sst_machines *machines) +{ + struct sst_machines *mach; + bool found = false; + + for (mach = machines; mach->codec_id; mach++) + if (ACPI_SUCCESS(acpi_get_devices(mach->codec_id, + sst_acpi_mach_match, + &found, NULL)) && found) + return mach; + + return NULL; +} + +int sst_acpi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret = 0; + struct intel_sst_drv *ctx; + const struct acpi_device_id *id; + struct sst_machines *mach; + struct platform_device *mdev; + struct platform_device *plat_dev; + unsigned int dev_id; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return -ENODEV; + dev_dbg(dev, "for %s", id->id); + + mach = (struct sst_machines *)id->driver_data; + mach = sst_acpi_find_machine(mach); + if (mach == NULL) { + dev_err(dev, "No matching machine driver found\n"); + return -ENODEV; + } + + ret = kstrtouint(id->id, 16, &dev_id); + if (ret < 0) { + dev_err(dev, "Unique device id conversion error: %d\n", ret); + return ret; + } + + dev_dbg(dev, "ACPI device id: %x\n", dev_id); + + plat_dev = platform_device_register_data(dev, mach->pdata->platform, -1, NULL, 0); + if (plat_dev == NULL) { + dev_err(dev, "Failed to create machine device: %s\n", mach->pdata->platform); + return -ENODEV; + } + + /* Create platform device for sst machine driver */ + mdev = platform_device_register_data(dev, mach->machine, -1, NULL, 0); + if (mdev == NULL) { + dev_err(dev, "Failed to create machine device: %s\n", mach->machine); + return -ENODEV; + } + + ret = sst_alloc_drv_context(&ctx, dev, dev_id); + if (ret < 0) + return ret; + + /* Fill sst platform data */ + ctx->pdata = mach->pdata; + strcpy(ctx->firmware_name, mach->firmware); + + ret = sst_platform_get_resources(ctx); + if (ret) + return ret; + + ret = sst_context_init(ctx); + if (ret < 0) + goto free_sst; + + /* need to save shim registers in BYT */ + ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64), + GFP_KERNEL); + if (!ctx->shim_regs64) + return -ENOMEM; + + sst_set_fw_state_locked(ctx, SST_RESET); + + ret = request_firmware_nowait(THIS_MODULE, true, mach->firmware, + dev, GFP_KERNEL, ctx, sst_firmware_load_cb); + if (ret) { + dev_err(ctx->dev, "Firmware download failed:%d\n", ret); + goto do_sst_cleanup; + } + + sst_configure_runtime_pm(ctx); + sst_register(dev); + platform_set_drvdata(pdev, ctx); + return ret; + +do_sst_cleanup: + destroy_workqueue(ctx->post_msg_wq); +free_sst: + platform_set_drvdata(pdev, NULL); + dev_err(ctx->dev, "failed with %d\n", ret); + return ret; +} + +/** +* intel_sst_remove - remove function +* +* @pdev: platform device structure +* +* This function is called by OS when a device is unloaded +* This frees the interrupt etc +*/ +int sst_acpi_remove(struct platform_device *pdev) +{ + struct intel_sst_drv *ctx; + + ctx = platform_get_drvdata(pdev); + sst_context_cleanup(ctx); + platform_set_drvdata(pdev, NULL); + return 0; +} + +#else +int sst_acpi_probe(struct platform_device *pdev) +{ + return -EINVAL; +} + +int sst_acpi_remove(struct platform_device *pdev) +{ + return -EINVAL; +} +#endif + +static struct sst_machines sst_acpi_bytcr[] = { + {"10EC5640", "T100", "bytt100_rt5640", NULL, "fw_sst_0f28.bin", + &byt_rvp_platform_data }, + {}, +}; + +static const struct acpi_device_id sst_acpi_ids[] = { + { "80860F28", (unsigned long)&sst_acpi_bytcr}, + { }, +}; + +static struct platform_driver sst_acpi_driver = { + .driver = { + .name = "intel_sst_acpi", + .owner = THIS_MODULE, + .acpi_match_table = ACPI_PTR(sst_acpi_ids), + .pm = &intel_sst_pm, + }, + .probe = sst_acpi_probe, + .remove = sst_acpi_remove, +}; + +module_platform_driver(sst_acpi_driver); + +MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine ACPI Driver"); +MODULE_AUTHOR("Ramesh Babu K V"); +MODULE_AUTHOR("Omair Mohammed Abdullah"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("sst"); diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/sst/sst_pvt.c index 1c2e081..e8efdd0 100644 --- a/sound/soc/intel/sst/sst_pvt.c +++ b/sound/soc/intel/sst/sst_pvt.c @@ -117,6 +117,7 @@ unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr)
switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: val = sst_shim_read64(sst->shim, addr); break; } @@ -128,6 +129,7 @@ void write_shim_data(struct intel_sst_drv *sst, int addr, { switch (sst->dev_id) { case SST_MRFLD_PCI_ID: + case SST_BYT_ACPI_ID: sst_shim_write64(sst->shim, addr, (u64) data); break; }
From: Subhransu S. Prusty subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com --- sound/soc/intel/Kconfig | 12 ++ sound/soc/intel/Makefile | 2 + sound/soc/intel/bytcr_dpcm_rt5640.c | 258 +++++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+), 0 deletions(-) create mode 100644 sound/soc/intel/bytcr_dpcm_rt5640.c
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index edff4a3..a8ccc3d 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -85,3 +85,15 @@ config SND_SOC_INTEL_BROADWELL_MACH Ultrabook platforms. Say Y if you have such a device If unsure select "N". + +config SND_SOC_INTEL_BYTCR_RT5640_MACH + tristate "ASoC Audio DSP Support for MID BYT Platform" + depends on X86 + select SND_SOC_RT5640 + select SND_SST_MFLD_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) MID Baytrail platform + used as alsa device in audio substem in Intel(R) MID devices + Say Y if you have such a device + If unsure select "N". diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index 9ab43be..fbde4b0 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -26,11 +26,13 @@ snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o snd-soc-sst-broadwell-objs := broadwell.o +snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o
obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o +obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o
# DSP driver obj-$(CONFIG_SND_SST_IPC) += sst/ diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/bytcr_dpcm_rt5640.c new file mode 100644 index 0000000..8a15bce --- /dev/null +++ b/sound/soc/intel/bytcr_dpcm_rt5640.c @@ -0,0 +1,258 @@ +/* + * byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform + * + * Copyright (C) 2014 Intel Corp + * Author: Subhransu S. Prusty subhransu.s.prusty@intel.com + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/gpio.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include "../codecs/rt5640.h" +#include "sst-atom-controls.h" + +static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static const struct snd_soc_dapm_route byt_audio_map[] = { + {"IN2P", NULL, "Headset Mic"}, + {"IN2N", NULL, "Headset Mic"}, + {"Headset Mic", NULL, "MICBIAS1"}, + {"IN1P", NULL, "MICBIAS1"}, + {"LDO2", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Ext Spk", NULL, "SPOLP"}, + {"Ext Spk", NULL, "SPOLN"}, + {"Ext Spk", NULL, "SPORP"}, + {"Ext Spk", NULL, "SPORN"}, + + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_kcontrol_new byt_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static int byt_aif1_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 = rtd->codec_dai; + int ret; + + if (strncmp(codec_dai->name, "rt5640-aif1", 11)) + return 0; + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec clock %d\n", ret); + return ret; + } + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1, + params_rate(params) * 50, + params_rate(params) * 512); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + snd_soc_dai_set_bclk_ratio(codec_dai, 50); + return 0; +} + +static const struct snd_soc_pcm_stream byt_dai_params = { + .formats = SNDRV_PCM_FMTBIT_S24_LE, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, +}; +static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd, + 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); + + /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - + SNDRV_PCM_HW_PARAM_FIRST_MASK], + SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + +static unsigned int rates_48000[] = { + 48000, +}; + +static struct snd_pcm_hw_constraint_list constraints_48000 = { + .count = ARRAY_SIZE(rates_48000), + .list = rates_48000, +}; + +static int byt_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_48000); +} + +static struct snd_soc_ops byt_aif1_ops = { + .startup = byt_aif1_startup, +}; + +static struct snd_soc_ops byt_be_ssp2_ops = { + .hw_params = byt_aif1_hw_params, +}; + +static struct snd_soc_dai_link byt_dailink[] = { + [MERR_DPCM_AUDIO] = { + .name = "Baytrail Audio Port", + .stream_name = "Baytrail Audio", + .cpu_dai_name = "media-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .ignore_suspend = 1, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_aif1_ops, + }, + [MERR_DPCM_COMPR] = { + .name = "Baytrail Compressed Port", + .stream_name = "Baytrail Compress", + .cpu_dai_name = "compress-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + }, + /* back ends */ + { + .name = "SSP2-Codec", + .be_id = 1, + .cpu_dai_name = "ssp2-port", + .platform_name = "sst-mfld-platform", + .no_pcm = 1, + .codec_dai_name = "rt5640-aif1", + .codec_name = "i2c-10EC5640:00", + .dai_fmt = SND_SOC_DAIFMT_I2S| SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .be_hw_params_fixup = byt_codec_fixup, + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &byt_be_ssp2_ops, + }, +}; + +#ifdef CONFIG_PM_SLEEP +static int snd_byt_prepare(struct device *dev) +{ + return snd_soc_suspend(dev); +} + +static void snd_byt_complete(struct device *dev) +{ + snd_soc_resume(dev); +} + +static int snd_byt_poweroff(struct device *dev) +{ + return snd_soc_poweroff(dev); +} +#else +#define snd_byt_prepare NULL +#define snd_byt_complete NULL +#define snd_byt_poweroff NULL +#endif + +/* SoC card */ +static struct snd_soc_card snd_soc_card_byt = { + .name = "baytrailcraudio", + .dai_link = byt_dailink, + .num_links = ARRAY_SIZE(byt_dailink), + .dapm_widgets = byt_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(byt_dapm_widgets), + .dapm_routes = byt_audio_map, + .num_dapm_routes = ARRAY_SIZE(byt_audio_map), + .controls = byt_mc_controls, + .num_controls = ARRAY_SIZE(byt_mc_controls), +}; + +static int snd_byt_mc_probe(struct platform_device *pdev) +{ + int ret_val = 0; + + /* register the soc card */ + snd_soc_card_byt.dev = &pdev->dev; + + ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_byt); + if (ret_val) { + dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &snd_soc_card_byt); + return ret_val; +} + +static const struct dev_pm_ops snd_byt_mc_pm_ops = { + .prepare = snd_byt_prepare, + .complete = snd_byt_complete, + .poweroff = snd_byt_poweroff, +}; + +static struct platform_driver snd_byt_mc_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "bytt100_rt5640", + .pm = &snd_byt_mc_pm_ops, + }, + .probe = snd_byt_mc_probe, +}; + +module_platform_driver(snd_byt_mc_driver); + +MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); +MODULE_AUTHOR("Subhransu S. Prusty subhransu.s.prusty@intel.com"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:bytrt5640-audio");
On 11/04/2014 07:31 AM, Vinod Koul wrote:
From: Subhransu S. Prusty subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com
sound/soc/intel/Kconfig | 12 ++ sound/soc/intel/Makefile | 2 + sound/soc/intel/bytcr_dpcm_rt5640.c | 258 +++++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+), 0 deletions(-) create mode 100644 sound/soc/intel/bytcr_dpcm_rt5640.c
...
+static const struct snd_kcontrol_new byt_mc_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
- SOC_DAPM_PIN_SWITCH("Int Mic"),
- SOC_DAPM_PIN_SWITCH("Ext Spk"),
+};
...
+static struct snd_soc_dai_link byt_dailink[] = {
- [MERR_DPCM_AUDIO] = {
.name = "Baytrail Audio Port",
.stream_name = "Baytrail Audio",
...
+/* SoC card */ +static struct snd_soc_card snd_soc_card_byt = {
- .name = "baytrailcraudio",
I think it's worth to have same kcontrol and card names than byt-rt5640 in case this is going to replace byt-rt5640.c since then users can continue to use the same asound.state file. E.g. speakers won't mute because of "Speaker" changes to "Ext Spk".
On Tue, Nov 04, 2014 at 11:19:10AM +0200, Jarkko Nikula wrote:
On 11/04/2014 07:31 AM, Vinod Koul wrote:
From: Subhransu S. Prusty subhransu.s.prusty@intel.com
Signed-off-by: Subhransu S. Prusty subhransu.s.prusty@intel.com Signed-off-by: Vinod Koul vinod.koul@intel.com
sound/soc/intel/Kconfig | 12 ++ sound/soc/intel/Makefile | 2 + sound/soc/intel/bytcr_dpcm_rt5640.c | 258 +++++++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+), 0 deletions(-) create mode 100644 sound/soc/intel/bytcr_dpcm_rt5640.c
...
+static const struct snd_kcontrol_new byt_mc_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
- SOC_DAPM_PIN_SWITCH("Int Mic"),
- SOC_DAPM_PIN_SWITCH("Ext Spk"),
+};
...
+static struct snd_soc_dai_link byt_dailink[] = {
- [MERR_DPCM_AUDIO] = {
.name = "Baytrail Audio Port",
.stream_name = "Baytrail Audio",
...
+/* SoC card */ +static struct snd_soc_card snd_soc_card_byt = {
- .name = "baytrailcraudio",
I think it's worth to have same kcontrol and card names than byt-rt5640 in case this is going to replace byt-rt5640.c since then users can continue to use the same asound.state file. E.g. speakers won't mute because of "Speaker" changes to "Ext Spk".
It would have helped if the DSP controls were not there. The DSP controls need to be routed too, so existing conf files would need to be updated.
So, do you still recommend changing :)
On 11/04/2014 11:32 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 11:19:10AM +0200, Jarkko Nikula wrote:
I think it's worth to have same kcontrol and card names than byt-rt5640 in case this is going to replace byt-rt5640.c since then users can continue to use the same asound.state file. E.g. speakers won't mute because of "Speaker" changes to "Ext Spk".
It would have helped if the DSP controls were not there. The DSP controls need to be routed too, so existing conf files would need to be updated.
So, do you still recommend changing :)
Do new controls affect PCM pass through? I was thinking if they affect only compressed streams then it'd be useful if existing state files continue working for PCM pass through. It's always painful if kcontol name changes render audio muted and user have to go through gazillions of kcontrols :-(
On Wed, Nov 05, 2014 at 09:54:59AM +0200, Jarkko Nikula wrote:
On 11/04/2014 11:32 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 11:19:10AM +0200, Jarkko Nikula wrote:
I think it's worth to have same kcontrol and card names than byt-rt5640 in case this is going to replace byt-rt5640.c since then users can continue to use the same asound.state file. E.g. speakers won't mute because of "Speaker" changes to "Ext Spk".
It would have helped if the DSP controls were not there. The DSP controls need to be routed too, so existing conf files would need to be updated.
So, do you still recommend changing :)
Do new controls affect PCM pass through? I was thinking if they affect only compressed streams then it'd be useful if existing state files continue working for PCM pass through. It's always painful if kcontol name changes render audio muted and user have to go through gazillions of kcontrols :-(
Yes they do and yes we have large number of controls :( Plus there are some algorithms like EQ etc which can be programmed using kcontrols
On 11/04/2014 07:31 AM, Vinod Koul wrote:
This is second rev of patch series which fixes the modules split as discussed in ML. The core part is now module along with PCI and ACPI one. Added fix reported by Dan as well. Also added the BYTCR machine driver
Subhransu S. Prusty (1): ASoC: Intel: add BYTCR machine driver with RT5640
Vinod Koul (4): ASoC: Intel: mrfld - remove unnecessary check for pointer ASoC: Intel: mrfld - create separate module for pci part ASoC: Intel: mrfld - add shim save restore ASoC: Intel: mrfld- add ACPI module
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
One difference at the moment is that byt-rt5640 machines out there have differences in audio routings but those are not too difficult to handle in the same machine driver.
Bigger question how to handle platform part? I.e. can these use the same drivers and ADSP firmware? If they can, is the firmware available for distributions to take?
Optimally all machines out there would use the same drivers and get support for compressed audio but meanwhile we should not break existing machines.
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
On 11/04/2014 07:31 AM, Vinod Koul wrote:
This is second rev of patch series which fixes the modules split as discussed in ML. The core part is now module along with PCI and ACPI one. Added fix reported by Dan as well. Also added the BYTCR machine driver
Subhransu S. Prusty (1): ASoC: Intel: add BYTCR machine driver with RT5640
Vinod Koul (4): ASoC: Intel: mrfld - remove unnecessary check for pointer ASoC: Intel: mrfld - create separate module for pci part ASoC: Intel: mrfld - add shim save restore ASoC: Intel: mrfld- add ACPI module
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
Liam's suggestion was to remove the current driver when all the bits are upstream
One difference at the moment is that byt-rt5640 machines out there have differences in audio routings but those are not too difficult to handle in the same machine driver.
Bigger question how to handle platform part? I.e. can these use the same drivers and ADSP firmware? If they can, is the firmware available for distributions to take?
The two firmware are *not* compatible and that is the big reason why we can't reuse the parts available
Optimally all machines out there would use the same drivers and get support for compressed audio but meanwhile we should not break existing machines.
Yes, I have tested this one on T100 and doesn't seem to break anything. Please do test and revert if you find issues on any other available board (I don't have any other board)
Hi
On 11/04/2014 10:25 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
Liam's suggestion was to remove the current driver when all the bits are upstream
Yeah, I'm not against it but we must avoid regressions and perhaps try to do seamless handover if possible. It's always more nice to find regression in a small than big patch when bisecting :-)
One difference at the moment is that byt-rt5640 machines out there have differences in audio routings but those are not too difficult to handle in the same machine driver.
Bigger question how to handle platform part? I.e. can these use the same drivers and ADSP firmware? If they can, is the firmware available for distributions to take?
The two firmware are *not* compatible and that is the big reason why we can't reuse the parts available
Ok, so firmware appears to works on other than CR Baytrails too. Is it available in linux-firmware since if it's not when changing the platform drivers there will be obvious regressions to users?
Optimally all machines out there would use the same drivers and get support for compressed audio but meanwhile we should not break existing machines.
Yes, I have tested this one on T100 and doesn't seem to break anything. Please do test and revert if you find issues on any other available board (I don't have any other board)
Well, those audio routing differences require to have DMI quirks. E.g. T100 has analogue internal mic, Dell Venue 8 Pro 5830 has digital mic connected to DMIC2 of the RT564x and some have it connected to DMIC1.
On Tue, 2014-11-04 at 11:05 +0200, Jarkko Nikula wrote:
Hi
On 11/04/2014 10:25 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
Liam's suggestion was to remove the current driver when all the bits are upstream
I think we need to keep the original driver around a bit longer until the new driver is stable on rambi and other platforms the old driver supports atm. A that point we can depricate the original driver with a view to eventual removal.
Yeah, I'm not against it but we must avoid regressions and perhaps try to do seamless handover if possible. It's always more nice to find regression in a small than big patch when bisecting :-)
Liam
--------------------------------------------------------------------- Intel Corporation (UK) Limited Registered No. 1134945 (England) Registered Office: Pipers Way, Swindon SN3 1RJ VAT No: 860 2173 47
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
On Tue, Nov 04, 2014 at 09:15:10AM +0000, Liam Girdwood wrote:
On Tue, 2014-11-04 at 11:05 +0200, Jarkko Nikula wrote:
Hi
On 11/04/2014 10:25 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
Liam's suggestion was to remove the current driver when all the bits are upstream
I think we need to keep the original driver around a bit longer until the new driver is stable on rambi and other platforms the old driver supports atm. A that point we can depricate the original driver with a view to eventual removal.
Yes agreed, taht would help
On Tue, Nov 04, 2014 at 11:05:34AM +0200, Jarkko Nikula wrote:
Hi
On 11/04/2014 10:25 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
I think there is need to have some consolidation with current byt-rt5640 and byt-max98090. Since existing drivers and this set are using the same ACPI IDs "80860F28" for the ADSP and "10EC5640" codec ACPIID for the machine driver probing these drivers won't work together.
Liam's suggestion was to remove the current driver when all the bits are upstream
Yeah, I'm not against it but we must avoid regressions and perhaps try to do seamless handover if possible. It's always more nice to find regression in a small than big patch when bisecting :-)
One difference at the moment is that byt-rt5640 machines out there have differences in audio routings but those are not too difficult to handle in the same machine driver.
Bigger question how to handle platform part? I.e. can these use the same drivers and ADSP firmware? If they can, is the firmware available for distributions to take?
The two firmware are *not* compatible and that is the big reason why we can't reuse the parts available
Ok, so firmware appears to works on other than CR Baytrails too. Is it available in linux-firmware since if it's not when changing the platform drivers there will be obvious regressions to users?
I will send it this week, was focusing on getting the code done, whcih is now mostly complete.
On Tue, Nov 04, 2014 at 11:05:34AM +0200, Jarkko Nikula wrote:
On 11/04/2014 10:25 AM, Vinod Koul wrote:
On Tue, Nov 04, 2014 at 10:09:40AM +0200, Jarkko Nikula wrote:
One difference at the moment is that byt-rt5640 machines out there have differences in audio routings but those are not too difficult to handle in the same machine driver.
Bigger question how to handle platform part? I.e. can these use the same drivers and ADSP firmware? If they can, is the firmware available for distributions to take?
The two firmware are *not* compatible and that is the big reason why we can't reuse the parts available
Ok, so firmware appears to works on other than CR Baytrails too. Is it available in linux-firmware since if it's not when changing the platform drivers there will be obvious regressions to users?
Can we take a step back here: what are the firmwares and hardware platforms we're talking about here?
Yes, I have tested this one on T100 and doesn't seem to break anything. Please do test and revert if you find issues on any other available board (I don't have any other board)
Well, those audio routing differences require to have DMI quirks. E.g. T100 has analogue internal mic, Dell Venue 8 Pro 5830 has digital mic connected to DMIC2 of the RT564x and some have it connected to DMIC1.
Are any of these things on sale at the minute? Looks like T100 and the Dell both are but I'm not sure if they're current or previous models.
On 11/04/2014 01:15 PM, Mark Brown wrote:
Ok, so firmware appears to works on other than CR Baytrails too. Is it available in linux-firmware since if it's not when changing the platform drivers there will be obvious regressions to users?
Can we take a step back here: what are the firmwares and hardware platforms we're talking about here?
Only Baytrail and its variants. Current upstreamed drivers use "intel/fw_sst_0f28.bin-48kHz_i2s_master" but that FW doesn't have as much features like compressed audio and is not compatible with the one Vinod's team is upstreaming.
Goal is to switch to new implementation since it covers more platforms but do switchover as seamlessly as possible for Baytrail. Problem at the moment for Baytrail that both current and new drivers probe using the same ACPIIDs and FW for new drivers is not yet in linux-firmware.
Well, those audio routing differences require to have DMI quirks. E.g. T100 has analogue internal mic, Dell Venue 8 Pro 5830 has digital mic connected to DMIC2 of the RT564x and some have it connected to DMIC1.
Are any of these things on sale at the minute? Looks like T100 and the Dell both are but I'm not sure if they're current or previous models.
T100 and Dell are. Third known audio routing difference is used in reference design so I guess that setup is found on some models too. Then there are byt-max98090 based Chromebooks that use current drivers and FW.
On Wed, Nov 05, 2014 at 09:49:35AM +0200, Jarkko Nikula wrote:
On 11/04/2014 01:15 PM, Mark Brown wrote:
Ok, so firmware appears to works on other than CR Baytrails too. Is it available in linux-firmware since if it's not when changing the platform drivers there will be obvious regressions to users?
Can we take a step back here: what are the firmwares and hardware platforms we're talking about here?
Only Baytrail and its variants. Current upstreamed drivers use "intel/fw_sst_0f28.bin-48kHz_i2s_master" but that FW doesn't have as much features like compressed audio and is not compatible with the one Vinod's team is upstreaming.
Goal is to switch to new implementation since it covers more platforms but do switchover as seamlessly as possible for Baytrail. Problem at the moment for Baytrail that both current and new drivers probe using the same ACPIIDs and FW for new drivers is not yet in linux-firmware.
Shouldn't that be okay, as user wouldn't select the new driver. Default is n :)
Only when driver is stable and verfied by users should we enable this and then start removing older driver
participants (4)
-
Jarkko Nikula
-
Liam Girdwood
-
Mark Brown
-
Vinod Koul