diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 116 |
1 files changed, 110 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d9e37ffdb048..4b099c603fe1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1085,6 +1085,15 @@ static unsigned int azx_get_response(struct hda_bus *bus, | |||
1085 | static void azx_power_notify(struct hda_bus *bus, bool power_up); | 1085 | static void azx_power_notify(struct hda_bus *bus, bool power_up); |
1086 | #endif | 1086 | #endif |
1087 | 1087 | ||
1088 | #ifdef CONFIG_SND_HDA_DSP_LOADER | ||
1089 | static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, | ||
1090 | unsigned int byte_size, | ||
1091 | struct snd_dma_buffer *bufp); | ||
1092 | static void azx_load_dsp_trigger(struct hda_bus *bus, bool start); | ||
1093 | static void azx_load_dsp_cleanup(struct hda_bus *bus, | ||
1094 | struct snd_dma_buffer *dmab); | ||
1095 | #endif | ||
1096 | |||
1088 | /* reset codec link */ | 1097 | /* reset codec link */ |
1089 | static int azx_reset(struct azx *chip, int full_reset) | 1098 | static int azx_reset(struct azx *chip, int full_reset) |
1090 | { | 1099 | { |
@@ -1408,7 +1417,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1408 | * set up a BDL entry | 1417 | * set up a BDL entry |
1409 | */ | 1418 | */ |
1410 | static int setup_bdle(struct azx *chip, | 1419 | static int setup_bdle(struct azx *chip, |
1411 | struct snd_pcm_substream *substream, | 1420 | struct snd_dma_buffer *dmab, |
1412 | struct azx_dev *azx_dev, u32 **bdlp, | 1421 | struct azx_dev *azx_dev, u32 **bdlp, |
1413 | int ofs, int size, int with_ioc) | 1422 | int ofs, int size, int with_ioc) |
1414 | { | 1423 | { |
@@ -1421,12 +1430,12 @@ static int setup_bdle(struct azx *chip, | |||
1421 | if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) | 1430 | if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) |
1422 | return -EINVAL; | 1431 | return -EINVAL; |
1423 | 1432 | ||
1424 | addr = snd_pcm_sgbuf_get_addr(substream, ofs); | 1433 | addr = snd_sgbuf_get_addr(dmab, ofs); |
1425 | /* program the address field of the BDL entry */ | 1434 | /* program the address field of the BDL entry */ |
1426 | bdl[0] = cpu_to_le32((u32)addr); | 1435 | bdl[0] = cpu_to_le32((u32)addr); |
1427 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); | 1436 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); |
1428 | /* program the size field of the BDL entry */ | 1437 | /* program the size field of the BDL entry */ |
1429 | chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); | 1438 | chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size); |
1430 | /* one BDLE cannot cross 4K boundary on CTHDA chips */ | 1439 | /* one BDLE cannot cross 4K boundary on CTHDA chips */ |
1431 | if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { | 1440 | if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) { |
1432 | u32 remain = 0x1000 - (ofs & 0xfff); | 1441 | u32 remain = 0x1000 - (ofs & 0xfff); |
@@ -1485,7 +1494,8 @@ static int azx_setup_periods(struct azx *chip, | |||
1485 | pci_name(chip->pci), bdl_pos_adj[chip->dev_index]); | 1494 | pci_name(chip->pci), bdl_pos_adj[chip->dev_index]); |
1486 | pos_adj = 0; | 1495 | pos_adj = 0; |
1487 | } else { | 1496 | } else { |
1488 | ofs = setup_bdle(chip, substream, azx_dev, | 1497 | ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), |
1498 | azx_dev, | ||
1489 | &bdl, ofs, pos_adj, true); | 1499 | &bdl, ofs, pos_adj, true); |
1490 | if (ofs < 0) | 1500 | if (ofs < 0) |
1491 | goto error; | 1501 | goto error; |
@@ -1494,10 +1504,12 @@ static int azx_setup_periods(struct azx *chip, | |||
1494 | pos_adj = 0; | 1504 | pos_adj = 0; |
1495 | for (i = 0; i < periods; i++) { | 1505 | for (i = 0; i < periods; i++) { |
1496 | if (i == periods - 1 && pos_adj) | 1506 | if (i == periods - 1 && pos_adj) |
1497 | ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, | 1507 | ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), |
1508 | azx_dev, &bdl, ofs, | ||
1498 | period_bytes - pos_adj, 0); | 1509 | period_bytes - pos_adj, 0); |
1499 | else | 1510 | else |
1500 | ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs, | 1511 | ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream), |
1512 | azx_dev, &bdl, ofs, | ||
1501 | period_bytes, | 1513 | period_bytes, |
1502 | !azx_dev->no_period_wakeup); | 1514 | !azx_dev->no_period_wakeup); |
1503 | if (ofs < 0) | 1515 | if (ofs < 0) |
@@ -1675,6 +1687,11 @@ static int azx_codec_create(struct azx *chip, const char *model) | |||
1675 | bus_temp.power_save = &power_save; | 1687 | bus_temp.power_save = &power_save; |
1676 | bus_temp.ops.pm_notify = azx_power_notify; | 1688 | bus_temp.ops.pm_notify = azx_power_notify; |
1677 | #endif | 1689 | #endif |
1690 | #ifdef CONFIG_SND_HDA_DSP_LOADER | ||
1691 | bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare; | ||
1692 | bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger; | ||
1693 | bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup; | ||
1694 | #endif | ||
1678 | 1695 | ||
1679 | err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); | 1696 | err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); |
1680 | if (err < 0) | 1697 | if (err < 0) |
@@ -2583,6 +2600,93 @@ static void azx_stop_chip(struct azx *chip) | |||
2583 | chip->initialized = 0; | 2600 | chip->initialized = 0; |
2584 | } | 2601 | } |
2585 | 2602 | ||
2603 | #ifdef CONFIG_SND_HDA_DSP_LOADER | ||
2604 | /* | ||
2605 | * DSP loading code (e.g. for CA0132) | ||
2606 | */ | ||
2607 | |||
2608 | /* use the first stream for loading DSP */ | ||
2609 | static struct azx_dev * | ||
2610 | azx_get_dsp_loader_dev(struct azx *chip) | ||
2611 | { | ||
2612 | return &chip->azx_dev[chip->playback_index_offset]; | ||
2613 | } | ||
2614 | |||
2615 | static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format, | ||
2616 | unsigned int byte_size, | ||
2617 | struct snd_dma_buffer *bufp) | ||
2618 | { | ||
2619 | u32 *bdl; | ||
2620 | struct azx *chip = bus->private_data; | ||
2621 | struct azx_dev *azx_dev; | ||
2622 | int err; | ||
2623 | |||
2624 | if (snd_hda_lock_devices(bus)) | ||
2625 | return -EBUSY; | ||
2626 | |||
2627 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, | ||
2628 | snd_dma_pci_data(chip->pci), | ||
2629 | byte_size, bufp); | ||
2630 | if (err < 0) | ||
2631 | goto error; | ||
2632 | |||
2633 | azx_dev = azx_get_dsp_loader_dev(chip); | ||
2634 | azx_dev->bufsize = byte_size; | ||
2635 | azx_dev->period_bytes = byte_size; | ||
2636 | azx_dev->format_val = format; | ||
2637 | |||
2638 | azx_stream_reset(chip, azx_dev); | ||
2639 | |||
2640 | /* reset BDL address */ | ||
2641 | azx_sd_writel(azx_dev, SD_BDLPL, 0); | ||
2642 | azx_sd_writel(azx_dev, SD_BDLPU, 0); | ||
2643 | |||
2644 | azx_dev->frags = 0; | ||
2645 | bdl = (u32 *)azx_dev->bdl.area; | ||
2646 | err = setup_bdle(chip, bufp, azx_dev, &bdl, 0, byte_size, 0); | ||
2647 | if (err < 0) | ||
2648 | goto error; | ||
2649 | |||
2650 | azx_setup_controller(chip, azx_dev); | ||
2651 | return azx_dev->stream_tag; | ||
2652 | |||
2653 | error: | ||
2654 | snd_hda_unlock_devices(bus); | ||
2655 | return err; | ||
2656 | } | ||
2657 | |||
2658 | static void azx_load_dsp_trigger(struct hda_bus *bus, bool start) | ||
2659 | { | ||
2660 | struct azx *chip = bus->private_data; | ||
2661 | struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip); | ||
2662 | |||
2663 | if (start) | ||
2664 | azx_stream_start(chip, azx_dev); | ||
2665 | else | ||
2666 | azx_stream_stop(chip, azx_dev); | ||
2667 | azx_dev->running = start; | ||
2668 | } | ||
2669 | |||
2670 | static void azx_load_dsp_cleanup(struct hda_bus *bus, | ||
2671 | struct snd_dma_buffer *dmab) | ||
2672 | { | ||
2673 | struct azx *chip = bus->private_data; | ||
2674 | struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip); | ||
2675 | |||
2676 | /* reset BDL address */ | ||
2677 | azx_sd_writel(azx_dev, SD_BDLPL, 0); | ||
2678 | azx_sd_writel(azx_dev, SD_BDLPU, 0); | ||
2679 | azx_sd_writel(azx_dev, SD_CTL, 0); | ||
2680 | azx_dev->bufsize = 0; | ||
2681 | azx_dev->period_bytes = 0; | ||
2682 | azx_dev->format_val = 0; | ||
2683 | |||
2684 | snd_dma_free_pages(dmab); | ||
2685 | |||
2686 | snd_hda_unlock_devices(bus); | ||
2687 | } | ||
2688 | #endif /* CONFIG_SND_HDA_DSP_LOADER */ | ||
2689 | |||
2586 | #ifdef CONFIG_PM | 2690 | #ifdef CONFIG_PM |
2587 | /* power-up/down the controller */ | 2691 | /* power-up/down the controller */ |
2588 | static void azx_power_notify(struct hda_bus *bus, bool power_up) | 2692 | static void azx_power_notify(struct hda_bus *bus, bool power_up) |