diff options
Diffstat (limited to 'sound/soc/intel')
| -rw-r--r-- | sound/soc/intel/boards/bxt_da7219_max98357a.c | 14 | ||||
| -rw-r--r-- | sound/soc/intel/skylake/skl-sst-ipc.c | 5 | ||||
| -rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 2 | ||||
| -rw-r--r-- | sound/soc/intel/skylake/skl.c | 162 | ||||
| -rw-r--r-- | sound/soc/intel/skylake/skl.h | 4 |
5 files changed, 106 insertions, 81 deletions
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 3a8c4d954a91..1866e31b6c29 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c | |||
| @@ -89,11 +89,6 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, | |||
| 89 | if (ret) | 89 | if (ret) |
| 90 | dev_err(card->dev, "failed to stop PLL: %d\n", ret); | 90 | dev_err(card->dev, "failed to stop PLL: %d\n", ret); |
| 91 | } else if(SND_SOC_DAPM_EVENT_ON(event)) { | 91 | } else if(SND_SOC_DAPM_EVENT_ON(event)) { |
| 92 | ret = snd_soc_dai_set_sysclk(codec_dai, | ||
| 93 | DA7219_CLKSRC_MCLK, 19200000, SND_SOC_CLOCK_IN); | ||
| 94 | if (ret) | ||
| 95 | dev_err(card->dev, "can't set codec sysclk configuration\n"); | ||
| 96 | |||
| 97 | ret = snd_soc_dai_set_pll(codec_dai, 0, | 92 | ret = snd_soc_dai_set_pll(codec_dai, 0, |
| 98 | DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304); | 93 | DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304); |
| 99 | if (ret) | 94 | if (ret) |
| @@ -187,8 +182,17 @@ static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, | |||
| 187 | static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) | 182 | static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) |
| 188 | { | 183 | { |
| 189 | int ret; | 184 | int ret; |
| 185 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 190 | struct snd_soc_codec *codec = rtd->codec; | 186 | struct snd_soc_codec *codec = rtd->codec; |
| 191 | 187 | ||
| 188 | /* Configure sysclk for codec */ | ||
| 189 | ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000, | ||
| 190 | SND_SOC_CLOCK_IN); | ||
| 191 | if (ret) { | ||
| 192 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); | ||
| 193 | return ret; | ||
| 194 | } | ||
| 195 | |||
| 192 | /* | 196 | /* |
| 193 | * Headset buttons map to the google Reference headset. | 197 | * Headset buttons map to the google Reference headset. |
| 194 | * These can be configured by userspace. | 198 | * These can be configured by userspace. |
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 58c525096a7c..498b15345b1a 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c | |||
| @@ -413,8 +413,11 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
| 413 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; | 413 | u32 reply = header.primary & IPC_GLB_REPLY_STATUS_MASK; |
| 414 | u64 *ipc_header = (u64 *)(&header); | 414 | u64 *ipc_header = (u64 *)(&header); |
| 415 | struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); | 415 | struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); |
| 416 | unsigned long flags; | ||
| 416 | 417 | ||
| 418 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); | ||
| 417 | msg = skl_ipc_reply_get_msg(ipc, *ipc_header); | 419 | msg = skl_ipc_reply_get_msg(ipc, *ipc_header); |
| 420 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); | ||
| 418 | if (msg == NULL) { | 421 | if (msg == NULL) { |
| 419 | dev_dbg(ipc->dev, "ipc: rx list is empty\n"); | 422 | dev_dbg(ipc->dev, "ipc: rx list is empty\n"); |
| 420 | return; | 423 | return; |
| @@ -456,8 +459,10 @@ static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, | |||
| 456 | } | 459 | } |
| 457 | } | 460 | } |
| 458 | 461 | ||
| 462 | spin_lock_irqsave(&ipc->dsp->spinlock, flags); | ||
| 459 | list_del(&msg->list); | 463 | list_del(&msg->list); |
| 460 | sst_ipc_tx_msg_reply_complete(ipc, msg); | 464 | sst_ipc_tx_msg_reply_complete(ipc, msg); |
| 465 | spin_unlock_irqrestore(&ipc->dsp->spinlock, flags); | ||
| 461 | } | 466 | } |
| 462 | 467 | ||
| 463 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) | 468 | irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context) |
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 3a99712e44a8..64a0f8ed33e1 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
| @@ -2502,7 +2502,7 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, | |||
| 2502 | 2502 | ||
| 2503 | if (ret < 0) | 2503 | if (ret < 0) |
| 2504 | return ret; | 2504 | return ret; |
| 2505 | tkn_count += ret; | 2505 | tkn_count = ret; |
| 2506 | 2506 | ||
| 2507 | tuple_size += tkn_count * | 2507 | tuple_size += tkn_count * |
| 2508 | sizeof(struct snd_soc_tplg_vendor_string_elem); | 2508 | sizeof(struct snd_soc_tplg_vendor_string_elem); |
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 6df3b317a476..4c9b5781282b 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
| @@ -410,7 +410,7 @@ static int skl_free(struct hdac_ext_bus *ebus) | |||
| 410 | struct skl *skl = ebus_to_skl(ebus); | 410 | struct skl *skl = ebus_to_skl(ebus); |
| 411 | struct hdac_bus *bus = ebus_to_hbus(ebus); | 411 | struct hdac_bus *bus = ebus_to_hbus(ebus); |
| 412 | 412 | ||
| 413 | skl->init_failed = 1; /* to be sure */ | 413 | skl->init_done = 0; /* to be sure */ |
| 414 | 414 | ||
| 415 | snd_hdac_ext_stop_streams(ebus); | 415 | snd_hdac_ext_stop_streams(ebus); |
| 416 | 416 | ||
| @@ -428,8 +428,10 @@ static int skl_free(struct hdac_ext_bus *ebus) | |||
| 428 | 428 | ||
| 429 | snd_hdac_ext_bus_exit(ebus); | 429 | snd_hdac_ext_bus_exit(ebus); |
| 430 | 430 | ||
| 431 | cancel_work_sync(&skl->probe_work); | ||
| 431 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | 432 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) |
| 432 | snd_hdac_i915_exit(&ebus->bus); | 433 | snd_hdac_i915_exit(&ebus->bus); |
| 434 | |||
| 433 | return 0; | 435 | return 0; |
| 434 | } | 436 | } |
| 435 | 437 | ||
| @@ -566,6 +568,84 @@ static const struct hdac_bus_ops bus_core_ops = { | |||
| 566 | .get_response = snd_hdac_bus_get_response, | 568 | .get_response = snd_hdac_bus_get_response, |
| 567 | }; | 569 | }; |
| 568 | 570 | ||
| 571 | static int skl_i915_init(struct hdac_bus *bus) | ||
| 572 | { | ||
| 573 | int err; | ||
| 574 | |||
| 575 | /* | ||
| 576 | * The HDMI codec is in GPU so we need to ensure that it is powered | ||
| 577 | * up and ready for probe | ||
| 578 | */ | ||
| 579 | err = snd_hdac_i915_init(bus); | ||
| 580 | if (err < 0) | ||
| 581 | return err; | ||
| 582 | |||
| 583 | err = snd_hdac_display_power(bus, true); | ||
| 584 | if (err < 0) | ||
| 585 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); | ||
| 586 | |||
| 587 | return err; | ||
| 588 | } | ||
| 589 | |||
| 590 | static void skl_probe_work(struct work_struct *work) | ||
| 591 | { | ||
| 592 | struct skl *skl = container_of(work, struct skl, probe_work); | ||
| 593 | struct hdac_ext_bus *ebus = &skl->ebus; | ||
| 594 | struct hdac_bus *bus = ebus_to_hbus(ebus); | ||
| 595 | struct hdac_ext_link *hlink = NULL; | ||
| 596 | int err; | ||
| 597 | |||
| 598 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
| 599 | err = skl_i915_init(bus); | ||
| 600 | if (err < 0) | ||
| 601 | return; | ||
| 602 | } | ||
| 603 | |||
| 604 | err = skl_init_chip(bus, true); | ||
| 605 | if (err < 0) { | ||
| 606 | dev_err(bus->dev, "Init chip failed with err: %d\n", err); | ||
| 607 | goto out_err; | ||
| 608 | } | ||
| 609 | |||
| 610 | /* codec detection */ | ||
| 611 | if (!bus->codec_mask) | ||
| 612 | dev_info(bus->dev, "no hda codecs found!\n"); | ||
| 613 | |||
| 614 | /* create codec instances */ | ||
| 615 | err = skl_codec_create(ebus); | ||
| 616 | if (err < 0) | ||
| 617 | goto out_err; | ||
| 618 | |||
| 619 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
| 620 | err = snd_hdac_display_power(bus, false); | ||
| 621 | if (err < 0) { | ||
| 622 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); | ||
| 623 | return; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | /* register platform dai and controls */ | ||
| 628 | err = skl_platform_register(bus->dev); | ||
| 629 | if (err < 0) | ||
| 630 | return; | ||
| 631 | /* | ||
| 632 | * we are done probing so decrement link counts | ||
| 633 | */ | ||
| 634 | list_for_each_entry(hlink, &ebus->hlink_list, list) | ||
| 635 | snd_hdac_ext_bus_link_put(ebus, hlink); | ||
| 636 | |||
| 637 | /* configure PM */ | ||
| 638 | pm_runtime_put_noidle(bus->dev); | ||
| 639 | pm_runtime_allow(bus->dev); | ||
| 640 | skl->init_done = 1; | ||
| 641 | |||
| 642 | return; | ||
| 643 | |||
| 644 | out_err: | ||
| 645 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | ||
| 646 | err = snd_hdac_display_power(bus, false); | ||
| 647 | } | ||
| 648 | |||
| 569 | /* | 649 | /* |
| 570 | * constructor | 650 | * constructor |
| 571 | */ | 651 | */ |
| @@ -593,6 +673,7 @@ static int skl_create(struct pci_dev *pci, | |||
| 593 | snd_hdac_ext_bus_init(ebus, &pci->dev, &bus_core_ops, io_ops); | 673 | snd_hdac_ext_bus_init(ebus, &pci->dev, &bus_core_ops, io_ops); |
| 594 | ebus->bus.use_posbuf = 1; | 674 | ebus->bus.use_posbuf = 1; |
| 595 | skl->pci = pci; | 675 | skl->pci = pci; |
| 676 | INIT_WORK(&skl->probe_work, skl_probe_work); | ||
| 596 | 677 | ||
| 597 | ebus->bus.bdl_pos_adj = 0; | 678 | ebus->bus.bdl_pos_adj = 0; |
| 598 | 679 | ||
| @@ -601,27 +682,6 @@ static int skl_create(struct pci_dev *pci, | |||
| 601 | return 0; | 682 | return 0; |
| 602 | } | 683 | } |
| 603 | 684 | ||
| 604 | static int skl_i915_init(struct hdac_bus *bus) | ||
| 605 | { | ||
| 606 | int err; | ||
| 607 | |||
| 608 | /* | ||
| 609 | * The HDMI codec is in GPU so we need to ensure that it is powered | ||
| 610 | * up and ready for probe | ||
| 611 | */ | ||
| 612 | err = snd_hdac_i915_init(bus); | ||
| 613 | if (err < 0) | ||
| 614 | return err; | ||
| 615 | |||
| 616 | err = snd_hdac_display_power(bus, true); | ||
| 617 | if (err < 0) { | ||
| 618 | dev_err(bus->dev, "Cannot turn on display power on i915\n"); | ||
| 619 | return err; | ||
| 620 | } | ||
| 621 | |||
| 622 | return err; | ||
| 623 | } | ||
| 624 | |||
| 625 | static int skl_first_init(struct hdac_ext_bus *ebus) | 685 | static int skl_first_init(struct hdac_ext_bus *ebus) |
| 626 | { | 686 | { |
| 627 | struct skl *skl = ebus_to_skl(ebus); | 687 | struct skl *skl = ebus_to_skl(ebus); |
| @@ -684,20 +744,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus) | |||
| 684 | /* initialize chip */ | 744 | /* initialize chip */ |
| 685 | skl_init_pci(skl); | 745 | skl_init_pci(skl); |
| 686 | 746 | ||
| 687 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | 747 | return skl_init_chip(bus, true); |
| 688 | err = skl_i915_init(bus); | ||
| 689 | if (err < 0) | ||
| 690 | return err; | ||
| 691 | } | ||
| 692 | |||
| 693 | skl_init_chip(bus, true); | ||
| 694 | |||
| 695 | /* codec detection */ | ||
| 696 | if (!bus->codec_mask) { | ||
| 697 | dev_info(bus->dev, "no hda codecs found!\n"); | ||
| 698 | } | ||
| 699 | |||
| 700 | return 0; | ||
| 701 | } | 748 | } |
| 702 | 749 | ||
| 703 | static int skl_probe(struct pci_dev *pci, | 750 | static int skl_probe(struct pci_dev *pci, |
| @@ -706,7 +753,6 @@ static int skl_probe(struct pci_dev *pci, | |||
| 706 | struct skl *skl; | 753 | struct skl *skl; |
| 707 | struct hdac_ext_bus *ebus = NULL; | 754 | struct hdac_ext_bus *ebus = NULL; |
| 708 | struct hdac_bus *bus = NULL; | 755 | struct hdac_bus *bus = NULL; |
| 709 | struct hdac_ext_link *hlink = NULL; | ||
| 710 | int err; | 756 | int err; |
| 711 | 757 | ||
| 712 | /* we use ext core ops, so provide NULL for ops here */ | 758 | /* we use ext core ops, so provide NULL for ops here */ |
| @@ -729,7 +775,7 @@ static int skl_probe(struct pci_dev *pci, | |||
| 729 | 775 | ||
| 730 | if (skl->nhlt == NULL) { | 776 | if (skl->nhlt == NULL) { |
| 731 | err = -ENODEV; | 777 | err = -ENODEV; |
| 732 | goto out_display_power_off; | 778 | goto out_free; |
| 733 | } | 779 | } |
| 734 | 780 | ||
| 735 | err = skl_nhlt_create_sysfs(skl); | 781 | err = skl_nhlt_create_sysfs(skl); |
| @@ -760,56 +806,24 @@ static int skl_probe(struct pci_dev *pci, | |||
| 760 | if (bus->mlcap) | 806 | if (bus->mlcap) |
| 761 | snd_hdac_ext_bus_get_ml_capabilities(ebus); | 807 | snd_hdac_ext_bus_get_ml_capabilities(ebus); |
| 762 | 808 | ||
| 809 | snd_hdac_bus_stop_chip(bus); | ||
| 810 | |||
| 763 | /* create device for soc dmic */ | 811 | /* create device for soc dmic */ |
| 764 | err = skl_dmic_device_register(skl); | 812 | err = skl_dmic_device_register(skl); |
| 765 | if (err < 0) | 813 | if (err < 0) |
| 766 | goto out_dsp_free; | 814 | goto out_dsp_free; |
| 767 | 815 | ||
| 768 | /* register platform dai and controls */ | 816 | schedule_work(&skl->probe_work); |
| 769 | err = skl_platform_register(bus->dev); | ||
| 770 | if (err < 0) | ||
| 771 | goto out_dmic_free; | ||
| 772 | |||
| 773 | /* create codec instances */ | ||
| 774 | err = skl_codec_create(ebus); | ||
| 775 | if (err < 0) | ||
| 776 | goto out_unregister; | ||
| 777 | |||
| 778 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | ||
| 779 | err = snd_hdac_display_power(bus, false); | ||
| 780 | if (err < 0) { | ||
| 781 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); | ||
| 782 | return err; | ||
| 783 | } | ||
| 784 | } | ||
| 785 | |||
| 786 | /* | ||
| 787 | * we are done probling so decrement link counts | ||
| 788 | */ | ||
| 789 | list_for_each_entry(hlink, &ebus->hlink_list, list) | ||
| 790 | snd_hdac_ext_bus_link_put(ebus, hlink); | ||
| 791 | |||
| 792 | /* configure PM */ | ||
| 793 | pm_runtime_put_noidle(bus->dev); | ||
| 794 | pm_runtime_allow(bus->dev); | ||
| 795 | 817 | ||
| 796 | return 0; | 818 | return 0; |
| 797 | 819 | ||
| 798 | out_unregister: | ||
| 799 | skl_platform_unregister(bus->dev); | ||
| 800 | out_dmic_free: | ||
| 801 | skl_dmic_device_unregister(skl); | ||
| 802 | out_dsp_free: | 820 | out_dsp_free: |
| 803 | skl_free_dsp(skl); | 821 | skl_free_dsp(skl); |
| 804 | out_mach_free: | 822 | out_mach_free: |
| 805 | skl_machine_device_unregister(skl); | 823 | skl_machine_device_unregister(skl); |
| 806 | out_nhlt_free: | 824 | out_nhlt_free: |
| 807 | skl_nhlt_free(skl->nhlt); | 825 | skl_nhlt_free(skl->nhlt); |
| 808 | out_display_power_off: | ||
| 809 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) | ||
| 810 | snd_hdac_display_power(bus, false); | ||
| 811 | out_free: | 826 | out_free: |
| 812 | skl->init_failed = 1; | ||
| 813 | skl_free(ebus); | 827 | skl_free(ebus); |
| 814 | 828 | ||
| 815 | return err; | 829 | return err; |
| @@ -828,7 +842,7 @@ static void skl_shutdown(struct pci_dev *pci) | |||
| 828 | 842 | ||
| 829 | skl = ebus_to_skl(ebus); | 843 | skl = ebus_to_skl(ebus); |
| 830 | 844 | ||
| 831 | if (skl->init_failed) | 845 | if (!skl->init_done) |
| 832 | return; | 846 | return; |
| 833 | 847 | ||
| 834 | snd_hdac_ext_stop_streams(ebus); | 848 | snd_hdac_ext_stop_streams(ebus); |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index a454f6035f3e..2a630fcb7f08 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h | |||
| @@ -46,7 +46,7 @@ struct skl { | |||
| 46 | struct hdac_ext_bus ebus; | 46 | struct hdac_ext_bus ebus; |
| 47 | struct pci_dev *pci; | 47 | struct pci_dev *pci; |
| 48 | 48 | ||
| 49 | unsigned int init_failed:1; /* delayed init failed */ | 49 | unsigned int init_done:1; /* delayed init status */ |
| 50 | struct platform_device *dmic_dev; | 50 | struct platform_device *dmic_dev; |
| 51 | struct platform_device *i2s_dev; | 51 | struct platform_device *i2s_dev; |
| 52 | struct snd_soc_platform *platform; | 52 | struct snd_soc_platform *platform; |
| @@ -64,6 +64,8 @@ struct skl { | |||
| 64 | const struct firmware *tplg; | 64 | const struct firmware *tplg; |
| 65 | 65 | ||
| 66 | int supend_active; | 66 | int supend_active; |
| 67 | |||
| 68 | struct work_struct probe_work; | ||
| 67 | }; | 69 | }; |
| 68 | 70 | ||
| 69 | #define skl_to_ebus(s) (&(s)->ebus) | 71 | #define skl_to_ebus(s) (&(s)->ebus) |
