1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
33static 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
43
44 if (ctx->dev_id == SST_MRFLD_PCI_ID) {
45 ctx->ddr_base = pci_resource_start(pci, 0);
46
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
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
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
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
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);
108do_release_regions:
109 pci_release_regions(pci);
110 return 0;
111}
112
113
114
115
116
117
118
119
120static 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
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
159do_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
167
168
169
170
171
172
173static 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
184static struct pci_device_id intel_sst_ids[] = {
185 { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
186 { 0, }
187};
188
189static 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
201module_pci_driver(sst_driver);
202
203MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
204MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
205MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
206MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
207MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
208MODULE_LICENSE("GPL v2");
209MODULE_ALIAS("sst");
210