| .. | .. |
|---|
| 336 | 336 | static int rk_multicodecs_hw_params(struct snd_pcm_substream *substream, |
|---|
| 337 | 337 | struct snd_pcm_hw_params *params) |
|---|
| 338 | 338 | { |
|---|
| 339 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
|---|
| 340 | | - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
|---|
| 339 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
|---|
| 340 | + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); |
|---|
| 341 | 341 | struct snd_soc_dai *codec_dai; |
|---|
| 342 | 342 | struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(rtd->card); |
|---|
| 343 | 343 | unsigned int mclk; |
|---|
| .. | .. |
|---|
| 345 | 345 | |
|---|
| 346 | 346 | mclk = params_rate(params) * mc_data->mclk_fs; |
|---|
| 347 | 347 | |
|---|
| 348 | | - for (i = 0; i < rtd->num_codecs; i++) { |
|---|
| 349 | | - codec_dai = rtd->codec_dais[i]; |
|---|
| 348 | + for_each_rtd_codec_dais(rtd, i, codec_dai) { |
|---|
| 350 | 349 | ret = snd_soc_dai_set_sysclk(codec_dai, substream->stream, mclk, |
|---|
| 351 | 350 | SND_SOC_CLOCK_IN); |
|---|
| 352 | 351 | if (ret && ret != -ENOTSUPP) { |
|---|
| .. | .. |
|---|
| 437 | 436 | int i; |
|---|
| 438 | 437 | |
|---|
| 439 | 438 | /* set jack for the first successful one */ |
|---|
| 440 | | - for (i = 0; i < rtd->num_codecs; i++) { |
|---|
| 441 | | - codec_dai = rtd->codec_dais[i]; |
|---|
| 439 | + for_each_rtd_codec_dais(rtd, i, codec_dai) { |
|---|
| 442 | 440 | ret = snd_soc_component_set_jack(codec_dai->component, |
|---|
| 443 | 441 | jack_headset, NULL); |
|---|
| 444 | 442 | if (ret >= 0) |
|---|
| .. | .. |
|---|
| 458 | 456 | dev_err(card->dev, "Failed to request headset detect irq"); |
|---|
| 459 | 457 | return ret; |
|---|
| 460 | 458 | } |
|---|
| 461 | | - |
|---|
| 462 | | - queue_delayed_work(system_power_efficient_wq, |
|---|
| 463 | | - &mc_data->handler, msecs_to_jiffies(50)); |
|---|
| 464 | 459 | } |
|---|
| 465 | 460 | } |
|---|
| 466 | 461 | |
|---|
| .. | .. |
|---|
| 584 | 579 | struct snd_soc_card *card; |
|---|
| 585 | 580 | struct device_node *np = pdev->dev.of_node; |
|---|
| 586 | 581 | struct snd_soc_dai_link *link; |
|---|
| 582 | + struct snd_soc_dai_link_component *cpus; |
|---|
| 583 | + struct snd_soc_dai_link_component *platforms; |
|---|
| 587 | 584 | struct snd_soc_dai_link_component *codecs; |
|---|
| 588 | 585 | struct multicodecs_data *mc_data; |
|---|
| 589 | 586 | struct of_phandle_args args; |
|---|
| 590 | 587 | struct device_node *node; |
|---|
| 591 | 588 | struct input_dev *input; |
|---|
| 592 | 589 | u32 val; |
|---|
| 593 | | - int count, value; |
|---|
| 590 | + int count, value, irq; |
|---|
| 594 | 591 | int ret = 0, i = 0, idx = 0; |
|---|
| 595 | 592 | const char *prefix = "rockchip,"; |
|---|
| 596 | 593 | |
|---|
| .. | .. |
|---|
| 602 | 599 | |
|---|
| 603 | 600 | mc_data = devm_kzalloc(&pdev->dev, sizeof(*mc_data), GFP_KERNEL); |
|---|
| 604 | 601 | if (!mc_data) |
|---|
| 602 | + return -ENOMEM; |
|---|
| 603 | + |
|---|
| 604 | + cpus = devm_kzalloc(&pdev->dev, sizeof(*cpus), GFP_KERNEL); |
|---|
| 605 | + if (!cpus) |
|---|
| 606 | + return -ENOMEM; |
|---|
| 607 | + |
|---|
| 608 | + platforms = devm_kzalloc(&pdev->dev, sizeof(*platforms), GFP_KERNEL); |
|---|
| 609 | + if (!platforms) |
|---|
| 605 | 610 | return -ENOMEM; |
|---|
| 606 | 611 | |
|---|
| 607 | 612 | card = &mc_data->snd_card; |
|---|
| .. | .. |
|---|
| 617 | 622 | link->stream_name = link->name; |
|---|
| 618 | 623 | link->init = rk_dailink_init; |
|---|
| 619 | 624 | link->ops = &rk_ops; |
|---|
| 625 | + link->cpus = cpus; |
|---|
| 626 | + link->platforms = platforms; |
|---|
| 627 | + link->num_cpus = 1; |
|---|
| 628 | + link->num_platforms = 1; |
|---|
| 620 | 629 | link->ignore_pmdown_time = 1; |
|---|
| 621 | 630 | |
|---|
| 622 | 631 | card->dai_link = link; |
|---|
| .. | .. |
|---|
| 673 | 682 | /* Only reference the codecs[0].of_node which maybe as master. */ |
|---|
| 674 | 683 | rk_multicodecs_parse_daifmt(np, codecs[0].of_node, mc_data, prefix); |
|---|
| 675 | 684 | |
|---|
| 676 | | - link->cpu_of_node = of_parse_phandle(np, "rockchip,cpu", 0); |
|---|
| 677 | | - if (!link->cpu_of_node) |
|---|
| 685 | + link->cpus->of_node = of_parse_phandle(np, "rockchip,cpu", 0); |
|---|
| 686 | + if (!link->cpus->of_node) |
|---|
| 678 | 687 | return -ENODEV; |
|---|
| 679 | 688 | |
|---|
| 680 | | - link->platform_of_node = link->cpu_of_node; |
|---|
| 689 | + link->platforms->of_node = link->cpus->of_node; |
|---|
| 681 | 690 | |
|---|
| 682 | 691 | mc_data->mclk_fs = DEFAULT_MCLK_FS; |
|---|
| 683 | 692 | if (!of_property_read_u32(np, "rockchip,mclk-fs", &val)) |
|---|
| .. | .. |
|---|
| 710 | 719 | |
|---|
| 711 | 720 | input = devm_input_allocate_device(&pdev->dev); |
|---|
| 712 | 721 | if (IS_ERR(input)) { |
|---|
| 713 | | - dev_err(&pdev->dev, "failed to allocate input device\n"); |
|---|
| 722 | + dev_err(&pdev->dev, "Failed to allocate input device\n"); |
|---|
| 714 | 723 | return PTR_ERR(input); |
|---|
| 715 | 724 | } |
|---|
| 716 | 725 | |
|---|
| .. | .. |
|---|
| 733 | 742 | mc_data->input = input; |
|---|
| 734 | 743 | ret = mc_keys_setup_polling(mc_data, mc_keys_poll); |
|---|
| 735 | 744 | if (ret) { |
|---|
| 736 | | - dev_err(&pdev->dev, "Unable to set up polling: %d\n", ret); |
|---|
| 745 | + dev_err(&pdev->dev, "Failed to set up polling: %d\n", ret); |
|---|
| 737 | 746 | return ret; |
|---|
| 738 | 747 | } |
|---|
| 739 | 748 | |
|---|
| .. | .. |
|---|
| 742 | 751 | |
|---|
| 743 | 752 | ret = input_register_device(mc_data->input); |
|---|
| 744 | 753 | if (ret) { |
|---|
| 745 | | - dev_err(&pdev->dev, "Unable to register input device: %d\n", ret); |
|---|
| 754 | + dev_err(&pdev->dev, "Failed to register input device: %d\n", ret); |
|---|
| 746 | 755 | return ret; |
|---|
| 747 | 756 | } |
|---|
| 748 | 757 | } |
|---|
| .. | .. |
|---|
| 767 | 776 | |
|---|
| 768 | 777 | mc_data->extcon = devm_extcon_dev_allocate(&pdev->dev, headset_extcon_cable); |
|---|
| 769 | 778 | if (IS_ERR(mc_data->extcon)) { |
|---|
| 770 | | - dev_err(&pdev->dev, "allocate extcon failed\n"); |
|---|
| 779 | + dev_err(&pdev->dev, "Failed to allocate extcon\n"); |
|---|
| 771 | 780 | return PTR_ERR(mc_data->extcon); |
|---|
| 772 | 781 | } |
|---|
| 773 | 782 | |
|---|
| 774 | 783 | ret = devm_extcon_dev_register(&pdev->dev, mc_data->extcon); |
|---|
| 775 | 784 | if (ret) { |
|---|
| 776 | | - dev_err(&pdev->dev, "failed to register extcon: %d\n", ret); |
|---|
| 785 | + dev_err(&pdev->dev, "Failed to register extcon: %d\n", ret); |
|---|
| 777 | 786 | return ret; |
|---|
| 778 | 787 | } |
|---|
| 779 | 788 | |
|---|
| 780 | | - ret = snd_soc_of_parse_audio_routing(card, "rockchip,audio-routing"); |
|---|
| 781 | | - if (ret < 0) |
|---|
| 782 | | - dev_warn(&pdev->dev, "Audio routing invalid/unspecified\n"); |
|---|
| 789 | + snd_soc_of_parse_audio_routing(card, "rockchip,audio-routing"); |
|---|
| 783 | 790 | |
|---|
| 784 | 791 | snd_soc_card_set_drvdata(card, mc_data); |
|---|
| 792 | + platform_set_drvdata(pdev, card); |
|---|
| 785 | 793 | |
|---|
| 786 | 794 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
|---|
| 787 | | - if (ret == -EPROBE_DEFER) |
|---|
| 788 | | - return -EPROBE_DEFER; |
|---|
| 789 | 795 | if (ret) { |
|---|
| 790 | | - dev_err(&pdev->dev, "card register failed %d\n", ret); |
|---|
| 796 | + dev_err(&pdev->dev, "Failed to register card: %d\n", ret); |
|---|
| 791 | 797 | return ret; |
|---|
| 792 | 798 | } |
|---|
| 793 | 799 | |
|---|
| 794 | | - platform_set_drvdata(pdev, card); |
|---|
| 800 | + irq = gpiod_to_irq(mc_data->hp_det_gpio); |
|---|
| 801 | + if (irq >= 0) |
|---|
| 802 | + queue_delayed_work(system_power_efficient_wq, |
|---|
| 803 | + &mc_data->handler, msecs_to_jiffies(50)); |
|---|
| 795 | 804 | |
|---|
| 796 | 805 | return ret; |
|---|
| 806 | +} |
|---|
| 807 | + |
|---|
| 808 | +static int rk_multicodec_remove(struct platform_device *pdev) |
|---|
| 809 | +{ |
|---|
| 810 | + struct snd_soc_card *card = platform_get_drvdata(pdev); |
|---|
| 811 | + struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card); |
|---|
| 812 | + |
|---|
| 813 | + cancel_delayed_work_sync(&mc_data->handler); |
|---|
| 814 | + |
|---|
| 815 | + return 0; |
|---|
| 816 | +} |
|---|
| 817 | + |
|---|
| 818 | +static void rk_multicodec_shutdown(struct platform_device *pdev) |
|---|
| 819 | +{ |
|---|
| 820 | + struct snd_soc_card *card = platform_get_drvdata(pdev); |
|---|
| 821 | + struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(card); |
|---|
| 822 | + |
|---|
| 823 | + cancel_delayed_work_sync(&mc_data->handler); |
|---|
| 797 | 824 | } |
|---|
| 798 | 825 | |
|---|
| 799 | 826 | static const struct of_device_id rockchip_multicodecs_of_match[] = { |
|---|
| .. | .. |
|---|
| 805 | 832 | |
|---|
| 806 | 833 | static struct platform_driver rockchip_multicodecs_driver = { |
|---|
| 807 | 834 | .probe = rk_multicodecs_probe, |
|---|
| 835 | + .remove = rk_multicodec_remove, |
|---|
| 836 | + .shutdown = rk_multicodec_shutdown, |
|---|
| 808 | 837 | .driver = { |
|---|
| 809 | 838 | .name = DRV_NAME, |
|---|
| 810 | 839 | .pm = &snd_soc_pm_ops, |
|---|