aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/Kconfig8
-rw-r--r--sound/pci/hda/hda_codec.h45
-rw-r--r--sound/pci/hda/hda_intel.c116
3 files changed, 163 insertions, 6 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 7105c3de1bca..ba1dbd8e00a0 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -236,4 +236,12 @@ config SND_HDA_POWER_SAVE_DEFAULT
236 The default time-out value in seconds for HD-audio automatic 236 The default time-out value in seconds for HD-audio automatic
237 power-save mode. 0 means to disable the power-save mode. 237 power-save mode. 0 means to disable the power-save mode.
238 238
239config SND_HDA_DSP_LOADER
240 bool "Enable DSP firmware loader"
241 depends on FW_LOADER
242 default y
243 help
244 Say Y here to enable the DSP firmware loader, used by certain
245 codecs (e.g. CA0132) to transfer their DSP binaries to the hardware.
246
239endif 247endif
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 507fe8a917b6..c218bf41261a 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -618,6 +618,17 @@ struct hda_bus_ops {
618 /* notify power-up/down from codec to controller */ 618 /* notify power-up/down from codec to controller */
619 void (*pm_notify)(struct hda_bus *bus, bool power_up); 619 void (*pm_notify)(struct hda_bus *bus, bool power_up);
620#endif 620#endif
621#ifdef CONFIG_SND_HDA_DSP_LOADER
622 /* prepare DSP transfer */
623 int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format,
624 unsigned int byte_size,
625 struct snd_dma_buffer *bufp);
626 /* start/stop DSP transfer */
627 void (*load_dsp_trigger)(struct hda_bus *bus, bool start);
628 /* clean up DSP transfer */
629 void (*load_dsp_cleanup)(struct hda_bus *bus,
630 struct snd_dma_buffer *dmab);
631#endif
621}; 632};
622 633
623/* template to pass to the bus constructor */ 634/* template to pass to the bus constructor */
@@ -1129,6 +1140,40 @@ static inline void snd_hda_power_sync(struct hda_codec *codec)
1129int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf); 1140int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
1130#endif 1141#endif
1131 1142
1143#ifdef CONFIG_SND_HDA_DSP_LOADER
1144static inline int
1145snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
1146 unsigned int size,
1147 struct snd_dma_buffer *bufp)
1148{
1149 return codec->bus->ops.load_dsp_prepare(codec->bus, format, size, bufp);
1150}
1151static inline void
1152snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start)
1153{
1154 return codec->bus->ops.load_dsp_trigger(codec->bus, start);
1155}
1156static inline void
1157snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
1158 struct snd_dma_buffer *dmab)
1159{
1160 return codec->bus->ops.load_dsp_cleanup(codec->bus, dmab);
1161}
1162#else
1163static inline int
1164snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
1165 unsigned int size,
1166 struct snd_dma_buffer *bufp)
1167{
1168 return 0;
1169}
1170static inline void
1171snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {}
1172static inline void
1173snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
1174 struct snd_dma_buffer *dmab) {}
1175#endif
1176
1132/* 1177/*
1133 * Codec modularization 1178 * Codec modularization
1134 */ 1179 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index cd2dbaf1be78..99e61b985d29 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1038,6 +1038,15 @@ static unsigned int azx_get_response(struct hda_bus *bus,
1038static void azx_power_notify(struct hda_bus *bus, bool power_up); 1038static void azx_power_notify(struct hda_bus *bus, bool power_up);
1039#endif 1039#endif
1040 1040
1041#ifdef CONFIG_SND_HDA_DSP_LOADER
1042static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
1043 unsigned int byte_size,
1044 struct snd_dma_buffer *bufp);
1045static void azx_load_dsp_trigger(struct hda_bus *bus, bool start);
1046static void azx_load_dsp_cleanup(struct hda_bus *bus,
1047 struct snd_dma_buffer *dmab);
1048#endif
1049
1041/* reset codec link */ 1050/* reset codec link */
1042static int azx_reset(struct azx *chip, int full_reset) 1051static int azx_reset(struct azx *chip, int full_reset)
1043{ 1052{
@@ -1359,7 +1368,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1359 * set up a BDL entry 1368 * set up a BDL entry
1360 */ 1369 */
1361static int setup_bdle(struct azx *chip, 1370static int setup_bdle(struct azx *chip,
1362 struct snd_pcm_substream *substream, 1371 struct snd_dma_buffer *dmab,
1363 struct azx_dev *azx_dev, u32 **bdlp, 1372 struct azx_dev *azx_dev, u32 **bdlp,
1364 int ofs, int size, int with_ioc) 1373 int ofs, int size, int with_ioc)
1365{ 1374{
@@ -1372,12 +1381,12 @@ static int setup_bdle(struct azx *chip,
1372 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) 1381 if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
1373 return -EINVAL; 1382 return -EINVAL;
1374 1383
1375 addr = snd_pcm_sgbuf_get_addr(substream, ofs); 1384 addr = snd_sgbuf_get_addr(dmab, ofs);
1376 /* program the address field of the BDL entry */ 1385 /* program the address field of the BDL entry */
1377 bdl[0] = cpu_to_le32((u32)addr); 1386 bdl[0] = cpu_to_le32((u32)addr);
1378 bdl[1] = cpu_to_le32(upper_32_bits(addr)); 1387 bdl[1] = cpu_to_le32(upper_32_bits(addr));
1379 /* program the size field of the BDL entry */ 1388 /* program the size field of the BDL entry */
1380 chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); 1389 chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size);
1381 /* one BDLE cannot cross 4K boundary on CTHDA chips */ 1390 /* one BDLE cannot cross 4K boundary on CTHDA chips */
1382 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { 1391 if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) {
1383 u32 remain = 0x1000 - (ofs & 0xfff); 1392 u32 remain = 0x1000 - (ofs & 0xfff);
@@ -1436,7 +1445,8 @@ static int azx_setup_periods(struct azx *chip,
1436 bdl_pos_adj[chip->dev_index]); 1445 bdl_pos_adj[chip->dev_index]);
1437 pos_adj = 0; 1446 pos_adj = 0;
1438 } else { 1447 } else {
1439 ofs = setup_bdle(chip, substream, azx_dev, 1448 ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
1449 azx_dev,
1440 &bdl, ofs, pos_adj, true); 1450 &bdl, ofs, pos_adj, true);
1441 if (ofs < 0) 1451 if (ofs < 0)
1442 goto error; 1452 goto error;
@@ -1445,10 +1455,12 @@ static int azx_setup_periods(struct azx *chip,
1445 pos_adj = 0; 1455 pos_adj = 0;
1446 for (i = 0; i < periods; i++) { 1456 for (i = 0; i < periods; i++) {
1447 if (i == periods - 1 && pos_adj) 1457 if (i == periods - 1 && pos_adj)
1448 ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, 1458 ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
1459 azx_dev, &bdl, ofs,
1449 period_bytes - pos_adj, 0); 1460 period_bytes - pos_adj, 0);
1450 else 1461 else
1451 ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, 1462 ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
1463 azx_dev, &bdl, ofs,
1452 period_bytes, 1464 period_bytes,
1453 !azx_dev->no_period_wakeup); 1465 !azx_dev->no_period_wakeup);
1454 if (ofs < 0) 1466 if (ofs < 0)
@@ -1610,6 +1622,11 @@ static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *mode
1610 bus_temp.power_save = &power_save; 1622 bus_temp.power_save = &power_save;
1611 bus_temp.ops.pm_notify = azx_power_notify; 1623 bus_temp.ops.pm_notify = azx_power_notify;
1612#endif 1624#endif
1625#ifdef CONFIG_SND_HDA_DSP_LOADER
1626 bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare;
1627 bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger;
1628 bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup;
1629#endif
1613 1630
1614 err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); 1631 err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
1615 if (err < 0) 1632 if (err < 0)
@@ -2427,6 +2444,93 @@ static void azx_stop_chip(struct azx *chip)
2427 chip->initialized = 0; 2444 chip->initialized = 0;
2428} 2445}
2429 2446
2447#ifdef CONFIG_SND_HDA_DSP_LOADER
2448/*
2449 * DSP loading code (e.g. for CA0132)
2450 */
2451
2452/* use the first stream for loading DSP */
2453static struct azx_dev *
2454azx_get_dsp_loader_dev(struct azx *chip)
2455{
2456 return &chip->azx_dev[chip->playback_index_offset];
2457}
2458
2459static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
2460 unsigned int byte_size,
2461 struct snd_dma_buffer *bufp)
2462{
2463 u32 *bdl;
2464 struct azx *chip = bus->private_data;
2465 struct azx_dev *azx_dev;
2466 int err;
2467
2468 if (snd_hda_lock_devices(bus))
2469 return -EBUSY;
2470
2471 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG,
2472 snd_dma_pci_data(chip->pci),
2473 byte_size, bufp);
2474 if (err < 0)
2475 goto error;
2476
2477 azx_dev = azx_get_dsp_loader_dev(chip);
2478 azx_dev->bufsize = byte_size;
2479 azx_dev->period_bytes = byte_size;
2480 azx_dev->format_val = format;
2481
2482 azx_stream_reset(chip, azx_dev);
2483
2484 /* reset BDL address */
2485 azx_sd_writel(azx_dev, SD_BDLPL, 0);
2486 azx_sd_writel(azx_dev, SD_BDLPU, 0);
2487
2488 azx_dev->frags = 0;
2489 bdl = (u32 *)azx_dev->bdl.area;
2490 err = setup_bdle(chip, bufp, azx_dev, &bdl, 0, byte_size, 0);
2491 if (err < 0)
2492 goto error;
2493
2494 azx_setup_controller(chip, azx_dev);
2495 return azx_dev->stream_tag;
2496
2497 error:
2498 snd_hda_unlock_devices(bus);
2499 return err;
2500}
2501
2502static void azx_load_dsp_trigger(struct hda_bus *bus, bool start)
2503{
2504 struct azx *chip = bus->private_data;
2505 struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
2506
2507 if (start)
2508 azx_stream_start(chip, azx_dev);
2509 else
2510 azx_stream_stop(chip, azx_dev);
2511 azx_dev->running = start;
2512}
2513
2514static void azx_load_dsp_cleanup(struct hda_bus *bus,
2515 struct snd_dma_buffer *dmab)
2516{
2517 struct azx *chip = bus->private_data;
2518 struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
2519
2520 /* reset BDL address */
2521 azx_sd_writel(azx_dev, SD_BDLPL, 0);
2522 azx_sd_writel(azx_dev, SD_BDLPU, 0);
2523 azx_sd_writel(azx_dev, SD_CTL, 0);
2524 azx_dev->bufsize = 0;
2525 azx_dev->period_bytes = 0;
2526 azx_dev->format_val = 0;
2527
2528 snd_dma_free_pages(dmab);
2529
2530 snd_hda_unlock_devices(bus);
2531}
2532#endif /* CONFIG_SND_HDA_DSP_LOADER */
2533
2430#ifdef CONFIG_PM 2534#ifdef CONFIG_PM
2431/* power-up/down the controller */ 2535/* power-up/down the controller */
2432static void azx_power_notify(struct hda_bus *bus, bool power_up) 2536static void azx_power_notify(struct hda_bus *bus, bool power_up)