1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/module.h>
15#include <linux/pci.h>
16#include <linux/fs.h>
17#include <linux/firmware.h>
18#include <linux/pm_runtime.h>
19#include <sound/core.h>
20#include <sound/soc.h>
21#include <asm/platform_sst_audio.h>
22#include "../sst-mfld-platform.h"
23#include "sst.h"
24
25static int sst_platform_get_resources(struct intel_sst_drv *ctx)
26{
27 int ddr_base, ret = 0;
28 struct pci_dev *pci = ctx->pci;
29
30 ret = pci_request_regions(pci, SST_DRV_NAME);
31 if (ret)
32 return ret;
33
34
35
36 if (ctx->dev_id == SST_MRFLD_PCI_ID) {
37 ctx->ddr_base = pci_resource_start(pci, 0);
38
39 ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
40 if (!ctx->pdata->lib_info) {
41 dev_err(ctx->dev, "lib_info pointer NULL\n");
42 ret = -EINVAL;
43 goto do_release_regions;
44 }
45 if (ddr_base != ctx->pdata->lib_info->mod_base) {
46 dev_err(ctx->dev,
47 "FW LSP DDR BASE does not match with IFWI\n");
48 ret = -EINVAL;
49 goto do_release_regions;
50 }
51 ctx->ddr_end = pci_resource_end(pci, 0);
52
53 ctx->ddr = pcim_iomap(pci, 0,
54 pci_resource_len(pci, 0));
55 if (!ctx->ddr) {
56 ret = -EINVAL;
57 goto do_release_regions;
58 }
59 dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
60 } else {
61 ctx->ddr = NULL;
62 }
63
64 ctx->shim_phy_add = pci_resource_start(pci, 1);
65 ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
66 if (!ctx->shim) {
67 ret = -EINVAL;
68 goto do_release_regions;
69 }
70 dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
71
72
73 ctx->mailbox_add = pci_resource_start(pci, 2);
74 ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
75 if (!ctx->mailbox) {
76 ret = -EINVAL;
77 goto do_release_regions;
78 }
79 dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
80
81
82 ctx->iram_end = pci_resource_end(pci, 3);
83 ctx->iram_base = pci_resource_start(pci, 3);
84 ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
85 if (!ctx->iram) {
86 ret = -EINVAL;
87 goto do_release_regions;
88 }
89 dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
90
91
92 ctx->dram_end = pci_resource_end(pci, 4);
93 ctx->dram_base = pci_resource_start(pci, 4);
94 ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
95 if (!ctx->dram) {
96 ret = -EINVAL;
97 goto do_release_regions;
98 }
99 dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
100do_release_regions:
101 pci_release_regions(pci);
102 return 0;
103}
104
105
106
107
108
109
110
111
112static int intel_sst_probe(struct pci_dev *pci,
113 const struct pci_device_id *pci_id)
114{
115 int ret = 0;
116 struct intel_sst_drv *sst_drv_ctx;
117 struct sst_platform_info *sst_pdata = pci->dev.platform_data;
118
119 dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
120 ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
121 if (ret < 0)
122 return ret;
123
124 sst_drv_ctx->pdata = sst_pdata;
125 sst_drv_ctx->irq_num = pci->irq;
126 snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
127 "%s%04x%s", "fw_sst_",
128 sst_drv_ctx->dev_id, ".bin");
129
130 ret = sst_context_init(sst_drv_ctx);
131 if (ret < 0)
132 return ret;
133
134
135 ret = pcim_enable_device(pci);
136 if (ret) {
137 dev_err(sst_drv_ctx->dev,
138 "device can't be enabled. Returned err: %d\n", ret);
139 goto do_free_drv_ctx;
140 }
141 sst_drv_ctx->pci = pci_dev_get(pci);
142 ret = sst_platform_get_resources(sst_drv_ctx);
143 if (ret < 0)
144 goto do_free_drv_ctx;
145
146 pci_set_drvdata(pci, sst_drv_ctx);
147 sst_configure_runtime_pm(sst_drv_ctx);
148
149 return ret;
150
151do_free_drv_ctx:
152 sst_context_cleanup(sst_drv_ctx);
153 dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
154 return ret;
155}
156
157
158
159
160
161
162
163
164
165static void intel_sst_remove(struct pci_dev *pci)
166{
167 struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
168
169 sst_context_cleanup(sst_drv_ctx);
170 pci_dev_put(sst_drv_ctx->pci);
171 pci_release_regions(pci);
172 pci_set_drvdata(pci, NULL);
173}
174
175
176static const struct pci_device_id intel_sst_ids[] = {
177 { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
178 { 0, }
179};
180
181static struct pci_driver sst_driver = {
182 .name = SST_DRV_NAME,
183 .id_table = intel_sst_ids,
184 .probe = intel_sst_probe,
185 .remove = intel_sst_remove,
186#ifdef CONFIG_PM
187 .driver = {
188 .pm = &intel_sst_pm,
189 },
190#endif
191};
192
193module_pci_driver(sst_driver);
194
195MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
196MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
197MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
198MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
199MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
200MODULE_LICENSE("GPL v2");
201MODULE_ALIAS("sst");
202