.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * rt5677.c -- RT5677 ALSA SoC audio codec driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2013 Realtek Semiconductor Corp. |
---|
5 | 6 | * Author: Oder Chiou <oder_chiou@realtek.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License version 2 as |
---|
9 | | - * published by the Free Software Foundation. |
---|
10 | 7 | */ |
---|
11 | 8 | |
---|
12 | 9 | #include <linux/acpi.h> |
---|
.. | .. |
---|
23 | 20 | #include <linux/firmware.h> |
---|
24 | 21 | #include <linux/of_device.h> |
---|
25 | 22 | #include <linux/property.h> |
---|
| 23 | +#include <linux/irq.h> |
---|
| 24 | +#include <linux/interrupt.h> |
---|
| 25 | +#include <linux/irqdomain.h> |
---|
| 26 | +#include <linux/workqueue.h> |
---|
26 | 27 | #include <sound/core.h> |
---|
27 | 28 | #include <sound/pcm.h> |
---|
28 | 29 | #include <sound/pcm_params.h> |
---|
.. | .. |
---|
36 | 37 | #include "rt5677-spi.h" |
---|
37 | 38 | |
---|
38 | 39 | #define RT5677_DEVICE_ID 0x6327 |
---|
| 40 | + |
---|
| 41 | +/* Register controlling boot vector */ |
---|
| 42 | +#define RT5677_DSP_BOOT_VECTOR 0x1801f090 |
---|
| 43 | +#define RT5677_MODEL_ADDR 0x5FFC9800 |
---|
39 | 44 | |
---|
40 | 45 | #define RT5677_PR_RANGE_BASE (0xff + 1) |
---|
41 | 46 | #define RT5677_PR_SPACING 0x100 |
---|
.. | .. |
---|
308 | 313 | case RT5677_IRQ_CTRL1: |
---|
309 | 314 | case RT5677_IRQ_CTRL2: |
---|
310 | 315 | case RT5677_GPIO_ST: |
---|
| 316 | + case RT5677_GPIO_CTRL1: /* Modified by DSP firmware */ |
---|
| 317 | + case RT5677_GPIO_CTRL2: /* Modified by DSP firmware */ |
---|
311 | 318 | case RT5677_DSP_INB1_SRC_CTRL4: |
---|
312 | 319 | case RT5677_DSP_INB2_SRC_CTRL4: |
---|
313 | 320 | case RT5677_DSP_INB3_SRC_CTRL4: |
---|
.. | .. |
---|
548 | 555 | * @rt5677: Private Data. |
---|
549 | 556 | * @addr: Address index. |
---|
550 | 557 | * @value: Address data. |
---|
551 | | - * |
---|
| 558 | + * @opcode: opcode value |
---|
552 | 559 | * |
---|
553 | 560 | * Returns 0 for success or negative error code. |
---|
554 | 561 | */ |
---|
.. | .. |
---|
603 | 610 | |
---|
604 | 611 | /** |
---|
605 | 612 | * rt5677_dsp_mode_i2c_read_addr - Read value from address on DSP mode. |
---|
606 | | - * rt5677: Private Data. |
---|
| 613 | + * @rt5677: Private Data. |
---|
607 | 614 | * @addr: Address index. |
---|
608 | 615 | * @value: Address data. |
---|
609 | 616 | * |
---|
.. | .. |
---|
652 | 659 | |
---|
653 | 660 | /** |
---|
654 | 661 | * rt5677_dsp_mode_i2c_write - Write register on DSP mode. |
---|
655 | | - * rt5677: Private Data. |
---|
| 662 | + * @rt5677: Private Data. |
---|
656 | 663 | * @reg: Register index. |
---|
657 | 664 | * @value: Register data. |
---|
658 | 665 | * |
---|
.. | .. |
---|
668 | 675 | |
---|
669 | 676 | /** |
---|
670 | 677 | * rt5677_dsp_mode_i2c_read - Read register on DSP mode. |
---|
671 | | - * @codec: SoC audio codec device. |
---|
| 678 | + * @rt5677: Private Data |
---|
672 | 679 | * @reg: Register index. |
---|
673 | 680 | * @value: Register data. |
---|
674 | 681 | * |
---|
.. | .. |
---|
686 | 693 | return ret; |
---|
687 | 694 | } |
---|
688 | 695 | |
---|
689 | | -static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on) |
---|
| 696 | +static void rt5677_set_dsp_mode(struct rt5677_priv *rt5677, bool on) |
---|
690 | 697 | { |
---|
691 | | - struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
692 | | - |
---|
693 | 698 | if (on) { |
---|
694 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2); |
---|
| 699 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, |
---|
| 700 | + RT5677_PWR_DSP, RT5677_PWR_DSP); |
---|
695 | 701 | rt5677->is_dsp_mode = true; |
---|
696 | 702 | } else { |
---|
697 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x0); |
---|
| 703 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, |
---|
| 704 | + RT5677_PWR_DSP, 0x0); |
---|
698 | 705 | rt5677->is_dsp_mode = false; |
---|
699 | 706 | } |
---|
| 707 | +} |
---|
| 708 | + |
---|
| 709 | +static unsigned int rt5677_set_vad_source(struct rt5677_priv *rt5677) |
---|
| 710 | +{ |
---|
| 711 | + struct snd_soc_dapm_context *dapm = |
---|
| 712 | + snd_soc_component_get_dapm(rt5677->component); |
---|
| 713 | + /* Force dapm to sync before we enable the |
---|
| 714 | + * DSP to prevent write corruption |
---|
| 715 | + */ |
---|
| 716 | + snd_soc_dapm_sync(dapm); |
---|
| 717 | + |
---|
| 718 | + /* DMIC1 power = enabled |
---|
| 719 | + * DMIC CLK = 256 * fs / 12 |
---|
| 720 | + */ |
---|
| 721 | + regmap_update_bits(rt5677->regmap, RT5677_DMIC_CTRL1, |
---|
| 722 | + RT5677_DMIC_CLK_MASK, 5 << RT5677_DMIC_CLK_SFT); |
---|
| 723 | + |
---|
| 724 | + /* I2S pre divide 2 = /6 (clk_sys2) */ |
---|
| 725 | + regmap_update_bits(rt5677->regmap, RT5677_CLK_TREE_CTRL1, |
---|
| 726 | + RT5677_I2S_PD2_MASK, RT5677_I2S_PD2_6); |
---|
| 727 | + |
---|
| 728 | + /* DSP Clock = MCLK1 (bypassed PLL2) */ |
---|
| 729 | + regmap_write(rt5677->regmap, RT5677_GLB_CLK2, |
---|
| 730 | + RT5677_DSP_CLK_SRC_BYPASS); |
---|
| 731 | + |
---|
| 732 | + /* SAD Threshold1 */ |
---|
| 733 | + regmap_write(rt5677->regmap, RT5677_VAD_CTRL2, 0x013f); |
---|
| 734 | + /* SAD Threshold2 */ |
---|
| 735 | + regmap_write(rt5677->regmap, RT5677_VAD_CTRL3, 0x0ae5); |
---|
| 736 | + /* SAD Sample Rate Converter = Up 6 (8K to 48K) |
---|
| 737 | + * SAD Output Sample Rate = Same as I2S |
---|
| 738 | + * SAD Threshold3 |
---|
| 739 | + */ |
---|
| 740 | + regmap_update_bits(rt5677->regmap, RT5677_VAD_CTRL4, |
---|
| 741 | + RT5677_VAD_OUT_SRC_RATE_MASK | RT5677_VAD_OUT_SRC_MASK | |
---|
| 742 | + RT5677_VAD_LV_DIFF_MASK, 0x7f << RT5677_VAD_LV_DIFF_SFT); |
---|
| 743 | + /* Minimum frame level within a pre-determined duration = 32 frames |
---|
| 744 | + * Bypass ADPCM Encoder/Decoder = Bypass ADPCM |
---|
| 745 | + * Automatic Push Data to SAD Buffer Once SAD Flag is triggered = enable |
---|
| 746 | + * SAD Buffer Over-Writing = enable |
---|
| 747 | + * SAD Buffer Pop Mode Control = disable |
---|
| 748 | + * SAD Buffer Push Mode Control = enable |
---|
| 749 | + * SAD Detector Control = enable |
---|
| 750 | + * SAD Function Control = enable |
---|
| 751 | + * SAD Function Reset = normal |
---|
| 752 | + */ |
---|
| 753 | + regmap_write(rt5677->regmap, RT5677_VAD_CTRL1, |
---|
| 754 | + RT5677_VAD_FUNC_RESET | RT5677_VAD_FUNC_ENABLE | |
---|
| 755 | + RT5677_VAD_DET_ENABLE | RT5677_VAD_BUF_PUSH | |
---|
| 756 | + RT5677_VAD_BUF_OW | RT5677_VAD_FG2ENC | |
---|
| 757 | + RT5677_VAD_ADPCM_BYPASS | 1 << RT5677_VAD_MIN_DUR_SFT); |
---|
| 758 | + |
---|
| 759 | + /* VAD/SAD is not routed to the IRQ output (i.e. MX-BE[14] = 0), but it |
---|
| 760 | + * is routed to DSP_IRQ_0, so DSP firmware may use it to sleep and save |
---|
| 761 | + * power. See ALC5677 datasheet section 9.17 "GPIO, Interrupt and Jack |
---|
| 762 | + * Detection" for more info. |
---|
| 763 | + */ |
---|
| 764 | + |
---|
| 765 | + /* Private register, no doc */ |
---|
| 766 | + regmap_update_bits(rt5677->regmap, RT5677_PR_BASE + RT5677_BIAS_CUR4, |
---|
| 767 | + 0x0f00, 0x0100); |
---|
| 768 | + |
---|
| 769 | + /* LDO2 output = 1.2V |
---|
| 770 | + * LDO1 output = 1.2V (LDO_IN = 1.8V) |
---|
| 771 | + */ |
---|
| 772 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, |
---|
| 773 | + RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, |
---|
| 774 | + 5 << RT5677_LDO1_SEL_SFT | 5 << RT5677_LDO2_SEL_SFT); |
---|
| 775 | + |
---|
| 776 | + /* Codec core power = power on |
---|
| 777 | + * LDO1 power = power on |
---|
| 778 | + */ |
---|
| 779 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, |
---|
| 780 | + RT5677_PWR_CORE | RT5677_PWR_LDO1, |
---|
| 781 | + RT5677_PWR_CORE | RT5677_PWR_LDO1); |
---|
| 782 | + |
---|
| 783 | + /* Isolation for DCVDD4 = normal (set during probe) |
---|
| 784 | + * Isolation for DCVDD2 = normal (set during probe) |
---|
| 785 | + * Isolation for DSP = normal |
---|
| 786 | + * Isolation for Band 0~7 = disable |
---|
| 787 | + * Isolation for InBound 4~10 and OutBound 4~10 = disable |
---|
| 788 | + */ |
---|
| 789 | + regmap_write(rt5677->regmap, RT5677_PWR_DSP2, |
---|
| 790 | + RT5677_PWR_CORE_ISO | RT5677_PWR_DSP_ISO | |
---|
| 791 | + RT5677_PWR_SR7_ISO | RT5677_PWR_SR6_ISO | |
---|
| 792 | + RT5677_PWR_SR5_ISO | RT5677_PWR_SR4_ISO | |
---|
| 793 | + RT5677_PWR_SR3_ISO | RT5677_PWR_SR2_ISO | |
---|
| 794 | + RT5677_PWR_SR1_ISO | RT5677_PWR_SR0_ISO | |
---|
| 795 | + RT5677_PWR_MLT_ISO); |
---|
| 796 | + |
---|
| 797 | + /* System Band 0~7 = power on |
---|
| 798 | + * InBound 4~10 and OutBound 4~10 = power on |
---|
| 799 | + * DSP = power on |
---|
| 800 | + * DSP CPU = stop (will be set to "run" after firmware loaded) |
---|
| 801 | + */ |
---|
| 802 | + regmap_write(rt5677->regmap, RT5677_PWR_DSP1, |
---|
| 803 | + RT5677_PWR_SR7 | RT5677_PWR_SR6 | |
---|
| 804 | + RT5677_PWR_SR5 | RT5677_PWR_SR4 | |
---|
| 805 | + RT5677_PWR_SR3 | RT5677_PWR_SR2 | |
---|
| 806 | + RT5677_PWR_SR1 | RT5677_PWR_SR0 | |
---|
| 807 | + RT5677_PWR_MLT | RT5677_PWR_DSP | |
---|
| 808 | + RT5677_PWR_DSP_CPU); |
---|
| 809 | + |
---|
| 810 | + return 0; |
---|
| 811 | +} |
---|
| 812 | + |
---|
| 813 | +static int rt5677_parse_and_load_dsp(struct rt5677_priv *rt5677, const u8 *buf, |
---|
| 814 | + unsigned int len) |
---|
| 815 | +{ |
---|
| 816 | + struct snd_soc_component *component = rt5677->component; |
---|
| 817 | + Elf32_Ehdr *elf_hdr; |
---|
| 818 | + Elf32_Phdr *pr_hdr; |
---|
| 819 | + Elf32_Half i; |
---|
| 820 | + int ret = 0; |
---|
| 821 | + |
---|
| 822 | + if (!buf || (len < sizeof(Elf32_Ehdr))) |
---|
| 823 | + return -ENOMEM; |
---|
| 824 | + |
---|
| 825 | + elf_hdr = (Elf32_Ehdr *)buf; |
---|
| 826 | +#ifndef EM_XTENSA |
---|
| 827 | +#define EM_XTENSA 94 |
---|
| 828 | +#endif |
---|
| 829 | + if (strncmp(elf_hdr->e_ident, ELFMAG, sizeof(ELFMAG) - 1)) |
---|
| 830 | + dev_err(component->dev, "Wrong ELF header prefix\n"); |
---|
| 831 | + if (elf_hdr->e_ehsize != sizeof(Elf32_Ehdr)) |
---|
| 832 | + dev_err(component->dev, "Wrong Elf header size\n"); |
---|
| 833 | + if (elf_hdr->e_machine != EM_XTENSA) |
---|
| 834 | + dev_err(component->dev, "Wrong DSP code file\n"); |
---|
| 835 | + |
---|
| 836 | + if (len < elf_hdr->e_phoff) |
---|
| 837 | + return -ENOMEM; |
---|
| 838 | + pr_hdr = (Elf32_Phdr *)(buf + elf_hdr->e_phoff); |
---|
| 839 | + for (i = 0; i < elf_hdr->e_phnum; i++) { |
---|
| 840 | + /* TODO: handle p_memsz != p_filesz */ |
---|
| 841 | + if (pr_hdr->p_paddr && pr_hdr->p_filesz) { |
---|
| 842 | + dev_info(component->dev, "Load 0x%x bytes to 0x%x\n", |
---|
| 843 | + pr_hdr->p_filesz, pr_hdr->p_paddr); |
---|
| 844 | + |
---|
| 845 | + ret = rt5677_spi_write(pr_hdr->p_paddr, |
---|
| 846 | + buf + pr_hdr->p_offset, |
---|
| 847 | + pr_hdr->p_filesz); |
---|
| 848 | + if (ret) |
---|
| 849 | + dev_err(component->dev, "Load firmware failed %d\n", |
---|
| 850 | + ret); |
---|
| 851 | + } |
---|
| 852 | + pr_hdr++; |
---|
| 853 | + } |
---|
| 854 | + return ret; |
---|
| 855 | +} |
---|
| 856 | + |
---|
| 857 | +static int rt5677_load_dsp_from_file(struct rt5677_priv *rt5677) |
---|
| 858 | +{ |
---|
| 859 | + const struct firmware *fwp; |
---|
| 860 | + struct device *dev = rt5677->component->dev; |
---|
| 861 | + int ret = 0; |
---|
| 862 | + |
---|
| 863 | + /* Load dsp firmware from rt5677_elf_vad file */ |
---|
| 864 | + ret = request_firmware(&fwp, "rt5677_elf_vad", dev); |
---|
| 865 | + if (ret) { |
---|
| 866 | + dev_err(dev, "Request rt5677_elf_vad failed %d\n", ret); |
---|
| 867 | + return ret; |
---|
| 868 | + } |
---|
| 869 | + dev_info(dev, "Requested rt5677_elf_vad (%zu)\n", fwp->size); |
---|
| 870 | + |
---|
| 871 | + ret = rt5677_parse_and_load_dsp(rt5677, fwp->data, fwp->size); |
---|
| 872 | + release_firmware(fwp); |
---|
| 873 | + return ret; |
---|
700 | 874 | } |
---|
701 | 875 | |
---|
702 | 876 | static int rt5677_set_dsp_vad(struct snd_soc_component *component, bool on) |
---|
703 | 877 | { |
---|
704 | 878 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
705 | | - static bool activity; |
---|
706 | | - int ret; |
---|
| 879 | + rt5677->dsp_vad_en_request = on; |
---|
| 880 | + rt5677->dsp_vad_en = on; |
---|
707 | 881 | |
---|
708 | 882 | if (!IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI)) |
---|
709 | 883 | return -ENXIO; |
---|
710 | 884 | |
---|
711 | | - if (on && !activity) { |
---|
| 885 | + schedule_delayed_work(&rt5677->dsp_work, 0); |
---|
| 886 | + return 0; |
---|
| 887 | +} |
---|
| 888 | + |
---|
| 889 | +static void rt5677_dsp_work(struct work_struct *work) |
---|
| 890 | +{ |
---|
| 891 | + struct rt5677_priv *rt5677 = |
---|
| 892 | + container_of(work, struct rt5677_priv, dsp_work.work); |
---|
| 893 | + static bool activity; |
---|
| 894 | + bool enable = rt5677->dsp_vad_en; |
---|
| 895 | + int i, val; |
---|
| 896 | + |
---|
| 897 | + |
---|
| 898 | + dev_info(rt5677->component->dev, "DSP VAD: enable=%d, activity=%d\n", |
---|
| 899 | + enable, activity); |
---|
| 900 | + |
---|
| 901 | + if (enable && !activity) { |
---|
712 | 902 | activity = true; |
---|
713 | 903 | |
---|
714 | | - regcache_cache_only(rt5677->regmap, false); |
---|
715 | | - regcache_cache_bypass(rt5677->regmap, true); |
---|
| 904 | + /* Before a hotword is detected, GPIO1 pin is configured as IRQ |
---|
| 905 | + * output so that jack detect works. When a hotword is detected, |
---|
| 906 | + * the DSP firmware configures the GPIO1 pin as GPIO1 and |
---|
| 907 | + * drives a 1. rt5677_irq() is called after a rising edge on |
---|
| 908 | + * the GPIO1 pin, due to either jack detect event or hotword |
---|
| 909 | + * event, or both. All possible events are checked and handled |
---|
| 910 | + * in rt5677_irq() where GPIO1 pin is configured back to IRQ |
---|
| 911 | + * output if a hotword is detected. |
---|
| 912 | + */ |
---|
716 | 913 | |
---|
717 | | - regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x1); |
---|
718 | | - regmap_update_bits(rt5677->regmap, |
---|
719 | | - RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0f00); |
---|
720 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, |
---|
721 | | - RT5677_LDO1_SEL_MASK, 0x0); |
---|
722 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, |
---|
723 | | - RT5677_PWR_LDO1, RT5677_PWR_LDO1); |
---|
724 | | - switch (rt5677->type) { |
---|
725 | | - case RT5677: |
---|
726 | | - regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1, |
---|
727 | | - RT5677_MCLK_SRC_MASK, RT5677_MCLK2_SRC); |
---|
728 | | - regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2, |
---|
729 | | - RT5677_PLL2_PR_SRC_MASK | |
---|
730 | | - RT5677_DSP_CLK_SRC_MASK, |
---|
731 | | - RT5677_PLL2_PR_SRC_MCLK2 | |
---|
732 | | - RT5677_DSP_CLK_SRC_BYPASS); |
---|
733 | | - break; |
---|
734 | | - case RT5676: |
---|
735 | | - regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2, |
---|
736 | | - RT5677_DSP_CLK_SRC_MASK, |
---|
737 | | - RT5677_DSP_CLK_SRC_BYPASS); |
---|
738 | | - break; |
---|
739 | | - default: |
---|
740 | | - break; |
---|
| 914 | + rt5677_set_vad_source(rt5677); |
---|
| 915 | + rt5677_set_dsp_mode(rt5677, true); |
---|
| 916 | + |
---|
| 917 | +#define RT5677_BOOT_RETRY 20 |
---|
| 918 | + for (i = 0; i < RT5677_BOOT_RETRY; i++) { |
---|
| 919 | + regmap_read(rt5677->regmap, RT5677_PWR_DSP_ST, &val); |
---|
| 920 | + if (val == 0x3ff) |
---|
| 921 | + break; |
---|
| 922 | + udelay(500); |
---|
741 | 923 | } |
---|
742 | | - regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff); |
---|
743 | | - regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd); |
---|
744 | | - rt5677_set_dsp_mode(component, true); |
---|
745 | | - |
---|
746 | | - ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1, |
---|
747 | | - component->dev); |
---|
748 | | - if (ret == 0) { |
---|
749 | | - rt5677_spi_write_firmware(0x50000000, rt5677->fw1); |
---|
750 | | - release_firmware(rt5677->fw1); |
---|
| 924 | + if (i == RT5677_BOOT_RETRY && val != 0x3ff) { |
---|
| 925 | + dev_err(rt5677->component->dev, "DSP Boot Timed Out!"); |
---|
| 926 | + return; |
---|
751 | 927 | } |
---|
752 | 928 | |
---|
753 | | - ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2, |
---|
754 | | - component->dev); |
---|
755 | | - if (ret == 0) { |
---|
756 | | - rt5677_spi_write_firmware(0x60000000, rt5677->fw2); |
---|
757 | | - release_firmware(rt5677->fw2); |
---|
758 | | - } |
---|
| 929 | + /* Boot the firmware from IRAM instead of SRAM0. */ |
---|
| 930 | + rt5677_dsp_mode_i2c_write_addr(rt5677, RT5677_DSP_BOOT_VECTOR, |
---|
| 931 | + 0x0009, 0x0003); |
---|
| 932 | + rt5677_dsp_mode_i2c_write_addr(rt5677, RT5677_DSP_BOOT_VECTOR, |
---|
| 933 | + 0x0019, 0x0003); |
---|
| 934 | + rt5677_dsp_mode_i2c_write_addr(rt5677, RT5677_DSP_BOOT_VECTOR, |
---|
| 935 | + 0x0009, 0x0003); |
---|
759 | 936 | |
---|
760 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x0); |
---|
| 937 | + rt5677_load_dsp_from_file(rt5677); |
---|
761 | 938 | |
---|
762 | | - regcache_cache_bypass(rt5677->regmap, false); |
---|
763 | | - regcache_cache_only(rt5677->regmap, true); |
---|
764 | | - } else if (!on && activity) { |
---|
| 939 | + /* Set DSP CPU to Run */ |
---|
| 940 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, |
---|
| 941 | + RT5677_PWR_DSP_CPU, 0x0); |
---|
| 942 | + } else if (!enable && activity) { |
---|
765 | 943 | activity = false; |
---|
766 | 944 | |
---|
767 | | - regcache_cache_only(rt5677->regmap, false); |
---|
768 | | - regcache_cache_bypass(rt5677->regmap, true); |
---|
| 945 | + /* Don't turn off the DSP while handling irqs */ |
---|
| 946 | + mutex_lock(&rt5677->irq_lock); |
---|
| 947 | + /* Set DSP CPU to Stop */ |
---|
| 948 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, |
---|
| 949 | + RT5677_PWR_DSP_CPU, RT5677_PWR_DSP_CPU); |
---|
769 | 950 | |
---|
770 | | - regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x1, 0x1); |
---|
771 | | - rt5677_set_dsp_mode(component, false); |
---|
772 | | - regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x0001); |
---|
| 951 | + rt5677_set_dsp_mode(rt5677, false); |
---|
773 | 952 | |
---|
774 | | - regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); |
---|
| 953 | + /* Disable and clear VAD interrupt */ |
---|
| 954 | + regmap_write(rt5677->regmap, RT5677_VAD_CTRL1, 0x2184); |
---|
775 | 955 | |
---|
776 | | - regcache_cache_bypass(rt5677->regmap, false); |
---|
777 | | - regcache_mark_dirty(rt5677->regmap); |
---|
778 | | - regcache_sync(rt5677->regmap); |
---|
| 956 | + /* Set GPIO1 pin back to be IRQ output for jack detect */ |
---|
| 957 | + regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, |
---|
| 958 | + RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ); |
---|
| 959 | + |
---|
| 960 | + mutex_unlock(&rt5677->irq_lock); |
---|
779 | 961 | } |
---|
780 | | - |
---|
781 | | - return 0; |
---|
782 | 962 | } |
---|
783 | 963 | |
---|
784 | 964 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); |
---|
.. | .. |
---|
803 | 983 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
804 | 984 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
805 | 985 | |
---|
806 | | - ucontrol->value.integer.value[0] = rt5677->dsp_vad_en; |
---|
| 986 | + ucontrol->value.integer.value[0] = rt5677->dsp_vad_en_request; |
---|
807 | 987 | |
---|
808 | 988 | return 0; |
---|
809 | 989 | } |
---|
.. | .. |
---|
812 | 992 | struct snd_ctl_elem_value *ucontrol) |
---|
813 | 993 | { |
---|
814 | 994 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
815 | | - struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
816 | 995 | |
---|
817 | | - rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0]; |
---|
818 | | - |
---|
819 | | - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) |
---|
820 | | - rt5677_set_dsp_vad(component, rt5677->dsp_vad_en); |
---|
| 996 | + rt5677_set_dsp_vad(component, !!ucontrol->value.integer.value[0]); |
---|
821 | 997 | |
---|
822 | 998 | return 0; |
---|
823 | 999 | } |
---|
.. | .. |
---|
833 | 1009 | |
---|
834 | 1010 | /* DAC Digital Volume */ |
---|
835 | 1011 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5677_DAC1_DIG_VOL, |
---|
836 | | - RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv), |
---|
| 1012 | + RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv), |
---|
837 | 1013 | SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5677_DAC2_DIG_VOL, |
---|
838 | | - RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv), |
---|
| 1014 | + RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv), |
---|
839 | 1015 | SOC_DOUBLE_TLV("DAC3 Playback Volume", RT5677_DAC3_DIG_VOL, |
---|
840 | | - RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv), |
---|
| 1016 | + RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv), |
---|
841 | 1017 | SOC_DOUBLE_TLV("DAC4 Playback Volume", RT5677_DAC4_DIG_VOL, |
---|
842 | | - RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv), |
---|
| 1018 | + RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv), |
---|
843 | 1019 | |
---|
844 | 1020 | /* IN1/IN2 Control */ |
---|
845 | 1021 | SOC_SINGLE_TLV("IN1 Boost", RT5677_IN1, RT5677_BST_SFT1, 8, 0, bst_tlv), |
---|
.. | .. |
---|
2608 | 2784 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0), |
---|
2609 | 2785 | SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0), |
---|
2610 | 2786 | SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0), |
---|
2611 | | - SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0), |
---|
| 2787 | + SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, |
---|
| 2788 | + rt5677_filter_power_event, SND_SOC_DAPM_POST_PMU), |
---|
2612 | 2789 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL, |
---|
2613 | 2790 | 0), |
---|
2614 | 2791 | SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL, |
---|
.. | .. |
---|
3007 | 3184 | SND_SOC_DAPM_AIF_OUT("AIF4TX", "AIF4 Capture", 0, SND_SOC_NOPM, 0, 0), |
---|
3008 | 3185 | SND_SOC_DAPM_AIF_IN("SLBRX", "SLIMBus Playback", 0, SND_SOC_NOPM, 0, 0), |
---|
3009 | 3186 | SND_SOC_DAPM_AIF_OUT("SLBTX", "SLIMBus Capture", 0, SND_SOC_NOPM, 0, 0), |
---|
| 3187 | + SND_SOC_DAPM_AIF_OUT("DSPTX", "DSP Buffer", 0, SND_SOC_NOPM, 0, 0), |
---|
3010 | 3188 | |
---|
3011 | 3189 | /* Sidetone Mux */ |
---|
3012 | 3190 | SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0, |
---|
.. | .. |
---|
3541 | 3719 | { "SLBTX", NULL, "SLB ADC3 Mux" }, |
---|
3542 | 3720 | { "SLBTX", NULL, "SLB ADC4 Mux" }, |
---|
3543 | 3721 | |
---|
| 3722 | + { "DSPTX", NULL, "IB01 Bypass Mux" }, |
---|
| 3723 | + |
---|
3544 | 3724 | { "IB01 Mux", "IF1 DAC 01", "IF1 DAC01" }, |
---|
3545 | 3725 | { "IB01 Mux", "IF2 DAC 01", "IF2 DAC01" }, |
---|
3546 | 3726 | { "IB01 Mux", "SLB DAC 01", "SLB DAC01" }, |
---|
3547 | 3727 | { "IB01 Mux", "STO1 ADC MIX", "Stereo1 ADC MIX" }, |
---|
3548 | | - { "IB01 Mux", "VAD ADC/DAC1 FS", "DAC1 FS" }, |
---|
| 3728 | + /* The IB01 Mux controls the source for InBound0 and InBound1. |
---|
| 3729 | + * When the mux option "VAD ADC/DAC1 FS" is selected, "VAD ADC" goes to |
---|
| 3730 | + * InBound0 and "DAC1 FS" goes to InBound1. "VAD ADC" is used for |
---|
| 3731 | + * hotwording. "DAC1 FS" is not used currently. |
---|
| 3732 | + * |
---|
| 3733 | + * Creating a common widget node for "VAD ADC" + "DAC1 FS" and |
---|
| 3734 | + * connecting the common widget to IB01 Mux causes the issue where |
---|
| 3735 | + * there is an active path going from system playback -> "DAC1 FS" -> |
---|
| 3736 | + * IB01 Mux -> DSP Buffer -> hotword stream. This wrong path confuses |
---|
| 3737 | + * DAPM. Therefore "DAC1 FS" is ignored for now. |
---|
| 3738 | + */ |
---|
| 3739 | + { "IB01 Mux", "VAD ADC/DAC1 FS", "VAD ADC Mux" }, |
---|
3549 | 3740 | |
---|
3550 | 3741 | { "IB01 Bypass Mux", "Bypass", "IB01 Mux" }, |
---|
3551 | 3742 | { "IB01 Bypass Mux", "Pass SRC", "IB01 Mux" }, |
---|
.. | .. |
---|
4418 | 4609 | break; |
---|
4419 | 4610 | case 25: |
---|
4420 | 4611 | slot_width_25 = 0x8080; |
---|
4421 | | - /* fall through */ |
---|
| 4612 | + fallthrough; |
---|
4422 | 4613 | case 24: |
---|
4423 | 4614 | val |= (2 << 8); |
---|
4424 | 4615 | break; |
---|
.. | .. |
---|
4454 | 4645 | enum snd_soc_bias_level level) |
---|
4455 | 4646 | { |
---|
4456 | 4647 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
| 4648 | + enum snd_soc_bias_level prev_bias = |
---|
| 4649 | + snd_soc_component_get_bias_level(component); |
---|
4457 | 4650 | |
---|
4458 | 4651 | switch (level) { |
---|
4459 | 4652 | case SND_SOC_BIAS_ON: |
---|
4460 | 4653 | break; |
---|
4461 | 4654 | |
---|
4462 | 4655 | case SND_SOC_BIAS_PREPARE: |
---|
4463 | | - if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { |
---|
4464 | | - rt5677_set_dsp_vad(component, false); |
---|
| 4656 | + if (prev_bias == SND_SOC_BIAS_STANDBY) { |
---|
4465 | 4657 | |
---|
4466 | 4658 | regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, |
---|
4467 | 4659 | RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, |
---|
4468 | | - 0x0055); |
---|
| 4660 | + 5 << RT5677_LDO1_SEL_SFT | |
---|
| 4661 | + 5 << RT5677_LDO2_SEL_SFT); |
---|
4469 | 4662 | regmap_update_bits(rt5677->regmap, |
---|
4470 | 4663 | RT5677_PR_BASE + RT5677_BIAS_CUR4, |
---|
4471 | 4664 | 0x0f00, 0x0f00); |
---|
.. | .. |
---|
4484 | 4677 | break; |
---|
4485 | 4678 | |
---|
4486 | 4679 | case SND_SOC_BIAS_STANDBY: |
---|
| 4680 | + if (prev_bias == SND_SOC_BIAS_OFF && |
---|
| 4681 | + rt5677->dsp_vad_en_request) { |
---|
| 4682 | + /* Re-enable the DSP if it was turned off at suspend */ |
---|
| 4683 | + rt5677->dsp_vad_en = true; |
---|
| 4684 | + /* The delay is to wait for MCLK */ |
---|
| 4685 | + schedule_delayed_work(&rt5677->dsp_work, |
---|
| 4686 | + msecs_to_jiffies(1000)); |
---|
| 4687 | + } |
---|
4487 | 4688 | break; |
---|
4488 | 4689 | |
---|
4489 | 4690 | case SND_SOC_BIAS_OFF: |
---|
| 4691 | + flush_delayed_work(&rt5677->dsp_work); |
---|
| 4692 | + if (rt5677->is_dsp_mode) { |
---|
| 4693 | + /* Turn off the DSP before suspend */ |
---|
| 4694 | + rt5677->dsp_vad_en = false; |
---|
| 4695 | + schedule_delayed_work(&rt5677->dsp_work, 0); |
---|
| 4696 | + flush_delayed_work(&rt5677->dsp_work); |
---|
| 4697 | + } |
---|
| 4698 | + |
---|
4490 | 4699 | regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); |
---|
4491 | 4700 | regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); |
---|
4492 | | - regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000); |
---|
4493 | | - regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022); |
---|
4494 | | - regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); |
---|
| 4701 | + regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, |
---|
| 4702 | + 2 << RT5677_LDO1_SEL_SFT | |
---|
| 4703 | + 2 << RT5677_LDO2_SEL_SFT); |
---|
| 4704 | + regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, |
---|
| 4705 | + RT5677_PWR_CORE, 0); |
---|
4495 | 4706 | regmap_update_bits(rt5677->regmap, |
---|
4496 | 4707 | RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); |
---|
4497 | 4708 | |
---|
.. | .. |
---|
4621 | 4832 | static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) |
---|
4622 | 4833 | { |
---|
4623 | 4834 | struct rt5677_priv *rt5677 = gpiochip_get_data(chip); |
---|
4624 | | - struct regmap_irq_chip_data *data = rt5677->irq_data; |
---|
4625 | 4835 | int irq; |
---|
4626 | 4836 | |
---|
4627 | 4837 | if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || |
---|
.. | .. |
---|
4647 | 4857 | return -ENXIO; |
---|
4648 | 4858 | } |
---|
4649 | 4859 | |
---|
4650 | | - return regmap_irq_get_virq(data, irq); |
---|
| 4860 | + return irq_create_mapping(rt5677->domain, irq); |
---|
4651 | 4861 | } |
---|
4652 | 4862 | |
---|
4653 | 4863 | static const struct gpio_chip rt5677_template_chip = { |
---|
4654 | | - .label = "rt5677", |
---|
| 4864 | + .label = RT5677_DRV_NAME, |
---|
4655 | 4865 | .owner = THIS_MODULE, |
---|
4656 | 4866 | .direction_output = rt5677_gpio_direction_out, |
---|
4657 | 4867 | .set = rt5677_gpio_set, |
---|
.. | .. |
---|
4717 | 4927 | |
---|
4718 | 4928 | snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); |
---|
4719 | 4929 | |
---|
4720 | | - regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020); |
---|
4721 | | - regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00); |
---|
| 4930 | + regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, |
---|
| 4931 | + ~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020); |
---|
| 4932 | + regmap_write(rt5677->regmap, RT5677_PWR_DSP2, |
---|
| 4933 | + RT5677_PWR_SLIM_ISO | RT5677_PWR_CORE_ISO); |
---|
4722 | 4934 | |
---|
4723 | 4935 | for (i = 0; i < RT5677_GPIO_NUM; i++) |
---|
4724 | 4936 | rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); |
---|
4725 | | - |
---|
4726 | | - if (rt5677->irq_data) { |
---|
4727 | | - regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, 0x8000, |
---|
4728 | | - 0x8000); |
---|
4729 | | - regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x0018, |
---|
4730 | | - 0x0008); |
---|
4731 | | - |
---|
4732 | | - if (rt5677->pdata.jd1_gpio) |
---|
4733 | | - regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, |
---|
4734 | | - RT5677_SEL_GPIO_JD1_MASK, |
---|
4735 | | - rt5677->pdata.jd1_gpio << |
---|
4736 | | - RT5677_SEL_GPIO_JD1_SFT); |
---|
4737 | | - |
---|
4738 | | - if (rt5677->pdata.jd2_gpio) |
---|
4739 | | - regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, |
---|
4740 | | - RT5677_SEL_GPIO_JD2_MASK, |
---|
4741 | | - rt5677->pdata.jd2_gpio << |
---|
4742 | | - RT5677_SEL_GPIO_JD2_SFT); |
---|
4743 | | - |
---|
4744 | | - if (rt5677->pdata.jd3_gpio) |
---|
4745 | | - regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, |
---|
4746 | | - RT5677_SEL_GPIO_JD3_MASK, |
---|
4747 | | - rt5677->pdata.jd3_gpio << |
---|
4748 | | - RT5677_SEL_GPIO_JD3_SFT); |
---|
4749 | | - } |
---|
4750 | 4937 | |
---|
4751 | 4938 | mutex_init(&rt5677->dsp_cmd_lock); |
---|
4752 | 4939 | mutex_init(&rt5677->dsp_pri_lock); |
---|
.. | .. |
---|
4758 | 4945 | { |
---|
4759 | 4946 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
4760 | 4947 | |
---|
| 4948 | + cancel_delayed_work_sync(&rt5677->dsp_work); |
---|
| 4949 | + |
---|
4761 | 4950 | regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); |
---|
4762 | 4951 | gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); |
---|
4763 | 4952 | gpiod_set_value_cansleep(rt5677->reset_pin, 1); |
---|
.. | .. |
---|
4767 | 4956 | static int rt5677_suspend(struct snd_soc_component *component) |
---|
4768 | 4957 | { |
---|
4769 | 4958 | struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component); |
---|
| 4959 | + |
---|
| 4960 | + if (rt5677->irq) { |
---|
| 4961 | + cancel_delayed_work_sync(&rt5677->resume_irq_check); |
---|
| 4962 | + disable_irq(rt5677->irq); |
---|
| 4963 | + } |
---|
4770 | 4964 | |
---|
4771 | 4965 | if (!rt5677->dsp_vad_en) { |
---|
4772 | 4966 | regcache_cache_only(rt5677->regmap, true); |
---|
.. | .. |
---|
4794 | 4988 | |
---|
4795 | 4989 | regcache_cache_only(rt5677->regmap, false); |
---|
4796 | 4990 | regcache_sync(rt5677->regmap); |
---|
| 4991 | + } |
---|
| 4992 | + |
---|
| 4993 | + if (rt5677->irq) { |
---|
| 4994 | + enable_irq(rt5677->irq); |
---|
| 4995 | + schedule_delayed_work(&rt5677->resume_irq_check, 0); |
---|
4797 | 4996 | } |
---|
4798 | 4997 | |
---|
4799 | 4998 | return 0; |
---|
.. | .. |
---|
4858 | 5057 | .set_sysclk = rt5677_set_dai_sysclk, |
---|
4859 | 5058 | .set_pll = rt5677_set_dai_pll, |
---|
4860 | 5059 | .set_tdm_slot = rt5677_set_tdm_slot, |
---|
| 5060 | +}; |
---|
| 5061 | + |
---|
| 5062 | +static const struct snd_soc_dai_ops rt5677_dsp_dai_ops = { |
---|
| 5063 | + .set_sysclk = rt5677_set_dai_sysclk, |
---|
| 5064 | + .set_pll = rt5677_set_dai_pll, |
---|
4861 | 5065 | }; |
---|
4862 | 5066 | |
---|
4863 | 5067 | static struct snd_soc_dai_driver rt5677_dai[] = { |
---|
.. | .. |
---|
4956 | 5160 | }, |
---|
4957 | 5161 | .ops = &rt5677_aif_dai_ops, |
---|
4958 | 5162 | }, |
---|
| 5163 | + { |
---|
| 5164 | + .name = "rt5677-dspbuffer", |
---|
| 5165 | + .id = RT5677_DSPBUFF, |
---|
| 5166 | + .capture = { |
---|
| 5167 | + .stream_name = "DSP Buffer", |
---|
| 5168 | + .channels_min = 1, |
---|
| 5169 | + .channels_max = 1, |
---|
| 5170 | + .rates = SNDRV_PCM_RATE_16000, |
---|
| 5171 | + .formats = SNDRV_PCM_FMTBIT_S16_LE, |
---|
| 5172 | + }, |
---|
| 5173 | + .ops = &rt5677_dsp_dai_ops, |
---|
| 5174 | + }, |
---|
4959 | 5175 | }; |
---|
4960 | 5176 | |
---|
4961 | 5177 | static const struct snd_soc_component_driver soc_component_dev_rt5677 = { |
---|
| 5178 | + .name = RT5677_DRV_NAME, |
---|
4962 | 5179 | .probe = rt5677_probe, |
---|
4963 | 5180 | .remove = rt5677_remove, |
---|
4964 | 5181 | .suspend = rt5677_suspend, |
---|
.. | .. |
---|
5020 | 5237 | }; |
---|
5021 | 5238 | MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match); |
---|
5022 | 5239 | |
---|
5023 | | -static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, |
---|
| 5240 | +static void rt5677_read_device_properties(struct rt5677_priv *rt5677, |
---|
5024 | 5241 | struct device *dev) |
---|
5025 | 5242 | { |
---|
5026 | 5243 | u32 val; |
---|
5027 | 5244 | |
---|
5028 | | - if (!device_property_read_u32(dev, "DCLK", &val)) |
---|
5029 | | - rt5677->pdata.dmic2_clk_pin = val; |
---|
| 5245 | + rt5677->pdata.in1_diff = |
---|
| 5246 | + device_property_read_bool(dev, "IN1") || |
---|
| 5247 | + device_property_read_bool(dev, "realtek,in1-differential"); |
---|
5030 | 5248 | |
---|
5031 | | - rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1"); |
---|
5032 | | - rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2"); |
---|
5033 | | - rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1"); |
---|
5034 | | - rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2"); |
---|
5035 | | - rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3"); |
---|
| 5249 | + rt5677->pdata.in2_diff = |
---|
| 5250 | + device_property_read_bool(dev, "IN2") || |
---|
| 5251 | + device_property_read_bool(dev, "realtek,in2-differential"); |
---|
5036 | 5252 | |
---|
5037 | | - device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio); |
---|
5038 | | - device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio); |
---|
5039 | | - device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio); |
---|
5040 | | -} |
---|
| 5253 | + rt5677->pdata.lout1_diff = |
---|
| 5254 | + device_property_read_bool(dev, "OUT1") || |
---|
| 5255 | + device_property_read_bool(dev, "realtek,lout1-differential"); |
---|
5041 | 5256 | |
---|
5042 | | -static void rt5677_read_device_properties(struct rt5677_priv *rt5677, |
---|
5043 | | - struct device *dev) |
---|
5044 | | -{ |
---|
5045 | | - rt5677->pdata.in1_diff = device_property_read_bool(dev, |
---|
5046 | | - "realtek,in1-differential"); |
---|
5047 | | - rt5677->pdata.in2_diff = device_property_read_bool(dev, |
---|
5048 | | - "realtek,in2-differential"); |
---|
5049 | | - rt5677->pdata.lout1_diff = device_property_read_bool(dev, |
---|
5050 | | - "realtek,lout1-differential"); |
---|
5051 | | - rt5677->pdata.lout2_diff = device_property_read_bool(dev, |
---|
5052 | | - "realtek,lout2-differential"); |
---|
5053 | | - rt5677->pdata.lout3_diff = device_property_read_bool(dev, |
---|
5054 | | - "realtek,lout3-differential"); |
---|
| 5257 | + rt5677->pdata.lout2_diff = |
---|
| 5258 | + device_property_read_bool(dev, "OUT2") || |
---|
| 5259 | + device_property_read_bool(dev, "realtek,lout2-differential"); |
---|
| 5260 | + |
---|
| 5261 | + rt5677->pdata.lout3_diff = |
---|
| 5262 | + device_property_read_bool(dev, "OUT3") || |
---|
| 5263 | + device_property_read_bool(dev, "realtek,lout3-differential"); |
---|
5055 | 5264 | |
---|
5056 | 5265 | device_property_read_u8_array(dev, "realtek,gpio-config", |
---|
5057 | | - rt5677->pdata.gpio_config, RT5677_GPIO_NUM); |
---|
| 5266 | + rt5677->pdata.gpio_config, |
---|
| 5267 | + RT5677_GPIO_NUM); |
---|
5058 | 5268 | |
---|
5059 | | - device_property_read_u32(dev, "realtek,jd1-gpio", |
---|
5060 | | - &rt5677->pdata.jd1_gpio); |
---|
5061 | | - device_property_read_u32(dev, "realtek,jd2-gpio", |
---|
5062 | | - &rt5677->pdata.jd2_gpio); |
---|
5063 | | - device_property_read_u32(dev, "realtek,jd3-gpio", |
---|
5064 | | - &rt5677->pdata.jd3_gpio); |
---|
| 5269 | + if (!device_property_read_u32(dev, "DCLK", &val) || |
---|
| 5270 | + !device_property_read_u32(dev, "realtek,dmic2_clk_pin", &val)) |
---|
| 5271 | + rt5677->pdata.dmic2_clk_pin = val; |
---|
| 5272 | + |
---|
| 5273 | + if (!device_property_read_u32(dev, "JD1", &val) || |
---|
| 5274 | + !device_property_read_u32(dev, "realtek,jd1-gpio", &val)) |
---|
| 5275 | + rt5677->pdata.jd1_gpio = val; |
---|
| 5276 | + |
---|
| 5277 | + if (!device_property_read_u32(dev, "JD2", &val) || |
---|
| 5278 | + !device_property_read_u32(dev, "realtek,jd2-gpio", &val)) |
---|
| 5279 | + rt5677->pdata.jd2_gpio = val; |
---|
| 5280 | + |
---|
| 5281 | + if (!device_property_read_u32(dev, "JD3", &val) || |
---|
| 5282 | + !device_property_read_u32(dev, "realtek,jd3-gpio", &val)) |
---|
| 5283 | + rt5677->pdata.jd3_gpio = val; |
---|
5065 | 5284 | } |
---|
5066 | 5285 | |
---|
5067 | | -static struct regmap_irq rt5677_irqs[] = { |
---|
| 5286 | +struct rt5677_irq_desc { |
---|
| 5287 | + unsigned int enable_mask; |
---|
| 5288 | + unsigned int status_mask; |
---|
| 5289 | + unsigned int polarity_mask; |
---|
| 5290 | +}; |
---|
| 5291 | + |
---|
| 5292 | +static const struct rt5677_irq_desc rt5677_irq_descs[] = { |
---|
5068 | 5293 | [RT5677_IRQ_JD1] = { |
---|
5069 | | - .reg_offset = 0, |
---|
5070 | | - .mask = RT5677_EN_IRQ_GPIO_JD1, |
---|
| 5294 | + .enable_mask = RT5677_EN_IRQ_GPIO_JD1, |
---|
| 5295 | + .status_mask = RT5677_STA_GPIO_JD1, |
---|
| 5296 | + .polarity_mask = RT5677_INV_GPIO_JD1, |
---|
5071 | 5297 | }, |
---|
5072 | 5298 | [RT5677_IRQ_JD2] = { |
---|
5073 | | - .reg_offset = 0, |
---|
5074 | | - .mask = RT5677_EN_IRQ_GPIO_JD2, |
---|
| 5299 | + .enable_mask = RT5677_EN_IRQ_GPIO_JD2, |
---|
| 5300 | + .status_mask = RT5677_STA_GPIO_JD2, |
---|
| 5301 | + .polarity_mask = RT5677_INV_GPIO_JD2, |
---|
5075 | 5302 | }, |
---|
5076 | 5303 | [RT5677_IRQ_JD3] = { |
---|
5077 | | - .reg_offset = 0, |
---|
5078 | | - .mask = RT5677_EN_IRQ_GPIO_JD3, |
---|
| 5304 | + .enable_mask = RT5677_EN_IRQ_GPIO_JD3, |
---|
| 5305 | + .status_mask = RT5677_STA_GPIO_JD3, |
---|
| 5306 | + .polarity_mask = RT5677_INV_GPIO_JD3, |
---|
5079 | 5307 | }, |
---|
5080 | 5308 | }; |
---|
5081 | 5309 | |
---|
5082 | | -static struct regmap_irq_chip rt5677_irq_chip = { |
---|
5083 | | - .name = "rt5677", |
---|
5084 | | - .irqs = rt5677_irqs, |
---|
5085 | | - .num_irqs = ARRAY_SIZE(rt5677_irqs), |
---|
| 5310 | +static bool rt5677_check_hotword(struct rt5677_priv *rt5677) |
---|
| 5311 | +{ |
---|
| 5312 | + int reg_gpio; |
---|
5086 | 5313 | |
---|
5087 | | - .num_regs = 1, |
---|
5088 | | - .status_base = RT5677_IRQ_CTRL1, |
---|
5089 | | - .mask_base = RT5677_IRQ_CTRL1, |
---|
5090 | | - .mask_invert = 1, |
---|
| 5314 | + if (!rt5677->is_dsp_mode) |
---|
| 5315 | + return false; |
---|
| 5316 | + |
---|
| 5317 | + if (regmap_read(rt5677->regmap, RT5677_GPIO_CTRL1, ®_gpio)) |
---|
| 5318 | + return false; |
---|
| 5319 | + |
---|
| 5320 | + /* Firmware sets GPIO1 pin to be GPIO1 after hotword is detected */ |
---|
| 5321 | + if ((reg_gpio & RT5677_GPIO1_PIN_MASK) == RT5677_GPIO1_PIN_IRQ) |
---|
| 5322 | + return false; |
---|
| 5323 | + |
---|
| 5324 | + /* Set GPIO1 pin back to be IRQ output for jack detect */ |
---|
| 5325 | + regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, |
---|
| 5326 | + RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ); |
---|
| 5327 | + |
---|
| 5328 | + rt5677_spi_hotword_detected(); |
---|
| 5329 | + return true; |
---|
| 5330 | +} |
---|
| 5331 | + |
---|
| 5332 | +static irqreturn_t rt5677_irq(int unused, void *data) |
---|
| 5333 | +{ |
---|
| 5334 | + struct rt5677_priv *rt5677 = data; |
---|
| 5335 | + int ret = 0, loop, i, reg_irq, virq; |
---|
| 5336 | + bool irq_fired = false; |
---|
| 5337 | + |
---|
| 5338 | + mutex_lock(&rt5677->irq_lock); |
---|
| 5339 | + |
---|
| 5340 | + /* |
---|
| 5341 | + * Loop to handle interrupts until the last i2c read shows no pending |
---|
| 5342 | + * irqs. The interrupt line is shared by multiple interrupt sources. |
---|
| 5343 | + * After the regmap_read() below, a new interrupt source line may |
---|
| 5344 | + * become high before the regmap_write() finishes, so there isn't a |
---|
| 5345 | + * rising edge on the shared interrupt line for the new interrupt. Thus, |
---|
| 5346 | + * the loop is needed to avoid missing irqs. |
---|
| 5347 | + * |
---|
| 5348 | + * A safeguard of 20 loops is used to avoid hanging in the irq handler |
---|
| 5349 | + * if there is something wrong with the interrupt status update. The |
---|
| 5350 | + * interrupt sources here are audio jack plug/unplug events which |
---|
| 5351 | + * shouldn't happen at a high frequency for a long period of time. |
---|
| 5352 | + * Empirically, more than 3 loops have never been seen. |
---|
| 5353 | + */ |
---|
| 5354 | + for (loop = 0; loop < 20; loop++) { |
---|
| 5355 | + /* Read interrupt status */ |
---|
| 5356 | + ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq); |
---|
| 5357 | + if (ret) { |
---|
| 5358 | + dev_err(rt5677->dev, "failed reading IRQ status: %d\n", |
---|
| 5359 | + ret); |
---|
| 5360 | + goto exit; |
---|
| 5361 | + } |
---|
| 5362 | + |
---|
| 5363 | + irq_fired = false; |
---|
| 5364 | + for (i = 0; i < RT5677_IRQ_NUM; i++) { |
---|
| 5365 | + if (reg_irq & rt5677_irq_descs[i].status_mask) { |
---|
| 5366 | + irq_fired = true; |
---|
| 5367 | + virq = irq_find_mapping(rt5677->domain, i); |
---|
| 5368 | + if (virq) |
---|
| 5369 | + handle_nested_irq(virq); |
---|
| 5370 | + |
---|
| 5371 | + /* Clear the interrupt by flipping the polarity |
---|
| 5372 | + * of the interrupt source line that fired |
---|
| 5373 | + */ |
---|
| 5374 | + reg_irq ^= rt5677_irq_descs[i].polarity_mask; |
---|
| 5375 | + } |
---|
| 5376 | + } |
---|
| 5377 | + |
---|
| 5378 | + /* Exit the loop only when we know for sure that GPIO1 pin |
---|
| 5379 | + * was low at some point since irq_lock was acquired. Any event |
---|
| 5380 | + * after that point creates a rising edge that triggers another |
---|
| 5381 | + * call to rt5677_irq(). |
---|
| 5382 | + */ |
---|
| 5383 | + if (!irq_fired && !rt5677_check_hotword(rt5677)) |
---|
| 5384 | + goto exit; |
---|
| 5385 | + |
---|
| 5386 | + ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq); |
---|
| 5387 | + if (ret) { |
---|
| 5388 | + dev_err(rt5677->dev, "failed updating IRQ status: %d\n", |
---|
| 5389 | + ret); |
---|
| 5390 | + goto exit; |
---|
| 5391 | + } |
---|
| 5392 | + } |
---|
| 5393 | +exit: |
---|
| 5394 | + WARN_ON_ONCE(loop == 20); |
---|
| 5395 | + mutex_unlock(&rt5677->irq_lock); |
---|
| 5396 | + if (irq_fired) |
---|
| 5397 | + return IRQ_HANDLED; |
---|
| 5398 | + else |
---|
| 5399 | + return IRQ_NONE; |
---|
| 5400 | +} |
---|
| 5401 | + |
---|
| 5402 | +static void rt5677_resume_irq_check(struct work_struct *work) |
---|
| 5403 | +{ |
---|
| 5404 | + int i, virq; |
---|
| 5405 | + struct rt5677_priv *rt5677 = |
---|
| 5406 | + container_of(work, struct rt5677_priv, resume_irq_check.work); |
---|
| 5407 | + |
---|
| 5408 | + /* This is needed to check and clear the interrupt status register |
---|
| 5409 | + * at resume. If the headset is plugged/unplugged when the device is |
---|
| 5410 | + * fully suspended, there won't be a rising edge at resume to trigger |
---|
| 5411 | + * the interrupt. Without this, we miss the next unplug/plug event. |
---|
| 5412 | + */ |
---|
| 5413 | + rt5677_irq(0, rt5677); |
---|
| 5414 | + |
---|
| 5415 | + /* Call all enabled jack detect irq handlers again. This is needed in |
---|
| 5416 | + * addition to the above check for a corner case caused by jack gpio |
---|
| 5417 | + * debounce. After codec irq is disabled at suspend, the delayed work |
---|
| 5418 | + * scheduled by soc-jack may run and read wrong jack gpio values, since |
---|
| 5419 | + * the regmap is in cache only mode. At resume, there is no irq because |
---|
| 5420 | + * rt5677_irq has already ran and cleared the irq status at suspend. |
---|
| 5421 | + * Without this explicit check, unplug the headset right after suspend |
---|
| 5422 | + * starts, then after resume the headset is still shown as plugged in. |
---|
| 5423 | + */ |
---|
| 5424 | + mutex_lock(&rt5677->irq_lock); |
---|
| 5425 | + for (i = 0; i < RT5677_IRQ_NUM; i++) { |
---|
| 5426 | + if (rt5677->irq_en & rt5677_irq_descs[i].enable_mask) { |
---|
| 5427 | + virq = irq_find_mapping(rt5677->domain, i); |
---|
| 5428 | + if (virq) |
---|
| 5429 | + handle_nested_irq(virq); |
---|
| 5430 | + } |
---|
| 5431 | + } |
---|
| 5432 | + mutex_unlock(&rt5677->irq_lock); |
---|
| 5433 | +} |
---|
| 5434 | + |
---|
| 5435 | +static void rt5677_irq_bus_lock(struct irq_data *data) |
---|
| 5436 | +{ |
---|
| 5437 | + struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data); |
---|
| 5438 | + |
---|
| 5439 | + mutex_lock(&rt5677->irq_lock); |
---|
| 5440 | +} |
---|
| 5441 | + |
---|
| 5442 | +static void rt5677_irq_bus_sync_unlock(struct irq_data *data) |
---|
| 5443 | +{ |
---|
| 5444 | + struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data); |
---|
| 5445 | + |
---|
| 5446 | + // Set the enable/disable bits for the jack detect IRQs. |
---|
| 5447 | + regmap_update_bits(rt5677->regmap, RT5677_IRQ_CTRL1, |
---|
| 5448 | + RT5677_EN_IRQ_GPIO_JD1 | RT5677_EN_IRQ_GPIO_JD2 | |
---|
| 5449 | + RT5677_EN_IRQ_GPIO_JD3, rt5677->irq_en); |
---|
| 5450 | + mutex_unlock(&rt5677->irq_lock); |
---|
| 5451 | +} |
---|
| 5452 | + |
---|
| 5453 | +static void rt5677_irq_enable(struct irq_data *data) |
---|
| 5454 | +{ |
---|
| 5455 | + struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data); |
---|
| 5456 | + |
---|
| 5457 | + rt5677->irq_en |= rt5677_irq_descs[data->hwirq].enable_mask; |
---|
| 5458 | +} |
---|
| 5459 | + |
---|
| 5460 | +static void rt5677_irq_disable(struct irq_data *data) |
---|
| 5461 | +{ |
---|
| 5462 | + struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data); |
---|
| 5463 | + |
---|
| 5464 | + rt5677->irq_en &= ~rt5677_irq_descs[data->hwirq].enable_mask; |
---|
| 5465 | +} |
---|
| 5466 | + |
---|
| 5467 | +static struct irq_chip rt5677_irq_chip = { |
---|
| 5468 | + .name = "rt5677_irq_chip", |
---|
| 5469 | + .irq_bus_lock = rt5677_irq_bus_lock, |
---|
| 5470 | + .irq_bus_sync_unlock = rt5677_irq_bus_sync_unlock, |
---|
| 5471 | + .irq_disable = rt5677_irq_disable, |
---|
| 5472 | + .irq_enable = rt5677_irq_enable, |
---|
| 5473 | +}; |
---|
| 5474 | + |
---|
| 5475 | +static int rt5677_irq_map(struct irq_domain *h, unsigned int virq, |
---|
| 5476 | + irq_hw_number_t hw) |
---|
| 5477 | +{ |
---|
| 5478 | + struct rt5677_priv *rt5677 = h->host_data; |
---|
| 5479 | + |
---|
| 5480 | + irq_set_chip_data(virq, rt5677); |
---|
| 5481 | + irq_set_chip(virq, &rt5677_irq_chip); |
---|
| 5482 | + irq_set_nested_thread(virq, 1); |
---|
| 5483 | + irq_set_noprobe(virq); |
---|
| 5484 | + return 0; |
---|
| 5485 | +} |
---|
| 5486 | + |
---|
| 5487 | + |
---|
| 5488 | +static const struct irq_domain_ops rt5677_domain_ops = { |
---|
| 5489 | + .map = rt5677_irq_map, |
---|
| 5490 | + .xlate = irq_domain_xlate_twocell, |
---|
5091 | 5491 | }; |
---|
5092 | 5492 | |
---|
5093 | 5493 | static int rt5677_init_irq(struct i2c_client *i2c) |
---|
5094 | 5494 | { |
---|
5095 | 5495 | int ret; |
---|
5096 | 5496 | struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); |
---|
| 5497 | + unsigned int jd_mask = 0, jd_val = 0; |
---|
5097 | 5498 | |
---|
5098 | 5499 | if (!rt5677->pdata.jd1_gpio && |
---|
5099 | 5500 | !rt5677->pdata.jd2_gpio && |
---|
.. | .. |
---|
5105 | 5506 | return -EINVAL; |
---|
5106 | 5507 | } |
---|
5107 | 5508 | |
---|
5108 | | - ret = regmap_add_irq_chip(rt5677->regmap, i2c->irq, |
---|
5109 | | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0, |
---|
5110 | | - &rt5677_irq_chip, &rt5677->irq_data); |
---|
| 5509 | + mutex_init(&rt5677->irq_lock); |
---|
| 5510 | + INIT_DELAYED_WORK(&rt5677->resume_irq_check, rt5677_resume_irq_check); |
---|
5111 | 5511 | |
---|
5112 | | - if (ret != 0) { |
---|
5113 | | - dev_err(&i2c->dev, "Failed to register IRQ chip: %d\n", ret); |
---|
5114 | | - return ret; |
---|
| 5512 | + /* |
---|
| 5513 | + * Select RC as the debounce clock so that GPIO works even when |
---|
| 5514 | + * MCLK is gated which happens when there is no audio stream |
---|
| 5515 | + * (SND_SOC_BIAS_OFF). |
---|
| 5516 | + */ |
---|
| 5517 | + regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, |
---|
| 5518 | + RT5677_IRQ_DEBOUNCE_SEL_MASK, |
---|
| 5519 | + RT5677_IRQ_DEBOUNCE_SEL_RC); |
---|
| 5520 | + /* Enable auto power on RC when GPIO states are changed */ |
---|
| 5521 | + regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL1, 0xff, 0xff); |
---|
| 5522 | + |
---|
| 5523 | + /* Select and enable jack detection sources per platform data */ |
---|
| 5524 | + if (rt5677->pdata.jd1_gpio) { |
---|
| 5525 | + jd_mask |= RT5677_SEL_GPIO_JD1_MASK; |
---|
| 5526 | + jd_val |= rt5677->pdata.jd1_gpio << RT5677_SEL_GPIO_JD1_SFT; |
---|
| 5527 | + } |
---|
| 5528 | + if (rt5677->pdata.jd2_gpio) { |
---|
| 5529 | + jd_mask |= RT5677_SEL_GPIO_JD2_MASK; |
---|
| 5530 | + jd_val |= rt5677->pdata.jd2_gpio << RT5677_SEL_GPIO_JD2_SFT; |
---|
| 5531 | + } |
---|
| 5532 | + if (rt5677->pdata.jd3_gpio) { |
---|
| 5533 | + jd_mask |= RT5677_SEL_GPIO_JD3_MASK; |
---|
| 5534 | + jd_val |= rt5677->pdata.jd3_gpio << RT5677_SEL_GPIO_JD3_SFT; |
---|
| 5535 | + } |
---|
| 5536 | + regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, jd_mask, jd_val); |
---|
| 5537 | + |
---|
| 5538 | + /* Set GPIO1 pin to be IRQ output */ |
---|
| 5539 | + regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, |
---|
| 5540 | + RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ); |
---|
| 5541 | + |
---|
| 5542 | + /* Ready to listen for interrupts */ |
---|
| 5543 | + rt5677->domain = irq_domain_add_linear(i2c->dev.of_node, |
---|
| 5544 | + RT5677_IRQ_NUM, &rt5677_domain_ops, rt5677); |
---|
| 5545 | + if (!rt5677->domain) { |
---|
| 5546 | + dev_err(&i2c->dev, "Failed to create IRQ domain\n"); |
---|
| 5547 | + return -ENOMEM; |
---|
5115 | 5548 | } |
---|
5116 | 5549 | |
---|
5117 | | - return 0; |
---|
5118 | | -} |
---|
| 5550 | + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, rt5677_irq, |
---|
| 5551 | + IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
---|
| 5552 | + "rt5677", rt5677); |
---|
| 5553 | + if (ret) |
---|
| 5554 | + dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret); |
---|
5119 | 5555 | |
---|
5120 | | -static void rt5677_free_irq(struct i2c_client *i2c) |
---|
5121 | | -{ |
---|
5122 | | - struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c); |
---|
| 5556 | + rt5677->irq = i2c->irq; |
---|
5123 | 5557 | |
---|
5124 | | - if (rt5677->irq_data) |
---|
5125 | | - regmap_del_irq_chip(i2c->irq, rt5677->irq_data); |
---|
| 5558 | + return ret; |
---|
5126 | 5559 | } |
---|
5127 | 5560 | |
---|
5128 | 5561 | static int rt5677_i2c_probe(struct i2c_client *i2c) |
---|
.. | .. |
---|
5136 | 5569 | if (rt5677 == NULL) |
---|
5137 | 5570 | return -ENOMEM; |
---|
5138 | 5571 | |
---|
| 5572 | + rt5677->dev = &i2c->dev; |
---|
| 5573 | + rt5677->set_dsp_vad = rt5677_set_dsp_vad; |
---|
| 5574 | + INIT_DELAYED_WORK(&rt5677->dsp_work, rt5677_dsp_work); |
---|
5139 | 5575 | i2c_set_clientdata(i2c, rt5677); |
---|
5140 | 5576 | |
---|
5141 | 5577 | if (i2c->dev.of_node) { |
---|
.. | .. |
---|
5144 | 5580 | match_id = of_match_device(rt5677_of_match, &i2c->dev); |
---|
5145 | 5581 | if (match_id) |
---|
5146 | 5582 | rt5677->type = (enum rt5677_type)match_id->data; |
---|
5147 | | - |
---|
5148 | | - rt5677_read_device_properties(rt5677, &i2c->dev); |
---|
5149 | 5583 | } else if (ACPI_HANDLE(&i2c->dev)) { |
---|
5150 | 5584 | const struct acpi_device_id *acpi_id; |
---|
5151 | 5585 | |
---|
5152 | 5586 | acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev); |
---|
5153 | 5587 | if (acpi_id) |
---|
5154 | 5588 | rt5677->type = (enum rt5677_type)acpi_id->driver_data; |
---|
5155 | | - |
---|
5156 | | - rt5677_read_acpi_properties(rt5677, &i2c->dev); |
---|
5157 | 5589 | } else { |
---|
5158 | 5590 | return -EINVAL; |
---|
5159 | 5591 | } |
---|
| 5592 | + |
---|
| 5593 | + rt5677_read_device_properties(rt5677, &i2c->dev); |
---|
5160 | 5594 | |
---|
5161 | 5595 | /* pow-ldo2 and reset are optional. The codec pins may be statically |
---|
5162 | 5596 | * connected on the board without gpios. If the gpio device property |
---|
.. | .. |
---|
5251 | 5685 | RT5677_MICBIAS1_CTRL_VDD_3_3V); |
---|
5252 | 5686 | |
---|
5253 | 5687 | rt5677_init_gpio(i2c); |
---|
5254 | | - rt5677_init_irq(i2c); |
---|
| 5688 | + ret = rt5677_init_irq(i2c); |
---|
| 5689 | + if (ret) |
---|
| 5690 | + dev_err(&i2c->dev, "Failed to initialize irq: %d\n", ret); |
---|
5255 | 5691 | |
---|
5256 | 5692 | return devm_snd_soc_register_component(&i2c->dev, |
---|
5257 | 5693 | &soc_component_dev_rt5677, |
---|
.. | .. |
---|
5260 | 5696 | |
---|
5261 | 5697 | static int rt5677_i2c_remove(struct i2c_client *i2c) |
---|
5262 | 5698 | { |
---|
5263 | | - rt5677_free_irq(i2c); |
---|
5264 | 5699 | rt5677_free_gpio(i2c); |
---|
5265 | 5700 | |
---|
5266 | 5701 | return 0; |
---|
.. | .. |
---|
5268 | 5703 | |
---|
5269 | 5704 | static struct i2c_driver rt5677_i2c_driver = { |
---|
5270 | 5705 | .driver = { |
---|
5271 | | - .name = "rt5677", |
---|
| 5706 | + .name = RT5677_DRV_NAME, |
---|
5272 | 5707 | .of_match_table = rt5677_of_match, |
---|
5273 | 5708 | .acpi_match_table = ACPI_PTR(rt5677_acpi_match), |
---|
5274 | 5709 | }, |
---|