.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * wm8961.c -- WM8961 ALSA SoC Audio driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2009-10 Wolfson Microelectronics, plc |
---|
5 | 6 | * |
---|
6 | 7 | * Author: Mark Brown |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | * |
---|
12 | 9 | * Currently unimplemented features: |
---|
13 | 10 | * - ALC |
---|
.. | .. |
---|
195 | 192 | struct snd_kcontrol *kcontrol, int event) |
---|
196 | 193 | { |
---|
197 | 194 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
198 | | - u16 hp_reg = snd_soc_component_read32(component, WM8961_ANALOGUE_HP_0); |
---|
199 | | - u16 cp_reg = snd_soc_component_read32(component, WM8961_CHARGE_PUMP_1); |
---|
200 | | - u16 pwr_reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_2); |
---|
201 | | - u16 dcs_reg = snd_soc_component_read32(component, WM8961_DC_SERVO_1); |
---|
| 195 | + u16 hp_reg = snd_soc_component_read(component, WM8961_ANALOGUE_HP_0); |
---|
| 196 | + u16 cp_reg = snd_soc_component_read(component, WM8961_CHARGE_PUMP_1); |
---|
| 197 | + u16 pwr_reg = snd_soc_component_read(component, WM8961_PWR_MGMT_2); |
---|
| 198 | + u16 dcs_reg = snd_soc_component_read(component, WM8961_DC_SERVO_1); |
---|
202 | 199 | int timeout = 500; |
---|
203 | 200 | |
---|
204 | 201 | if (event & SND_SOC_DAPM_POST_PMU) { |
---|
.. | .. |
---|
232 | 229 | snd_soc_component_write(component, WM8961_DC_SERVO_1, dcs_reg); |
---|
233 | 230 | do { |
---|
234 | 231 | msleep(1); |
---|
235 | | - dcs_reg = snd_soc_component_read32(component, WM8961_DC_SERVO_1); |
---|
| 232 | + dcs_reg = snd_soc_component_read(component, WM8961_DC_SERVO_1); |
---|
236 | 233 | } while (--timeout && |
---|
237 | 234 | dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR | |
---|
238 | 235 | WM8961_DCS_TRIG_STARTUP_HPL)); |
---|
.. | .. |
---|
287 | 284 | struct snd_kcontrol *kcontrol, int event) |
---|
288 | 285 | { |
---|
289 | 286 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
290 | | - u16 pwr_reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_2); |
---|
291 | | - u16 spk_reg = snd_soc_component_read32(component, WM8961_CLASS_D_CONTROL_1); |
---|
| 287 | + u16 pwr_reg = snd_soc_component_read(component, WM8961_PWR_MGMT_2); |
---|
| 288 | + u16 spk_reg = snd_soc_component_read(component, WM8961_CLASS_D_CONTROL_1); |
---|
292 | 289 | |
---|
293 | 290 | if (event & SND_SOC_DAPM_POST_PMU) { |
---|
294 | 291 | /* Enable the PGA */ |
---|
.. | .. |
---|
524 | 521 | abs(wm8961_srate[best].rate - fs)) |
---|
525 | 522 | best = i; |
---|
526 | 523 | } |
---|
527 | | - reg = snd_soc_component_read32(component, WM8961_ADDITIONAL_CONTROL_3); |
---|
| 524 | + reg = snd_soc_component_read(component, WM8961_ADDITIONAL_CONTROL_3); |
---|
528 | 525 | reg &= ~WM8961_SAMPLE_RATE_MASK; |
---|
529 | 526 | reg |= wm8961_srate[best].val; |
---|
530 | 527 | snd_soc_component_write(component, WM8961_ADDITIONAL_CONTROL_3, reg); |
---|
.. | .. |
---|
557 | 554 | wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs, |
---|
558 | 555 | wm8961->sysclk / fs); |
---|
559 | 556 | |
---|
560 | | - reg = snd_soc_component_read32(component, WM8961_CLOCKING_4); |
---|
| 557 | + reg = snd_soc_component_read(component, WM8961_CLOCKING_4); |
---|
561 | 558 | reg &= ~WM8961_CLK_SYS_RATE_MASK; |
---|
562 | 559 | reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT; |
---|
563 | 560 | snd_soc_component_write(component, WM8961_CLOCKING_4, reg); |
---|
564 | 561 | |
---|
565 | | - reg = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_0); |
---|
| 562 | + reg = snd_soc_component_read(component, WM8961_AUDIO_INTERFACE_0); |
---|
566 | 563 | reg &= ~WM8961_WL_MASK; |
---|
567 | 564 | switch (params_width(params)) { |
---|
568 | 565 | case 16: |
---|
.. | .. |
---|
582 | 579 | snd_soc_component_write(component, WM8961_AUDIO_INTERFACE_0, reg); |
---|
583 | 580 | |
---|
584 | 581 | /* Sloping stop-band filter is recommended for <= 24kHz */ |
---|
585 | | - reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_2); |
---|
| 582 | + reg = snd_soc_component_read(component, WM8961_ADC_DAC_CONTROL_2); |
---|
586 | 583 | if (fs <= 24000) |
---|
587 | 584 | reg |= WM8961_DACSLOPE; |
---|
588 | 585 | else |
---|
.. | .. |
---|
598 | 595 | { |
---|
599 | 596 | struct snd_soc_component *component = dai->component; |
---|
600 | 597 | struct wm8961_priv *wm8961 = snd_soc_component_get_drvdata(component); |
---|
601 | | - u16 reg = snd_soc_component_read32(component, WM8961_CLOCKING1); |
---|
| 598 | + u16 reg = snd_soc_component_read(component, WM8961_CLOCKING1); |
---|
602 | 599 | |
---|
603 | 600 | if (freq > 33000000) { |
---|
604 | 601 | dev_err(component->dev, "MCLK must be <33MHz\n"); |
---|
.. | .. |
---|
624 | 621 | static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
---|
625 | 622 | { |
---|
626 | 623 | struct snd_soc_component *component = dai->component; |
---|
627 | | - u16 aif = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_0); |
---|
| 624 | + u16 aif = snd_soc_component_read(component, WM8961_AUDIO_INTERFACE_0); |
---|
628 | 625 | |
---|
629 | 626 | aif &= ~(WM8961_BCLKINV | WM8961_LRP | |
---|
630 | 627 | WM8961_MS | WM8961_FORMAT_MASK); |
---|
.. | .. |
---|
653 | 650 | |
---|
654 | 651 | case SND_SOC_DAIFMT_DSP_B: |
---|
655 | 652 | aif |= WM8961_LRP; |
---|
656 | | - /* fall through */ |
---|
| 653 | + fallthrough; |
---|
657 | 654 | case SND_SOC_DAIFMT_DSP_A: |
---|
658 | 655 | aif |= 3; |
---|
659 | 656 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
---|
.. | .. |
---|
691 | 688 | static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate) |
---|
692 | 689 | { |
---|
693 | 690 | struct snd_soc_component *component = dai->component; |
---|
694 | | - u16 reg = snd_soc_component_read32(component, WM8961_ADDITIONAL_CONTROL_2); |
---|
| 691 | + u16 reg = snd_soc_component_read(component, WM8961_ADDITIONAL_CONTROL_2); |
---|
695 | 692 | |
---|
696 | 693 | if (tristate) |
---|
697 | 694 | reg |= WM8961_TRIS; |
---|
.. | .. |
---|
701 | 698 | return snd_soc_component_write(component, WM8961_ADDITIONAL_CONTROL_2, reg); |
---|
702 | 699 | } |
---|
703 | 700 | |
---|
704 | | -static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute) |
---|
| 701 | +static int wm8961_mute(struct snd_soc_dai *dai, int mute, int direction) |
---|
705 | 702 | { |
---|
706 | 703 | struct snd_soc_component *component = dai->component; |
---|
707 | | - u16 reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_1); |
---|
| 704 | + u16 reg = snd_soc_component_read(component, WM8961_ADC_DAC_CONTROL_1); |
---|
708 | 705 | |
---|
709 | 706 | if (mute) |
---|
710 | 707 | reg |= WM8961_DACMU; |
---|
.. | .. |
---|
723 | 720 | |
---|
724 | 721 | switch (div_id) { |
---|
725 | 722 | case WM8961_BCLK: |
---|
726 | | - reg = snd_soc_component_read32(component, WM8961_CLOCKING2); |
---|
| 723 | + reg = snd_soc_component_read(component, WM8961_CLOCKING2); |
---|
727 | 724 | reg &= ~WM8961_BCLKDIV_MASK; |
---|
728 | 725 | reg |= div; |
---|
729 | 726 | snd_soc_component_write(component, WM8961_CLOCKING2, reg); |
---|
730 | 727 | break; |
---|
731 | 728 | |
---|
732 | 729 | case WM8961_LRCLK: |
---|
733 | | - reg = snd_soc_component_read32(component, WM8961_AUDIO_INTERFACE_2); |
---|
| 730 | + reg = snd_soc_component_read(component, WM8961_AUDIO_INTERFACE_2); |
---|
734 | 731 | reg &= ~WM8961_LRCLK_RATE_MASK; |
---|
735 | 732 | reg |= div; |
---|
736 | 733 | snd_soc_component_write(component, WM8961_AUDIO_INTERFACE_2, reg); |
---|
.. | .. |
---|
760 | 757 | case SND_SOC_BIAS_PREPARE: |
---|
761 | 758 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { |
---|
762 | 759 | /* Enable bias generation */ |
---|
763 | | - reg = snd_soc_component_read32(component, WM8961_ANTI_POP); |
---|
| 760 | + reg = snd_soc_component_read(component, WM8961_ANTI_POP); |
---|
764 | 761 | reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; |
---|
765 | 762 | snd_soc_component_write(component, WM8961_ANTI_POP, reg); |
---|
766 | 763 | |
---|
767 | 764 | /* VMID=2*50k, VREF */ |
---|
768 | | - reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1); |
---|
| 765 | + reg = snd_soc_component_read(component, WM8961_PWR_MGMT_1); |
---|
769 | 766 | reg &= ~WM8961_VMIDSEL_MASK; |
---|
770 | 767 | reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF; |
---|
771 | 768 | snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg); |
---|
.. | .. |
---|
775 | 772 | case SND_SOC_BIAS_STANDBY: |
---|
776 | 773 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_PREPARE) { |
---|
777 | 774 | /* VREF off */ |
---|
778 | | - reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1); |
---|
| 775 | + reg = snd_soc_component_read(component, WM8961_PWR_MGMT_1); |
---|
779 | 776 | reg &= ~WM8961_VREF; |
---|
780 | 777 | snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg); |
---|
781 | 778 | |
---|
782 | 779 | /* Bias generation off */ |
---|
783 | | - reg = snd_soc_component_read32(component, WM8961_ANTI_POP); |
---|
| 780 | + reg = snd_soc_component_read(component, WM8961_ANTI_POP); |
---|
784 | 781 | reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN); |
---|
785 | 782 | snd_soc_component_write(component, WM8961_ANTI_POP, reg); |
---|
786 | 783 | |
---|
787 | 784 | /* VMID off */ |
---|
788 | | - reg = snd_soc_component_read32(component, WM8961_PWR_MGMT_1); |
---|
| 785 | + reg = snd_soc_component_read(component, WM8961_PWR_MGMT_1); |
---|
789 | 786 | reg &= ~WM8961_VMIDSEL_MASK; |
---|
790 | 787 | snd_soc_component_write(component, WM8961_PWR_MGMT_1, reg); |
---|
791 | 788 | } |
---|
.. | .. |
---|
809 | 806 | .hw_params = wm8961_hw_params, |
---|
810 | 807 | .set_sysclk = wm8961_set_sysclk, |
---|
811 | 808 | .set_fmt = wm8961_set_fmt, |
---|
812 | | - .digital_mute = wm8961_digital_mute, |
---|
| 809 | + .mute_stream = wm8961_mute, |
---|
813 | 810 | .set_tristate = wm8961_set_tristate, |
---|
814 | 811 | .set_clkdiv = wm8961_set_clkdiv, |
---|
| 812 | + .no_capture_mute = 1, |
---|
815 | 813 | }; |
---|
816 | 814 | |
---|
817 | 815 | static struct snd_soc_dai_driver wm8961_dai = { |
---|
.. | .. |
---|
836 | 834 | u16 reg; |
---|
837 | 835 | |
---|
838 | 836 | /* Enable class W */ |
---|
839 | | - reg = snd_soc_component_read32(component, WM8961_CHARGE_PUMP_B); |
---|
| 837 | + reg = snd_soc_component_read(component, WM8961_CHARGE_PUMP_B); |
---|
840 | 838 | reg |= WM8961_CP_DYN_PWR_MASK; |
---|
841 | 839 | snd_soc_component_write(component, WM8961_CHARGE_PUMP_B, reg); |
---|
842 | 840 | |
---|
843 | 841 | /* Latch volume update bits (right channel only, we always |
---|
844 | 842 | * write both out) and default ZC on. */ |
---|
845 | | - reg = snd_soc_component_read32(component, WM8961_ROUT1_VOLUME); |
---|
| 843 | + reg = snd_soc_component_read(component, WM8961_ROUT1_VOLUME); |
---|
846 | 844 | snd_soc_component_write(component, WM8961_ROUT1_VOLUME, |
---|
847 | 845 | reg | WM8961_LO1ZC | WM8961_OUT1VU); |
---|
848 | 846 | snd_soc_component_write(component, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC); |
---|
849 | | - reg = snd_soc_component_read32(component, WM8961_ROUT2_VOLUME); |
---|
| 847 | + reg = snd_soc_component_read(component, WM8961_ROUT2_VOLUME); |
---|
850 | 848 | snd_soc_component_write(component, WM8961_ROUT2_VOLUME, |
---|
851 | 849 | reg | WM8961_SPKRZC | WM8961_SPKVU); |
---|
852 | 850 | snd_soc_component_write(component, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC); |
---|
853 | 851 | |
---|
854 | | - reg = snd_soc_component_read32(component, WM8961_RIGHT_ADC_VOLUME); |
---|
| 852 | + reg = snd_soc_component_read(component, WM8961_RIGHT_ADC_VOLUME); |
---|
855 | 853 | snd_soc_component_write(component, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU); |
---|
856 | | - reg = snd_soc_component_read32(component, WM8961_RIGHT_INPUT_VOLUME); |
---|
| 854 | + reg = snd_soc_component_read(component, WM8961_RIGHT_INPUT_VOLUME); |
---|
857 | 855 | snd_soc_component_write(component, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU); |
---|
858 | 856 | |
---|
859 | 857 | /* Use soft mute by default */ |
---|
860 | | - reg = snd_soc_component_read32(component, WM8961_ADC_DAC_CONTROL_2); |
---|
| 858 | + reg = snd_soc_component_read(component, WM8961_ADC_DAC_CONTROL_2); |
---|
861 | 859 | reg |= WM8961_DACSMM; |
---|
862 | 860 | snd_soc_component_write(component, WM8961_ADC_DAC_CONTROL_2, reg); |
---|
863 | 861 | |
---|
864 | 862 | /* Use automatic clocking mode by default; for now this is all |
---|
865 | 863 | * we support. |
---|
866 | 864 | */ |
---|
867 | | - reg = snd_soc_component_read32(component, WM8961_CLOCKING_3); |
---|
| 865 | + reg = snd_soc_component_read(component, WM8961_CLOCKING_3); |
---|
868 | 866 | reg &= ~WM8961_MANUAL_MODE; |
---|
869 | 867 | snd_soc_component_write(component, WM8961_CLOCKING_3, reg); |
---|
870 | 868 | |
---|