* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#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"
return 0;
}
+EXPORT_SYMBOL_GPL(sst_alloc_drv_context);
int sst_context_init(struct intel_sst_drv *ctx)
{
return -EINVAL;
sst_init_locks(ctx);
+ sst_set_fw_state_locked(ctx, SST_RESET);
/* pvt_id 0 reserved for async messages */
ctx->pvt_id = 1;
}
pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
+
+ dev_dbg(ctx->dev, "Requesting FW %s now...\n", ctx->firmware_name);
+ ret = request_firmware_nowait(THIS_MODULE, true, ctx->firmware_name,
+ ctx->dev, GFP_KERNEL, ctx, sst_firmware_load_cb);
+ if (ret) {
+ dev_err(ctx->dev, "Firmware download failed:%d\n", ret);
+ goto do_free_mem;
+ }
+ sst_register(ctx->dev);
return 0;
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)
{
sst_memcpy_free_resources(ctx);
ctx = NULL;
}
+EXPORT_SYMBOL_GPL(sst_context_cleanup);
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)
{
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);
+EXPORT_SYMBOL_GPL(intel_sst_pm);
--- /dev/null
+/*
+ * 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;
+ snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
+ "%s%04x%s", "fw_sst_",
+ sst_drv_ctx->dev_id, ".bin");
+
+ ret = sst_context_init(sst_drv_ctx);
+ if (ret < 0)
+ return ret;
+
+ /* 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_free_drv_ctx;
+ }
+ sst_drv_ctx->pci = pci_dev_get(pci);
+ ret = sst_platform_get_resources(sst_drv_ctx);
+ if (ret < 0)
+ goto do_free_drv_ctx;
+
+ pci_set_drvdata(pci, sst_drv_ctx);
+ sst_configure_runtime_pm(sst_drv_ctx);
+
+ return ret;
+
+do_free_drv_ctx:
+ sst_context_cleanup(sst_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");