.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * wm8962.c -- WM8962 ALSA SoC Audio driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2010-2 Wolfson Microelectronics plc |
---|
5 | 6 | * |
---|
6 | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
---|
7 | | - * |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License version 2 as |
---|
11 | | - * published by the Free Software Foundation. |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
14 | 10 | #include <linux/module.h> |
---|
.. | .. |
---|
122 | 118 | { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ |
---|
123 | 119 | { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ |
---|
124 | 120 | { 7, 0x000A }, /* R7 - Audio Interface 0 */ |
---|
125 | | - |
---|
| 121 | + { 8, 0x01E4 }, /* R8 - Clocking2 */ |
---|
126 | 122 | { 9, 0x0300 }, /* R9 - Audio Interface 1 */ |
---|
127 | 123 | { 10, 0x00C0 }, /* R10 - Left DAC volume */ |
---|
128 | 124 | { 11, 0x00C0 }, /* R11 - Right DAC volume */ |
---|
.. | .. |
---|
792 | 788 | { |
---|
793 | 789 | switch (reg) { |
---|
794 | 790 | case WM8962_CLOCKING1: |
---|
795 | | - case WM8962_CLOCKING2: |
---|
796 | 791 | case WM8962_SOFTWARE_RESET: |
---|
797 | 792 | case WM8962_THERMAL_SHUTDOWN_STATUS: |
---|
798 | 793 | case WM8962_ADDITIONAL_CONTROL_4: |
---|
.. | .. |
---|
961 | 956 | case WM8962_EQ39: |
---|
962 | 957 | case WM8962_EQ40: |
---|
963 | 958 | case WM8962_EQ41: |
---|
964 | | - case WM8962_GPIO_BASE: |
---|
965 | 959 | case WM8962_GPIO_2: |
---|
966 | 960 | case WM8962_GPIO_3: |
---|
967 | 961 | case WM8962_GPIO_5: |
---|
.. | .. |
---|
1485 | 1479 | |
---|
1486 | 1480 | static int wm8962_dsp2_set_enable(struct snd_soc_component *component, u16 val) |
---|
1487 | 1481 | { |
---|
1488 | | - u16 adcl = snd_soc_component_read32(component, WM8962_LEFT_ADC_VOLUME); |
---|
1489 | | - u16 adcr = snd_soc_component_read32(component, WM8962_RIGHT_ADC_VOLUME); |
---|
1490 | | - u16 dac = snd_soc_component_read32(component, WM8962_ADC_DAC_CONTROL_1); |
---|
| 1482 | + u16 adcl = snd_soc_component_read(component, WM8962_LEFT_ADC_VOLUME); |
---|
| 1483 | + u16 adcr = snd_soc_component_read(component, WM8962_RIGHT_ADC_VOLUME); |
---|
| 1484 | + u16 dac = snd_soc_component_read(component, WM8962_ADC_DAC_CONTROL_1); |
---|
1491 | 1485 | |
---|
1492 | 1486 | /* Mute the ADCs and DACs */ |
---|
1493 | 1487 | snd_soc_component_write(component, WM8962_LEFT_ADC_VOLUME, 0); |
---|
.. | .. |
---|
1566 | 1560 | struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); |
---|
1567 | 1561 | int old = wm8962->dsp2_ena; |
---|
1568 | 1562 | int ret = 0; |
---|
1569 | | - int dsp2_running = snd_soc_component_read32(component, WM8962_DSP2_POWER_MANAGEMENT) & |
---|
| 1563 | + int dsp2_running = snd_soc_component_read(component, WM8962_DSP2_POWER_MANAGEMENT) & |
---|
1570 | 1564 | WM8962_DSP2_ENA; |
---|
1571 | 1565 | |
---|
1572 | 1566 | mutex_lock(&wm8962->dsp2_ena_lock); |
---|
.. | .. |
---|
1609 | 1603 | return 0; |
---|
1610 | 1604 | |
---|
1611 | 1605 | /* If the left PGA is enabled hit that VU bit... */ |
---|
1612 | | - ret = snd_soc_component_read32(component, WM8962_PWR_MGMT_2); |
---|
| 1606 | + ret = snd_soc_component_read(component, WM8962_PWR_MGMT_2); |
---|
1613 | 1607 | if (ret & WM8962_HPOUTL_PGA_ENA) { |
---|
1614 | 1608 | snd_soc_component_write(component, WM8962_HPOUTL_VOLUME, |
---|
1615 | | - snd_soc_component_read32(component, WM8962_HPOUTL_VOLUME)); |
---|
| 1609 | + snd_soc_component_read(component, WM8962_HPOUTL_VOLUME)); |
---|
1616 | 1610 | return 1; |
---|
1617 | 1611 | } |
---|
1618 | 1612 | |
---|
1619 | 1613 | /* ...otherwise the right. The VU is stereo. */ |
---|
1620 | 1614 | if (ret & WM8962_HPOUTR_PGA_ENA) |
---|
1621 | 1615 | snd_soc_component_write(component, WM8962_HPOUTR_VOLUME, |
---|
1622 | | - snd_soc_component_read32(component, WM8962_HPOUTR_VOLUME)); |
---|
| 1616 | + snd_soc_component_read(component, WM8962_HPOUTR_VOLUME)); |
---|
1623 | 1617 | |
---|
1624 | 1618 | return 1; |
---|
1625 | 1619 | } |
---|
.. | .. |
---|
1639 | 1633 | return 0; |
---|
1640 | 1634 | |
---|
1641 | 1635 | /* If the left PGA is enabled hit that VU bit... */ |
---|
1642 | | - ret = snd_soc_component_read32(component, WM8962_PWR_MGMT_2); |
---|
| 1636 | + ret = snd_soc_component_read(component, WM8962_PWR_MGMT_2); |
---|
1643 | 1637 | if (ret & WM8962_SPKOUTL_PGA_ENA) { |
---|
1644 | 1638 | snd_soc_component_write(component, WM8962_SPKOUTL_VOLUME, |
---|
1645 | | - snd_soc_component_read32(component, WM8962_SPKOUTL_VOLUME)); |
---|
| 1639 | + snd_soc_component_read(component, WM8962_SPKOUTL_VOLUME)); |
---|
1646 | 1640 | return 1; |
---|
1647 | 1641 | } |
---|
1648 | 1642 | |
---|
1649 | 1643 | /* ...otherwise the right. The VU is stereo. */ |
---|
1650 | 1644 | if (ret & WM8962_SPKOUTR_PGA_ENA) |
---|
1651 | 1645 | snd_soc_component_write(component, WM8962_SPKOUTR_VOLUME, |
---|
1652 | | - snd_soc_component_read32(component, WM8962_SPKOUTR_VOLUME)); |
---|
| 1646 | + snd_soc_component_read(component, WM8962_SPKOUTR_VOLUME)); |
---|
1653 | 1647 | |
---|
1654 | 1648 | return 1; |
---|
1655 | 1649 | } |
---|
.. | .. |
---|
1708 | 1702 | SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0), |
---|
1709 | 1703 | SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0), |
---|
1710 | 1704 | SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0), |
---|
| 1705 | +SOC_SINGLE("DAC Monomix Switch", WM8962_DAC_DSP_MIXING_1, WM8962_DAC_MONOMIX_SHIFT, 1, 0), |
---|
| 1706 | +SOC_SINGLE("ADC Monomix Switch", WM8962_THREED1, WM8962_ADC_MONOMIX_SHIFT, 1, 0), |
---|
1711 | 1707 | |
---|
1712 | 1708 | SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1, |
---|
1713 | 1709 | 5, 1, 0), |
---|
.. | .. |
---|
1844 | 1840 | 4, 1, 0, inmix_tlv), |
---|
1845 | 1841 | }; |
---|
1846 | 1842 | |
---|
| 1843 | +static int tp_event(struct snd_soc_dapm_widget *w, |
---|
| 1844 | + struct snd_kcontrol *kcontrol, int event) |
---|
| 1845 | +{ |
---|
| 1846 | + int ret, reg, val, mask; |
---|
| 1847 | + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
| 1848 | + |
---|
| 1849 | + ret = pm_runtime_resume_and_get(component->dev); |
---|
| 1850 | + if (ret < 0) { |
---|
| 1851 | + dev_err(component->dev, "Failed to resume device: %d\n", ret); |
---|
| 1852 | + return ret; |
---|
| 1853 | + } |
---|
| 1854 | + |
---|
| 1855 | + reg = WM8962_ADDITIONAL_CONTROL_4; |
---|
| 1856 | + |
---|
| 1857 | + if (!strcmp(w->name, "TEMP_HP")) { |
---|
| 1858 | + mask = WM8962_TEMP_ENA_HP_MASK; |
---|
| 1859 | + val = WM8962_TEMP_ENA_HP; |
---|
| 1860 | + } else if (!strcmp(w->name, "TEMP_SPK")) { |
---|
| 1861 | + mask = WM8962_TEMP_ENA_SPK_MASK; |
---|
| 1862 | + val = WM8962_TEMP_ENA_SPK; |
---|
| 1863 | + } else { |
---|
| 1864 | + pm_runtime_put(component->dev); |
---|
| 1865 | + return -EINVAL; |
---|
| 1866 | + } |
---|
| 1867 | + |
---|
| 1868 | + switch (event) { |
---|
| 1869 | + case SND_SOC_DAPM_POST_PMD: |
---|
| 1870 | + val = 0; |
---|
| 1871 | + fallthrough; |
---|
| 1872 | + case SND_SOC_DAPM_POST_PMU: |
---|
| 1873 | + ret = snd_soc_component_update_bits(component, reg, mask, val); |
---|
| 1874 | + break; |
---|
| 1875 | + default: |
---|
| 1876 | + WARN(1, "Invalid event %d\n", event); |
---|
| 1877 | + pm_runtime_put(component->dev); |
---|
| 1878 | + return -EINVAL; |
---|
| 1879 | + } |
---|
| 1880 | + |
---|
| 1881 | + pm_runtime_put(component->dev); |
---|
| 1882 | + |
---|
| 1883 | + return 0; |
---|
| 1884 | +} |
---|
| 1885 | + |
---|
1847 | 1886 | static int cp_event(struct snd_soc_dapm_widget *w, |
---|
1848 | 1887 | struct snd_kcontrol *kcontrol, int event) |
---|
1849 | 1888 | { |
---|
.. | .. |
---|
1893 | 1932 | timeout = 0; |
---|
1894 | 1933 | do { |
---|
1895 | 1934 | msleep(1); |
---|
1896 | | - reg = snd_soc_component_read32(component, WM8962_DC_SERVO_6); |
---|
| 1935 | + reg = snd_soc_component_read(component, WM8962_DC_SERVO_6); |
---|
1897 | 1936 | if (reg < 0) { |
---|
1898 | 1937 | dev_err(component->dev, |
---|
1899 | 1938 | "Failed to read DCS status: %d\n", |
---|
.. | .. |
---|
1980 | 2019 | |
---|
1981 | 2020 | switch (event) { |
---|
1982 | 2021 | case SND_SOC_DAPM_POST_PMU: |
---|
1983 | | - return snd_soc_component_write(component, reg, snd_soc_component_read32(component, reg)); |
---|
| 2022 | + return snd_soc_component_write(component, reg, |
---|
| 2023 | + snd_soc_component_read(component, reg)); |
---|
1984 | 2024 | default: |
---|
1985 | 2025 | WARN(1, "Invalid event %d\n", event); |
---|
1986 | 2026 | return -EINVAL; |
---|
.. | .. |
---|
2136 | 2176 | SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, |
---|
2137 | 2177 | WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, |
---|
2138 | 2178 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
---|
2139 | | -SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0), |
---|
2140 | | -SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0), |
---|
| 2179 | +SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event, |
---|
| 2180 | + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), |
---|
| 2181 | +SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event, |
---|
| 2182 | + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), |
---|
2141 | 2183 | |
---|
2142 | 2184 | SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, |
---|
2143 | 2185 | inpgal, ARRAY_SIZE(inpgal)), |
---|
.. | .. |
---|
2447 | 2489 | snd_soc_component_update_bits(component, WM8962_CLOCKING2, |
---|
2448 | 2490 | WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA); |
---|
2449 | 2491 | |
---|
2450 | | - dspclk = snd_soc_component_read32(component, WM8962_CLOCKING1); |
---|
| 2492 | + /* DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate |
---|
| 2493 | + * correct frequency of LRCLK and BCLK. Sometimes the read-only value |
---|
| 2494 | + * can't be updated timely after enabling SYSCLK. This results in wrong |
---|
| 2495 | + * calculation values. Delay is introduced here to wait for newest |
---|
| 2496 | + * value from register. The time of the delay should be at least |
---|
| 2497 | + * 500~1000us according to test. |
---|
| 2498 | + */ |
---|
| 2499 | + usleep_range(500, 1000); |
---|
| 2500 | + dspclk = snd_soc_component_read(component, WM8962_CLOCKING1); |
---|
2451 | 2501 | |
---|
2452 | 2502 | if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) |
---|
2453 | 2503 | snd_soc_component_update_bits(component, WM8962_CLOCKING2, |
---|
.. | .. |
---|
2649 | 2699 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
---|
2650 | 2700 | case SND_SOC_DAIFMT_DSP_B: |
---|
2651 | 2701 | aif0 |= WM8962_LRCLK_INV | 3; |
---|
2652 | | - /* fall through */ |
---|
| 2702 | + fallthrough; |
---|
2653 | 2703 | case SND_SOC_DAIFMT_DSP_A: |
---|
2654 | 2704 | aif0 |= 3; |
---|
2655 | 2705 | |
---|
.. | .. |
---|
2885 | 2935 | |
---|
2886 | 2936 | ret = pm_runtime_get_sync(component->dev); |
---|
2887 | 2937 | if (ret < 0) { |
---|
| 2938 | + pm_runtime_put_noidle(component->dev); |
---|
2888 | 2939 | dev_err(component->dev, "Failed to resume device: %d\n", ret); |
---|
2889 | 2940 | return ret; |
---|
2890 | 2941 | } |
---|
.. | .. |
---|
2921 | 2972 | return 0; |
---|
2922 | 2973 | } |
---|
2923 | 2974 | |
---|
2924 | | -static int wm8962_mute(struct snd_soc_dai *dai, int mute) |
---|
| 2975 | +static int wm8962_mute(struct snd_soc_dai *dai, int mute, int direction) |
---|
2925 | 2976 | { |
---|
2926 | 2977 | struct snd_soc_component *component = dai->component; |
---|
2927 | 2978 | int val, ret; |
---|
.. | .. |
---|
2954 | 3005 | .hw_params = wm8962_hw_params, |
---|
2955 | 3006 | .set_sysclk = wm8962_set_dai_sysclk, |
---|
2956 | 3007 | .set_fmt = wm8962_set_dai_fmt, |
---|
2957 | | - .digital_mute = wm8962_mute, |
---|
| 3008 | + .mute_stream = wm8962_mute, |
---|
| 3009 | + .no_capture_mute = 1, |
---|
2958 | 3010 | }; |
---|
2959 | 3011 | |
---|
2960 | 3012 | static struct snd_soc_dai_driver wm8962_dai = { |
---|
.. | .. |
---|
2987 | 3039 | int irq_pol = 0; |
---|
2988 | 3040 | int reg; |
---|
2989 | 3041 | |
---|
2990 | | - reg = snd_soc_component_read32(component, WM8962_ADDITIONAL_CONTROL_4); |
---|
| 3042 | + reg = snd_soc_component_read(component, WM8962_ADDITIONAL_CONTROL_4); |
---|
2991 | 3043 | |
---|
2992 | 3044 | if (reg & WM8962_MICDET_STS) { |
---|
2993 | 3045 | status |= SND_JACK_MICROPHONE; |
---|
.. | .. |
---|
3017 | 3069 | |
---|
3018 | 3070 | ret = pm_runtime_get_sync(dev); |
---|
3019 | 3071 | if (ret < 0) { |
---|
| 3072 | + pm_runtime_put_noidle(dev); |
---|
3020 | 3073 | dev_err(dev, "Failed to resume: %d\n", ret); |
---|
3021 | 3074 | return IRQ_NONE; |
---|
3022 | 3075 | } |
---|
.. | .. |
---|
3424 | 3477 | |
---|
3425 | 3478 | /* This should really be moved into the regulator core */ |
---|
3426 | 3479 | for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) { |
---|
3427 | | - ret = regulator_register_notifier(wm8962->supplies[i].consumer, |
---|
3428 | | - &wm8962->disable_nb[i]); |
---|
| 3480 | + ret = devm_regulator_register_notifier( |
---|
| 3481 | + wm8962->supplies[i].consumer, |
---|
| 3482 | + &wm8962->disable_nb[i]); |
---|
3429 | 3483 | if (ret != 0) { |
---|
3430 | 3484 | dev_err(component->dev, |
---|
3431 | 3485 | "Failed to register regulator notifier: %d\n", |
---|
.. | .. |
---|
3438 | 3492 | /* Save boards having to disable DMIC when not in use */ |
---|
3439 | 3493 | dmicclk = false; |
---|
3440 | 3494 | dmicdat = false; |
---|
3441 | | - for (i = 0; i < WM8962_MAX_GPIO; i++) { |
---|
3442 | | - switch (snd_soc_component_read32(component, WM8962_GPIO_BASE + i) |
---|
| 3495 | + for (i = 1; i < WM8962_MAX_GPIO; i++) { |
---|
| 3496 | + /* |
---|
| 3497 | + * Register 515 (WM8962_GPIO_BASE + 3) does not exist, |
---|
| 3498 | + * so skip its access |
---|
| 3499 | + */ |
---|
| 3500 | + if (i == 3) |
---|
| 3501 | + continue; |
---|
| 3502 | + switch (snd_soc_component_read(component, WM8962_GPIO_BASE + i) |
---|
3443 | 3503 | & WM8962_GP2_FN_MASK) { |
---|
3444 | 3504 | case WM8962_GPIO_FN_DMICCLK: |
---|
3445 | 3505 | dmicclk = true; |
---|
.. | .. |
---|
3467 | 3527 | static void wm8962_remove(struct snd_soc_component *component) |
---|
3468 | 3528 | { |
---|
3469 | 3529 | struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component); |
---|
3470 | | - int i; |
---|
3471 | 3530 | |
---|
3472 | 3531 | cancel_delayed_work_sync(&wm8962->mic_work); |
---|
3473 | 3532 | |
---|
3474 | 3533 | wm8962_free_gpio(component); |
---|
3475 | 3534 | wm8962_free_beep(component); |
---|
3476 | | - for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) |
---|
3477 | | - regulator_unregister_notifier(wm8962->supplies[i].consumer, |
---|
3478 | | - &wm8962->disable_nb[i]); |
---|
3479 | 3535 | } |
---|
3480 | 3536 | |
---|
3481 | 3537 | static const struct snd_soc_component_driver soc_component_dev_wm8962 = { |
---|
.. | .. |
---|
3757 | 3813 | if (ret < 0) |
---|
3758 | 3814 | goto err_pm_runtime; |
---|
3759 | 3815 | |
---|
| 3816 | + regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4, |
---|
| 3817 | + WM8962_TEMP_ENA_HP_MASK, 0); |
---|
| 3818 | + regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4, |
---|
| 3819 | + WM8962_TEMP_ENA_SPK_MASK, 0); |
---|
| 3820 | + |
---|
3760 | 3821 | regcache_cache_only(wm8962->regmap, true); |
---|
3761 | 3822 | |
---|
3762 | 3823 | /* The drivers should power up as needed */ |
---|
.. | .. |
---|
3806 | 3867 | /* SYSCLK defaults to on; make sure it is off so we can safely |
---|
3807 | 3868 | * write to registers if the device is declocked. |
---|
3808 | 3869 | */ |
---|
3809 | | - regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, |
---|
3810 | | - WM8962_SYSCLK_ENA, 0); |
---|
| 3870 | + regmap_write_bits(wm8962->regmap, WM8962_CLOCKING2, |
---|
| 3871 | + WM8962_SYSCLK_ENA, 0); |
---|
3811 | 3872 | |
---|
3812 | 3873 | /* Ensure we have soft control over all registers */ |
---|
3813 | 3874 | regmap_update_bits(wm8962->regmap, WM8962_CLOCKING2, |
---|
.. | .. |
---|
3861 | 3922 | #endif |
---|
3862 | 3923 | |
---|
3863 | 3924 | static const struct dev_pm_ops wm8962_pm = { |
---|
| 3925 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) |
---|
3864 | 3926 | SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL) |
---|
3865 | 3927 | }; |
---|
3866 | 3928 | |
---|