diff options
-rw-r--r-- | sound/soc/intel/Kconfig | 6 | ||||
-rw-r--r-- | sound/soc/intel/sst/Makefile | 8 | ||||
-rw-r--r-- | sound/soc/intel/sst/sst.c | 212 | ||||
-rw-r--r-- | sound/soc/intel/sst/sst.h | 6 | ||||
-rw-r--r-- | sound/soc/intel/sst/sst_pci.c | 209 | ||||
-rw-r--r-- | sound/soc/intel/sst/sst_pvt.c | 1 |
6 files changed, 243 insertions, 199 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index ae7f87221a3c..c963a5d34111 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -3,7 +3,7 @@ config SND_MFLD_MACHINE | |||
3 | depends on INTEL_SCU_IPC | 3 | depends on INTEL_SCU_IPC |
4 | select SND_SOC_SN95031 | 4 | select SND_SOC_SN95031 |
5 | select SND_SST_MFLD_PLATFORM | 5 | select SND_SST_MFLD_PLATFORM |
6 | select SND_SST_IPC | 6 | select SND_SST_IPC_PCI |
7 | help | 7 | help |
8 | This adds support for ASoC machine driver for Intel(R) MID Medfield platform | 8 | This adds support for ASoC machine driver for Intel(R) MID Medfield platform |
9 | used as alsa device in audio substem in Intel(R) MID devices | 9 | used as alsa device in audio substem in Intel(R) MID devices |
@@ -16,6 +16,10 @@ config SND_SST_MFLD_PLATFORM | |||
16 | config SND_SST_IPC | 16 | config SND_SST_IPC |
17 | tristate | 17 | tristate |
18 | 18 | ||
19 | config SND_SST_IPC_PCI | ||
20 | tristate | ||
21 | select SND_SST_IPC | ||
22 | |||
19 | config SND_SOC_INTEL_SST | 23 | config SND_SOC_INTEL_SST |
20 | tristate "ASoC support for Intel(R) Smart Sound Technology" | 24 | tristate "ASoC support for Intel(R) Smart Sound Technology" |
21 | select SND_SOC_INTEL_SST_ACPI if ACPI | 25 | select SND_SOC_INTEL_SST_ACPI if ACPI |
diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/sst/Makefile index 4d0e79b1f8ce..b8aa1d35df74 100644 --- a/sound/soc/intel/sst/Makefile +++ b/sound/soc/intel/sst/Makefile | |||
@@ -1,3 +1,7 @@ | |||
1 | snd-intel-sst-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o | 1 | snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o |
2 | snd-intel-sst-pci-objs += sst_pci.o | ||
3 | |||
4 | |||
5 | obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst-core.o | ||
6 | obj-$(CONFIG_SND_SST_IPC_PCI) += snd-intel-sst-pci.o | ||
2 | 7 | ||
3 | 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 2bfb404ea7c1..875375485989 100644 --- a/sound/soc/intel/sst/sst.c +++ b/sound/soc/intel/sst/sst.c | |||
@@ -20,20 +20,14 @@ | |||
20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
21 | */ | 21 | */ |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/pci.h> | ||
24 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
25 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
26 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
28 | #include <linux/pm_qos.h> | 27 | #include <linux/pm_qos.h> |
29 | #include <linux/async.h> | 28 | #include <linux/async.h> |
30 | #include <linux/delay.h> | ||
31 | #include <linux/acpi.h> | ||
32 | #include <sound/core.h> | 29 | #include <sound/core.h> |
33 | #include <sound/pcm.h> | ||
34 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
35 | #include <sound/compress_driver.h> | ||
36 | #include <asm/intel-mid.h> | ||
37 | #include <asm/platform_sst_audio.h> | 31 | #include <asm/platform_sst_audio.h> |
38 | #include "../sst-mfld-platform.h" | 32 | #include "../sst-mfld-platform.h" |
39 | #include "sst.h" | 33 | #include "sst.h" |
@@ -242,6 +236,7 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx, | |||
242 | 236 | ||
243 | return 0; | 237 | return 0; |
244 | } | 238 | } |
239 | EXPORT_SYMBOL_GPL(sst_alloc_drv_context); | ||
245 | 240 | ||
246 | int sst_context_init(struct intel_sst_drv *ctx) | 241 | int sst_context_init(struct intel_sst_drv *ctx) |
247 | { | 242 | { |
@@ -260,6 +255,7 @@ int sst_context_init(struct intel_sst_drv *ctx) | |||
260 | return -EINVAL; | 255 | return -EINVAL; |
261 | 256 | ||
262 | sst_init_locks(ctx); | 257 | sst_init_locks(ctx); |
258 | sst_set_fw_state_locked(ctx, SST_RESET); | ||
263 | 259 | ||
264 | /* pvt_id 0 reserved for async messages */ | 260 | /* pvt_id 0 reserved for async messages */ |
265 | ctx->pvt_id = 1; | 261 | ctx->pvt_id = 1; |
@@ -307,12 +303,22 @@ int sst_context_init(struct intel_sst_drv *ctx) | |||
307 | } | 303 | } |
308 | pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY, | 304 | pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY, |
309 | PM_QOS_DEFAULT_VALUE); | 305 | PM_QOS_DEFAULT_VALUE); |
306 | |||
307 | dev_dbg(ctx->dev, "Requesting FW %s now...\n", ctx->firmware_name); | ||
308 | ret = request_firmware_nowait(THIS_MODULE, true, ctx->firmware_name, | ||
309 | ctx->dev, GFP_KERNEL, ctx, sst_firmware_load_cb); | ||
310 | if (ret) { | ||
311 | dev_err(ctx->dev, "Firmware download failed:%d\n", ret); | ||
312 | goto do_free_mem; | ||
313 | } | ||
314 | sst_register(ctx->dev); | ||
310 | return 0; | 315 | return 0; |
311 | 316 | ||
312 | do_free_mem: | 317 | do_free_mem: |
313 | destroy_workqueue(ctx->post_msg_wq); | 318 | destroy_workqueue(ctx->post_msg_wq); |
314 | return ret; | 319 | return ret; |
315 | } | 320 | } |
321 | EXPORT_SYMBOL_GPL(sst_context_init); | ||
316 | 322 | ||
317 | void sst_context_cleanup(struct intel_sst_drv *ctx) | 323 | void sst_context_cleanup(struct intel_sst_drv *ctx) |
318 | { | 324 | { |
@@ -331,6 +337,7 @@ void sst_context_cleanup(struct intel_sst_drv *ctx) | |||
331 | sst_memcpy_free_resources(ctx); | 337 | sst_memcpy_free_resources(ctx); |
332 | ctx = NULL; | 338 | ctx = NULL; |
333 | } | 339 | } |
340 | EXPORT_SYMBOL_GPL(sst_context_cleanup); | ||
334 | 341 | ||
335 | void sst_configure_runtime_pm(struct intel_sst_drv *ctx) | 342 | void sst_configure_runtime_pm(struct intel_sst_drv *ctx) |
336 | { | 343 | { |
@@ -339,175 +346,7 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx) | |||
339 | pm_runtime_allow(ctx->dev); | 346 | pm_runtime_allow(ctx->dev); |
340 | pm_runtime_put_noidle(ctx->dev); | 347 | pm_runtime_put_noidle(ctx->dev); |
341 | } | 348 | } |
342 | 349 | EXPORT_SYMBOL_GPL(sst_configure_runtime_pm); | |
343 | static int sst_platform_get_resources(struct intel_sst_drv *ctx) | ||
344 | { | ||
345 | int ddr_base, ret = 0; | ||
346 | struct pci_dev *pci = ctx->pci; | ||
347 | ret = pci_request_regions(pci, SST_DRV_NAME); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | |||
351 | /* map registers */ | ||
352 | /* DDR base */ | ||
353 | if (ctx->dev_id == SST_MRFLD_PCI_ID) { | ||
354 | ctx->ddr_base = pci_resource_start(pci, 0); | ||
355 | /* check that the relocated IMR base matches with FW Binary */ | ||
356 | ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base); | ||
357 | if (!ctx->pdata->lib_info) { | ||
358 | dev_err(ctx->dev, "lib_info pointer NULL\n"); | ||
359 | ret = -EINVAL; | ||
360 | goto do_release_regions; | ||
361 | } | ||
362 | if (ddr_base != ctx->pdata->lib_info->mod_base) { | ||
363 | dev_err(ctx->dev, | ||
364 | "FW LSP DDR BASE does not match with IFWI\n"); | ||
365 | ret = -EINVAL; | ||
366 | goto do_release_regions; | ||
367 | } | ||
368 | ctx->ddr_end = pci_resource_end(pci, 0); | ||
369 | |||
370 | ctx->ddr = pcim_iomap(pci, 0, | ||
371 | pci_resource_len(pci, 0)); | ||
372 | if (!ctx->ddr) { | ||
373 | ret = -EINVAL; | ||
374 | goto do_release_regions; | ||
375 | } | ||
376 | dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr); | ||
377 | } else { | ||
378 | ctx->ddr = NULL; | ||
379 | } | ||
380 | /* SHIM */ | ||
381 | ctx->shim_phy_add = pci_resource_start(pci, 1); | ||
382 | ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); | ||
383 | if (!ctx->shim) { | ||
384 | ret = -EINVAL; | ||
385 | goto do_release_regions; | ||
386 | } | ||
387 | dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim); | ||
388 | |||
389 | /* Shared SRAM */ | ||
390 | ctx->mailbox_add = pci_resource_start(pci, 2); | ||
391 | ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); | ||
392 | if (!ctx->mailbox) { | ||
393 | ret = -EINVAL; | ||
394 | goto do_release_regions; | ||
395 | } | ||
396 | dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox); | ||
397 | |||
398 | /* IRAM */ | ||
399 | ctx->iram_end = pci_resource_end(pci, 3); | ||
400 | ctx->iram_base = pci_resource_start(pci, 3); | ||
401 | ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); | ||
402 | if (!ctx->iram) { | ||
403 | ret = -EINVAL; | ||
404 | goto do_release_regions; | ||
405 | } | ||
406 | dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram); | ||
407 | |||
408 | /* DRAM */ | ||
409 | ctx->dram_end = pci_resource_end(pci, 4); | ||
410 | ctx->dram_base = pci_resource_start(pci, 4); | ||
411 | ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); | ||
412 | if (!ctx->dram) { | ||
413 | ret = -EINVAL; | ||
414 | goto do_release_regions; | ||
415 | } | ||
416 | dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); | ||
417 | do_release_regions: | ||
418 | pci_release_regions(pci); | ||
419 | return 0; | ||
420 | } | ||
421 | /* | ||
422 | * intel_sst_probe - PCI probe function | ||
423 | * | ||
424 | * @pci: PCI device structure | ||
425 | * @pci_id: PCI device ID structure | ||
426 | * | ||
427 | */ | ||
428 | static int intel_sst_probe(struct pci_dev *pci, | ||
429 | const struct pci_device_id *pci_id) | ||
430 | { | ||
431 | int ret = 0; | ||
432 | struct intel_sst_drv *sst_drv_ctx; | ||
433 | struct sst_platform_info *sst_pdata = pci->dev.platform_data; | ||
434 | |||
435 | dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); | ||
436 | |||
437 | ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); | ||
438 | if (ret < 0) | ||
439 | return ret; | ||
440 | |||
441 | sst_drv_ctx->pdata = sst_pdata; | ||
442 | sst_drv_ctx->irq_num = pci->irq; | ||
443 | |||
444 | ret = sst_context_init(sst_drv_ctx); | ||
445 | if (ret < 0) | ||
446 | goto do_free_drv_ctx; | ||
447 | |||
448 | |||
449 | /* Init the device */ | ||
450 | ret = pcim_enable_device(pci); | ||
451 | if (ret) { | ||
452 | dev_err(sst_drv_ctx->dev, | ||
453 | "device can't be enabled. Returned err: %d\n", ret); | ||
454 | goto do_destroy_wq; | ||
455 | } | ||
456 | sst_drv_ctx->pci = pci_dev_get(pci); | ||
457 | |||
458 | ret = sst_platform_get_resources(sst_drv_ctx); | ||
459 | if (ret < 0) | ||
460 | goto do_destroy_wq; | ||
461 | |||
462 | sst_set_fw_state_locked(sst_drv_ctx, SST_RESET); | ||
463 | snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), | ||
464 | "%s%04x%s", "fw_sst_", | ||
465 | sst_drv_ctx->dev_id, ".bin"); | ||
466 | dev_dbg(sst_drv_ctx->dev, | ||
467 | "Requesting FW %s now...\n", sst_drv_ctx->firmware_name); | ||
468 | ret = request_firmware_nowait(THIS_MODULE, 1, | ||
469 | sst_drv_ctx->firmware_name, sst_drv_ctx->dev, | ||
470 | GFP_KERNEL, sst_drv_ctx, sst_firmware_load_cb); | ||
471 | |||
472 | if (ret) { | ||
473 | dev_err(sst_drv_ctx->dev, | ||
474 | "Firmware load failed with error: %d\n", ret); | ||
475 | goto do_release_regions; | ||
476 | } | ||
477 | |||
478 | |||
479 | pci_set_drvdata(pci, sst_drv_ctx); | ||
480 | sst_configure_runtime_pm(sst_drv_ctx); | ||
481 | sst_register(sst_drv_ctx->dev); | ||
482 | |||
483 | return ret; | ||
484 | |||
485 | do_release_regions: | ||
486 | pci_release_regions(pci); | ||
487 | do_destroy_wq: | ||
488 | destroy_workqueue(sst_drv_ctx->post_msg_wq); | ||
489 | do_free_drv_ctx: | ||
490 | dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | /** | ||
495 | * intel_sst_remove - PCI remove function | ||
496 | * | ||
497 | * @pci: PCI device structure | ||
498 | * | ||
499 | * This function is called by OS when a device is unloaded | ||
500 | * This frees the interrupt etc | ||
501 | */ | ||
502 | static void intel_sst_remove(struct pci_dev *pci) | ||
503 | { | ||
504 | struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); | ||
505 | |||
506 | sst_context_cleanup(sst_drv_ctx); | ||
507 | pci_dev_put(sst_drv_ctx->pci); | ||
508 | pci_release_regions(pci); | ||
509 | pci_set_drvdata(pci, NULL); | ||
510 | } | ||
511 | 350 | ||
512 | static int intel_sst_runtime_suspend(struct device *dev) | 351 | static int intel_sst_runtime_suspend(struct device *dev) |
513 | { | 352 | { |
@@ -546,27 +385,8 @@ static int intel_sst_runtime_resume(struct device *dev) | |||
546 | return ret; | 385 | return ret; |
547 | } | 386 | } |
548 | 387 | ||
549 | static const struct dev_pm_ops intel_sst_pm = { | 388 | const struct dev_pm_ops intel_sst_pm = { |
550 | .runtime_suspend = intel_sst_runtime_suspend, | 389 | .runtime_suspend = intel_sst_runtime_suspend, |
551 | .runtime_resume = intel_sst_runtime_resume, | 390 | .runtime_resume = intel_sst_runtime_resume, |
552 | }; | 391 | }; |
553 | 392 | EXPORT_SYMBOL_GPL(intel_sst_pm); | |
554 | /* PCI Routines */ | ||
555 | static struct pci_device_id intel_sst_ids[] = { | ||
556 | { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, | ||
557 | { 0, } | ||
558 | }; | ||
559 | |||
560 | static struct pci_driver sst_driver = { | ||
561 | .name = SST_DRV_NAME, | ||
562 | .id_table = intel_sst_ids, | ||
563 | .probe = intel_sst_probe, | ||
564 | .remove = intel_sst_remove, | ||
565 | #ifdef CONFIG_PM | ||
566 | .driver = { | ||
567 | .pm = &intel_sst_pm, | ||
568 | }, | ||
569 | #endif | ||
570 | }; | ||
571 | |||
572 | module_pci_driver(sst_driver); | ||
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/sst/sst.h index b65b9c0d8750..3ee555e31716 100644 --- a/sound/soc/intel/sst/sst.h +++ b/sound/soc/intel/sst/sst.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #define MRFLD_FW_FEATURE_BASE_OFFSET 0x4 | 40 | #define MRFLD_FW_FEATURE_BASE_OFFSET 0x4 |
41 | #define MRFLD_FW_BSS_RESET_BIT 0 | 41 | #define MRFLD_FW_BSS_RESET_BIT 0 |
42 | 42 | ||
43 | extern const struct dev_pm_ops intel_sst_pm; | ||
43 | enum sst_states { | 44 | enum sst_states { |
44 | SST_FW_LOADING = 1, | 45 | SST_FW_LOADING = 1, |
45 | SST_FW_RUNNING, | 46 | SST_FW_RUNNING, |
@@ -537,4 +538,9 @@ void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg, | |||
537 | int sst_register(struct device *); | 538 | int sst_register(struct device *); |
538 | int sst_unregister(struct device *); | 539 | int sst_unregister(struct device *); |
539 | 540 | ||
541 | int sst_alloc_drv_context(struct intel_sst_drv **ctx, | ||
542 | struct device *dev, unsigned int dev_id); | ||
543 | int sst_context_init(struct intel_sst_drv *ctx); | ||
544 | void sst_context_cleanup(struct intel_sst_drv *ctx); | ||
545 | void sst_configure_runtime_pm(struct intel_sst_drv *ctx); | ||
540 | #endif | 546 | #endif |
diff --git a/sound/soc/intel/sst/sst_pci.c b/sound/soc/intel/sst/sst_pci.c new file mode 100644 index 000000000000..3a0b3bf0af97 --- /dev/null +++ b/sound/soc/intel/sst/sst_pci.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * sst_pci.c - SST (LPE) driver init file for pci enumeration. | ||
3 | * | ||
4 | * Copyright (C) 2008-14 Intel Corp | ||
5 | * Authors: Vinod Koul <vinod.koul@intel.com> | ||
6 | * Harsha Priya <priya.harsha@intel.com> | ||
7 | * Dharageswari R <dharageswari.r@intel.com> | ||
8 | * KP Jeeja <jeeja.kp@intel.com> | ||
9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; version 2 of the License. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but | ||
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | * General Public License for more details. | ||
19 | * | ||
20 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
21 | */ | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/fs.h> | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/pm_runtime.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <asm/platform_sst_audio.h> | ||
30 | #include "../sst-mfld-platform.h" | ||
31 | #include "sst.h" | ||
32 | |||
33 | static int sst_platform_get_resources(struct intel_sst_drv *ctx) | ||
34 | { | ||
35 | int ddr_base, ret = 0; | ||
36 | struct pci_dev *pci = ctx->pci; | ||
37 | |||
38 | ret = pci_request_regions(pci, SST_DRV_NAME); | ||
39 | if (ret) | ||
40 | return ret; | ||
41 | |||
42 | /* map registers */ | ||
43 | /* DDR base */ | ||
44 | if (ctx->dev_id == SST_MRFLD_PCI_ID) { | ||
45 | ctx->ddr_base = pci_resource_start(pci, 0); | ||
46 | /* check that the relocated IMR base matches with FW Binary */ | ||
47 | ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base); | ||
48 | if (!ctx->pdata->lib_info) { | ||
49 | dev_err(ctx->dev, "lib_info pointer NULL\n"); | ||
50 | ret = -EINVAL; | ||
51 | goto do_release_regions; | ||
52 | } | ||
53 | if (ddr_base != ctx->pdata->lib_info->mod_base) { | ||
54 | dev_err(ctx->dev, | ||
55 | "FW LSP DDR BASE does not match with IFWI\n"); | ||
56 | ret = -EINVAL; | ||
57 | goto do_release_regions; | ||
58 | } | ||
59 | ctx->ddr_end = pci_resource_end(pci, 0); | ||
60 | |||
61 | ctx->ddr = pcim_iomap(pci, 0, | ||
62 | pci_resource_len(pci, 0)); | ||
63 | if (!ctx->ddr) { | ||
64 | ret = -EINVAL; | ||
65 | goto do_release_regions; | ||
66 | } | ||
67 | dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr); | ||
68 | } else { | ||
69 | ctx->ddr = NULL; | ||
70 | } | ||
71 | /* SHIM */ | ||
72 | ctx->shim_phy_add = pci_resource_start(pci, 1); | ||
73 | ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1)); | ||
74 | if (!ctx->shim) { | ||
75 | ret = -EINVAL; | ||
76 | goto do_release_regions; | ||
77 | } | ||
78 | dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim); | ||
79 | |||
80 | /* Shared SRAM */ | ||
81 | ctx->mailbox_add = pci_resource_start(pci, 2); | ||
82 | ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2)); | ||
83 | if (!ctx->mailbox) { | ||
84 | ret = -EINVAL; | ||
85 | goto do_release_regions; | ||
86 | } | ||
87 | dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox); | ||
88 | |||
89 | /* IRAM */ | ||
90 | ctx->iram_end = pci_resource_end(pci, 3); | ||
91 | ctx->iram_base = pci_resource_start(pci, 3); | ||
92 | ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3)); | ||
93 | if (!ctx->iram) { | ||
94 | ret = -EINVAL; | ||
95 | goto do_release_regions; | ||
96 | } | ||
97 | dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram); | ||
98 | |||
99 | /* DRAM */ | ||
100 | ctx->dram_end = pci_resource_end(pci, 4); | ||
101 | ctx->dram_base = pci_resource_start(pci, 4); | ||
102 | ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4)); | ||
103 | if (!ctx->dram) { | ||
104 | ret = -EINVAL; | ||
105 | goto do_release_regions; | ||
106 | } | ||
107 | dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram); | ||
108 | do_release_regions: | ||
109 | pci_release_regions(pci); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * intel_sst_probe - PCI probe function | ||
115 | * | ||
116 | * @pci: PCI device structure | ||
117 | * @pci_id: PCI device ID structure | ||
118 | * | ||
119 | */ | ||
120 | static int intel_sst_probe(struct pci_dev *pci, | ||
121 | const struct pci_device_id *pci_id) | ||
122 | { | ||
123 | int ret = 0; | ||
124 | struct intel_sst_drv *sst_drv_ctx; | ||
125 | struct sst_platform_info *sst_pdata = pci->dev.platform_data; | ||
126 | |||
127 | dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device); | ||
128 | ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device); | ||
129 | if (ret < 0) | ||
130 | return ret; | ||
131 | |||
132 | sst_drv_ctx->pdata = sst_pdata; | ||
133 | sst_drv_ctx->irq_num = pci->irq; | ||
134 | snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name), | ||
135 | "%s%04x%s", "fw_sst_", | ||
136 | sst_drv_ctx->dev_id, ".bin"); | ||
137 | |||
138 | ret = sst_context_init(sst_drv_ctx); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | /* Init the device */ | ||
143 | ret = pcim_enable_device(pci); | ||
144 | if (ret) { | ||
145 | dev_err(sst_drv_ctx->dev, | ||
146 | "device can't be enabled. Returned err: %d\n", ret); | ||
147 | goto do_free_drv_ctx; | ||
148 | } | ||
149 | sst_drv_ctx->pci = pci_dev_get(pci); | ||
150 | ret = sst_platform_get_resources(sst_drv_ctx); | ||
151 | if (ret < 0) | ||
152 | goto do_free_drv_ctx; | ||
153 | |||
154 | pci_set_drvdata(pci, sst_drv_ctx); | ||
155 | sst_configure_runtime_pm(sst_drv_ctx); | ||
156 | |||
157 | return ret; | ||
158 | |||
159 | do_free_drv_ctx: | ||
160 | sst_context_cleanup(sst_drv_ctx); | ||
161 | dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * intel_sst_remove - PCI remove function | ||
167 | * | ||
168 | * @pci: PCI device structure | ||
169 | * | ||
170 | * This function is called by OS when a device is unloaded | ||
171 | * This frees the interrupt etc | ||
172 | */ | ||
173 | static void intel_sst_remove(struct pci_dev *pci) | ||
174 | { | ||
175 | struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); | ||
176 | |||
177 | sst_context_cleanup(sst_drv_ctx); | ||
178 | pci_dev_put(sst_drv_ctx->pci); | ||
179 | pci_release_regions(pci); | ||
180 | pci_set_drvdata(pci, NULL); | ||
181 | } | ||
182 | |||
183 | /* PCI Routines */ | ||
184 | static struct pci_device_id intel_sst_ids[] = { | ||
185 | { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, | ||
186 | { 0, } | ||
187 | }; | ||
188 | |||
189 | static struct pci_driver sst_driver = { | ||
190 | .name = SST_DRV_NAME, | ||
191 | .id_table = intel_sst_ids, | ||
192 | .probe = intel_sst_probe, | ||
193 | .remove = intel_sst_remove, | ||
194 | #ifdef CONFIG_PM | ||
195 | .driver = { | ||
196 | .pm = &intel_sst_pm, | ||
197 | }, | ||
198 | #endif | ||
199 | }; | ||
200 | |||
201 | module_pci_driver(sst_driver); | ||
202 | |||
203 | MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver"); | ||
204 | MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); | ||
205 | MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); | ||
206 | MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>"); | ||
207 | MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>"); | ||
208 | MODULE_LICENSE("GPL v2"); | ||
209 | MODULE_ALIAS("sst"); | ||
diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/sst/sst_pvt.c index 1c2e081fd813..9a5df1936516 100644 --- a/sound/soc/intel/sst/sst_pvt.c +++ b/sound/soc/intel/sst/sst_pvt.c | |||
@@ -433,6 +433,7 @@ u32 relocate_imr_addr_mrfld(u32 base_addr) | |||
433 | base_addr = MRFLD_FW_VIRTUAL_BASE + (base_addr % (512 * 1024 * 1024)); | 433 | base_addr = MRFLD_FW_VIRTUAL_BASE + (base_addr % (512 * 1024 * 1024)); |
434 | return base_addr; | 434 | return base_addr; |
435 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(relocate_imr_addr_mrfld); | ||
436 | 437 | ||
437 | void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst, | 438 | void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst, |
438 | struct ipc_post *msg) | 439 | struct ipc_post *msg) |