~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/amd/ps/pci-ps.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * AMD Pink Sardine ACP PCI Driver
  4  *
  5  * Copyright 2022 Advanced Micro Devices, Inc.
  6  */
  7 
  8 #include <linux/pci.h>
  9 #include <linux/bitops.h>
 10 #include <linux/module.h>
 11 #include <linux/io.h>
 12 #include <linux/delay.h>
 13 #include <linux/platform_device.h>
 14 #include <linux/acpi.h>
 15 #include <linux/interrupt.h>
 16 #include <sound/pcm_params.h>
 17 #include <linux/pm_runtime.h>
 18 #include <linux/iopoll.h>
 19 #include <linux/soundwire/sdw_amd.h>
 20 #include "../mach-config.h"
 21 
 22 #include "acp63.h"
 23 
 24 static int acp63_power_on(void __iomem *acp_base)
 25 {
 26         u32 val;
 27 
 28         val = readl(acp_base + ACP_PGFSM_STATUS);
 29 
 30         if (!val)
 31                 return val;
 32 
 33         if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
 34                 writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
 35 
 36         return readl_poll_timeout(acp_base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT);
 37 }
 38 
 39 static int acp63_reset(void __iomem *acp_base)
 40 {
 41         u32 val;
 42         int ret;
 43 
 44         writel(1, acp_base + ACP_SOFT_RESET);
 45 
 46         ret = readl_poll_timeout(acp_base + ACP_SOFT_RESET, val,
 47                                  val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK,
 48                                  DELAY_US, ACP_TIMEOUT);
 49         if (ret)
 50                 return ret;
 51 
 52         writel(0, acp_base + ACP_SOFT_RESET);
 53 
 54         return readl_poll_timeout(acp_base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
 55 }
 56 
 57 static void acp63_enable_interrupts(void __iomem *acp_base)
 58 {
 59         writel(1, acp_base + ACP_EXTERNAL_INTR_ENB);
 60         writel(ACP_ERROR_IRQ, acp_base + ACP_EXTERNAL_INTR_CNTL);
 61 }
 62 
 63 static void acp63_disable_interrupts(void __iomem *acp_base)
 64 {
 65         writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + ACP_EXTERNAL_INTR_STAT);
 66         writel(0, acp_base + ACP_EXTERNAL_INTR_CNTL);
 67         writel(0, acp_base + ACP_EXTERNAL_INTR_ENB);
 68 }
 69 
 70 static int acp63_init(void __iomem *acp_base, struct device *dev)
 71 {
 72         int ret;
 73 
 74         ret = acp63_power_on(acp_base);
 75         if (ret) {
 76                 dev_err(dev, "ACP power on failed\n");
 77                 return ret;
 78         }
 79         writel(0x01, acp_base + ACP_CONTROL);
 80         ret = acp63_reset(acp_base);
 81         if (ret) {
 82                 dev_err(dev, "ACP reset failed\n");
 83                 return ret;
 84         }
 85         acp63_enable_interrupts(acp_base);
 86         return 0;
 87 }
 88 
 89 static int acp63_deinit(void __iomem *acp_base, struct device *dev)
 90 {
 91         int ret;
 92 
 93         acp63_disable_interrupts(acp_base);
 94         ret = acp63_reset(acp_base);
 95         if (ret) {
 96                 dev_err(dev, "ACP reset failed\n");
 97                 return ret;
 98         }
 99         writel(0, acp_base + ACP_CONTROL);
100         return 0;
101 }
102 
103 static irqreturn_t acp63_irq_thread(int irq, void *context)
104 {
105         struct sdw_dma_dev_data *sdw_dma_data;
106         struct acp63_dev_data *adata = context;
107         u32 stream_index;
108 
109         sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev);
110 
111         for (stream_index = 0; stream_index < ACP63_SDW0_DMA_MAX_STREAMS; stream_index++) {
112                 if (adata->sdw0_dma_intr_stat[stream_index]) {
113                         if (sdw_dma_data->sdw0_dma_stream[stream_index])
114                                 snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]);
115                         adata->sdw0_dma_intr_stat[stream_index] = 0;
116                 }
117         }
118         for (stream_index = 0; stream_index < ACP63_SDW1_DMA_MAX_STREAMS; stream_index++) {
119                 if (adata->sdw1_dma_intr_stat[stream_index]) {
120                         if (sdw_dma_data->sdw1_dma_stream[stream_index])
121                                 snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]);
122                         adata->sdw1_dma_intr_stat[stream_index] = 0;
123                 }
124         }
125         return IRQ_HANDLED;
126 }
127 
128 static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
129 {
130         struct acp63_dev_data *adata;
131         struct pdm_dev_data *ps_pdm_data;
132         struct amd_sdw_manager *amd_manager;
133         u32 ext_intr_stat, ext_intr_stat1;
134         u32 stream_id = 0;
135         u16 irq_flag = 0;
136         u16 sdw_dma_irq_flag = 0;
137         u16 index;
138 
139         adata = dev_id;
140         if (!adata)
141                 return IRQ_NONE;
142         /* ACP interrupts will be cleared by reading particular bit and writing
143          * same value to the status register. writing zero's doesn't have any
144          * effect.
145          * Bit by bit checking of IRQ field is implemented.
146          */
147         ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
148         if (ext_intr_stat & ACP_SDW0_STAT) {
149                 writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
150                 amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
151                 if (amd_manager)
152                         schedule_work(&amd_manager->amd_sdw_irq_thread);
153                 irq_flag = 1;
154         }
155 
156         ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
157         if (ext_intr_stat1 & ACP_SDW1_STAT) {
158                 writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
159                 amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
160                 if (amd_manager)
161                         schedule_work(&amd_manager->amd_sdw_irq_thread);
162                 irq_flag = 1;
163         }
164 
165         if (ext_intr_stat & ACP_ERROR_IRQ) {
166                 writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
167                 /* TODO: Report SoundWire Manager instance errors */
168                 writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON);
169                 writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON);
170                 writel(0, adata->acp63_base + ACP_ERROR_STATUS);
171                 irq_flag = 1;
172         }
173 
174         if (ext_intr_stat & BIT(PDM_DMA_STAT)) {
175                 ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev);
176                 writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
177                 if (ps_pdm_data->capture_stream)
178                         snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
179                 irq_flag = 1;
180         }
181         if (ext_intr_stat & ACP_SDW_DMA_IRQ_MASK) {
182                 for (index = ACP_AUDIO2_RX_THRESHOLD; index <= ACP_AUDIO0_TX_THRESHOLD; index++) {
183                         if (ext_intr_stat & BIT(index)) {
184                                 writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
185                                 switch (index) {
186                                 case ACP_AUDIO0_TX_THRESHOLD:
187                                         stream_id = ACP_SDW0_AUDIO0_TX;
188                                         break;
189                                 case ACP_AUDIO1_TX_THRESHOLD:
190                                         stream_id = ACP_SDW0_AUDIO1_TX;
191                                         break;
192                                 case ACP_AUDIO2_TX_THRESHOLD:
193                                         stream_id = ACP_SDW0_AUDIO2_TX;
194                                         break;
195                                 case ACP_AUDIO0_RX_THRESHOLD:
196                                         stream_id = ACP_SDW0_AUDIO0_RX;
197                                         break;
198                                 case ACP_AUDIO1_RX_THRESHOLD:
199                                         stream_id = ACP_SDW0_AUDIO1_RX;
200                                         break;
201                                 case ACP_AUDIO2_RX_THRESHOLD:
202                                         stream_id = ACP_SDW0_AUDIO2_RX;
203                                         break;
204                                 }
205 
206                                 adata->sdw0_dma_intr_stat[stream_id] = 1;
207                                 sdw_dma_irq_flag = 1;
208                         }
209                 }
210         }
211 
212         if (ext_intr_stat1 & ACP_P1_AUDIO1_RX_THRESHOLD) {
213                 writel(ACP_P1_AUDIO1_RX_THRESHOLD,
214                        adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
215                 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1;
216                 sdw_dma_irq_flag = 1;
217         }
218 
219         if (ext_intr_stat1 & ACP_P1_AUDIO1_TX_THRESHOLD) {
220                 writel(ACP_P1_AUDIO1_TX_THRESHOLD,
221                        adata->acp63_base + ACP_EXTERNAL_INTR_STAT1);
222                 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1;
223                 sdw_dma_irq_flag = 1;
224         }
225 
226         if (sdw_dma_irq_flag)
227                 return IRQ_WAKE_THREAD;
228 
229         if (irq_flag)
230                 return IRQ_HANDLED;
231         else
232                 return IRQ_NONE;
233 }
234 
235 #if IS_ENABLED(CONFIG_SND_SOC_AMD_SOUNDWIRE)
236 static int acp_scan_sdw_devices(struct device *dev, u64 addr)
237 {
238         struct acpi_device *sdw_dev;
239         struct acp63_dev_data *acp_data;
240 
241         acp_data = dev_get_drvdata(dev);
242         if (!addr)
243                 return -ENODEV;
244 
245         sdw_dev = acpi_find_child_device(ACPI_COMPANION(dev), addr, 0);
246         if (!sdw_dev)
247                 return -ENODEV;
248 
249         acp_data->info.handle = sdw_dev->handle;
250         acp_data->info.count = AMD_SDW_MAX_MANAGERS;
251         return amd_sdw_scan_controller(&acp_data->info);
252 }
253 
254 static int amd_sdw_probe(struct device *dev)
255 {
256         struct acp63_dev_data *acp_data;
257         struct sdw_amd_res sdw_res;
258         int ret;
259 
260         acp_data = dev_get_drvdata(dev);
261         memset(&sdw_res, 0, sizeof(sdw_res));
262         sdw_res.addr = acp_data->addr;
263         sdw_res.reg_range = acp_data->reg_range;
264         sdw_res.handle = acp_data->info.handle;
265         sdw_res.parent = dev;
266         sdw_res.dev = dev;
267         sdw_res.acp_lock = &acp_data->acp_lock;
268         sdw_res.count = acp_data->info.count;
269         sdw_res.mmio_base = acp_data->acp63_base;
270         sdw_res.link_mask = acp_data->info.link_mask;
271         ret = sdw_amd_probe(&sdw_res, &acp_data->sdw);
272         if (ret)
273                 dev_err(dev, "error: SoundWire probe failed\n");
274         return ret;
275 }
276 
277 static int amd_sdw_exit(struct acp63_dev_data *acp_data)
278 {
279         if (acp_data->sdw)
280                 sdw_amd_exit(acp_data->sdw);
281         acp_data->sdw = NULL;
282 
283         return 0;
284 }
285 
286 static struct snd_soc_acpi_mach *acp63_sdw_machine_select(struct device *dev)
287 {
288         struct snd_soc_acpi_mach *mach;
289         const struct snd_soc_acpi_link_adr *link;
290         struct acp63_dev_data *acp_data = dev_get_drvdata(dev);
291         int ret, i;
292 
293         if (acp_data->info.count) {
294                 ret = sdw_amd_get_slave_info(acp_data->sdw);
295                 if (ret) {
296                         dev_dbg(dev, "failed to read slave information\n");
297                         return NULL;
298                 }
299                 for (mach = acp_data->machines; mach; mach++) {
300                         if (!mach->links)
301                                 break;
302                         link = mach->links;
303                         for (i = 0; i < acp_data->info.count && link->num_adr; link++, i++) {
304                                 if (!snd_soc_acpi_sdw_link_slaves_found(dev, link,
305                                                                         acp_data->sdw->ids,
306                                                                         acp_data->sdw->num_slaves))
307                                         break;
308                         }
309                         if (i == acp_data->info.count || !link->num_adr)
310                                 break;
311                 }
312                 if (mach && mach->link_mask) {
313                         mach->mach_params.links = mach->links;
314                         mach->mach_params.link_mask = mach->link_mask;
315                         return mach;
316                 }
317         }
318         dev_dbg(dev, "No SoundWire machine driver found\n");
319         return NULL;
320 }
321 #else
322 static int acp_scan_sdw_devices(struct device *dev, u64 addr)
323 {
324         return 0;
325 }
326 
327 static int amd_sdw_probe(struct device *dev)
328 {
329         return 0;
330 }
331 
332 static int amd_sdw_exit(struct acp63_dev_data *acp_data)
333 {
334         return 0;
335 }
336 
337 static struct snd_soc_acpi_mach *acp63_sdw_machine_select(struct device *dev)
338 {
339         return NULL;
340 }
341 #endif
342 
343 static int acp63_machine_register(struct device *dev)
344 {
345         struct snd_soc_acpi_mach *mach;
346         struct acp63_dev_data *adata = dev_get_drvdata(dev);
347         int size;
348 
349         if (adata->is_sdw_dev && adata->is_sdw_config) {
350                 size = sizeof(*adata->machines);
351                 mach = acp63_sdw_machine_select(dev);
352                 if (mach) {
353                         adata->mach_dev = platform_device_register_data(dev, mach->drv_name,
354                                                                         PLATFORM_DEVID_NONE, mach,
355                                                                         size);
356                         if (IS_ERR(adata->mach_dev)) {
357                                 dev_err(dev,
358                                         "cannot register Machine device for SoundWire Interface\n");
359                                 return PTR_ERR(adata->mach_dev);
360                         }
361                 }
362 
363         } else if (adata->is_pdm_dev && !adata->is_sdw_dev && adata->is_pdm_config) {
364                 adata->mach_dev = platform_device_register_data(dev, "acp_ps_mach",
365                                                                 PLATFORM_DEVID_NONE, NULL, 0);
366                 if (IS_ERR(adata->mach_dev)) {
367                         dev_err(dev, "cannot register amd_ps_mach device\n");
368                         return PTR_ERR(adata->mach_dev);
369                 }
370         }
371         return 0;
372 }
373 
374 static int get_acp63_device_config(struct pci_dev *pci, struct acp63_dev_data *acp_data)
375 {
376         struct acpi_device *pdm_dev;
377         const union acpi_object *obj;
378         u32 config;
379         bool is_dmic_dev = false;
380         bool is_sdw_dev = false;
381         int ret;
382 
383         config = readl(acp_data->acp63_base + ACP_PIN_CONFIG);
384         switch (config) {
385         case ACP_CONFIG_4:
386         case ACP_CONFIG_5:
387         case ACP_CONFIG_10:
388         case ACP_CONFIG_11:
389                 acp_data->is_pdm_config = true;
390                 break;
391         case ACP_CONFIG_2:
392         case ACP_CONFIG_3:
393                 acp_data->is_sdw_config = true;
394                 break;
395         case ACP_CONFIG_6:
396         case ACP_CONFIG_7:
397         case ACP_CONFIG_12:
398         case ACP_CONFIG_8:
399         case ACP_CONFIG_13:
400         case ACP_CONFIG_14:
401                 acp_data->is_pdm_config = true;
402                 acp_data->is_sdw_config = true;
403                 break;
404         default:
405                 break;
406         }
407 
408         if (acp_data->is_pdm_config) {
409                 pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
410                 if (pdm_dev) {
411                         /* is_dmic_dev flag will be set when ACP PDM controller device exists */
412                         if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type",
413                                                    ACPI_TYPE_INTEGER, &obj) &&
414                                                    obj->integer.value == ACP_DMIC_DEV)
415                                 is_dmic_dev = true;
416                 }
417         }
418 
419         if (acp_data->is_sdw_config) {
420                 ret = acp_scan_sdw_devices(&pci->dev, ACP63_SDW_ADDR);
421                 if (!ret && acp_data->info.link_mask)
422                         is_sdw_dev = true;
423         }
424 
425         acp_data->is_pdm_dev = is_dmic_dev;
426         acp_data->is_sdw_dev = is_sdw_dev;
427         if (!is_dmic_dev && !is_sdw_dev) {
428                 dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n");
429                 return -ENODEV;
430         }
431         return 0;
432 }
433 
434 static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,
435                                          struct device *parent,
436                                          struct fwnode_handle *fw_node,
437                                          char *name, unsigned int id,
438                                          const struct resource *res,
439                                          unsigned int num_res,
440                                          const void *data,
441                                          size_t size_data)
442 {
443         pdevinfo->name = name;
444         pdevinfo->id = id;
445         pdevinfo->parent = parent;
446         pdevinfo->num_res = num_res;
447         pdevinfo->res = res;
448         pdevinfo->data = data;
449         pdevinfo->size_data = size_data;
450         pdevinfo->fwnode = fw_node;
451 }
452 
453 static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)
454 {
455         struct platform_device_info pdevinfo;
456         struct device *parent;
457         int ret;
458 
459         parent = &pci->dev;
460 
461         if (adata->is_sdw_dev || adata->is_pdm_dev) {
462                 adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
463                 if (!adata->res) {
464                         ret = -ENOMEM;
465                         goto de_init;
466                 }
467                 adata->res->flags = IORESOURCE_MEM;
468                 adata->res->start = addr;
469                 adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
470                 memset(&pdevinfo, 0, sizeof(pdevinfo));
471         }
472 
473         if (adata->is_pdm_dev && adata->is_pdm_config) {
474                 acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "acp_ps_pdm_dma",
475                                              0, adata->res, 1, NULL, 0);
476 
477                 adata->pdm_dev = platform_device_register_full(&pdevinfo);
478                 if (IS_ERR(adata->pdm_dev)) {
479                         dev_err(&pci->dev,
480                                 "cannot register %s device\n", pdevinfo.name);
481                         ret = PTR_ERR(adata->pdm_dev);
482                         goto de_init;
483                 }
484                 memset(&pdevinfo, 0, sizeof(pdevinfo));
485                 acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "dmic-codec",
486                                              0, NULL, 0, NULL, 0);
487                 adata->dmic_codec_dev = platform_device_register_full(&pdevinfo);
488                 if (IS_ERR(adata->dmic_codec_dev)) {
489                         dev_err(&pci->dev,
490                                 "cannot register %s device\n", pdevinfo.name);
491                         ret = PTR_ERR(adata->dmic_codec_dev);
492                         goto unregister_pdm_dev;
493                 }
494         }
495         if (adata->is_sdw_dev && adata->is_sdw_config) {
496                 ret = amd_sdw_probe(&pci->dev);
497                 if (ret) {
498                         if (adata->is_pdm_dev)
499                                 goto unregister_dmic_codec_dev;
500                         else
501                                 goto de_init;
502                 }
503                 memset(&pdevinfo, 0, sizeof(pdevinfo));
504                 acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "amd_ps_sdw_dma",
505                                              0, adata->res, 1, NULL, 0);
506 
507                 adata->sdw_dma_dev = platform_device_register_full(&pdevinfo);
508                 if (IS_ERR(adata->sdw_dma_dev)) {
509                         dev_err(&pci->dev,
510                                 "cannot register %s device\n", pdevinfo.name);
511                         ret = PTR_ERR(adata->sdw_dma_dev);
512                         if (adata->is_pdm_dev)
513                                 goto unregister_dmic_codec_dev;
514                         else
515                                 goto de_init;
516                 }
517         }
518 
519         return 0;
520 unregister_dmic_codec_dev:
521                 platform_device_unregister(adata->dmic_codec_dev);
522 unregister_pdm_dev:
523                 platform_device_unregister(adata->pdm_dev);
524 de_init:
525         if (acp63_deinit(adata->acp63_base, &pci->dev))
526                 dev_err(&pci->dev, "ACP de-init failed\n");
527         return ret;
528 }
529 
530 static int snd_acp63_probe(struct pci_dev *pci,
531                            const struct pci_device_id *pci_id)
532 {
533         struct acp63_dev_data *adata;
534         u32 addr;
535         u32 irqflags, flag;
536         int ret;
537 
538         irqflags = IRQF_SHARED;
539 
540         /* Return if acp config flag is defined */
541         flag = snd_amd_acp_find_config(pci);
542         if (flag)
543                 return -ENODEV;
544 
545         /* Pink Sardine device check */
546         switch (pci->revision) {
547         case 0x63:
548                 break;
549         default:
550                 dev_dbg(&pci->dev, "acp63 pci device not found\n");
551                 return -ENODEV;
552         }
553         if (pci_enable_device(pci)) {
554                 dev_err(&pci->dev, "pci_enable_device failed\n");
555                 return -ENODEV;
556         }
557 
558         ret = pci_request_regions(pci, "AMD ACP6.2 audio");
559         if (ret < 0) {
560                 dev_err(&pci->dev, "pci_request_regions failed\n");
561                 goto disable_pci;
562         }
563         adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data),
564                              GFP_KERNEL);
565         if (!adata) {
566                 ret = -ENOMEM;
567                 goto release_regions;
568         }
569 
570         addr = pci_resource_start(pci, 0);
571         adata->acp63_base = devm_ioremap(&pci->dev, addr,
572                                          pci_resource_len(pci, 0));
573         if (!adata->acp63_base) {
574                 ret = -ENOMEM;
575                 goto release_regions;
576         }
577         adata->addr = addr;
578         adata->reg_range = ACP63_REG_END - ACP63_REG_START;
579         pci_set_master(pci);
580         pci_set_drvdata(pci, adata);
581         mutex_init(&adata->acp_lock);
582         ret = acp63_init(adata->acp63_base, &pci->dev);
583         if (ret)
584                 goto release_regions;
585         ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler,
586                                         acp63_irq_thread, irqflags, "ACP_PCI_IRQ", adata);
587         if (ret) {
588                 dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
589                 goto de_init;
590         }
591         ret = get_acp63_device_config(pci, adata);
592         /* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */
593         if (ret) {
594                 dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret);
595                 goto skip_pdev_creation;
596         }
597         ret = create_acp63_platform_devs(pci, adata, addr);
598         if (ret < 0) {
599                 dev_err(&pci->dev, "ACP platform devices creation failed\n");
600                 goto de_init;
601         }
602         ret = acp63_machine_register(&pci->dev);
603         if (ret) {
604                 dev_err(&pci->dev, "ACP machine register failed\n");
605                 goto de_init;
606         }
607 skip_pdev_creation:
608         device_set_wakeup_enable(&pci->dev, true);
609         pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
610         pm_runtime_use_autosuspend(&pci->dev);
611         pm_runtime_put_noidle(&pci->dev);
612         pm_runtime_allow(&pci->dev);
613         return 0;
614 de_init:
615         if (acp63_deinit(adata->acp63_base, &pci->dev))
616                 dev_err(&pci->dev, "ACP de-init failed\n");
617 release_regions:
618         pci_release_regions(pci);
619 disable_pci:
620         pci_disable_device(pci);
621 
622         return ret;
623 }
624 
625 static bool check_acp_sdw_enable_status(struct acp63_dev_data *adata)
626 {
627         u32 sdw0_en, sdw1_en;
628 
629         sdw0_en = readl(adata->acp63_base + ACP_SW0_EN);
630         sdw1_en = readl(adata->acp63_base + ACP_SW1_EN);
631         return (sdw0_en || sdw1_en);
632 }
633 
634 static void handle_acp63_sdw_pme_event(struct acp63_dev_data *adata)
635 {
636         u32 val;
637 
638         val = readl(adata->acp63_base + ACP_SW0_WAKE_EN);
639         if (val && adata->sdw->pdev[0])
640                 pm_request_resume(&adata->sdw->pdev[0]->dev);
641 
642         val = readl(adata->acp63_base + ACP_SW1_WAKE_EN);
643         if (val && adata->sdw->pdev[1])
644                 pm_request_resume(&adata->sdw->pdev[1]->dev);
645 }
646 
647 static int __maybe_unused snd_acp63_suspend(struct device *dev)
648 {
649         struct acp63_dev_data *adata;
650         int ret;
651 
652         adata = dev_get_drvdata(dev);
653         if (adata->is_sdw_dev) {
654                 adata->sdw_en_stat = check_acp_sdw_enable_status(adata);
655                 if (adata->sdw_en_stat)
656                         return 0;
657         }
658         ret = acp63_deinit(adata->acp63_base, dev);
659         if (ret)
660                 dev_err(dev, "ACP de-init failed\n");
661 
662         return ret;
663 }
664 
665 static int __maybe_unused snd_acp63_runtime_resume(struct device *dev)
666 {
667         struct acp63_dev_data *adata;
668         int ret;
669 
670         adata = dev_get_drvdata(dev);
671         if (adata->sdw_en_stat)
672                 return 0;
673 
674         ret = acp63_init(adata->acp63_base, dev);
675         if (ret) {
676                 dev_err(dev, "ACP init failed\n");
677                 return ret;
678         }
679 
680         if (!adata->sdw_en_stat)
681                 handle_acp63_sdw_pme_event(adata);
682         return 0;
683 }
684 
685 static int __maybe_unused snd_acp63_resume(struct device *dev)
686 {
687         struct acp63_dev_data *adata;
688         int ret;
689 
690         adata = dev_get_drvdata(dev);
691         if (adata->sdw_en_stat)
692                 return 0;
693 
694         ret = acp63_init(adata->acp63_base, dev);
695         if (ret)
696                 dev_err(dev, "ACP init failed\n");
697 
698         return ret;
699 }
700 
701 static const struct dev_pm_ops acp63_pm_ops = {
702         SET_RUNTIME_PM_OPS(snd_acp63_suspend, snd_acp63_runtime_resume, NULL)
703         SET_SYSTEM_SLEEP_PM_OPS(snd_acp63_suspend, snd_acp63_resume)
704 };
705 
706 static void snd_acp63_remove(struct pci_dev *pci)
707 {
708         struct acp63_dev_data *adata;
709         int ret;
710 
711         adata = pci_get_drvdata(pci);
712         if (adata->sdw) {
713                 amd_sdw_exit(adata);
714                 platform_device_unregister(adata->sdw_dma_dev);
715         }
716         if (adata->is_pdm_dev) {
717                 platform_device_unregister(adata->pdm_dev);
718                 platform_device_unregister(adata->dmic_codec_dev);
719         }
720         if (adata->mach_dev)
721                 platform_device_unregister(adata->mach_dev);
722         ret = acp63_deinit(adata->acp63_base, &pci->dev);
723         if (ret)
724                 dev_err(&pci->dev, "ACP de-init failed\n");
725         pm_runtime_forbid(&pci->dev);
726         pm_runtime_get_noresume(&pci->dev);
727         pci_release_regions(pci);
728         pci_disable_device(pci);
729 }
730 
731 static const struct pci_device_id snd_acp63_ids[] = {
732         { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
733         .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
734         .class_mask = 0xffffff },
735         { 0, },
736 };
737 MODULE_DEVICE_TABLE(pci, snd_acp63_ids);
738 
739 static struct pci_driver ps_acp63_driver  = {
740         .name = KBUILD_MODNAME,
741         .id_table = snd_acp63_ids,
742         .probe = snd_acp63_probe,
743         .remove = snd_acp63_remove,
744         .driver = {
745                 .pm = &acp63_pm_ops,
746         }
747 };
748 
749 module_pci_driver(ps_acp63_driver);
750 
751 MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
752 MODULE_AUTHOR("Syed.SabaKareem@amd.com");
753 MODULE_DESCRIPTION("AMD ACP Pink Sardine PCI driver");
754 MODULE_IMPORT_NS(SOUNDWIRE_AMD_INIT);
755 MODULE_IMPORT_NS(SND_AMD_SOUNDWIRE_ACPI);
756 MODULE_LICENSE("GPL v2");
757 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php