aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@linux.intel.com>2014-02-19 09:35:58 -0500
committerMark Brown <broonie@linaro.org>2014-02-19 11:42:07 -0500
commit6dda27cbbd1d2d2ac4833236f5fd8a81c14d200a (patch)
tree2226ac218edf7e191e56be82df722dbb1ffd8833
parent7bcd84878ebd87168682b117e1cb9dd8a55a1a8b (diff)
ASoC: Intel: sst-acpi: Add support for multiple machine drivers per platform
Initial implementation of this driver focused only matching SST ACPI ID with single machine driver and same firmware file per platform. It was known restriction to be improved incrementally. This patch is now changing this that SST ACPI ID refers purely to platform specific data which refers to machine drivers on this platform, not vice versa. Matching machine driver is found by looking at ACPI ID which would best match with the driver. Typically this would be the ACPI ID of audio codec but is not tied to it. This patch also changes that DSP firmware name is machine not platform specific. Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/intel/sst-acpi.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/sst-acpi.c
index 64154a77d904..c7e36c9ee52f 100644
--- a/sound/soc/intel/sst-acpi.c
+++ b/sound/soc/intel/sst-acpi.c
@@ -26,9 +26,20 @@
26#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000 26#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
27#define SST_LPT_DSP_DMA_SIZE (1024 - 1) 27#define SST_LPT_DSP_DMA_SIZE (1024 - 1)
28 28
29/* Descriptor for SST ASoC machine driver */
30struct sst_acpi_mach {
31 /* ACPI ID for the matching machine driver. Audio codec for instance */
32 const u8 id[ACPI_ID_LEN];
33 /* machine driver name */
34 const char *drv_name;
35 /* firmware file name */
36 const char *fw_filename;
37};
38
29/* Descriptor for setting up SST platform data */ 39/* Descriptor for setting up SST platform data */
30struct sst_acpi_desc { 40struct sst_acpi_desc {
31 const char *drv_name; 41 const char *drv_name;
42 struct sst_acpi_mach *machines;
32 /* Platform resource indexes. Must set to -1 if not used */ 43 /* Platform resource indexes. Must set to -1 if not used */
33 int resindex_lpe_base; 44 int resindex_lpe_base;
34 int resindex_pcicfg_base; 45 int resindex_pcicfg_base;
@@ -37,24 +48,17 @@ struct sst_acpi_desc {
37 int resindex_dma_base; 48 int resindex_dma_base;
38 /* Unique number identifying the SST core on platform */ 49 /* Unique number identifying the SST core on platform */
39 int sst_id; 50 int sst_id;
40 /* firmware file name */
41 const char *fw_filename;
42 /* DMA only valid when resindex_dma_base != -1*/ 51 /* DMA only valid when resindex_dma_base != -1*/
43 int dma_engine; 52 int dma_engine;
44 int dma_size; 53 int dma_size;
45}; 54};
46 55
47/* Descriptor for SST ASoC machine driver */
48struct sst_acpi_mach {
49 const char *drv_name;
50 struct sst_acpi_desc *res_desc;
51};
52
53struct sst_acpi_priv { 56struct sst_acpi_priv {
54 struct platform_device *pdev_mach; 57 struct platform_device *pdev_mach;
55 struct platform_device *pdev_pcm; 58 struct platform_device *pdev_pcm;
56 struct sst_pdata sst_pdata; 59 struct sst_pdata sst_pdata;
57 struct sst_acpi_desc *desc; 60 struct sst_acpi_desc *desc;
61 struct sst_acpi_mach *mach;
58}; 62};
59 63
60static void sst_acpi_fw_cb(const struct firmware *fw, void *context) 64static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
@@ -64,10 +68,11 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
64 struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev); 68 struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
65 struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata; 69 struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
66 struct sst_acpi_desc *desc = sst_acpi->desc; 70 struct sst_acpi_desc *desc = sst_acpi->desc;
71 struct sst_acpi_mach *mach = sst_acpi->mach;
67 72
68 sst_pdata->fw = fw; 73 sst_pdata->fw = fw;
69 if (!fw) { 74 if (!fw) {
70 dev_err(dev, "Cannot load firmware %s\n", desc->fw_filename); 75 dev_err(dev, "Cannot load firmware %s\n", mach->fw_filename);
71 return; 76 return;
72 } 77 }
73 78
@@ -83,6 +88,28 @@ static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
83 return; 88 return;
84} 89}
85 90
91static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
92 void *context, void **ret)
93{
94 *(bool *)context = true;
95 return AE_OK;
96}
97
98static struct sst_acpi_mach *sst_acpi_find_machine(
99 struct sst_acpi_mach *machines)
100{
101 struct sst_acpi_mach *mach;
102 bool found = false;
103
104 for (mach = machines; mach->id[0]; mach++)
105 if (ACPI_SUCCESS(acpi_get_devices(mach->id,
106 sst_acpi_mach_match,
107 &found, NULL)) && found)
108 return mach;
109
110 return NULL;
111}
112
86static int sst_acpi_probe(struct platform_device *pdev) 113static int sst_acpi_probe(struct platform_device *pdev)
87{ 114{
88 const struct acpi_device_id *id; 115 const struct acpi_device_id *id;
@@ -102,8 +129,13 @@ static int sst_acpi_probe(struct platform_device *pdev)
102 if (!id) 129 if (!id)
103 return -ENODEV; 130 return -ENODEV;
104 131
105 mach = (struct sst_acpi_mach *)id->driver_data; 132 desc = (struct sst_acpi_desc *)id->driver_data;
106 desc = mach->res_desc; 133 mach = sst_acpi_find_machine(desc->machines);
134 if (mach == NULL) {
135 dev_err(dev, "No matching ASoC machine driver found\n");
136 return -ENODEV;
137 }
138
107 sst_pdata = &sst_acpi->sst_pdata; 139 sst_pdata = &sst_acpi->sst_pdata;
108 sst_pdata->id = desc->sst_id; 140 sst_pdata->id = desc->sst_id;
109 sst_acpi->desc = desc; 141 sst_acpi->desc = desc;
@@ -154,7 +186,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
154 return PTR_ERR(sst_acpi->pdev_mach); 186 return PTR_ERR(sst_acpi->pdev_mach);
155 187
156 /* continue SST probing after firmware is loaded */ 188 /* continue SST probing after firmware is loaded */
157 ret = request_firmware_nowait(THIS_MODULE, true, desc->fw_filename, 189 ret = request_firmware_nowait(THIS_MODULE, true, mach->fw_filename,
158 dev, GFP_KERNEL, pdev, sst_acpi_fw_cb); 190 dev, GFP_KERNEL, pdev, sst_acpi_fw_cb);
159 if (ret) 191 if (ret)
160 platform_device_unregister(sst_acpi->pdev_mach); 192 platform_device_unregister(sst_acpi->pdev_mach);
@@ -175,45 +207,45 @@ static int sst_acpi_remove(struct platform_device *pdev)
175 return 0; 207 return 0;
176} 208}
177 209
210static struct sst_acpi_mach haswell_machines[] = {
211 { "INT33CA", "haswell-audio", "intel/IntcSST1.bin" },
212 {}
213};
214
178static struct sst_acpi_desc sst_acpi_haswell_desc = { 215static struct sst_acpi_desc sst_acpi_haswell_desc = {
179 .drv_name = "haswell-pcm-audio", 216 .drv_name = "haswell-pcm-audio",
217 .machines = haswell_machines,
180 .resindex_lpe_base = 0, 218 .resindex_lpe_base = 0,
181 .resindex_pcicfg_base = 1, 219 .resindex_pcicfg_base = 1,
182 .resindex_fw_base = -1, 220 .resindex_fw_base = -1,
183 .irqindex_host_ipc = 0, 221 .irqindex_host_ipc = 0,
184 .sst_id = SST_DEV_ID_LYNX_POINT, 222 .sst_id = SST_DEV_ID_LYNX_POINT,
185 .fw_filename = "intel/IntcSST1.bin",
186 .dma_engine = SST_DMA_TYPE_DW, 223 .dma_engine = SST_DMA_TYPE_DW,
187 .resindex_dma_base = SST_LPT_DSP_DMA_ADDR_OFFSET, 224 .resindex_dma_base = SST_LPT_DSP_DMA_ADDR_OFFSET,
188 .dma_size = SST_LPT_DSP_DMA_SIZE, 225 .dma_size = SST_LPT_DSP_DMA_SIZE,
189}; 226};
190 227
228static struct sst_acpi_mach broadwell_machines[] = {
229 { "INT343A", "broadwell-audio", "intel/IntcSST2.bin" },
230 {}
231};
232
191static struct sst_acpi_desc sst_acpi_broadwell_desc = { 233static struct sst_acpi_desc sst_acpi_broadwell_desc = {
192 .drv_name = "haswell-pcm-audio", 234 .drv_name = "haswell-pcm-audio",
235 .machines = broadwell_machines,
193 .resindex_lpe_base = 0, 236 .resindex_lpe_base = 0,
194 .resindex_pcicfg_base = 1, 237 .resindex_pcicfg_base = 1,
195 .resindex_fw_base = -1, 238 .resindex_fw_base = -1,
196 .irqindex_host_ipc = 0, 239 .irqindex_host_ipc = 0,
197 .sst_id = SST_DEV_ID_WILDCAT_POINT, 240 .sst_id = SST_DEV_ID_WILDCAT_POINT,
198 .fw_filename = "intel/IntcSST2.bin",
199 .dma_engine = SST_DMA_TYPE_DW, 241 .dma_engine = SST_DMA_TYPE_DW,
200 .resindex_dma_base = SST_WPT_DSP_DMA_ADDR_OFFSET, 242 .resindex_dma_base = SST_WPT_DSP_DMA_ADDR_OFFSET,
201 .dma_size = SST_LPT_DSP_DMA_SIZE, 243 .dma_size = SST_LPT_DSP_DMA_SIZE,
202}; 244};
203 245
204static struct sst_acpi_mach haswell_mach = {
205 .drv_name = "haswell-audio",
206 .res_desc = &sst_acpi_haswell_desc,
207};
208
209static struct sst_acpi_mach broadwell_mach = {
210 .drv_name = "broadwell-audio",
211 .res_desc = &sst_acpi_broadwell_desc,
212};
213
214static struct acpi_device_id sst_acpi_match[] = { 246static struct acpi_device_id sst_acpi_match[] = {
215 { "INT33C8", (unsigned long)&haswell_mach }, 247 { "INT33C8", (unsigned long)&sst_acpi_haswell_desc },
216 { "INT3438", (unsigned long)&broadwell_mach }, 248 { "INT3438", (unsigned long)&sst_acpi_broadwell_desc },
217 { } 249 { }
218}; 250};
219MODULE_DEVICE_TABLE(acpi, sst_acpi_match); 251MODULE_DEVICE_TABLE(acpi, sst_acpi_match);