ASoC: Updates for v4.2
The big thing this release has been Liam's addition of topology support
 to the core.  We've also seen quite a bit of driver work and the
 continuation of Lars' refactoring for component support.
 
  - Support for loading ASoC topology maps from firmware, intended to be
    used to allow self-describing DSP firmware images to be built which
    can map controls added by the DSP to userspace without the kernel
    needing to know about individual DSP firmwares.
  - Lots of refactoring to avoid direct access to snd_soc_codec where
    it's not needed supporting future refactoring.
  - Big refactoring and cleanup serieses for the Wolfson ADSP and TI
    TAS2552 drivers.
  - Support for TI TAS571x power amplifiers.
  - Support for Qualcomm APQ8016 and ZTE ZX296702 SoCs.
  - Support for x86 systems with RT5650 and Qualcomm Storm.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJVddV1AAoJECTWi3JdVIfQQQsH/RG3lgOeot5jLWMsxJSKChEl
 KI+aaMcOw6Dj2LDccN8i6vUp8q44cKSXIc7lGLOzJW4K+OydCCGAvE+sJGyRE1dd
 yOHwcbvjJi4zFlt01RZchJ/Wa/S6zFucl5N9HxWsV4bEtfAA59IuhJLtospUlwsA
 mf9mpvSdeUAeh3lM2+AqAbXhTo6dYfD5ky5nrtpAkZjG8gqUG0u8Tpauja0lLcHi
 72/3EkzKR6KHaefyPw3LdN+/H/YK79uHCVcctZnQg5xUUymcO16ReoTxKwV9cnDb
 lBJ6wO8RpUAO9evoG2Yj/l4p+czDCm5VkHMq0nPklHVRh7s/2PwKfox1aw4Pumg=
 =wolq
 -----END PGP SIGNATURE-----
Merge tag 'asoc-v4.2' into asoc-next
ASoC: Updates for v4.2
The big thing this release has been Liam's addition of topology support
to the core.  We've also seen quite a bit of driver work and the
continuation of Lars' refactoring for component support.
 - Support for loading ASoC topology maps from firmware, intended to be
   used to allow self-describing DSP firmware images to be built which
   can map controls added by the DSP to userspace without the kernel
   needing to know about individual DSP firmwares.
 - Lots of refactoring to avoid direct access to snd_soc_codec where
   it's not needed supporting future refactoring.
 - Big refactoring and cleanup serieses for the Wolfson ADSP and TI
   TAS2552 drivers.
 - Support for TI TAS571x power amplifiers.
 - Support for Qualcomm APQ8016 and ZTE ZX296702 SoCs.
 - Support for x86 systems with RT5650 and Qualcomm Storm.
# gpg: Signature made Mon 08 Jun 2015 18:48:37 BST using RSA key ID 5D5487D0
# gpg: Oops: keyid_from_fingerprint: no pubkey
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg:                 aka "Mark Brown <broonie@debian.org>"
# gpg:                 aka "Mark Brown <broonie@kernel.org>"
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg:                 aka "Mark Brown <broonie@linaro.org>"
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>"
	
	
This commit is contained in:
		
				commit
				
					
						208a128f6b
					
				
			
		
					 222 changed files with 9466 additions and 2318 deletions
				
			
		| 
						 | 
					@ -20,6 +20,8 @@ Optional properties:
 | 
				
			||||||
			pin configurations as described in the datasheet,
 | 
								pin configurations as described in the datasheet,
 | 
				
			||||||
			table 53. Note that the value of this property has
 | 
								table 53. Note that the value of this property has
 | 
				
			||||||
			to be prefixed with '/bits/ 8'.
 | 
								to be prefixed with '/bits/ 8'.
 | 
				
			||||||
 | 
					 - avdd-supply: 	Power supply for AVDD, providing 3.3V
 | 
				
			||||||
 | 
					 - dvdd-supply: 	Power supply for DVDD, providing 3.3V
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Examples:
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +30,8 @@ Examples:
 | 
				
			||||||
			compatible = "adi,adau1701";
 | 
								compatible = "adi,adau1701";
 | 
				
			||||||
			reg = <0x34>;
 | 
								reg = <0x34>;
 | 
				
			||||||
			reset-gpio = <&gpio 23 0>;
 | 
								reset-gpio = <&gpio 23 0>;
 | 
				
			||||||
 | 
								avdd-supply = <&vdd_3v3_reg>;
 | 
				
			||||||
 | 
								dvdd-supply = <&vdd_3v3_reg>;
 | 
				
			||||||
			adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>;
 | 
								adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>;
 | 
				
			||||||
			adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
 | 
								adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
 | 
				
			||||||
                                                   0x4 0x4 0x4 0x4 0x4 0x4>;
 | 
					                                                   0x4 0x4 0x4 0x4 0x4 0x4>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								Documentation/devicetree/bindings/sound/bt-sco.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Documentation/devicetree/bindings/sound/bt-sco.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					Bluetooth-SCO audio CODEC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This device support generic Bluetooth SCO link.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - compatible : "delta,dfbmcs320"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					codec: bt_sco {
 | 
				
			||||||
 | 
						compatible = "delta,dfbmcs320";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										13
									
								
								Documentation/devicetree/bindings/sound/gtm601.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Documentation/devicetree/bindings/sound/gtm601.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					GTM601 UMTS modem audio interface CODEC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This device has no configuration interface. Sample rate is fixed - 8kHz.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - compatible : "option,gtm601"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					codec: gtm601_codec {
 | 
				
			||||||
 | 
						compatible = "option,gtm601";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,12 @@ Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- maxim,dmic-freq: Frequency at which to clock DMIC
 | 
					- maxim,dmic-freq: Frequency at which to clock DMIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are:
 | 
				
			||||||
 | 
						0 - 2.2v
 | 
				
			||||||
 | 
						1 - 2.55v
 | 
				
			||||||
 | 
						2 - 2.4v
 | 
				
			||||||
 | 
						3 - 2.8v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Pins on the device (for linking into audio routes):
 | 
					Pins on the device (for linking into audio routes):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  * MIC1
 | 
					  * MIC1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,12 +4,21 @@ This node models the Qualcomm Technologies Low-Power Audio SubSystem (LPASS).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Required properties:
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- compatible		: "qcom,lpass-cpu"
 | 
					- compatible		: "qcom,lpass-cpu" or "qcom,apq8016-lpass-cpu"
 | 
				
			||||||
- clocks		: Must contain an entry for each entry in clock-names.
 | 
					- clocks		: Must contain an entry for each entry in clock-names.
 | 
				
			||||||
- clock-names		: A list which must include the following entries:
 | 
					- clock-names		: A list which must include the following entries:
 | 
				
			||||||
				* "ahbix-clk"
 | 
									* "ahbix-clk"
 | 
				
			||||||
				* "mi2s-osr-clk"
 | 
									* "mi2s-osr-clk"
 | 
				
			||||||
				* "mi2s-bit-clk"
 | 
									* "mi2s-bit-clk"
 | 
				
			||||||
 | 
								: required clocks for "qcom,lpass-cpu-apq8016"
 | 
				
			||||||
 | 
									* "ahbix-clk"
 | 
				
			||||||
 | 
									* "mi2s-bit-clk0"
 | 
				
			||||||
 | 
									* "mi2s-bit-clk1"
 | 
				
			||||||
 | 
									* "mi2s-bit-clk2"
 | 
				
			||||||
 | 
									* "mi2s-bit-clk3"
 | 
				
			||||||
 | 
									* "pcnoc-mport-clk"
 | 
				
			||||||
 | 
									* "pcnoc-sway-clk"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- interrupts		: Must contain an entry for each entry in
 | 
					- interrupts		: Must contain an entry for each entry in
 | 
				
			||||||
			  interrupt-names.
 | 
								  interrupt-names.
 | 
				
			||||||
- interrupt-names	: A list which must include the following entries:
 | 
					- interrupt-names	: A list which must include the following entries:
 | 
				
			||||||
| 
						 | 
					@ -22,6 +31,8 @@ Required properties:
 | 
				
			||||||
- reg-names		: A list which must include the following entries:
 | 
					- reg-names		: A list which must include the following entries:
 | 
				
			||||||
				* "lpass-lpaif"
 | 
									* "lpass-lpaif"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Optional properties:
 | 
					Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- qcom,adsp		: Phandle for the audio DSP node
 | 
					- qcom,adsp		: Phandle for the audio DSP node
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ DAI subnode properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rcar_sound: rcar_sound@ec500000 {
 | 
					rcar_sound: sound@ec500000 {
 | 
				
			||||||
	#sound-dai-cells = <1>;
 | 
						#sound-dai-cells = <1>;
 | 
				
			||||||
	compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
 | 
						compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
 | 
				
			||||||
	reg =	<0 0xec500000 0 0x1000>, /* SCU */
 | 
						reg =	<0 0xec500000 0 0x1000>, /* SCU */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@ Required properties:
 | 
				
			||||||
Optional properties:
 | 
					Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
 | 
					- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
 | 
				
			||||||
 | 
					- realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- realtek,in1-differential
 | 
					- realtek,in1-differential
 | 
				
			||||||
- realtek,in2-differential
 | 
					- realtek,in2-differential
 | 
				
			||||||
| 
						 | 
					@ -70,6 +71,7 @@ rt5677 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	realtek,pow-ldo2-gpio =
 | 
						realtek,pow-ldo2-gpio =
 | 
				
			||||||
		<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
 | 
							<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
 | 
				
			||||||
 | 
						realtek,reset-gpio = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_LOW>;
 | 
				
			||||||
	realtek,in1-differential = "true";
 | 
						realtek,in1-differential = "true";
 | 
				
			||||||
	realtek,gpio-config = /bits/ 8  <0 0 0 0 0 2>;   /* pull up GPIO6 */
 | 
						realtek,gpio-config = /bits/ 8  <0 0 0 0 0 2>;   /* pull up GPIO6 */
 | 
				
			||||||
	realtek,jd2-gpio = <3>;  /* Enables Jack detection for GPIO6 */
 | 
						realtek,jd2-gpio = <3>;  /* Enables Jack detection for GPIO6 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										41
									
								
								Documentation/devicetree/bindings/sound/tas571x.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								Documentation/devicetree/bindings/sound/tas571x.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					Texas Instruments TAS5711/TAS5717/TAS5719 stereo power amplifiers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The codec is controlled through an I2C interface.  It also has two other
 | 
				
			||||||
 | 
					signals that can be wired up to GPIOs: reset (strongly recommended), and
 | 
				
			||||||
 | 
					powerdown (optional).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- compatible: "ti,tas5711", "ti,tas5717", or "ti,tas5719"
 | 
				
			||||||
 | 
					- reg: The I2C address of the device
 | 
				
			||||||
 | 
					- #sound-dai-cells: must be equal to 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- reset-gpios: GPIO specifier for the TAS571x's active low reset line
 | 
				
			||||||
 | 
					- pdn-gpios: GPIO specifier for the TAS571x's active low powerdown line
 | 
				
			||||||
 | 
					- clocks: clock phandle for the MCLK input
 | 
				
			||||||
 | 
					- clock-names: should be "mclk"
 | 
				
			||||||
 | 
					- AVDD-supply: regulator phandle for the AVDD supply (all chips)
 | 
				
			||||||
 | 
					- DVDD-supply: regulator phandle for the DVDD supply (all chips)
 | 
				
			||||||
 | 
					- HPVDD-supply: regulator phandle for the HPVDD supply (5717/5719)
 | 
				
			||||||
 | 
					- PVDD_AB-supply: regulator phandle for the PVDD_AB supply (5717/5719)
 | 
				
			||||||
 | 
					- PVDD_CD-supply: regulator phandle for the PVDD_CD supply (5717/5719)
 | 
				
			||||||
 | 
					- PVDD_A-supply: regulator phandle for the PVDD_A supply (5711)
 | 
				
			||||||
 | 
					- PVDD_B-supply: regulator phandle for the PVDD_B supply (5711)
 | 
				
			||||||
 | 
					- PVDD_C-supply: regulator phandle for the PVDD_C supply (5711)
 | 
				
			||||||
 | 
					- PVDD_D-supply: regulator phandle for the PVDD_D supply (5711)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tas5717: audio-codec@2a {
 | 
				
			||||||
 | 
							compatible = "ti,tas5717";
 | 
				
			||||||
 | 
							reg = <0x2a>;
 | 
				
			||||||
 | 
							#sound-dai-cells = <0>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
 | 
				
			||||||
 | 
							pdn-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							clocks = <&clk_core CLK_I2S>;
 | 
				
			||||||
 | 
							clock-names = "mclk";
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
| 
						 | 
					@ -10,9 +10,20 @@ Required properties:
 | 
				
			||||||
  - reg : the I2C address of the device for I2C, the chip select
 | 
					  - reg : the I2C address of the device for I2C, the chip select
 | 
				
			||||||
          number for SPI.
 | 
					          number for SPI.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - diff-mode: Differential output mode configuration. Default value for field
 | 
				
			||||||
 | 
					    DIFF in register R8 (MODE_CONTROL_2). If absent, the default is 0, shall be:
 | 
				
			||||||
 | 
					    0 = stereo
 | 
				
			||||||
 | 
					    1 = mono left
 | 
				
			||||||
 | 
					    2 = stereo reversed
 | 
				
			||||||
 | 
					    3 = mono right
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
codec: wm8741@1a {
 | 
					codec: wm8741@1a {
 | 
				
			||||||
	compatible = "wlf,wm8741";
 | 
						compatible = "wlf,wm8741";
 | 
				
			||||||
	reg = <0x1a>;
 | 
						reg = <0x1a>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						diff-mode = <3>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										44
									
								
								Documentation/devicetree/bindings/sound/zte,zx-i2s.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Documentation/devicetree/bindings/sound/zte,zx-i2s.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					ZTE ZX296702 I2S controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					 - compatible : Must be "zte,zx296702-i2s"
 | 
				
			||||||
 | 
					 - reg : Must contain I2S core's registers location and length
 | 
				
			||||||
 | 
					 - clocks : Pairs of phandle and specifier referencing the controller's clocks.
 | 
				
			||||||
 | 
					 - clock-names: "tx" for the clock to the I2S interface.
 | 
				
			||||||
 | 
					 - dmas: Pairs of phandle and specifier for the DMA channel that is used by
 | 
				
			||||||
 | 
					   the core. The core expects two dma channels for transmit.
 | 
				
			||||||
 | 
					 - dma-names : Must be "tx" and "rx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
 | 
				
			||||||
 | 
					please check:
 | 
				
			||||||
 | 
						* resource-names.txt
 | 
				
			||||||
 | 
						* clock/clock-bindings.txt
 | 
				
			||||||
 | 
						* dma/dma.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
						i2s0: i2s0@0b005000 {
 | 
				
			||||||
 | 
							#sound-dai-cells = <0>;
 | 
				
			||||||
 | 
							compatible = "zte,zx296702-i2s";
 | 
				
			||||||
 | 
							reg = <0x0b005000 0x1000>;
 | 
				
			||||||
 | 
							clocks = <&lsp0clk ZX296702_I2S0_DIV>;
 | 
				
			||||||
 | 
							clock-names = "tx";
 | 
				
			||||||
 | 
							interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
 | 
							dmas = <&dma 5>, <&dma 6>;
 | 
				
			||||||
 | 
							dma-names = "tx", "rx";
 | 
				
			||||||
 | 
							status = "okay";
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sound {
 | 
				
			||||||
 | 
							compatible = "simple-audio-card";
 | 
				
			||||||
 | 
							simple-audio-card,name = "zx296702_snd";
 | 
				
			||||||
 | 
							simple-audio-card,format = "left_j";
 | 
				
			||||||
 | 
							simple-audio-card,bitclock-master = <&sndcodec>;
 | 
				
			||||||
 | 
							simple-audio-card,frame-master = <&sndcodec>;
 | 
				
			||||||
 | 
							sndcpu: simple-audio-card,cpu {
 | 
				
			||||||
 | 
								sound-dai = <&i2s0>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sndcodec: simple-audio-card,codec {
 | 
				
			||||||
 | 
								sound-dai = <&acodec>;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
							
								
								
									
										28
									
								
								Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					ZTE ZX296702 SPDIF controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					 - compatible : Must be "zte,zx296702-spdif"
 | 
				
			||||||
 | 
					 - reg : Must contain SPDIF core's registers location and length
 | 
				
			||||||
 | 
					 - clocks : Pairs of phandle and specifier referencing the controller's clocks.
 | 
				
			||||||
 | 
					 - clock-names: "tx" for the clock to the SPDIF interface.
 | 
				
			||||||
 | 
					 - dmas: Pairs of phandle and specifier for the DMA channel that is used by
 | 
				
			||||||
 | 
					   the core. The core expects one dma channel for transmit.
 | 
				
			||||||
 | 
					 - dma-names : Must be "tx"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
 | 
				
			||||||
 | 
					please check:
 | 
				
			||||||
 | 
						* resource-names.txt
 | 
				
			||||||
 | 
						* clock/clock-bindings.txt
 | 
				
			||||||
 | 
						* dma/dma.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
						spdif0: spdif0@0b004000 {
 | 
				
			||||||
 | 
							compatible = "zte,zx296702-spdif";
 | 
				
			||||||
 | 
							reg = <0x0b004000 0x1000>;
 | 
				
			||||||
 | 
							clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
 | 
				
			||||||
 | 
							clock-names = "tx";
 | 
				
			||||||
 | 
							interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
 | 
							dmas = <&dma 4>;
 | 
				
			||||||
 | 
							dma-names = "tx";
 | 
				
			||||||
 | 
							status = "okay";
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ cosmic	Cosmic Circuits
 | 
				
			||||||
crystalfontz	Crystalfontz America, Inc.
 | 
					crystalfontz	Crystalfontz America, Inc.
 | 
				
			||||||
dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 | 
					dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 | 
				
			||||||
davicom	DAVICOM Semiconductor, Inc.
 | 
					davicom	DAVICOM Semiconductor, Inc.
 | 
				
			||||||
 | 
					delta	Delta Electronics, Inc.
 | 
				
			||||||
denx	Denx Software Engineering
 | 
					denx	Denx Software Engineering
 | 
				
			||||||
digi	Digi International Inc.
 | 
					digi	Digi International Inc.
 | 
				
			||||||
digilent	Diglent, Inc.
 | 
					digilent	Diglent, Inc.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9924,6 +9924,12 @@ L:	netdev@vger.kernel.org
 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
F:	drivers/net/ethernet/ti/netcp*
 | 
					F:	drivers/net/ethernet/ti/netcp*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TI TAS571X FAMILY ASoC CODEC DRIVER
 | 
				
			||||||
 | 
					M:	Kevin Cernekee <cernekee@chromium.org>
 | 
				
			||||||
 | 
					L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
 | 
				
			||||||
 | 
					S:	Odd Fixes
 | 
				
			||||||
 | 
					F:	sound/soc/codecs/tas571x*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TI TWL4030 SERIES SOC CODEC DRIVER
 | 
					TI TWL4030 SERIES SOC CODEC DRIVER
 | 
				
			||||||
M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
 | 
					M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
 | 
				
			||||||
L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
 | 
					L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -465,6 +465,7 @@ static dma_cookie_t rcar_dmac_tx_submit(struct dma_async_tx_descriptor *tx)
 | 
				
			||||||
static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
					static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rcar_dmac_desc_page *page;
 | 
						struct rcar_dmac_desc_page *page;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
	LIST_HEAD(list);
 | 
						LIST_HEAD(list);
 | 
				
			||||||
	unsigned int i;
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,10 +483,10 @@ static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
				
			||||||
		list_add_tail(&desc->node, &list);
 | 
							list_add_tail(&desc->node, &list);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	list_splice_tail(&list, &chan->desc.free);
 | 
						list_splice_tail(&list, &chan->desc.free);
 | 
				
			||||||
	list_add_tail(&page->node, &chan->desc.pages);
 | 
						list_add_tail(&page->node, &chan->desc.pages);
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -516,6 +517,7 @@ static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan,
 | 
				
			||||||
static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
 | 
					static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rcar_dmac_desc *desc, *_desc;
 | 
						struct rcar_dmac_desc *desc, *_desc;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
	LIST_HEAD(list);
 | 
						LIST_HEAD(list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -524,9 +526,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
 | 
				
			||||||
	 * list_for_each_entry_safe, isn't safe if we release the channel lock
 | 
						 * list_for_each_entry_safe, isn't safe if we release the channel lock
 | 
				
			||||||
	 * around the rcar_dmac_desc_put() call.
 | 
						 * around the rcar_dmac_desc_put() call.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	list_splice_init(&chan->desc.wait, &list);
 | 
						list_splice_init(&chan->desc.wait, &list);
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry_safe(desc, _desc, &list, node) {
 | 
						list_for_each_entry_safe(desc, _desc, &list, node) {
 | 
				
			||||||
		if (async_tx_test_ack(&desc->async_tx)) {
 | 
							if (async_tx_test_ack(&desc->async_tx)) {
 | 
				
			||||||
| 
						 | 
					@ -539,9 +541,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Put the remaining descriptors back in the wait list. */
 | 
						/* Put the remaining descriptors back in the wait list. */
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	list_splice(&list, &chan->desc.wait);
 | 
						list_splice(&list, &chan->desc.wait);
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -556,12 +558,13 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
 | 
				
			||||||
static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
 | 
					static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rcar_dmac_desc *desc;
 | 
						struct rcar_dmac_desc *desc;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Recycle acked descriptors before attempting allocation. */
 | 
						/* Recycle acked descriptors before attempting allocation. */
 | 
				
			||||||
	rcar_dmac_desc_recycle_acked(chan);
 | 
						rcar_dmac_desc_recycle_acked(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (list_empty(&chan->desc.free)) {
 | 
						while (list_empty(&chan->desc.free)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -570,17 +573,17 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
 | 
				
			||||||
		 * allocated descriptors. If the allocation fails return an
 | 
							 * allocated descriptors. If the allocation fails return an
 | 
				
			||||||
		 * error.
 | 
							 * error.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		spin_unlock_irq(&chan->lock);
 | 
							spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
		ret = rcar_dmac_desc_alloc(chan, GFP_NOWAIT);
 | 
							ret = rcar_dmac_desc_alloc(chan, GFP_NOWAIT);
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		spin_lock_irq(&chan->lock);
 | 
							spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	desc = list_first_entry(&chan->desc.free, struct rcar_dmac_desc, node);
 | 
						desc = list_first_entry(&chan->desc.free, struct rcar_dmac_desc, node);
 | 
				
			||||||
	list_del(&desc->node);
 | 
						list_del(&desc->node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return desc;
 | 
						return desc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -593,6 +596,7 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
 | 
				
			||||||
static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
					static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rcar_dmac_desc_page *page;
 | 
						struct rcar_dmac_desc_page *page;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
	LIST_HEAD(list);
 | 
						LIST_HEAD(list);
 | 
				
			||||||
	unsigned int i;
 | 
						unsigned int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -606,10 +610,10 @@ static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
 | 
				
			||||||
		list_add_tail(&chunk->node, &list);
 | 
							list_add_tail(&chunk->node, &list);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	list_splice_tail(&list, &chan->desc.chunks_free);
 | 
						list_splice_tail(&list, &chan->desc.chunks_free);
 | 
				
			||||||
	list_add_tail(&page->node, &chan->desc.pages);
 | 
						list_add_tail(&page->node, &chan->desc.pages);
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -627,9 +631,10 @@ static struct rcar_dmac_xfer_chunk *
 | 
				
			||||||
rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
 | 
					rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rcar_dmac_xfer_chunk *chunk;
 | 
						struct rcar_dmac_xfer_chunk *chunk;
 | 
				
			||||||
 | 
						unsigned long flags;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock_irq(&chan->lock);
 | 
						spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (list_empty(&chan->desc.chunks_free)) {
 | 
						while (list_empty(&chan->desc.chunks_free)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
| 
						 | 
					@ -638,18 +643,18 @@ rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
 | 
				
			||||||
		 * allocated descriptors. If the allocation fails return an
 | 
							 * allocated descriptors. If the allocation fails return an
 | 
				
			||||||
		 * error.
 | 
							 * error.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		spin_unlock_irq(&chan->lock);
 | 
							spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
		ret = rcar_dmac_xfer_chunk_alloc(chan, GFP_NOWAIT);
 | 
							ret = rcar_dmac_xfer_chunk_alloc(chan, GFP_NOWAIT);
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			return NULL;
 | 
								return NULL;
 | 
				
			||||||
		spin_lock_irq(&chan->lock);
 | 
							spin_lock_irqsave(&chan->lock, flags);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chunk = list_first_entry(&chan->desc.chunks_free,
 | 
						chunk = list_first_entry(&chan->desc.chunks_free,
 | 
				
			||||||
				 struct rcar_dmac_xfer_chunk, node);
 | 
									 struct rcar_dmac_xfer_chunk, node);
 | 
				
			||||||
	list_del(&chunk->node);
 | 
						list_del(&chunk->node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_unlock_irq(&chan->lock);
 | 
						spin_unlock_irqrestore(&chan->lock, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return chunk;
 | 
						return chunk;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
 | 
				
			||||||
	if (ret != 0)
 | 
						if (ret != 0)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
 | 
					 | 
				
			||||||
				 ARIZONA_SUBSYS_MAX_FREQ, val);
 | 
					 | 
				
			||||||
	if (ret != 0)
 | 
					 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (val)
 | 
						if (val)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								include/dt-bindings/sound/apq8016-lpass.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								include/dt-bindings/sound/apq8016-lpass.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					#ifndef __DT_APQ8016_LPASS_H
 | 
				
			||||||
 | 
					#define __DT_APQ8016_LPASS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MI2S_PRIMARY	0
 | 
				
			||||||
 | 
					#define MI2S_SECONDARY	1
 | 
				
			||||||
 | 
					#define MI2S_TERTIARY	2
 | 
				
			||||||
 | 
					#define MI2S_QUATERNARY	3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DT_APQ8016_LPASS_H */
 | 
				
			||||||
							
								
								
									
										9
									
								
								include/dt-bindings/sound/audio-jack-events.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								include/dt-bindings/sound/audio-jack-events.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					#ifndef __AUDIO_JACK_EVENTS_H
 | 
				
			||||||
 | 
					#define __AUDIO_JACK_EVENTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define JACK_HEADPHONE		1
 | 
				
			||||||
 | 
					#define JACK_MICROPHONE		2
 | 
				
			||||||
 | 
					#define JACK_LINEOUT		3
 | 
				
			||||||
 | 
					#define JACK_LINEIN		4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __AUDIO_JACK_EVENTS_H */
 | 
				
			||||||
							
								
								
									
										18
									
								
								include/dt-bindings/sound/tas2552.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								include/dt-bindings/sound/tas2552.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					#ifndef __DT_TAS2552_H
 | 
				
			||||||
 | 
					#define __DT_TAS2552_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TAS2552_PLL_CLKIN		(0)
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK			(1)
 | 
				
			||||||
 | 
					#define TAS2552_CLK_TARGET_MASK		(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TAS2552_PLL_CLKIN_MCLK		((0 << 1) | TAS2552_PLL_CLKIN)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_CLKIN_BCLK		((1 << 1) | TAS2552_PLL_CLKIN)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_CLKIN_IVCLKIN	((2 << 1) | TAS2552_PLL_CLKIN)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_CLKIN_1_8_FIXED	((3 << 1) | TAS2552_PLL_CLKIN)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK_PLL		((0 << 1) | TAS2552_PDM_CLK)
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK_IVCLKIN		((1 << 1) | TAS2552_PDM_CLK)
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK_BCLK		((2 << 1) | TAS2552_PDM_CLK)
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK_MCLK		((3 << 1) | TAS2552_PDM_CLK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __DT_TAS2552_H */
 | 
				
			||||||
| 
						 | 
					@ -90,11 +90,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
 | 
				
			||||||
 * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
 | 
					 * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
 | 
					#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * The platforms dmaengine driver does not support reporting the amount of
 | 
					 | 
				
			||||||
 * bytes that are still left to transfer.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(2)
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * The PCM is half duplex and the DMA channel is shared between capture and
 | 
					 * The PCM is half duplex and the DMA channel is shared between capture and
 | 
				
			||||||
 * playback.
 | 
					 * playback.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,6 @@ struct rt5645_platform_data {
 | 
				
			||||||
	/* IN2 can optionally be differential */
 | 
						/* IN2 can optionally be differential */
 | 
				
			||||||
	bool in2_diff;
 | 
						bool in2_diff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool dmic_en;
 | 
					 | 
				
			||||||
	unsigned int dmic1_data_pin;
 | 
						unsigned int dmic1_data_pin;
 | 
				
			||||||
	/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
 | 
						/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
 | 
				
			||||||
	unsigned int dmic2_data_pin;
 | 
						unsigned int dmic2_data_pin;
 | 
				
			||||||
| 
						 | 
					@ -24,8 +23,6 @@ struct rt5645_platform_data {
 | 
				
			||||||
	unsigned int hp_det_gpio;
 | 
						unsigned int hp_det_gpio;
 | 
				
			||||||
	bool gpio_hp_det_active_high;
 | 
						bool gpio_hp_det_active_high;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* true if codec's jd function is used */
 | 
					 | 
				
			||||||
	bool en_jd_func;
 | 
					 | 
				
			||||||
	unsigned int jd_mode;
 | 
						unsigned int jd_mode;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/types.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <sound/control.h>
 | 
					#include <sound/control.h>
 | 
				
			||||||
 | 
					#include <sound/soc-topology.h>
 | 
				
			||||||
 | 
					#include <sound/asoc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct device;
 | 
					struct device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +109,10 @@ struct device;
 | 
				
			||||||
{	.id = snd_soc_dapm_mux, .name = wname, \
 | 
					{	.id = snd_soc_dapm_mux, .name = wname, \
 | 
				
			||||||
	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
 | 
						SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
 | 
				
			||||||
	.kcontrol_news = wcontrols, .num_kcontrols = 1}
 | 
						.kcontrol_news = wcontrols, .num_kcontrols = 1}
 | 
				
			||||||
 | 
					#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \
 | 
				
			||||||
 | 
					{	.id = snd_soc_dapm_demux, .name = wname, \
 | 
				
			||||||
 | 
						SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
 | 
				
			||||||
 | 
						.kcontrol_news = wcontrols, .num_kcontrols = 1}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
 | 
					/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
 | 
				
			||||||
#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
 | 
					#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
 | 
				
			||||||
| 
						 | 
					@ -444,11 +450,15 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
 | 
				
			||||||
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
 | 
					struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
 | 
				
			||||||
	struct snd_kcontrol *kcontrol);
 | 
						struct snd_kcontrol *kcontrol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
 | 
						enum snd_soc_bias_level level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* dapm widget types */
 | 
					/* dapm widget types */
 | 
				
			||||||
enum snd_soc_dapm_type {
 | 
					enum snd_soc_dapm_type {
 | 
				
			||||||
	snd_soc_dapm_input = 0,		/* input pin */
 | 
						snd_soc_dapm_input = 0,		/* input pin */
 | 
				
			||||||
	snd_soc_dapm_output,		/* output pin */
 | 
						snd_soc_dapm_output,		/* output pin */
 | 
				
			||||||
	snd_soc_dapm_mux,			/* selects 1 analog signal from many inputs */
 | 
						snd_soc_dapm_mux,			/* selects 1 analog signal from many inputs */
 | 
				
			||||||
 | 
						snd_soc_dapm_demux,			/* connects the input to one of multiple outputs */
 | 
				
			||||||
	snd_soc_dapm_mixer,			/* mixes several analog signals together */
 | 
						snd_soc_dapm_mixer,			/* mixes several analog signals together */
 | 
				
			||||||
	snd_soc_dapm_mixer_named_ctl,		/* mixer with named controls */
 | 
						snd_soc_dapm_mixer_named_ctl,		/* mixer with named controls */
 | 
				
			||||||
	snd_soc_dapm_pga,			/* programmable gain/attenuation (volume) */
 | 
						snd_soc_dapm_pga,			/* programmable gain/attenuation (volume) */
 | 
				
			||||||
| 
						 | 
					@ -563,6 +573,7 @@ struct snd_soc_dapm_widget {
 | 
				
			||||||
	int num_kcontrols;
 | 
						int num_kcontrols;
 | 
				
			||||||
	const struct snd_kcontrol_new *kcontrol_news;
 | 
						const struct snd_kcontrol_new *kcontrol_news;
 | 
				
			||||||
	struct snd_kcontrol **kcontrols;
 | 
						struct snd_kcontrol **kcontrols;
 | 
				
			||||||
 | 
						struct snd_soc_dobj dobj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* widget input and outputs */
 | 
						/* widget input and outputs */
 | 
				
			||||||
	struct list_head sources;
 | 
						struct list_head sources;
 | 
				
			||||||
| 
						 | 
					@ -585,6 +596,10 @@ struct snd_soc_dapm_update {
 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct snd_soc_dapm_wcache {
 | 
				
			||||||
 | 
						struct snd_soc_dapm_widget *widget;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* DAPM context */
 | 
					/* DAPM context */
 | 
				
			||||||
struct snd_soc_dapm_context {
 | 
					struct snd_soc_dapm_context {
 | 
				
			||||||
	enum snd_soc_bias_level bias_level;
 | 
						enum snd_soc_bias_level bias_level;
 | 
				
			||||||
| 
						 | 
					@ -606,6 +621,9 @@ struct snd_soc_dapm_context {
 | 
				
			||||||
	int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
 | 
						int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
			      enum snd_soc_bias_level level);
 | 
								      enum snd_soc_bias_level level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct snd_soc_dapm_wcache path_sink_cache;
 | 
				
			||||||
 | 
						struct snd_soc_dapm_wcache path_source_cache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	struct dentry *debugfs_dapm;
 | 
						struct dentry *debugfs_dapm;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -623,4 +641,35 @@ struct snd_soc_dapm_stats {
 | 
				
			||||||
	int neighbour_checks;
 | 
						int neighbour_checks;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
 | 
				
			||||||
 | 
					 * @dapm: The DAPM context to initialize
 | 
				
			||||||
 | 
					 * @level: The DAPM level to initialize to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function only sets the driver internal state of the DAPM level and will
 | 
				
			||||||
 | 
					 * not modify the state of the device. Hence it should not be used during normal
 | 
				
			||||||
 | 
					 * operation, but only to synchronize the internal state to the device state.
 | 
				
			||||||
 | 
					 * E.g. during driver probe to set the DAPM level to the one corresponding with
 | 
				
			||||||
 | 
					 * the power-on reset state of the device.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void snd_soc_dapm_init_bias_level(
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dapm->bias_level = level;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_dapm_get_bias_level() - Get current DAPM bias level
 | 
				
			||||||
 | 
					 * @dapm: The context for which to get the bias level
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns: The current bias level of the passed DAPM context.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return dapm->bias_level;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										168
									
								
								include/sound/soc-topology.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								include/sound/soc-topology.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,168 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * linux/sound/soc-topology.h -- ALSA SoC Firmware Controls and DAPM
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 Texas Instruments Inc.
 | 
				
			||||||
 | 
					 * Copyright (C) 2015 Intel Corporation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					 * published by the Free Software Foundation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
 | 
				
			||||||
 | 
					 * algorithms, equalisers, DAIs, widgets, FE caps, BE caps, codec link caps etc.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __LINUX_SND_SOC_TPLG_H
 | 
				
			||||||
 | 
					#define __LINUX_SND_SOC_TPLG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sound/asoc.h>
 | 
				
			||||||
 | 
					#include <linux/list.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct firmware;
 | 
				
			||||||
 | 
					struct snd_kcontrol;
 | 
				
			||||||
 | 
					struct snd_soc_tplg_pcm_be;
 | 
				
			||||||
 | 
					struct snd_ctl_elem_value;
 | 
				
			||||||
 | 
					struct snd_ctl_elem_info;
 | 
				
			||||||
 | 
					struct snd_soc_dapm_widget;
 | 
				
			||||||
 | 
					struct snd_soc_component;
 | 
				
			||||||
 | 
					struct snd_soc_tplg_pcm_fe;
 | 
				
			||||||
 | 
					struct snd_soc_dapm_context;
 | 
				
			||||||
 | 
					struct snd_soc_card;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* object scan be loaded and unloaded in groups with identfying indexes */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_INDEX_ALL	0	/* ID that matches all FW objects */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* dynamic object type */
 | 
				
			||||||
 | 
					enum snd_soc_dobj_type {
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_NONE		= 0,	/* object is not dynamic */
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_MIXER,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_ENUM,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_BYTES,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_PCM,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_DAI_LINK,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_CODEC_LINK,
 | 
				
			||||||
 | 
						SND_SOC_DOBJ_WIDGET,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* dynamic control object */
 | 
				
			||||||
 | 
					struct snd_soc_dobj_control {
 | 
				
			||||||
 | 
						struct snd_kcontrol *kcontrol;
 | 
				
			||||||
 | 
						char **dtexts;
 | 
				
			||||||
 | 
						unsigned long *dvalues;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* dynamic widget object */
 | 
				
			||||||
 | 
					struct snd_soc_dobj_widget {
 | 
				
			||||||
 | 
						unsigned int kcontrol_enum:1;	/* this widget is an enum kcontrol */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* dynamic PCM DAI object */
 | 
				
			||||||
 | 
					struct snd_soc_dobj_pcm_dai {
 | 
				
			||||||
 | 
						struct snd_soc_tplg_pcm_dai *pd;
 | 
				
			||||||
 | 
						unsigned int count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* generic dynamic object - all dynamic objects belong to this struct */
 | 
				
			||||||
 | 
					struct snd_soc_dobj {
 | 
				
			||||||
 | 
						enum snd_soc_dobj_type type;
 | 
				
			||||||
 | 
						unsigned int index;	/* objects can belong in different groups */
 | 
				
			||||||
 | 
						struct list_head list;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ops *ops;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct snd_soc_dobj_control control;
 | 
				
			||||||
 | 
							struct snd_soc_dobj_widget widget;
 | 
				
			||||||
 | 
							struct snd_soc_dobj_pcm_dai pcm_dai;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						void *private; /* core does not touch this */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kcontrol operations - used to map handlers onto firmware based controls.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_kcontrol_ops {
 | 
				
			||||||
 | 
						u32 id;
 | 
				
			||||||
 | 
						int (*get)(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
								struct snd_ctl_elem_value *ucontrol);
 | 
				
			||||||
 | 
						int (*put)(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
								struct snd_ctl_elem_value *ucontrol);
 | 
				
			||||||
 | 
						int (*info)(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
							struct snd_ctl_elem_info *uinfo);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * DAPM widget event handlers - used to map handlers onto widgets.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_widget_events {
 | 
				
			||||||
 | 
						u16 type;
 | 
				
			||||||
 | 
						int (*event_handler)(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
								struct snd_kcontrol *k, int event);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Public API - Used by component drivers to load and unload dynamic objects
 | 
				
			||||||
 | 
					 * and their resources.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_ops {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* external kcontrol init - used for any driver specific init */
 | 
				
			||||||
 | 
						int (*control_load)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_kcontrol_new *, struct snd_soc_tplg_ctl_hdr *);
 | 
				
			||||||
 | 
						int (*control_unload)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_dobj *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* external widget init - used for any driver specific init */
 | 
				
			||||||
 | 
						int (*widget_load)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_dapm_widget *,
 | 
				
			||||||
 | 
							struct snd_soc_tplg_dapm_widget *);
 | 
				
			||||||
 | 
						int (*widget_unload)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_dobj *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* FE - used for any driver specific init */
 | 
				
			||||||
 | 
						int (*pcm_dai_load)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_tplg_pcm_dai *pcm_dai, int num_fe);
 | 
				
			||||||
 | 
						int (*pcm_dai_unload)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_dobj *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* callback to handle vendor bespoke data */
 | 
				
			||||||
 | 
						int (*vendor_load)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_tplg_hdr *);
 | 
				
			||||||
 | 
						int (*vendor_unload)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_tplg_hdr *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* completion - called at completion of firmware loading */
 | 
				
			||||||
 | 
						void (*complete)(struct snd_soc_component *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* manifest - optional to inform component of manifest */
 | 
				
			||||||
 | 
						int (*manifest)(struct snd_soc_component *,
 | 
				
			||||||
 | 
							struct snd_soc_tplg_manifest *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* bespoke kcontrol handlers available for binding */
 | 
				
			||||||
 | 
						const struct snd_soc_tplg_kcontrol_ops *io_ops;
 | 
				
			||||||
 | 
						int io_ops_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* gets a pointer to data from the firmware block header */
 | 
				
			||||||
 | 
					static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const void *ptr = hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ptr + sizeof(*hdr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Dynamic Object loading and removal for component drivers */
 | 
				
			||||||
 | 
					int snd_soc_tplg_component_load(struct snd_soc_component *comp,
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ops *ops, const struct firmware *fw,
 | 
				
			||||||
 | 
						u32 index);
 | 
				
			||||||
 | 
					int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Widget removal - widgets also removed wth component API */
 | 
				
			||||||
 | 
					void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w);
 | 
				
			||||||
 | 
					void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
 | 
						u32 index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Binds event handlers to dynamic widgets */
 | 
				
			||||||
 | 
					int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
						const struct snd_soc_tplg_widget_events *events, int num_events,
 | 
				
			||||||
 | 
						u16 event_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
#include <sound/compress_driver.h>
 | 
					#include <sound/compress_driver.h>
 | 
				
			||||||
#include <sound/control.h>
 | 
					#include <sound/control.h>
 | 
				
			||||||
#include <sound/ac97_codec.h>
 | 
					#include <sound/ac97_codec.h>
 | 
				
			||||||
 | 
					#include <sound/soc-topology.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Convenience kcontrol builders
 | 
					 * Convenience kcontrol builders
 | 
				
			||||||
| 
						 | 
					@ -190,8 +191,12 @@
 | 
				
			||||||
#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \
 | 
					#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \
 | 
				
			||||||
{	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
 | 
					{	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
 | 
				
			||||||
	.mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues}
 | 
						.mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues}
 | 
				
			||||||
#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xnitmes, xtexts, xvalues) \
 | 
					#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
 | 
				
			||||||
	SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xnitmes, xtexts, xvalues)
 | 
						SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xitems, xtexts, xvalues)
 | 
				
			||||||
 | 
					#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
 | 
				
			||||||
 | 
					{	.reg = xreg, .shift_l = xshift, .shift_r = xshift, \
 | 
				
			||||||
 | 
						.mask = xmask, .items = xitems, .texts = xtexts, \
 | 
				
			||||||
 | 
						.values = xvalues, .autodisable = 1}
 | 
				
			||||||
#define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \
 | 
					#define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \
 | 
				
			||||||
	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
 | 
						SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
 | 
				
			||||||
#define SOC_ENUM(xname, xenum) \
 | 
					#define SOC_ENUM(xname, xenum) \
 | 
				
			||||||
| 
						 | 
					@ -312,6 +317,11 @@
 | 
				
			||||||
							ARRAY_SIZE(xtexts), xtexts, xvalues)
 | 
												ARRAY_SIZE(xtexts), xtexts, xvalues)
 | 
				
			||||||
#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
 | 
					#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
 | 
				
			||||||
	SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
 | 
						SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
 | 
				
			||||||
 | 
						const struct soc_enum name = SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, \
 | 
				
			||||||
 | 
							xshift, xmask, ARRAY_SIZE(xtexts), xtexts, xvalues)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
 | 
					#define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
 | 
				
			||||||
	const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
 | 
						const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -767,6 +777,9 @@ struct snd_soc_component {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mutex io_mutex;
 | 
						struct mutex io_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* attached dynamic objects */
 | 
				
			||||||
 | 
						struct list_head dobj_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	struct dentry *debugfs_root;
 | 
						struct dentry *debugfs_root;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -819,7 +832,7 @@ struct snd_soc_codec {
 | 
				
			||||||
	/* component */
 | 
						/* component */
 | 
				
			||||||
	struct snd_soc_component component;
 | 
						struct snd_soc_component component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* dapm */
 | 
						/* Don't access this directly, use snd_soc_codec_get_dapm() */
 | 
				
			||||||
	struct snd_soc_dapm_context dapm;
 | 
						struct snd_soc_dapm_context dapm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
| 
						 | 
					@ -961,30 +974,6 @@ struct snd_soc_dai_link {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
 | 
						enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Keep DAI active over suspend */
 | 
					 | 
				
			||||||
	unsigned int ignore_suspend:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Symmetry requirements */
 | 
					 | 
				
			||||||
	unsigned int symmetric_rates:1;
 | 
					 | 
				
			||||||
	unsigned int symmetric_channels:1;
 | 
					 | 
				
			||||||
	unsigned int symmetric_samplebits:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Mark this pcm with non atomic ops */
 | 
					 | 
				
			||||||
	bool nonatomic;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Do not create a PCM for this DAI link (Backend link) */
 | 
					 | 
				
			||||||
	unsigned int no_pcm:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* This DAI link can route to other DAI links at runtime (Frontend)*/
 | 
					 | 
				
			||||||
	unsigned int dynamic:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* DPCM capture and Playback support */
 | 
					 | 
				
			||||||
	unsigned int dpcm_capture:1;
 | 
					 | 
				
			||||||
	unsigned int dpcm_playback:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pmdown_time is ignored at stop */
 | 
					 | 
				
			||||||
	unsigned int ignore_pmdown_time:1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* codec/machine specific init - e.g. add machine controls */
 | 
						/* codec/machine specific init - e.g. add machine controls */
 | 
				
			||||||
	int (*init)(struct snd_soc_pcm_runtime *rtd);
 | 
						int (*init)(struct snd_soc_pcm_runtime *rtd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -999,6 +988,33 @@ struct snd_soc_dai_link {
 | 
				
			||||||
	/* For unidirectional dai links */
 | 
						/* For unidirectional dai links */
 | 
				
			||||||
	bool playback_only;
 | 
						bool playback_only;
 | 
				
			||||||
	bool capture_only;
 | 
						bool capture_only;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Mark this pcm with non atomic ops */
 | 
				
			||||||
 | 
						bool nonatomic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Keep DAI active over suspend */
 | 
				
			||||||
 | 
						unsigned int ignore_suspend:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Symmetry requirements */
 | 
				
			||||||
 | 
						unsigned int symmetric_rates:1;
 | 
				
			||||||
 | 
						unsigned int symmetric_channels:1;
 | 
				
			||||||
 | 
						unsigned int symmetric_samplebits:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Do not create a PCM for this DAI link (Backend link) */
 | 
				
			||||||
 | 
						unsigned int no_pcm:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* This DAI link can route to other DAI links at runtime (Frontend)*/
 | 
				
			||||||
 | 
						unsigned int dynamic:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* DPCM capture and Playback support */
 | 
				
			||||||
 | 
						unsigned int dpcm_capture:1;
 | 
				
			||||||
 | 
						unsigned int dpcm_playback:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* DPCM used FE & BE merged format */
 | 
				
			||||||
 | 
						unsigned int dpcm_merged_format:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* pmdown_time is ignored at stop */
 | 
				
			||||||
 | 
						unsigned int ignore_pmdown_time:1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_soc_codec_conf {
 | 
					struct snd_soc_codec_conf {
 | 
				
			||||||
| 
						 | 
					@ -1111,6 +1127,9 @@ struct snd_soc_card {
 | 
				
			||||||
	struct list_head dapm_list;
 | 
						struct list_head dapm_list;
 | 
				
			||||||
	struct list_head dapm_dirty;
 | 
						struct list_head dapm_dirty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* attached dynamic objects */
 | 
				
			||||||
 | 
						struct list_head dobj_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Generic DAPM context for the card */
 | 
						/* Generic DAPM context for the card */
 | 
				
			||||||
	struct snd_soc_dapm_context dapm;
 | 
						struct snd_soc_dapm_context dapm;
 | 
				
			||||||
	struct snd_soc_dapm_stats dapm_stats;
 | 
						struct snd_soc_dapm_stats dapm_stats;
 | 
				
			||||||
| 
						 | 
					@ -1170,6 +1189,7 @@ struct soc_mixer_control {
 | 
				
			||||||
	unsigned int sign_bit;
 | 
						unsigned int sign_bit;
 | 
				
			||||||
	unsigned int invert:1;
 | 
						unsigned int invert:1;
 | 
				
			||||||
	unsigned int autodisable:1;
 | 
						unsigned int autodisable:1;
 | 
				
			||||||
 | 
						struct snd_soc_dobj dobj;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct soc_bytes {
 | 
					struct soc_bytes {
 | 
				
			||||||
| 
						 | 
					@ -1180,6 +1200,8 @@ struct soc_bytes {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct soc_bytes_ext {
 | 
					struct soc_bytes_ext {
 | 
				
			||||||
	int max;
 | 
						int max;
 | 
				
			||||||
 | 
						struct snd_soc_dobj dobj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* used for TLV byte control */
 | 
						/* used for TLV byte control */
 | 
				
			||||||
	int (*get)(unsigned int __user *bytes, unsigned int size);
 | 
						int (*get)(unsigned int __user *bytes, unsigned int size);
 | 
				
			||||||
	int (*put)(const unsigned int __user *bytes, unsigned int size);
 | 
						int (*put)(const unsigned int __user *bytes, unsigned int size);
 | 
				
			||||||
| 
						 | 
					@ -1200,6 +1222,8 @@ struct soc_enum {
 | 
				
			||||||
	unsigned int mask;
 | 
						unsigned int mask;
 | 
				
			||||||
	const char * const *texts;
 | 
						const char * const *texts;
 | 
				
			||||||
	const unsigned int *values;
 | 
						const unsigned int *values;
 | 
				
			||||||
 | 
						unsigned int autodisable:1;
 | 
				
			||||||
 | 
						struct snd_soc_dobj dobj;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1281,6 +1305,58 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
 | 
				
			||||||
	return component->dapm_ptr;
 | 
						return component->dapm_ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
 | 
				
			||||||
 | 
					 * @codec: The CODEC for which to get the DAPM context
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note: Use this function instead of directly accessing the CODEC's dapm field
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return &codec->dapm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
 | 
				
			||||||
 | 
					 * @dapm: The CODEC for which to initialize the DAPM bias level
 | 
				
			||||||
 | 
					 * @level: The DAPM level to initialize to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
						enum snd_soc_bias_level level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
 | 
				
			||||||
 | 
					 * @codec: The CODEC for which to get the DAPM bias level
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns: The current DAPM bias level of the CODEC.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
 | 
				
			||||||
 | 
					 * @codec: The CODEC for which to set the level
 | 
				
			||||||
 | 
					 * @level: The level to set to
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Forces the CODEC bias level to a specific state. See
 | 
				
			||||||
 | 
					 * snd_soc_dapm_force_bias_level().
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
						enum snd_soc_bias_level level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
 | 
				
			||||||
 | 
							level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
 | 
					 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
 | 
				
			||||||
 * @kcontrol: The kcontrol
 | 
					 * @kcontrol: The kcontrol
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,12 +31,7 @@
 | 
				
			||||||
 *                       ~(sizeof(unsigned int) - 1)) ....
 | 
					 *                       ~(sizeof(unsigned int) - 1)) ....
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SNDRV_CTL_TLVT_CONTAINER 0	/* one level down - group of TLVs */
 | 
					#include <uapi/sound/tlv.h>
 | 
				
			||||||
#define SNDRV_CTL_TLVT_DB_SCALE	1       /* dB scale */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_DB_LINEAR 2	/* linear volume */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_DB_RANGE 3	/* dB range container */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_DB_MINMAX 4	/* dB scale with min/max */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5	/* dB scale with min/max with mute */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TLV_ITEM(type, ...) \
 | 
					#define TLV_ITEM(type, ...) \
 | 
				
			||||||
	(type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__
 | 
						(type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__
 | 
				
			||||||
| 
						 | 
					@ -90,12 +85,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TLV_DB_GAIN_MUTE	-9999999
 | 
					#define TLV_DB_GAIN_MUTE	-9999999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * channel-mapping TLV items
 | 
					 | 
				
			||||||
 *  TLV length must match with num_channels
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_CHMAP_FIXED	0x101	/* fixed channel position */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_CHMAP_VAR	0x102	/* channels freely swappable */
 | 
					 | 
				
			||||||
#define SNDRV_CTL_TLVT_CHMAP_PAIRED	0x103	/* pair-wise swappable */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* __SOUND_TLV_H */
 | 
					#endif /* __SOUND_TLV_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										388
									
								
								include/uapi/sound/asoc.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								include/uapi/sound/asoc.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,388 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * uapi/sound/asoc.h -- ALSA SoC Firmware Controls and DAPM
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2012 Texas Instruments Inc.
 | 
				
			||||||
 | 
					 * Copyright (C) 2015 Intel Corporation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU General Public License version 2 as
 | 
				
			||||||
 | 
					 * published by the Free Software Foundation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
 | 
				
			||||||
 | 
					 * algorithms, equalisers, DAIs, widgets etc.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __LINUX_UAPI_SND_ASOC_H
 | 
				
			||||||
 | 
					#define __LINUX_UAPI_SND_ASOC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/types.h>
 | 
				
			||||||
 | 
					#include <sound/asound.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Maximum number of channels topology kcontrol can represent.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_MAX_CHAN		8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Maximum number of PCM formats capability
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_MAX_FORMATS	16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Maximum number of PCM stream configs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_STREAM_CONFIG_MAX  8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* individual kcontrol info types - can be mixed with other types */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_VOLSW		1
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_VOLSW_SX	2
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_VOLSW_XR_SX	3
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_ENUM		4
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_BYTES		5
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_ENUM_VALUE	6
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_RANGE		7
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_CTL_STROBE		8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* individual widget kcontrol info types - can be mixed with other types */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_CTL_VOLSW		64
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE	65
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT		66
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE	67
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_CTL_PIN		68
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DAPM widget types - add new items to the end */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_INPUT		0
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_OUTPUT	1
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_MUX		2
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_MIXER		3
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_PGA		4
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_OUT_DRV	5
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_ADC		6
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_DAC		7
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_SWITCH	8
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_PRE		9
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_POST		10
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_AIF_IN	11
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_AIF_OUT	12
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_DAI_IN	13
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_DAI_OUT	14
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_DAI_LINK	15
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_DAPM_LAST		SND_SOC_TPLG_DAPM_DAI_LINK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Header magic number and string sizes */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_MAGIC		0x41536F43 /* ASoC */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* string sizes */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_NUM_TEXTS		16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ABI version */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_ABI_VERSION	0x2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Max size of TLV data */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TLV_SIZE		32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * File and Block header data types.
 | 
				
			||||||
 | 
					 * Add new generic and vendor types to end of list.
 | 
				
			||||||
 | 
					 * Generic types are handled by the core whilst vendors types are passed
 | 
				
			||||||
 | 
					 * to the component drivers for handling.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_MIXER		1
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_BYTES		2
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_ENUM		3
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_DAPM_GRAPH	4
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_DAPM_WIDGET	5
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_DAI_LINK	6
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_PCM		7
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_MANIFEST	8
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_CODEC_LINK	9
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_MAX	SND_SOC_TPLG_TYPE_CODEC_LINK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* vendor block IDs - please add new vendor types to end */
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_VENDOR_FW	1000
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_VENDOR_CONFIG	1001
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPE_VENDOR_COEFF	1002
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_TYPEVENDOR_CODEC	1003
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_STREAM_PLAYBACK	0
 | 
				
			||||||
 | 
					#define SND_SOC_TPLG_STREAM_CAPTURE	1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Block Header.
 | 
				
			||||||
 | 
					 * This header preceeds all object and object arrays below.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_hdr {
 | 
				
			||||||
 | 
						__le32 magic;		/* magic number */
 | 
				
			||||||
 | 
						__le32 abi;		/* ABI version */
 | 
				
			||||||
 | 
						__le32 version;		/* optional vendor specific version details */
 | 
				
			||||||
 | 
						__le32 type;		/* SND_SOC_TPLG_TYPE_ */
 | 
				
			||||||
 | 
						__le32 size;		/* size of this structure */
 | 
				
			||||||
 | 
						__le32 vendor_type;	/* optional vendor specific type info */
 | 
				
			||||||
 | 
						__le32 payload_size;	/* data bytes, excluding this header */
 | 
				
			||||||
 | 
						__le32 index;		/* identifier for block */
 | 
				
			||||||
 | 
						__le32 count;		/* number of elements in block */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Private data.
 | 
				
			||||||
 | 
					 * All topology objects may have private data that can be used by the driver or
 | 
				
			||||||
 | 
					 * firmware. Core will ignore this data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_private {
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of private data */
 | 
				
			||||||
 | 
						char data[0];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kcontrol TLV data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_ctl_tlv {
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes aligned to 4 */
 | 
				
			||||||
 | 
						__le32 numid;	/* control element numeric identification */
 | 
				
			||||||
 | 
						__le32 count;	/* number of elem in data array */
 | 
				
			||||||
 | 
						__le32 data[SND_SOC_TPLG_TLV_SIZE];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kcontrol channel data
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_channel {
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 reg;
 | 
				
			||||||
 | 
						__le32 shift;
 | 
				
			||||||
 | 
						__le32 id;	/* ID maps to Left, Right, LFE etc */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kcontrol Operations IDs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_kcontrol_ops_id {
 | 
				
			||||||
 | 
						__le32 get;
 | 
				
			||||||
 | 
						__le32 put;
 | 
				
			||||||
 | 
						__le32 info;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * kcontrol header
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_ctl_hdr {
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 type;
 | 
				
			||||||
 | 
						char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						__le32 access;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_kcontrol_ops_id ops;
 | 
				
			||||||
 | 
						__le32 tlv_size;	/* non zero means control has TLV data */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Stream Capabilities
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_stream_caps {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						__le64 formats[SND_SOC_TPLG_MAX_FORMATS];	/* supported formats SNDRV_PCM_FMTBIT_* */
 | 
				
			||||||
 | 
						__le32 rates;		/* supported rates SNDRV_PCM_RATE_* */
 | 
				
			||||||
 | 
						__le32 rate_min;	/* min rate */
 | 
				
			||||||
 | 
						__le32 rate_max;	/* max rate */
 | 
				
			||||||
 | 
						__le32 channels_min;	/* min channels */
 | 
				
			||||||
 | 
						__le32 channels_max;	/* max channels */
 | 
				
			||||||
 | 
						__le32 periods_min;	/* min number of periods */
 | 
				
			||||||
 | 
						__le32 periods_max;	/* max number of periods */
 | 
				
			||||||
 | 
						__le32 period_size_min;	/* min period size bytes */
 | 
				
			||||||
 | 
						__le32 period_size_max;	/* max period size bytes */
 | 
				
			||||||
 | 
						__le32 buffer_size_min;	/* min buffer size bytes */
 | 
				
			||||||
 | 
						__le32 buffer_size_max;	/* max buffer size bytes */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * FE or BE Stream configuration supported by SW/FW
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_stream {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le64 format;		/* SNDRV_PCM_FMTBIT_* */
 | 
				
			||||||
 | 
						__le32 rate;		/* SNDRV_PCM_RATE_* */
 | 
				
			||||||
 | 
						__le32 period_bytes;	/* size of period in bytes */
 | 
				
			||||||
 | 
						__le32 buffer_bytes;	/* size of buffer in bytes */
 | 
				
			||||||
 | 
						__le32 channels;	/* channels */
 | 
				
			||||||
 | 
						__le32 tdm_slot;	/* optional BE bitmask of supported TDM slots */
 | 
				
			||||||
 | 
						__le32 dai_fmt;		/* SND_SOC_DAIFMT_  */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Duplex stream configuration supported by SW/FW.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_stream_config {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						struct snd_soc_tplg_stream playback;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_stream capture;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Manifest. List totals for each payload type. Not used in parsing, but will
 | 
				
			||||||
 | 
					 * be passed to the component driver before any other objects in order for any
 | 
				
			||||||
 | 
					 * global componnent resource allocations.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for manifest :-
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr           |  1 |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_manifest      |  1 |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_manifest {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 control_elems;	/* number of control elements */
 | 
				
			||||||
 | 
						__le32 widget_elems;	/* number of widget elements */
 | 
				
			||||||
 | 
						__le32 graph_elems;	/* number of graph elements */
 | 
				
			||||||
 | 
						__le32 dai_elems;	/* number of DAI elements */
 | 
				
			||||||
 | 
						__le32 dai_link_elems;	/* number of DAI link elements */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Mixer kcontrol.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for mixer kcontrol :-
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr           |  1 |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_mixer_control |  N |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_mixer_control {
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ctl_hdr hdr;
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 min;
 | 
				
			||||||
 | 
						__le32 max;
 | 
				
			||||||
 | 
						__le32 platform_max;
 | 
				
			||||||
 | 
						__le32 invert;
 | 
				
			||||||
 | 
						__le32 num_channels;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ctl_tlv tlv;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_private priv;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enumerated kcontrol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for enum kcontrol :-
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr           |  1 |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_enum_control  |  N |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_enum_control {
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ctl_hdr hdr;
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 num_channels;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
 | 
				
			||||||
 | 
						__le32 items;
 | 
				
			||||||
 | 
						__le32 mask;
 | 
				
			||||||
 | 
						__le32 count;
 | 
				
			||||||
 | 
						char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						__le32 values[SND_SOC_TPLG_NUM_TEXTS * SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
 | 
				
			||||||
 | 
						struct snd_soc_tplg_private priv;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Bytes kcontrol
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for bytes kcontrol :-
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr           |  1 |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_bytes_control |  N |
 | 
				
			||||||
 | 
					 * +-----------------------------------+----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_bytes_control {
 | 
				
			||||||
 | 
						struct snd_soc_tplg_ctl_hdr hdr;
 | 
				
			||||||
 | 
						__le32 size;	/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 max;
 | 
				
			||||||
 | 
						__le32 mask;
 | 
				
			||||||
 | 
						__le32 base;
 | 
				
			||||||
 | 
						__le32 num_regs;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_private priv;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * DAPM Graph Element
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for DAPM graph elements :-
 | 
				
			||||||
 | 
					 * +-------------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr             |  1 |
 | 
				
			||||||
 | 
					 * +-------------------------------------+----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_dapm_graph_elem |  N |
 | 
				
			||||||
 | 
					 * +-------------------------------------+----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_dapm_graph_elem {
 | 
				
			||||||
 | 
						char sink[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						char control[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						char source[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * DAPM Widget.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for DAPM widget :-
 | 
				
			||||||
 | 
					 * +-------------------------------------+-----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr             |  1  |
 | 
				
			||||||
 | 
					 * +-------------------------------------+-----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_dapm_widget     |  N  |
 | 
				
			||||||
 | 
					 * +-------------------------------------+-----+
 | 
				
			||||||
 | 
					 * |   struct snd_soc_tplg_enum_control  | 0|1 |
 | 
				
			||||||
 | 
					 * |   struct snd_soc_tplg_mixer_control | 0|N |
 | 
				
			||||||
 | 
					 * +-------------------------------------+-----+
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Optional enum or mixer control can be appended to the end of each widget
 | 
				
			||||||
 | 
					 * in the block.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_dapm_widget {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						__le32 id;		/* SND_SOC_DAPM_CTL */
 | 
				
			||||||
 | 
						char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						char sname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__le32 reg;		/* negative reg = no direct dapm */
 | 
				
			||||||
 | 
						__le32 shift;		/* bits to shift */
 | 
				
			||||||
 | 
						__le32 mask;		/* non-shifted mask */
 | 
				
			||||||
 | 
						__u32 invert;		/* invert the power bit */
 | 
				
			||||||
 | 
						__u32 ignore_suspend;	/* kept enabled over suspend */
 | 
				
			||||||
 | 
						__u16 event_flags;
 | 
				
			||||||
 | 
						__u16 event_type;
 | 
				
			||||||
 | 
						__u16 num_kcontrols;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_private priv;
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * kcontrols that relate to this widget
 | 
				
			||||||
 | 
						 * follow here after widget private data
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct snd_soc_tplg_pcm_cfg_caps {
 | 
				
			||||||
 | 
						struct snd_soc_tplg_stream_caps caps;
 | 
				
			||||||
 | 
						struct snd_soc_tplg_stream_config configs[SND_SOC_TPLG_STREAM_CONFIG_MAX];
 | 
				
			||||||
 | 
						__le32 num_configs;	/* number of configs */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Describes SW/FW specific features of PCM or DAI link.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * File block representation for PCM/DAI-Link :-
 | 
				
			||||||
 | 
					 * +-----------------------------------+-----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_hdr           |  1  |
 | 
				
			||||||
 | 
					 * +-----------------------------------+-----+
 | 
				
			||||||
 | 
					 * | struct snd_soc_tplg_dapm_pcm_dai  |  N  |
 | 
				
			||||||
 | 
					 * +-----------------------------------+-----+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct snd_soc_tplg_pcm_dai {
 | 
				
			||||||
 | 
						__le32 size;		/* in bytes of this structure */
 | 
				
			||||||
 | 
						char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 | 
				
			||||||
 | 
						__le32 id;			/* unique ID - used to match */
 | 
				
			||||||
 | 
						__le32 playback;		/* supports playback mode */
 | 
				
			||||||
 | 
						__le32 capture;			/* supports capture mode */
 | 
				
			||||||
 | 
						__le32 compress;		/* 1 = compressed; 0 = PCM */
 | 
				
			||||||
 | 
						struct snd_soc_tplg_pcm_cfg_caps capconf[2];	/* capabilities and configs */
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										31
									
								
								include/uapi/sound/tlv.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								include/uapi/sound/tlv.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *   This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 *   it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 *   the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 *   (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 *   GNU General Public License for more details.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __UAPI_SOUND_TLV_H
 | 
				
			||||||
 | 
					#define __UAPI_SOUND_TLV_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_CONTAINER 0	/* one level down - group of TLVs */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_DB_SCALE	1       /* dB scale */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_DB_LINEAR 2	/* linear volume */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_DB_RANGE 3	/* dB range container */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_DB_MINMAX 4	/* dB scale with min/max */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5	/* dB scale with min/max with mute */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * channel-mapping TLV items
 | 
				
			||||||
 | 
					 *  TLV length must match with num_channels
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_CHMAP_FIXED	0x101	/* fixed channel position */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_CHMAP_VAR	0x102	/* channels freely swappable */
 | 
				
			||||||
 | 
					#define SNDRV_CTL_TLVT_CHMAP_PAIRED	0x103	/* pair-wise swappable */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,7 @@ source "sound/soc/tegra/Kconfig"
 | 
				
			||||||
source "sound/soc/txx9/Kconfig"
 | 
					source "sound/soc/txx9/Kconfig"
 | 
				
			||||||
source "sound/soc/ux500/Kconfig"
 | 
					source "sound/soc/ux500/Kconfig"
 | 
				
			||||||
source "sound/soc/xtensa/Kconfig"
 | 
					source "sound/soc/xtensa/Kconfig"
 | 
				
			||||||
 | 
					source "sound/soc/zte/Kconfig"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Supported codecs
 | 
					# Supported codecs
 | 
				
			||||||
source "sound/soc/codecs/Kconfig"
 | 
					source "sound/soc/codecs/Kconfig"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
 | 
					snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
 | 
				
			||||||
snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o
 | 
					snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o
 | 
				
			||||||
 | 
					snd-soc-core-objs += soc-topology.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
 | 
					ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
 | 
				
			||||||
snd-soc-core-objs += soc-generic-dmaengine-pcm.o
 | 
					snd-soc-core-objs += soc-generic-dmaengine-pcm.o
 | 
				
			||||||
| 
						 | 
					@ -38,3 +39,4 @@ obj-$(CONFIG_SND_SOC)	+= tegra/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= txx9/
 | 
					obj-$(CONFIG_SND_SOC)	+= txx9/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= ux500/
 | 
					obj-$(CONFIG_SND_SOC)	+= ux500/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= xtensa/
 | 
					obj-$(CONFIG_SND_SOC)	+= xtensa/
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC)	+= zte/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,27 +6,22 @@ config SND_ATMEL_SOC
 | 
				
			||||||
	  the ATMEL SSC interface. You will also need
 | 
						  the ATMEL SSC interface. You will also need
 | 
				
			||||||
	  to select the audio interfaces to support below.
 | 
						  to select the audio interfaces to support below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if SND_ATMEL_SOC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_ATMEL_SOC_PDC
 | 
					config SND_ATMEL_SOC_PDC
 | 
				
			||||||
	tristate
 | 
						bool
 | 
				
			||||||
	depends on SND_ATMEL_SOC
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_ATMEL_SOC_DMA
 | 
					config SND_ATMEL_SOC_DMA
 | 
				
			||||||
	tristate
 | 
						bool
 | 
				
			||||||
	depends on SND_ATMEL_SOC
 | 
					 | 
				
			||||||
	select SND_SOC_GENERIC_DMAENGINE_PCM
 | 
						select SND_SOC_GENERIC_DMAENGINE_PCM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_ATMEL_SOC_SSC
 | 
					config SND_ATMEL_SOC_SSC
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
	depends on SND_ATMEL_SOC
 | 
					 | 
				
			||||||
	help
 | 
					 | 
				
			||||||
	  Say Y or M if you want to add support for codecs the
 | 
					 | 
				
			||||||
	  ATMEL SSC interface. You will also needs to select the individual
 | 
					 | 
				
			||||||
	  machine drivers to support below.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_AT91_SOC_SAM9G20_WM8731
 | 
					config SND_AT91_SOC_SAM9G20_WM8731
 | 
				
			||||||
	tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
 | 
						tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
 | 
				
			||||||
	depends on ARCH_AT91 || COMPILE_TEST
 | 
						depends on ARCH_AT91 || COMPILE_TEST
 | 
				
			||||||
	depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
 | 
						depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
 | 
				
			||||||
	select SND_ATMEL_SOC_PDC
 | 
						select SND_ATMEL_SOC_PDC
 | 
				
			||||||
	select SND_ATMEL_SOC_SSC
 | 
						select SND_ATMEL_SOC_SSC
 | 
				
			||||||
	select SND_SOC_WM8731
 | 
						select SND_SOC_WM8731
 | 
				
			||||||
| 
						 | 
					@ -37,7 +32,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
 | 
				
			||||||
config SND_ATMEL_SOC_WM8904
 | 
					config SND_ATMEL_SOC_WM8904
 | 
				
			||||||
	tristate "Atmel ASoC driver for boards using WM8904 codec"
 | 
						tristate "Atmel ASoC driver for boards using WM8904 codec"
 | 
				
			||||||
	depends on ARCH_AT91 || COMPILE_TEST
 | 
						depends on ARCH_AT91 || COMPILE_TEST
 | 
				
			||||||
	depends on ATMEL_SSC && SND_ATMEL_SOC && I2C
 | 
						depends on ATMEL_SSC && I2C
 | 
				
			||||||
	select SND_ATMEL_SOC_SSC
 | 
						select SND_ATMEL_SOC_SSC
 | 
				
			||||||
	select SND_ATMEL_SOC_DMA
 | 
						select SND_ATMEL_SOC_DMA
 | 
				
			||||||
	select SND_SOC_WM8904
 | 
						select SND_SOC_WM8904
 | 
				
			||||||
| 
						 | 
					@ -48,10 +43,11 @@ config SND_ATMEL_SOC_WM8904
 | 
				
			||||||
config SND_AT91_SOC_SAM9X5_WM8731
 | 
					config SND_AT91_SOC_SAM9X5_WM8731
 | 
				
			||||||
	tristate "SoC Audio support for WM8731-based at91sam9x5 board"
 | 
						tristate "SoC Audio support for WM8731-based at91sam9x5 board"
 | 
				
			||||||
	depends on ARCH_AT91 || COMPILE_TEST
 | 
						depends on ARCH_AT91 || COMPILE_TEST
 | 
				
			||||||
	depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
 | 
						depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
 | 
				
			||||||
	select SND_ATMEL_SOC_SSC
 | 
						select SND_ATMEL_SOC_SSC
 | 
				
			||||||
	select SND_ATMEL_SOC_DMA
 | 
						select SND_ATMEL_SOC_DMA
 | 
				
			||||||
	select SND_SOC_WM8731
 | 
						select SND_SOC_WM8731
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Say Y if you want to add support for audio SoC on an
 | 
						  Say Y if you want to add support for audio SoC on an
 | 
				
			||||||
	  at91sam9x5 based board that is using WM8731 codec.
 | 
						  at91sam9x5 based board that is using WM8731 codec.
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,8 @@
 | 
				
			||||||
# AT91 Platform Support
 | 
					# AT91 Platform Support
 | 
				
			||||||
snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
 | 
					snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_PDC) := atmel-pcm-pdc.o
 | 
				
			||||||
snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
 | 
					snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_DMA) += atmel-pcm-dma.o
 | 
				
			||||||
snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
 | 
					snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o $(snd-soc-atmel-pcm-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
 | 
					obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# AT91 Machine Support
 | 
					# AT91 Machine Support
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,8 +124,7 @@ static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int atmel_pcm_dma_platform_register(struct device *dev)
 | 
					int atmel_pcm_dma_platform_register(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config,
 | 
						return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, 0);
 | 
				
			||||||
			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
 | 
					EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,8 +95,9 @@ static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dapm_route intercon[] = {
 | 
					static const struct snd_soc_dapm_route intercon[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* speaker connected to LHPOUT */
 | 
						/* speaker connected to LHPOUT/RHPOUT */
 | 
				
			||||||
	{"Ext Spk", NULL, "LHPOUT"},
 | 
						{"Ext Spk", NULL, "LHPOUT"},
 | 
				
			||||||
 | 
						{"Ext Spk", NULL, "RHPOUT"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* mic is connected to Mic Jack, with WM8731 Mic Bias */
 | 
						/* mic is connected to Mic Jack, with WM8731 Mic Bias */
 | 
				
			||||||
	{"MICIN", NULL, "Mic Bias"},
 | 
						{"MICIN", NULL, "Mic Bias"},
 | 
				
			||||||
| 
						 | 
					@ -108,9 +109,7 @@ static const struct snd_soc_dapm_route intercon[] = {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 | 
					static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = rtd->codec;
 | 
					 | 
				
			||||||
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 | 
						struct snd_soc_dai *codec_dai = rtd->codec_dai;
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
					 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printk(KERN_DEBUG
 | 
						printk(KERN_DEBUG
 | 
				
			||||||
| 
						 | 
					@ -124,10 +123,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* not connected */
 | 
					 | 
				
			||||||
	snd_soc_dapm_nc_pin(dapm, "RLINEIN");
 | 
					 | 
				
			||||||
	snd_soc_dapm_nc_pin(dapm, "LLINEIN");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef ENABLE_MIC_INPUT
 | 
					#ifndef ENABLE_MIC_INPUT
 | 
				
			||||||
	snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
 | 
						snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -158,6 +153,7 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
 | 
				
			||||||
	.num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
 | 
						.num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
 | 
				
			||||||
	.dapm_routes = intercon,
 | 
						.dapm_routes = intercon,
 | 
				
			||||||
	.num_dapm_routes = ARRAY_SIZE(intercon),
 | 
						.num_dapm_routes = ARRAY_SIZE(intercon),
 | 
				
			||||||
 | 
						.fully_routed = true,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
 | 
					static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@
 | 
				
			||||||
#include "../codecs/wm8731.h"
 | 
					#include "../codecs/wm8731.h"
 | 
				
			||||||
#include "psc.h"
 | 
					#include "psc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_device_id db1200_pids[] = {
 | 
					static const struct platform_device_id db1200_pids[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name		= "db1200-ac97",
 | 
							.name		= "db1200-ac97",
 | 
				
			||||||
		.driver_data	= 0,
 | 
							.driver_data	= 0,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,7 +60,6 @@ int devm_ep93xx_pcm_platform_register(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return devm_snd_dmaengine_pcm_register(dev,
 | 
						return devm_snd_dmaengine_pcm_register(dev,
 | 
				
			||||||
		&ep93xx_dmaengine_pcm_config,
 | 
							&ep93xx_dmaengine_pcm_config,
 | 
				
			||||||
		SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
 | 
					 | 
				
			||||||
		SND_DMAENGINE_PCM_FLAG_NO_DT |
 | 
							SND_DMAENGINE_PCM_FLAG_NO_DT |
 | 
				
			||||||
		SND_DMAENGINE_PCM_FLAG_COMPAT);
 | 
							SND_DMAENGINE_PCM_FLAG_COMPAT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1140,7 +1140,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			/* Enable Audio PLL & Audio section */
 | 
								/* Enable Audio PLL & Audio section */
 | 
				
			||||||
			data = AUDIO_PLL | AUDIO_SECTION_ON;
 | 
								data = AUDIO_PLL | AUDIO_SECTION_ON;
 | 
				
			||||||
			pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
 | 
								pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
 | 
				
			||||||
| 
						 | 
					@ -1156,7 +1156,6 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0);
 | 
							pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_88PM860X if MFD_88PM860X
 | 
						select SND_SOC_88PM860X if MFD_88PM860X
 | 
				
			||||||
	select SND_SOC_L3
 | 
						select SND_SOC_L3
 | 
				
			||||||
	select SND_SOC_AB8500_CODEC if ABX500_CORE
 | 
						select SND_SOC_AB8500_CODEC if ABX500_CORE
 | 
				
			||||||
	select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
 | 
						select SND_SOC_AC97_CODEC
 | 
				
			||||||
	select SND_SOC_AD1836 if SPI_MASTER
 | 
						select SND_SOC_AD1836 if SPI_MASTER
 | 
				
			||||||
	select SND_SOC_AD193X_SPI if SPI_MASTER
 | 
						select SND_SOC_AD193X_SPI if SPI_MASTER
 | 
				
			||||||
	select SND_SOC_AD193X_I2C if I2C
 | 
						select SND_SOC_AD193X_I2C if I2C
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_CS4271_SPI if SPI_MASTER
 | 
						select SND_SOC_CS4271_SPI if SPI_MASTER
 | 
				
			||||||
	select SND_SOC_CS42XX8_I2C if I2C
 | 
						select SND_SOC_CS42XX8_I2C if I2C
 | 
				
			||||||
	select SND_SOC_CX20442 if TTY
 | 
						select SND_SOC_CX20442 if TTY
 | 
				
			||||||
	select SND_SOC_DA7210 if I2C
 | 
						select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
 | 
				
			||||||
	select SND_SOC_DA7213 if I2C
 | 
						select SND_SOC_DA7213 if I2C
 | 
				
			||||||
	select SND_SOC_DA732X if I2C
 | 
						select SND_SOC_DA732X if I2C
 | 
				
			||||||
	select SND_SOC_DA9055 if I2C
 | 
						select SND_SOC_DA9055 if I2C
 | 
				
			||||||
| 
						 | 
					@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
 | 
						select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
 | 
				
			||||||
	select SND_SOC_TAS2552 if I2C
 | 
						select SND_SOC_TAS2552 if I2C
 | 
				
			||||||
	select SND_SOC_TAS5086 if I2C
 | 
						select SND_SOC_TAS5086 if I2C
 | 
				
			||||||
 | 
						select SND_SOC_TAS571X if I2C
 | 
				
			||||||
	select SND_SOC_TFA9879 if I2C
 | 
						select SND_SOC_TFA9879 if I2C
 | 
				
			||||||
	select SND_SOC_TLV320AIC23_I2C if I2C
 | 
						select SND_SOC_TLV320AIC23_I2C if I2C
 | 
				
			||||||
	select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
 | 
						select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
 | 
				
			||||||
| 
						 | 
					@ -211,8 +212,9 @@ config SND_SOC_AB8500_CODEC
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_AC97_CODEC
 | 
					config SND_SOC_AC97_CODEC
 | 
				
			||||||
	tristate
 | 
						tristate "Build generic ASoC AC97 CODEC driver"
 | 
				
			||||||
	select SND_AC97_CODEC
 | 
						select SND_AC97_CODEC
 | 
				
			||||||
 | 
						select SND_SOC_AC97_BUS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_AD1836
 | 
					config SND_SOC_AD1836
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
| 
						 | 
					@ -611,6 +613,10 @@ config SND_SOC_TAS5086
 | 
				
			||||||
	tristate "Texas Instruments TAS5086 speaker amplifier"
 | 
						tristate "Texas Instruments TAS5086 speaker amplifier"
 | 
				
			||||||
	depends on I2C
 | 
						depends on I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SND_SOC_TAS571X
 | 
				
			||||||
 | 
						tristate "Texas Instruments TAS5711/TAS5717/TAS5719 power amplifiers"
 | 
				
			||||||
 | 
						depends on I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_TFA9879
 | 
					config SND_SOC_TFA9879
 | 
				
			||||||
	tristate "NXP Semiconductors TFA9879 amplifier"
 | 
						tristate "NXP Semiconductors TFA9879 amplifier"
 | 
				
			||||||
	depends on I2C
 | 
						depends on I2C
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,6 +106,7 @@ snd-soc-sta350-objs := sta350.o
 | 
				
			||||||
snd-soc-sta529-objs := sta529.o
 | 
					snd-soc-sta529-objs := sta529.o
 | 
				
			||||||
snd-soc-stac9766-objs := stac9766.o
 | 
					snd-soc-stac9766-objs := stac9766.o
 | 
				
			||||||
snd-soc-tas5086-objs := tas5086.o
 | 
					snd-soc-tas5086-objs := tas5086.o
 | 
				
			||||||
 | 
					snd-soc-tas571x-objs := tas571x.o
 | 
				
			||||||
snd-soc-tfa9879-objs := tfa9879.o
 | 
					snd-soc-tfa9879-objs := tfa9879.o
 | 
				
			||||||
snd-soc-tlv320aic23-objs := tlv320aic23.o
 | 
					snd-soc-tlv320aic23-objs := tlv320aic23.o
 | 
				
			||||||
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
 | 
					snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
 | 
				
			||||||
| 
						 | 
					@ -288,6 +289,7 @@ obj-$(CONFIG_SND_SOC_STA529)   += snd-soc-sta529.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_STAC9766)	+= snd-soc-stac9766.o
 | 
					obj-$(CONFIG_SND_SOC_STAC9766)	+= snd-soc-stac9766.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_TAS2552)	+= snd-soc-tas2552.o
 | 
					obj-$(CONFIG_SND_SOC_TAS2552)	+= snd-soc-tas2552.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.o
 | 
					obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC_TAS571X)	+= snd-soc-tas571x.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_TFA9879)	+= snd-soc-tfa9879.o
 | 
					obj-$(CONFIG_SND_SOC_TFA9879)	+= snd-soc-tfa9879.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
 | 
					obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)	+= snd-soc-tlv320aic23-i2c.o
 | 
					obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C)	+= snd-soc-tlv320aic23-i2c.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1209,6 +1209,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
				struct snd_ctl_elem_value *ucontrol)
 | 
									struct snd_ctl_elem_value *ucontrol)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
						struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
 | 
						struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
 | 
				
			||||||
	struct device *dev = codec->dev;
 | 
						struct device *dev = codec->dev;
 | 
				
			||||||
	bool apply_fir, apply_iir;
 | 
						bool apply_fir, apply_iir;
 | 
				
			||||||
| 
						 | 
					@ -1234,15 +1235,14 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
 | 
						apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
 | 
				
			||||||
	apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
 | 
						apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = snd_soc_dapm_force_enable_pin(&codec->dapm,
 | 
						status = snd_soc_dapm_force_enable_pin(dapm, "ANC Configure Input");
 | 
				
			||||||
					"ANC Configure Input");
 | 
					 | 
				
			||||||
	if (status < 0) {
 | 
						if (status < 0) {
 | 
				
			||||||
		dev_err(dev,
 | 
							dev_err(dev,
 | 
				
			||||||
			"%s: ERROR: Failed to enable power (status = %d)!\n",
 | 
								"%s: ERROR: Failed to enable power (status = %d)!\n",
 | 
				
			||||||
			__func__, status);
 | 
								__func__, status);
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	snd_soc_dapm_sync(&codec->dapm);
 | 
						snd_soc_dapm_sync(dapm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	anc_configure(codec, apply_fir, apply_iir);
 | 
						anc_configure(codec, apply_fir, apply_iir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1259,8 +1259,8 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
			drvdata->anc_status =  ANC_IIR_CONFIGURED;
 | 
								drvdata->anc_status =  ANC_IIR_CONFIGURED;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
 | 
						status = snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
 | 
				
			||||||
	snd_soc_dapm_sync(&codec->dapm);
 | 
						snd_soc_dapm_sync(dapm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cleanup:
 | 
					cleanup:
 | 
				
			||||||
	mutex_unlock(&drvdata->ctrl_lock);
 | 
						mutex_unlock(&drvdata->ctrl_lock);
 | 
				
			||||||
| 
						 | 
					@ -1947,6 +1947,7 @@ static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
 | 
				
			||||||
static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
 | 
					static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
 | 
				
			||||||
			struct amic_settings *amics)
 | 
								struct amic_settings *amics)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	u8 value8;
 | 
						u8 value8;
 | 
				
			||||||
	unsigned int value;
 | 
						unsigned int value;
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
| 
						 | 
					@ -1973,15 +1974,15 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
 | 
				
			||||||
	dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
 | 
						dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
 | 
				
			||||||
		amic_micbias_str(amics->mic1a_micbias));
 | 
							amic_micbias_str(amics->mic1a_micbias));
 | 
				
			||||||
	route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
 | 
						route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
 | 
				
			||||||
	status = snd_soc_dapm_add_routes(&codec->dapm, route, 1);
 | 
						status = snd_soc_dapm_add_routes(dapm, route, 1);
 | 
				
			||||||
	dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
 | 
						dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
 | 
				
			||||||
		amic_micbias_str(amics->mic1b_micbias));
 | 
							amic_micbias_str(amics->mic1b_micbias));
 | 
				
			||||||
	route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
 | 
						route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
 | 
				
			||||||
	status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
 | 
						status |= snd_soc_dapm_add_routes(dapm, route, 1);
 | 
				
			||||||
	dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
 | 
						dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
 | 
				
			||||||
		amic_micbias_str(amics->mic2_micbias));
 | 
							amic_micbias_str(amics->mic2_micbias));
 | 
				
			||||||
	route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
 | 
						route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
 | 
				
			||||||
	status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
 | 
						status |= snd_soc_dapm_add_routes(dapm, route, 1);
 | 
				
			||||||
	if (status < 0) {
 | 
						if (status < 0) {
 | 
				
			||||||
		dev_err(codec->dev,
 | 
							dev_err(codec->dev,
 | 
				
			||||||
			"%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
 | 
								"%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
 | 
				
			||||||
| 
						 | 
					@ -2461,6 +2462,7 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ab8500_codec_probe(struct snd_soc_codec *codec)
 | 
					static int ab8500_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct device *dev = codec->dev;
 | 
						struct device *dev = codec->dev;
 | 
				
			||||||
	struct device_node *np = dev->of_node;
 | 
						struct device_node *np = dev->of_node;
 | 
				
			||||||
	struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
 | 
						struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
 | 
				
			||||||
| 
						 | 
					@ -2541,7 +2543,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		&ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
 | 
							&ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
 | 
				
			||||||
	drvdata->sid_fir_values = (long *)fc->value;
 | 
						drvdata->sid_fir_values = (long *)fc->value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	(void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
 | 
						snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_init(&drvdata->ctrl_lock);
 | 
						mutex_init(&drvdata->ctrl_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,10 +44,6 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
 | 
				
			||||||
	return snd_ac97_set_rate(ac97, reg, substream->runtime->rate);
 | 
						return snd_ac97_set_rate(ac97, reg, substream->runtime->rate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 | 
					 | 
				
			||||||
		SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
 | 
					 | 
				
			||||||
		SNDRV_PCM_RATE_48000)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct snd_soc_dai_ops ac97_dai_ops = {
 | 
					static const struct snd_soc_dai_ops ac97_dai_ops = {
 | 
				
			||||||
	.prepare	= ac97_prepare,
 | 
						.prepare	= ac97_prepare,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -58,13 +54,13 @@ static struct snd_soc_dai_driver ac97_dai = {
 | 
				
			||||||
		.stream_name = "AC97 Playback",
 | 
							.stream_name = "AC97 Playback",
 | 
				
			||||||
		.channels_min = 1,
 | 
							.channels_min = 1,
 | 
				
			||||||
		.channels_max = 2,
 | 
							.channels_max = 2,
 | 
				
			||||||
		.rates = STD_AC97_RATES,
 | 
							.rates = SNDRV_PCM_RATE_KNOT,
 | 
				
			||||||
		.formats = SND_SOC_STD_AC97_FMTS,},
 | 
							.formats = SND_SOC_STD_AC97_FMTS,},
 | 
				
			||||||
	.capture = {
 | 
						.capture = {
 | 
				
			||||||
		.stream_name = "AC97 Capture",
 | 
							.stream_name = "AC97 Capture",
 | 
				
			||||||
		.channels_min = 1,
 | 
							.channels_min = 1,
 | 
				
			||||||
		.channels_max = 2,
 | 
							.channels_max = 2,
 | 
				
			||||||
		.rates = STD_AC97_RATES,
 | 
							.rates = SNDRV_PCM_RATE_KNOT,
 | 
				
			||||||
		.formats = SND_SOC_STD_AC97_FMTS,},
 | 
							.formats = SND_SOC_STD_AC97_FMTS,},
 | 
				
			||||||
	.ops = &ac97_dai_ops,
 | 
						.ops = &ac97_dai_ops,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,7 +251,7 @@ static int ad1836_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
static int ad1836_probe(struct snd_soc_codec *codec)
 | 
					static int ad1836_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 | 
						struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	int num_dacs, num_adcs;
 | 
						int num_dacs, num_adcs;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1444,7 +1444,6 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
			ADAU1373_PWDN_CTRL3_PWR_EN, 0);
 | 
								ADAU1373_PWDN_CTRL3_PWR_EN, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
#include <linux/of.h>
 | 
					#include <linux/of.h>
 | 
				
			||||||
#include <linux/of_gpio.h>
 | 
					#include <linux/of_gpio.h>
 | 
				
			||||||
#include <linux/of_device.h>
 | 
					#include <linux/of_device.h>
 | 
				
			||||||
 | 
					#include <linux/regulator/consumer.h>
 | 
				
			||||||
#include <linux/regmap.h>
 | 
					#include <linux/regmap.h>
 | 
				
			||||||
#include <sound/core.h>
 | 
					#include <sound/core.h>
 | 
				
			||||||
#include <sound/pcm.h>
 | 
					#include <sound/pcm.h>
 | 
				
			||||||
| 
						 | 
					@ -101,6 +102,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ADAU1701_FIRMWARE "adau1701.bin"
 | 
					#define ADAU1701_FIRMWARE "adau1701.bin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const supply_names[] = {
 | 
				
			||||||
 | 
						"dvdd", "avdd"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct adau1701 {
 | 
					struct adau1701 {
 | 
				
			||||||
	int gpio_nreset;
 | 
						int gpio_nreset;
 | 
				
			||||||
	int gpio_pll_mode[2];
 | 
						int gpio_pll_mode[2];
 | 
				
			||||||
| 
						 | 
					@ -112,6 +117,7 @@ struct adau1701 {
 | 
				
			||||||
	u8 pin_config[12];
 | 
						u8 pin_config[12];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct sigmadsp *sigmadsp;
 | 
						struct sigmadsp *sigmadsp;
 | 
				
			||||||
 | 
						struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new adau1701_controls[] = {
 | 
					static const struct snd_kcontrol_new adau1701_controls[] = {
 | 
				
			||||||
| 
						 | 
					@ -565,7 +571,6 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -669,6 +674,13 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
 | 
				
			||||||
 | 
									    adau1701->supplies);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Let the pll_clkdiv variable default to something that won't happen
 | 
						 * Let the pll_clkdiv variable default to something that won't happen
 | 
				
			||||||
	 * at runtime. That way, we can postpone the firmware download from
 | 
						 * at runtime. That way, we can postpone the firmware download from
 | 
				
			||||||
| 
						 | 
					@ -680,7 +692,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	/* initalize with pre-configured pll mode settings */
 | 
						/* initalize with pre-configured pll mode settings */
 | 
				
			||||||
	ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
 | 
						ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return ret;
 | 
							goto exit_regulators_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set up pin config */
 | 
						/* set up pin config */
 | 
				
			||||||
	val = 0;
 | 
						val = 0;
 | 
				
			||||||
| 
						 | 
					@ -696,10 +708,60 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
 | 
						regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit_regulators_disable:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int adau1701_remove(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gpio_is_valid(adau1701->gpio_nreset))
 | 
				
			||||||
 | 
							gpio_set_value_cansleep(adau1701->gpio_nreset, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					static int adau1701_suspend(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
 | 
				
			||||||
 | 
								       adau1701->supplies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int adau1701_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
 | 
				
			||||||
 | 
									    adau1701->supplies);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return adau1701_reset(codec, adau1701->pll_clkdiv, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define adau1701_resume 	NULL
 | 
				
			||||||
 | 
					#define adau1701_suspend 	NULL
 | 
				
			||||||
 | 
					#endif /* CONFIG_PM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct snd_soc_codec_driver adau1701_codec_drv = {
 | 
					static struct snd_soc_codec_driver adau1701_codec_drv = {
 | 
				
			||||||
	.probe			= adau1701_probe,
 | 
						.probe			= adau1701_probe,
 | 
				
			||||||
 | 
						.remove			= adau1701_remove,
 | 
				
			||||||
 | 
						.resume			= adau1701_resume,
 | 
				
			||||||
 | 
						.suspend		= adau1701_suspend,
 | 
				
			||||||
	.set_bias_level		= adau1701_set_bias_level,
 | 
						.set_bias_level		= adau1701_set_bias_level,
 | 
				
			||||||
	.idle_bias_off		= true,
 | 
						.idle_bias_off		= true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -730,32 +792,58 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 | 
				
			||||||
	struct device *dev = &client->dev;
 | 
						struct device *dev = &client->dev;
 | 
				
			||||||
	int gpio_nreset = -EINVAL;
 | 
						int gpio_nreset = -EINVAL;
 | 
				
			||||||
	int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
 | 
						int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
 | 
				
			||||||
	int ret;
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
 | 
						adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
 | 
				
			||||||
	if (!adau1701)
 | 
						if (!adau1701)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 | 
				
			||||||
 | 
							adau1701->supplies[i].supply = supply_names[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies),
 | 
				
			||||||
 | 
								adau1701->supplies);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							dev_err(dev, "Failed to get regulators: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
 | 
				
			||||||
 | 
								adau1701->supplies);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							dev_err(dev, "Failed to enable regulators: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adau1701->client = client;
 | 
						adau1701->client = client;
 | 
				
			||||||
	adau1701->regmap = devm_regmap_init(dev, NULL, client,
 | 
						adau1701->regmap = devm_regmap_init(dev, NULL, client,
 | 
				
			||||||
					    &adau1701_regmap);
 | 
										    &adau1701_regmap);
 | 
				
			||||||
	if (IS_ERR(adau1701->regmap))
 | 
						if (IS_ERR(adau1701->regmap)) {
 | 
				
			||||||
		return PTR_ERR(adau1701->regmap);
 | 
							ret = PTR_ERR(adau1701->regmap);
 | 
				
			||||||
 | 
							goto exit_regulators_disable;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->of_node) {
 | 
						if (dev->of_node) {
 | 
				
			||||||
		gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
 | 
							gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
 | 
				
			||||||
		if (gpio_nreset < 0 && gpio_nreset != -ENOENT)
 | 
							if (gpio_nreset < 0 && gpio_nreset != -ENOENT) {
 | 
				
			||||||
			return gpio_nreset;
 | 
								ret = gpio_nreset;
 | 
				
			||||||
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
 | 
							gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
 | 
				
			||||||
						   "adi,pll-mode-gpios", 0);
 | 
											   "adi,pll-mode-gpios", 0);
 | 
				
			||||||
		if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT)
 | 
							if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) {
 | 
				
			||||||
			return gpio_pll_mode[0];
 | 
								ret = gpio_pll_mode[0];
 | 
				
			||||||
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
 | 
							gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
 | 
				
			||||||
						   "adi,pll-mode-gpios", 1);
 | 
											   "adi,pll-mode-gpios", 1);
 | 
				
			||||||
		if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT)
 | 
							if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) {
 | 
				
			||||||
			return gpio_pll_mode[1];
 | 
								ret = gpio_pll_mode[1];
 | 
				
			||||||
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
 | 
							of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
 | 
				
			||||||
				     &adau1701->pll_clkdiv);
 | 
									     &adau1701->pll_clkdiv);
 | 
				
			||||||
| 
						 | 
					@ -769,7 +857,7 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 | 
				
			||||||
		ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
 | 
							ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
 | 
				
			||||||
					    "ADAU1701 Reset");
 | 
										    "ADAU1701 Reset");
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			return ret;
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gpio_is_valid(gpio_pll_mode[0]) &&
 | 
						if (gpio_is_valid(gpio_pll_mode[0]) &&
 | 
				
			||||||
| 
						 | 
					@ -778,13 +866,13 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 | 
				
			||||||
					    GPIOF_OUT_INIT_LOW,
 | 
										    GPIOF_OUT_INIT_LOW,
 | 
				
			||||||
					    "ADAU1701 PLL mode 0");
 | 
										    "ADAU1701 PLL mode 0");
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			return ret;
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
 | 
							ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
 | 
				
			||||||
					    GPIOF_OUT_INIT_LOW,
 | 
										    GPIOF_OUT_INIT_LOW,
 | 
				
			||||||
					    "ADAU1701 PLL mode 1");
 | 
										    "ADAU1701 PLL mode 1");
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
			return ret;
 | 
								goto exit_regulators_disable;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adau1701->gpio_nreset = gpio_nreset;
 | 
						adau1701->gpio_nreset = gpio_nreset;
 | 
				
			||||||
| 
						 | 
					@ -795,11 +883,17 @@ static int adau1701_i2c_probe(struct i2c_client *client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
 | 
						adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
 | 
				
			||||||
		&adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
 | 
							&adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
 | 
				
			||||||
	if (IS_ERR(adau1701->sigmadsp))
 | 
						if (IS_ERR(adau1701->sigmadsp)) {
 | 
				
			||||||
		return PTR_ERR(adau1701->sigmadsp);
 | 
							ret = PTR_ERR(adau1701->sigmadsp);
 | 
				
			||||||
 | 
							goto exit_regulators_disable;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
 | 
						ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
 | 
				
			||||||
			&adau1701_dai, 1);
 | 
								&adau1701_dai, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit_regulators_disable:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -466,7 +466,6 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,6 +482,7 @@ static enum adau1761_output_mode adau1761_get_lineout_mode(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 | 
					static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
						struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	enum adau1761_digmic_jackdet_pin_mode mode;
 | 
						enum adau1761_digmic_jackdet_pin_mode mode;
 | 
				
			||||||
| 
						 | 
					@ -515,21 +515,18 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
	case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
 | 
						case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
 | 
				
			||||||
			adau1761_no_dmic_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1761_no_dmic_routes));
 | 
								ARRAY_SIZE(adau1761_no_dmic_routes));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
 | 
						case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
 | 
				
			||||||
			adau1761_dmic_widgets,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1761_dmic_widgets));
 | 
								ARRAY_SIZE(adau1761_dmic_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
 | 
				
			||||||
			adau1761_dmic_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1761_dmic_routes));
 | 
								ARRAY_SIZE(adau1761_dmic_routes));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
| 
						 | 
					@ -547,6 +544,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 | 
					static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
						struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
				
			||||||
	enum adau1761_output_mode mode;
 | 
						enum adau1761_output_mode mode;
 | 
				
			||||||
| 
						 | 
					@ -577,12 +575,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
 | 
						if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			adau1761_capless_dapm_widgets,
 | 
								adau1761_capless_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(adau1761_capless_dapm_widgets));
 | 
								ARRAY_SIZE(adau1761_capless_dapm_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			adau1761_capless_dapm_routes,
 | 
								adau1761_capless_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(adau1761_capless_dapm_routes));
 | 
								ARRAY_SIZE(adau1761_capless_dapm_routes));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -590,12 +588,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 | 
				
			||||||
			ARRAY_SIZE(adau1761_mono_controls));
 | 
								ARRAY_SIZE(adau1761_mono_controls));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			adau1761_mono_dapm_widgets,
 | 
								adau1761_mono_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(adau1761_mono_dapm_widgets));
 | 
								ARRAY_SIZE(adau1761_mono_dapm_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			adau1761_mono_dapm_routes,
 | 
								adau1761_mono_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(adau1761_mono_dapm_routes));
 | 
								ARRAY_SIZE(adau1761_mono_dapm_routes));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -640,6 +638,7 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1761_codec_probe(struct snd_soc_codec *codec)
 | 
					static int adau1761_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
						struct adau1761_platform_data *pdata = codec->dev->platform_data;
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -692,14 +691,12 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adau->type == ADAU1761) {
 | 
						if (adau->type == ADAU1761) {
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
 | 
				
			||||||
			adau1761_dapm_widgets,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1761_dapm_widgets));
 | 
								ARRAY_SIZE(adau1761_dapm_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
 | 
				
			||||||
			adau1761_dapm_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1761_dapm_routes));
 | 
								ARRAY_SIZE(adau1761_dapm_routes));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -339,7 +339,6 @@ static int adau1781_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -383,6 +382,7 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1781_codec_probe(struct snd_soc_codec *codec)
 | 
					static int adau1781_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
 | 
						struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -403,19 +403,17 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pdata && pdata->use_dmic) {
 | 
						if (pdata && pdata->use_dmic) {
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			adau1781_dmic_dapm_widgets,
 | 
								adau1781_dmic_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(adau1781_dmic_dapm_widgets));
 | 
								ARRAY_SIZE(adau1781_dmic_dapm_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau1781_dmic_dapm_routes,
 | 
				
			||||||
			adau1781_dmic_dapm_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1781_dmic_dapm_routes));
 | 
								ARRAY_SIZE(adau1781_dmic_dapm_routes));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau1781_adc_dapm_routes,
 | 
				
			||||||
			adau1781_adc_dapm_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau1781_adc_dapm_routes));
 | 
								ARRAY_SIZE(adau1781_adc_dapm_routes));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,6 +155,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_ctl_elem_value *ucontrol)
 | 
						struct snd_ctl_elem_value *ucontrol)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
 | 
						struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 | 
						struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 | 
				
			||||||
	struct snd_soc_dapm_update update;
 | 
						struct snd_soc_dapm_update update;
 | 
				
			||||||
| 
						 | 
					@ -188,7 +189,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
		update.reg = reg;
 | 
							update.reg = reg;
 | 
				
			||||||
		update.val = val;
 | 
							update.val = val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_dapm_mux_update_power(&codec->dapm, kcontrol,
 | 
							snd_soc_dapm_mux_update_power(dapm, kcontrol,
 | 
				
			||||||
				ucontrol->value.enumerated.item[0], e, &update);
 | 
									ucontrol->value.enumerated.item[0], e, &update);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -444,8 +445,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
 | 
				
			||||||
static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
 | 
					static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
 | 
				
			||||||
		int clk_id, unsigned int freq, int dir)
 | 
							int clk_id, unsigned int freq, int dir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &dai->codec->dapm;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (clk_id) {
 | 
						switch (clk_id) {
 | 
				
			||||||
	case ADAU17X1_CLK_SRC_MCLK:
 | 
						case ADAU17X1_CLK_SRC_MCLK:
 | 
				
			||||||
| 
						 | 
					@ -804,6 +805,7 @@ EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int adau17x1_add_widgets(struct snd_soc_codec *codec)
 | 
					int adau17x1_add_widgets(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -811,14 +813,13 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
 | 
				
			||||||
		ARRAY_SIZE(adau17x1_controls));
 | 
							ARRAY_SIZE(adau17x1_controls));
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets,
 | 
						ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets,
 | 
				
			||||||
		ARRAY_SIZE(adau17x1_dapm_widgets));
 | 
							ARRAY_SIZE(adau17x1_dapm_widgets));
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adau17x1_has_dsp(adau)) {
 | 
						if (adau17x1_has_dsp(adau)) {
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets,
 | 
				
			||||||
			adau17x1_dsp_dapm_widgets,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
 | 
								ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
 | 
				
			||||||
		if (ret)
 | 
							if (ret)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
| 
						 | 
					@ -840,21 +841,20 @@ EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int adau17x1_add_routes(struct snd_soc_codec *codec)
 | 
					int adau17x1_add_routes(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau *adau = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes,
 | 
						ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes,
 | 
				
			||||||
		ARRAY_SIZE(adau17x1_dapm_routes));
 | 
							ARRAY_SIZE(adau17x1_dapm_routes));
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (adau17x1_has_dsp(adau)) {
 | 
						if (adau17x1_has_dsp(adau)) {
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau17x1_dsp_dapm_routes,
 | 
				
			||||||
			adau17x1_dsp_dapm_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau17x1_dsp_dapm_routes));
 | 
								ARRAY_SIZE(adau17x1_dsp_dapm_routes));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ret = snd_soc_dapm_add_routes(&codec->dapm,
 | 
							ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes,
 | 
				
			||||||
			adau17x1_no_dsp_dapm_routes,
 | 
					 | 
				
			||||||
			ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
 | 
								ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {
 | 
				
			||||||
		ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
 | 
							ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ADAU1977_DC_SUB_SWITCH(x) \
 | 
					#define ADAU1977_DC_SUB_SWITCH(x) \
 | 
				
			||||||
	SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \
 | 
						SOC_SINGLE("ADC" #x " DC Subtraction Capture Switch", \
 | 
				
			||||||
		ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
 | 
							ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new adau1977_snd_controls[] = {
 | 
					static const struct snd_kcontrol_new adau1977_snd_controls[] = {
 | 
				
			||||||
| 
						 | 
					@ -485,7 +485,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			ret = adau1977_power_enable(adau1977);
 | 
								ret = adau1977_power_enable(adau1977);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
| 
						 | 
					@ -493,12 +493,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret)
 | 
						return ret;
 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 | 
					static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 | 
				
			||||||
| 
						 | 
					@ -853,12 +848,13 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adau1977_codec_probe(struct snd_soc_codec *codec)
 | 
					static int adau1977_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
 | 
						struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (adau1977->type) {
 | 
						switch (adau1977->type) {
 | 
				
			||||||
	case ADAU1977:
 | 
						case ADAU1977:
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			adau1977_micbias_dapm_widgets,
 | 
								adau1977_micbias_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(adau1977_micbias_dapm_widgets));
 | 
								ARRAY_SIZE(adau1977_micbias_dapm_widgets));
 | 
				
			||||||
		if (ret < 0)
 | 
							if (ret < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
 | 
				
			||||||
			      unsigned int freq, int dir)
 | 
								      unsigned int freq, int dir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
						struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dir == SND_SOC_CLOCK_IN) {
 | 
						if (dir == SND_SOC_CLOCK_IN) {
 | 
				
			||||||
		switch (clk_id) {
 | 
							switch (clk_id) {
 | 
				
			||||||
| 
						 | 
					@ -622,6 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
 | 
				
			||||||
static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
 | 
					static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
 | 
				
			||||||
		int source, unsigned int freq_in, unsigned int freq_out)
 | 
							int source, unsigned int freq_in, unsigned int freq_out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
						struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	unsigned int pll_ctrl1 = 0;
 | 
						unsigned int pll_ctrl1 = 0;
 | 
				
			||||||
	unsigned int pll_ctrl2 = 0;
 | 
						unsigned int pll_ctrl2 = 0;
 | 
				
			||||||
| 
						 | 
					@ -687,7 +688,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		adav80x->pll_src = source;
 | 
							adav80x->pll_src = source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_dapm_sync(&codec->dapm);
 | 
							snd_soc_dapm_sync(dapm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -714,7 +715,6 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -801,11 +801,12 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int adav80x_probe(struct snd_soc_codec *codec)
 | 
					static int adav80x_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
						struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Force PLLs on for SYSCLK output */
 | 
						/* Force PLLs on for SYSCLK output */
 | 
				
			||||||
	snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
 | 
						snd_soc_dapm_force_enable_pin(dapm, "PLL1");
 | 
				
			||||||
	snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");
 | 
						snd_soc_dapm_force_enable_pin(dapm, "PLL2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Power down S/PDIF receiver, since it is currently not supported */
 | 
						/* Power down S/PDIF receiver, since it is currently not supported */
 | 
				
			||||||
	regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
 | 
						regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -341,7 +341,6 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
 | 
							snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -412,7 +412,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
 | 
							snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			if (pdata && gpio_is_valid(pdata->gpio_power))
 | 
								if (pdata && gpio_is_valid(pdata->gpio_power))
 | 
				
			||||||
				gpio_set_value(pdata->gpio_power, 1);
 | 
									gpio_set_value(pdata->gpio_power, 1);
 | 
				
			||||||
			mdelay(1);
 | 
								mdelay(1);
 | 
				
			||||||
| 
						 | 
					@ -439,7 +439,6 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		regcache_mark_dirty(ak4641->regmap);
 | 
							regcache_mark_dirty(ak4641->regmap);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,7 +482,6 @@ static int ak4642_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
 | 
							snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -577,7 +577,6 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
 | 
							snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -826,7 +826,6 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
 | 
							snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -894,7 +893,7 @@ static int alc5623_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
static int alc5623_probe(struct snd_soc_codec *codec)
 | 
					static int alc5623_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
 | 
						struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	alc5623_reset(codec);
 | 
						alc5623_reset(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1000,7 +1000,6 @@ static int alc5632_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				ALC5632_PWR_MANAG_ADD1_MASK, 0);
 | 
									ALC5632_PWR_MANAG_ADD1_MASK, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -208,11 +208,12 @@ static const struct snd_soc_dapm_widget arizona_spkr =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arizona_init_spk(struct snd_soc_codec *codec)
 | 
					int arizona_init_spk(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct arizona *arizona = priv->arizona;
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1);
 | 
						ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
 | 
				
			||||||
	if (ret != 0)
 | 
						if (ret != 0)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,8 +221,7 @@ int arizona_init_spk(struct snd_soc_codec *codec)
 | 
				
			||||||
	case WM8997:
 | 
						case WM8997:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ret = snd_soc_dapm_new_controls(&codec->dapm,
 | 
							ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
 | 
				
			||||||
						&arizona_spkr, 1);
 | 
					 | 
				
			||||||
		if (ret != 0)
 | 
							if (ret != 0)
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -258,13 +258,14 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arizona_init_mono(struct snd_soc_codec *codec)
 | 
					int arizona_init_mono(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct arizona *arizona = priv->arizona;
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
 | 
						for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
 | 
				
			||||||
		if (arizona->pdata.out_mono[i])
 | 
							if (arizona->pdata.out_mono[i])
 | 
				
			||||||
			snd_soc_dapm_add_routes(&codec->dapm,
 | 
								snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
						&arizona_mono_routes[i], 1);
 | 
											&arizona_mono_routes[i], 1);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -274,6 +275,7 @@ EXPORT_SYMBOL_GPL(arizona_init_mono);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arizona_init_gpio(struct snd_soc_codec *codec)
 | 
					int arizona_init_gpio(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct arizona *arizona = priv->arizona;
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -281,23 +283,21 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
 | 
				
			||||||
	switch (arizona->type) {
 | 
						switch (arizona->type) {
 | 
				
			||||||
	case WM5110:
 | 
						case WM5110:
 | 
				
			||||||
	case WM8280:
 | 
						case WM8280:
 | 
				
			||||||
		snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
 | 
							snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
 | 
						snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
 | 
						for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
 | 
				
			||||||
		switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
 | 
							switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
 | 
				
			||||||
		case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
 | 
							case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
 | 
				
			||||||
			snd_soc_dapm_enable_pin(&codec->dapm,
 | 
								snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity");
 | 
				
			||||||
						"DRC1 Signal Activity");
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
 | 
							case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
 | 
				
			||||||
			snd_soc_dapm_enable_pin(&codec->dapm,
 | 
								snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity");
 | 
				
			||||||
						"DRC2 Signal Activity");
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -851,6 +851,134 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(arizona_hp_ev);
 | 
					EXPORT_SYMBOL_GPL(arizona_hp_ev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int arizona_dvfs_enable(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regmap_update_bits(arizona->regmap,
 | 
				
			||||||
 | 
									 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
 | 
				
			||||||
 | 
									 ARIZONA_SUBSYS_MAX_FREQ,
 | 
				
			||||||
 | 
									 ARIZONA_SUBSYS_MAX_FREQ);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
 | 
				
			||||||
 | 
							regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int arizona_dvfs_disable(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regmap_update_bits(arizona->regmap,
 | 
				
			||||||
 | 
									 ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
 | 
				
			||||||
 | 
									 ARIZONA_SUBSYS_MAX_FREQ, 0);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!priv->dvfs_cached && !priv->dvfs_reqs) {
 | 
				
			||||||
 | 
							ret = arizona_dvfs_enable(codec);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv->dvfs_reqs |= flags;
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						mutex_unlock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(arizona_dvfs_up);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						unsigned int old_reqs;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						old_reqs = priv->dvfs_reqs;
 | 
				
			||||||
 | 
						priv->dvfs_reqs &= ~flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
 | 
				
			||||||
 | 
							ret = arizona_dvfs_disable(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(arizona_dvfs_down);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
								   struct snd_kcontrol *kcontrol, int event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (event) {
 | 
				
			||||||
 | 
						case SND_SOC_DAPM_POST_PMU:
 | 
				
			||||||
 | 
							if (priv->dvfs_reqs)
 | 
				
			||||||
 | 
								ret = arizona_dvfs_enable(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							priv->dvfs_cached = false;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAPM_PRE_PMD:
 | 
				
			||||||
 | 
							/* We must ensure DVFS is disabled before the codec goes into
 | 
				
			||||||
 | 
							 * suspend so that we are never in an illegal state of DVFS
 | 
				
			||||||
 | 
							 * enabled without enough DCVDD
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							priv->dvfs_cached = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (priv->dvfs_reqs)
 | 
				
			||||||
 | 
								ret = arizona_dvfs_disable(codec);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&priv->dvfs_lock);
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void arizona_init_dvfs(struct arizona_priv *priv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mutex_init(&priv->dvfs_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(arizona_init_dvfs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int arizona_sysclk_48k_rates[] = {
 | 
					static unsigned int arizona_sysclk_48k_rates[] = {
 | 
				
			||||||
	6144000,
 | 
						6144000,
 | 
				
			||||||
	12288000,
 | 
						12288000,
 | 
				
			||||||
| 
						 | 
					@ -1266,7 +1394,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
				
			||||||
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 | 
						struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 | 
				
			||||||
	int base = dai->driver->base;
 | 
						int base = dai->driver->base;
 | 
				
			||||||
	int i, sr_val;
 | 
						int i, sr_val, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We will need to be more flexible than this in future,
 | 
						 * We will need to be more flexible than this in future,
 | 
				
			||||||
| 
						 | 
					@ -1282,6 +1410,23 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sr_val = i;
 | 
						sr_val = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (priv->arizona->type) {
 | 
				
			||||||
 | 
						case WM5102:
 | 
				
			||||||
 | 
						case WM8997:
 | 
				
			||||||
 | 
							if (arizona_sr_vals[sr_val] >= 88200)
 | 
				
			||||||
 | 
								ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ret) {
 | 
				
			||||||
 | 
								arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (dai_priv->clk) {
 | 
						switch (dai_priv->clk) {
 | 
				
			||||||
	case ARIZONA_CLK_SYSCLK:
 | 
						case ARIZONA_CLK_SYSCLK:
 | 
				
			||||||
		switch (priv->arizona->type) {
 | 
							switch (priv->arizona->type) {
 | 
				
			||||||
| 
						 | 
					@ -1474,6 +1619,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 | 
				
			||||||
				  int clk_id, unsigned int freq, int dir)
 | 
									  int clk_id, unsigned int freq, int dir)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = dai->codec;
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 | 
						struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
 | 
				
			||||||
	struct snd_soc_dapm_route routes[2];
 | 
						struct snd_soc_dapm_route routes[2];
 | 
				
			||||||
| 
						 | 
					@ -1504,15 +1650,15 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	routes[0].source = arizona_dai_clk_str(dai_priv->clk);
 | 
						routes[0].source = arizona_dai_clk_str(dai_priv->clk);
 | 
				
			||||||
	routes[1].source = arizona_dai_clk_str(dai_priv->clk);
 | 
						routes[1].source = arizona_dai_clk_str(dai_priv->clk);
 | 
				
			||||||
	snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
 | 
						snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	routes[0].source = arizona_dai_clk_str(clk_id);
 | 
						routes[0].source = arizona_dai_clk_str(clk_id);
 | 
				
			||||||
	routes[1].source = arizona_dai_clk_str(clk_id);
 | 
						routes[1].source = arizona_dai_clk_str(clk_id);
 | 
				
			||||||
	snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
 | 
						snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dai_priv->clk = clk_id;
 | 
						dai_priv->clk = clk_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return snd_soc_dapm_sync(&codec->dapm);
 | 
						return snd_soc_dapm_sync(dapm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 | 
					static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,9 @@
 | 
				
			||||||
#define ARIZONA_MAX_DAI  6
 | 
					#define ARIZONA_MAX_DAI  6
 | 
				
			||||||
#define ARIZONA_MAX_ADSP 4
 | 
					#define ARIZONA_MAX_ADSP 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARIZONA_DVFS_SR1_RQ	0x001
 | 
				
			||||||
 | 
					#define ARIZONA_DVFS_ADSP1_RQ	0x100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct arizona;
 | 
					struct arizona;
 | 
				
			||||||
struct wm_adsp;
 | 
					struct wm_adsp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +87,10 @@ struct arizona_priv {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int spk_ena:2;
 | 
						unsigned int spk_ena:2;
 | 
				
			||||||
	unsigned int spk_ena_pending:1;
 | 
						unsigned int spk_ena_pending:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int dvfs_reqs;
 | 
				
			||||||
 | 
						struct mutex dvfs_lock;
 | 
				
			||||||
 | 
						bool dvfs_cached;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARIZONA_NUM_MIXER_INPUTS 103
 | 
					#define ARIZONA_NUM_MIXER_INPUTS 103
 | 
				
			||||||
| 
						 | 
					@ -107,8 +114,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
 | 
				
			||||||
			     arizona_mixer_tlv)
 | 
								     arizona_mixer_tlv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARIZONA_MUX_ENUM_DECL(name, reg) \
 | 
					#define ARIZONA_MUX_ENUM_DECL(name, reg) \
 | 
				
			||||||
	SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff,			\
 | 
						SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
 | 
				
			||||||
				   arizona_mixer_texts, arizona_mixer_values)
 | 
							name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARIZONA_MUX_CTL_DECL(name) \
 | 
					#define ARIZONA_MUX_CTL_DECL(name) \
 | 
				
			||||||
	const struct snd_kcontrol_new name##_mux =	\
 | 
						const struct snd_kcontrol_new name##_mux =	\
 | 
				
			||||||
| 
						 | 
					@ -245,6 +252,12 @@ struct arizona_fll {
 | 
				
			||||||
	char clock_ok_name[ARIZONA_FLL_NAME_LEN];
 | 
						char clock_ok_name[ARIZONA_FLL_NAME_LEN];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags);
 | 
				
			||||||
 | 
					extern int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags);
 | 
				
			||||||
 | 
					extern int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
									  struct snd_kcontrol *kcontrol, int event);
 | 
				
			||||||
 | 
					extern void arizona_init_dvfs(struct arizona_priv *priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int arizona_init_fll(struct arizona *arizona, int id, int base,
 | 
					extern int arizona_init_fll(struct arizona *arizona, int id, int base,
 | 
				
			||||||
			    int lock_irq, int ok_irq, struct arizona_fll *fll);
 | 
								    int lock_irq, int ok_irq, struct arizona_fll *fll);
 | 
				
			||||||
extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 | 
					extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ static int bt_sco_remove(struct platform_device *pdev)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_device_id bt_sco_driver_ids[] = {
 | 
					static const struct platform_device_id bt_sco_driver_ids[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name		= "dfbmcs320",
 | 
							.name		= "dfbmcs320",
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
| 
						 | 
					@ -74,9 +74,18 @@ static struct platform_device_id bt_sco_driver_ids[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
 | 
					MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_OF)
 | 
				
			||||||
 | 
					static const struct of_device_id bt_sco_codec_of_match[] = {
 | 
				
			||||||
 | 
						{ .compatible = "delta,dfbmcs320", },
 | 
				
			||||||
 | 
						{},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct platform_driver bt_sco_driver = {
 | 
					static struct platform_driver bt_sco_driver = {
 | 
				
			||||||
	.driver = {
 | 
						.driver = {
 | 
				
			||||||
		.name = "bt-sco",
 | 
							.name = "bt-sco",
 | 
				
			||||||
 | 
							.of_match_table = of_match_ptr(bt_sco_codec_of_match),
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	.probe = bt_sco_probe,
 | 
						.probe = bt_sco_probe,
 | 
				
			||||||
	.remove = bt_sco_remove,
 | 
						.remove = bt_sco_remove,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,6 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
			     DAVINCI_VC_REG12_POWER_ALL_OFF);
 | 
								     DAVINCI_VC_REG12_POWER_ALL_OFF);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/moduleparam.h>
 | 
					#include <linux/moduleparam.h>
 | 
				
			||||||
#include <linux/version.h>
 | 
					 | 
				
			||||||
#include <linux/kernel.h>
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
#include <linux/init.h>
 | 
					#include <linux/init.h>
 | 
				
			||||||
#include <linux/delay.h>
 | 
					#include <linux/delay.h>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -503,7 +503,6 @@ static int cs4265_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
			CS4265_PWRCTL_PDN);
 | 
								CS4265_PWRCTL_PDN);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -897,7 +897,7 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				    CS42L52_PWRCTL1_PDN_CODEC, 0);
 | 
									    CS42L52_PWRCTL1_PDN_CODEC, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			regcache_cache_only(cs42l52->regmap, false);
 | 
								regcache_cache_only(cs42l52->regmap, false);
 | 
				
			||||||
			regcache_sync(cs42l52->regmap);
 | 
								regcache_sync(cs42l52->regmap);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -908,7 +908,6 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		regcache_cache_only(cs42l52->regmap, true);
 | 
							regcache_cache_only(cs42l52->regmap, true);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -956,7 +955,7 @@ static void cs42l52_beep_work(struct work_struct *work)
 | 
				
			||||||
	struct cs42l52_private *cs42l52 =
 | 
						struct cs42l52_private *cs42l52 =
 | 
				
			||||||
		container_of(work, struct cs42l52_private, beep_work);
 | 
							container_of(work, struct cs42l52_private, beep_work);
 | 
				
			||||||
	struct snd_soc_codec *codec = cs42l52->codec;
 | 
						struct snd_soc_codec *codec = cs42l52->codec;
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int val = 0;
 | 
						int val = 0;
 | 
				
			||||||
	int best = 0;
 | 
						int best = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -953,7 +953,7 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				    CS42L56_PDN_ALL_MASK, 0);
 | 
									    CS42L56_PDN_ALL_MASK, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			regcache_cache_only(cs42l56->regmap, false);
 | 
								regcache_cache_only(cs42l56->regmap, false);
 | 
				
			||||||
			regcache_sync(cs42l56->regmap);
 | 
								regcache_sync(cs42l56->regmap);
 | 
				
			||||||
			ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
 | 
								ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
 | 
				
			||||||
| 
						 | 
					@ -978,7 +978,6 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
						    cs42l56->supplies);
 | 
											    cs42l56->supplies);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1026,7 +1025,7 @@ static void cs42l56_beep_work(struct work_struct *work)
 | 
				
			||||||
	struct cs42l56_private *cs42l56 =
 | 
						struct cs42l56_private *cs42l56 =
 | 
				
			||||||
		container_of(work, struct cs42l56_private, beep_work);
 | 
							container_of(work, struct cs42l56_private, beep_work);
 | 
				
			||||||
	struct snd_soc_codec *codec = cs42l56->codec;
 | 
						struct snd_soc_codec *codec = cs42l56->codec;
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int val = 0;
 | 
						int val = 0;
 | 
				
			||||||
	int best = 0;
 | 
						int best = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1208,7 +1208,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			regcache_cache_only(cs42l73->regmap, false);
 | 
								regcache_cache_only(cs42l73->regmap, false);
 | 
				
			||||||
			regcache_sync(cs42l73->regmap);
 | 
								regcache_sync(cs42l73->regmap);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1228,7 +1228,6 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
 | 
							snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
 | 
				
			||||||
static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
 | 
					static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
 | 
						struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cs42xx8->drvdata->num_adcs) {
 | 
						switch (cs42xx8->drvdata->num_adcs) {
 | 
				
			||||||
	case 3:
 | 
						case 3:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -333,7 +333,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (level) {
 | 
						switch (level) {
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
 | 
							if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_STANDBY)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (IS_ERR(cx20442->por))
 | 
							if (IS_ERR(cx20442->por))
 | 
				
			||||||
			err = PTR_ERR(cx20442->por);
 | 
								err = PTR_ERR(cx20442->por);
 | 
				
			||||||
| 
						 | 
					@ -341,7 +341,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
			err = regulator_enable(cx20442->por);
 | 
								err = regulator_enable(cx20442->por);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
 | 
							if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_PREPARE)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (IS_ERR(cx20442->por))
 | 
							if (IS_ERR(cx20442->por))
 | 
				
			||||||
			err = PTR_ERR(cx20442->por);
 | 
								err = PTR_ERR(cx20442->por);
 | 
				
			||||||
| 
						 | 
					@ -351,8 +351,6 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (!err)
 | 
					 | 
				
			||||||
		codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1374,7 +1374,7 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			/* Enable VMID reference & master bias */
 | 
								/* Enable VMID reference & master bias */
 | 
				
			||||||
			snd_soc_update_bits(codec, DA7213_REFERENCES,
 | 
								snd_soc_update_bits(codec, DA7213_REFERENCES,
 | 
				
			||||||
					    DA7213_VMID_EN | DA7213_BIAS_EN,
 | 
										    DA7213_VMID_EN | DA7213_BIAS_EN,
 | 
				
			||||||
| 
						 | 
					@ -1387,7 +1387,6 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				    DA7213_VMID_EN | DA7213_BIAS_EN, 0);
 | 
									    DA7213_VMID_EN | DA7213_BIAS_EN, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1432,7 +1432,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			/* Init Codec */
 | 
								/* Init Codec */
 | 
				
			||||||
			snd_soc_write(codec, DA732X_REG_REF1,
 | 
								snd_soc_write(codec, DA732X_REG_REF1,
 | 
				
			||||||
				      DA732X_VMID_FASTCHG);
 | 
									      DA732X_VMID_FASTCHG);
 | 
				
			||||||
| 
						 | 
					@ -1502,8 +1502,6 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1364,7 +1364,7 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			/* Enable VMID reference & master bias */
 | 
								/* Enable VMID reference & master bias */
 | 
				
			||||||
			snd_soc_update_bits(codec, DA9055_REFERENCES,
 | 
								snd_soc_update_bits(codec, DA9055_REFERENCES,
 | 
				
			||||||
					    DA9055_VMID_EN | DA9055_BIAS_EN,
 | 
										    DA9055_VMID_EN | DA9055_BIAS_EN,
 | 
				
			||||||
| 
						 | 
					@ -1377,7 +1377,6 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				    DA9055_VMID_EN | DA9055_BIAS_EN, 0);
 | 
									    DA9055_VMID_EN | DA9055_BIAS_EN, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -536,7 +536,7 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			snd_soc_update_bits(codec, ES8328_CONTROL1,
 | 
								snd_soc_update_bits(codec, ES8328_CONTROL1,
 | 
				
			||||||
					ES8328_CONTROL1_VMIDSEL_MASK |
 | 
										ES8328_CONTROL1_VMIDSEL_MASK |
 | 
				
			||||||
					ES8328_CONTROL1_ENREF,
 | 
										ES8328_CONTROL1_ENREF,
 | 
				
			||||||
| 
						 | 
					@ -566,7 +566,6 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				0);
 | 
									0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -909,8 +909,6 @@ static int isabelle_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		/* The only way to clear the suspend flag is to reset the codec */
 | 
							/* The only way to clear the suspend flag is to reset the codec */
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			jz4740_codec_wakeup(regmap);
 | 
								jz4740_codec_wakeup(regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mask = JZ4740_CODEC_1_VREF_DISABLE |
 | 
							mask = JZ4740_CODEC_1_VREF_DISABLE |
 | 
				
			||||||
| 
						 | 
					@ -281,8 +281,6 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,11 +23,6 @@
 | 
				
			||||||
#include <sound/soc.h>
 | 
					#include <sound/soc.h>
 | 
				
			||||||
#include <sound/tlv.h>
 | 
					#include <sound/tlv.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct lm4857 {
 | 
					 | 
				
			||||||
	struct regmap *regmap;
 | 
					 | 
				
			||||||
	uint8_t mode;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct reg_default lm4857_default_regs[] = {
 | 
					static const struct reg_default lm4857_default_regs[] = {
 | 
				
			||||||
	{ 0x0, 0x00 },
 | 
						{ 0x0, 0x00 },
 | 
				
			||||||
	{ 0x1, 0x00 },
 | 
						{ 0x1, 0x00 },
 | 
				
			||||||
| 
						 | 
					@ -46,66 +41,33 @@ static const struct reg_default lm4857_default_regs[] = {
 | 
				
			||||||
#define LM4857_WAKEUP 5
 | 
					#define LM4857_WAKEUP 5
 | 
				
			||||||
#define LM4857_EPGAIN 4
 | 
					#define LM4857_EPGAIN 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
 | 
					static const unsigned int lm4857_mode_values[] = {
 | 
				
			||||||
	struct snd_ctl_elem_value *ucontrol)
 | 
						0,
 | 
				
			||||||
{
 | 
						6,
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
						7,
 | 
				
			||||||
	struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
 | 
						8,
 | 
				
			||||||
 | 
						9,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ucontrol->value.integer.value[0] = lm4857->mode;
 | 
					static const char * const lm4857_mode_texts[] = {
 | 
				
			||||||
 | 
						"Off",
 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
 | 
					 | 
				
			||||||
	struct snd_ctl_elem_value *ucontrol)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
					 | 
				
			||||||
	struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
 | 
					 | 
				
			||||||
	uint8_t value = ucontrol->value.integer.value[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lm4857->mode = value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
 | 
					 | 
				
			||||||
		regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, value + 6);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int lm4857_set_bias_level(struct snd_soc_codec *codec,
 | 
					 | 
				
			||||||
				 enum snd_soc_bias_level level)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (level) {
 | 
					 | 
				
			||||||
	case SND_SOC_BIAS_ON:
 | 
					 | 
				
			||||||
		regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F,
 | 
					 | 
				
			||||||
			lm4857->mode + 6);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
					 | 
				
			||||||
		regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, 0);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char *lm4857_mode[] = {
 | 
					 | 
				
			||||||
	"Earpiece",
 | 
						"Earpiece",
 | 
				
			||||||
	"Loudspeaker",
 | 
						"Loudspeaker",
 | 
				
			||||||
	"Loudspeaker + Headphone",
 | 
						"Loudspeaker + Headphone",
 | 
				
			||||||
	"Headphone",
 | 
						"Headphone",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode);
 | 
					static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(lm4857_mode_enum,
 | 
				
			||||||
 | 
						LM4857_CTRL, 0, 0xf, lm4857_mode_texts, lm4857_mode_values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new lm4857_mode_ctrl =
 | 
				
			||||||
 | 
						SOC_DAPM_ENUM("Mode", lm4857_mode_enum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
 | 
					static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
 | 
				
			||||||
	SND_SOC_DAPM_INPUT("IN"),
 | 
						SND_SOC_DAPM_INPUT("IN"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_DEMUX("Mode", SND_SOC_NOPM, 0, 0, &lm4857_mode_ctrl),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SND_SOC_DAPM_OUTPUT("LS"),
 | 
						SND_SOC_DAPM_OUTPUT("LS"),
 | 
				
			||||||
	SND_SOC_DAPM_OUTPUT("HP"),
 | 
						SND_SOC_DAPM_OUTPUT("HP"),
 | 
				
			||||||
	SND_SOC_DAPM_OUTPUT("EP"),
 | 
						SND_SOC_DAPM_OUTPUT("EP"),
 | 
				
			||||||
| 
						 | 
					@ -127,24 +89,18 @@ static const struct snd_kcontrol_new lm4857_controls[] = {
 | 
				
			||||||
		LM4857_WAKEUP, 1, 0),
 | 
							LM4857_WAKEUP, 1, 0),
 | 
				
			||||||
	SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
 | 
						SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
 | 
				
			||||||
		LM4857_EPGAIN, 1, 0),
 | 
							LM4857_EPGAIN, 1, 0),
 | 
				
			||||||
 | 
					 | 
				
			||||||
	SOC_ENUM_EXT("Mode", lm4857_mode_enum,
 | 
					 | 
				
			||||||
		lm4857_get_mode, lm4857_set_mode),
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* There is a demux between the input signal and the output signals.
 | 
					 | 
				
			||||||
 * Currently there is no easy way to model it in ASoC and since it does not make
 | 
					 | 
				
			||||||
 * much of a difference in practice simply connect the input direclty to the
 | 
					 | 
				
			||||||
 * outputs. */
 | 
					 | 
				
			||||||
static const struct snd_soc_dapm_route lm4857_routes[] = {
 | 
					static const struct snd_soc_dapm_route lm4857_routes[] = {
 | 
				
			||||||
	{"LS", NULL, "IN"},
 | 
						{ "Mode", NULL, "IN" },
 | 
				
			||||||
	{"HP", NULL, "IN"},
 | 
						{ "LS", "Loudspeaker", "Mode" },
 | 
				
			||||||
	{"EP", NULL, "IN"},
 | 
						{ "LS", "Loudspeaker + Headphone", "Mode" },
 | 
				
			||||||
 | 
						{ "HP", "Headphone", "Mode" },
 | 
				
			||||||
 | 
						{ "HP", "Loudspeaker + Headphone", "Mode" },
 | 
				
			||||||
 | 
						{ "EP", "Earpiece", "Mode" },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
 | 
					static struct snd_soc_component_driver lm4857_component_driver = {
 | 
				
			||||||
	.set_bias_level = lm4857_set_bias_level,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	.controls = lm4857_controls,
 | 
						.controls = lm4857_controls,
 | 
				
			||||||
	.num_controls = ARRAY_SIZE(lm4857_controls),
 | 
						.num_controls = ARRAY_SIZE(lm4857_controls),
 | 
				
			||||||
	.dapm_widgets = lm4857_dapm_widgets,
 | 
						.dapm_widgets = lm4857_dapm_widgets,
 | 
				
			||||||
| 
						 | 
					@ -167,25 +123,14 @@ static const struct regmap_config lm4857_regmap_config = {
 | 
				
			||||||
static int lm4857_i2c_probe(struct i2c_client *i2c,
 | 
					static int lm4857_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
			    const struct i2c_device_id *id)
 | 
								    const struct i2c_device_id *id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct lm4857 *lm4857;
 | 
						struct regmap *regmap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL);
 | 
						regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config);
 | 
				
			||||||
	if (!lm4857)
 | 
						if (IS_ERR(regmap))
 | 
				
			||||||
		return -ENOMEM;
 | 
							return PTR_ERR(regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i2c_set_clientdata(i2c, lm4857);
 | 
						return devm_snd_soc_register_component(&i2c->dev,
 | 
				
			||||||
 | 
							&lm4857_component_driver, NULL, 0);
 | 
				
			||||||
	lm4857->regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config);
 | 
					 | 
				
			||||||
	if (IS_ERR(lm4857->regmap))
 | 
					 | 
				
			||||||
		return PTR_ERR(lm4857->regmap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int lm4857_i2c_remove(struct i2c_client *i2c)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	snd_soc_unregister_codec(&i2c->dev);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct i2c_device_id lm4857_i2c_id[] = {
 | 
					static const struct i2c_device_id lm4857_i2c_id[] = {
 | 
				
			||||||
| 
						 | 
					@ -200,7 +145,6 @@ static struct i2c_driver lm4857_i2c_driver = {
 | 
				
			||||||
		.owner = THIS_MODULE,
 | 
							.owner = THIS_MODULE,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	.probe = lm4857_i2c_probe,
 | 
						.probe = lm4857_i2c_probe,
 | 
				
			||||||
	.remove = lm4857_i2c_remove,
 | 
					 | 
				
			||||||
	.id_table = lm4857_i2c_id,
 | 
						.id_table = lm4857_i2c_id,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1271,7 +1271,7 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			regcache_sync(lm49453->regmap);
 | 
								regcache_sync(lm49453->regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
 | 
							snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
 | 
				
			||||||
| 
						 | 
					@ -1284,8 +1284,6 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1571,7 +1571,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			regcache_sync(max98088->regmap);
 | 
								regcache_sync(max98088->regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
 | 
							snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
 | 
				
			||||||
| 
						 | 
					@ -1584,7 +1584,6 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		regcache_mark_dirty(max98088->regmap);
 | 
							regcache_mark_dirty(max98088->regmap);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1500,7 +1500,7 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
 | 
				
			||||||
static int max98090_add_widgets(struct snd_soc_codec *codec)
 | 
					static int max98090_add_widgets(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
 | 
						struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_add_codec_controls(codec, max98090_snd_controls,
 | 
						snd_soc_add_codec_controls(codec, max98090_snd_controls,
 | 
				
			||||||
		ARRAY_SIZE(max98090_snd_controls));
 | 
							ARRAY_SIZE(max98090_snd_controls));
 | 
				
			||||||
| 
						 | 
					@ -1798,16 +1798,17 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		 * away from ON. Disable the clock in that case, otherwise
 | 
							 * away from ON. Disable the clock in that case, otherwise
 | 
				
			||||||
		 * enable it.
 | 
							 * enable it.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (!IS_ERR(max98090->mclk)) {
 | 
							if (IS_ERR(max98090->mclk))
 | 
				
			||||||
			if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
 | 
								break;
 | 
				
			||||||
				clk_disable_unprepare(max98090->mclk);
 | 
					
 | 
				
			||||||
			else
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON)
 | 
				
			||||||
				clk_prepare_enable(max98090->mclk);
 | 
								clk_disable_unprepare(max98090->mclk);
 | 
				
			||||||
		}
 | 
							else
 | 
				
			||||||
 | 
								clk_prepare_enable(max98090->mclk);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regcache_sync(max98090->regmap);
 | 
								ret = regcache_sync(max98090->regmap);
 | 
				
			||||||
			if (ret != 0) {
 | 
								if (ret != 0) {
 | 
				
			||||||
				dev_err(codec->dev,
 | 
									dev_err(codec->dev,
 | 
				
			||||||
| 
						 | 
					@ -1824,7 +1825,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		regcache_mark_dirty(max98090->regmap);
 | 
							regcache_mark_dirty(max98090->regmap);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2187,7 +2187,6 @@ static void max98090_jack_work(struct work_struct *work)
 | 
				
			||||||
		struct max98090_priv,
 | 
							struct max98090_priv,
 | 
				
			||||||
		jack_work.work);
 | 
							jack_work.work);
 | 
				
			||||||
	struct snd_soc_codec *codec = max98090->codec;
 | 
						struct snd_soc_codec *codec = max98090->codec;
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
					 | 
				
			||||||
	int status = 0;
 | 
						int status = 0;
 | 
				
			||||||
	int reg;
 | 
						int reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2266,8 +2265,6 @@ static void max98090_jack_work(struct work_struct *work)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_jack_report(max98090->jack, status,
 | 
						snd_soc_jack_report(max98090->jack, status,
 | 
				
			||||||
			    SND_JACK_HEADSET | SND_JACK_BTN_0);
 | 
								    SND_JACK_HEADSET | SND_JACK_BTN_0);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	snd_soc_dapm_sync(dapm);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static irqreturn_t max98090_interrupt(int irq, void *data)
 | 
					static irqreturn_t max98090_interrupt(int irq, void *data)
 | 
				
			||||||
| 
						 | 
					@ -2422,6 +2419,8 @@ static int max98090_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	struct max98090_cdata *cdata;
 | 
						struct max98090_cdata *cdata;
 | 
				
			||||||
	enum max98090_type devtype;
 | 
						enum max98090_type devtype;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
						int err;
 | 
				
			||||||
 | 
						unsigned int micbias;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev_dbg(codec->dev, "max98090_probe\n");
 | 
						dev_dbg(codec->dev, "max98090_probe\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2506,8 +2505,17 @@ static int max98090_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
 | 
						snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
 | 
				
			||||||
		M98090_VCM_MODE_MASK);
 | 
							M98090_VCM_MODE_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = device_property_read_u32(codec->dev, "maxim,micbias", &micbias);
 | 
				
			||||||
 | 
						if (err) {
 | 
				
			||||||
 | 
							micbias = M98090_MBVSEL_2V8;
 | 
				
			||||||
 | 
							dev_info(codec->dev, "use default 2.8v micbias\n");
 | 
				
			||||||
 | 
						} else if (micbias < M98090_MBVSEL_2V2 || micbias > M98090_MBVSEL_2V8) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
 | 
				
			||||||
 | 
							micbias = M98090_MBVSEL_2V8;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
 | 
						snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
 | 
				
			||||||
		M98090_MBVSEL_MASK, M98090_MBVSEL_2V8);
 | 
							M98090_MBVSEL_MASK, micbias);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	max98090_add_widgets(codec);
 | 
						max98090_add_widgets(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1650,16 +1650,17 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		 * away from ON. Disable the clock in that case, otherwise
 | 
							 * away from ON. Disable the clock in that case, otherwise
 | 
				
			||||||
		 * enable it.
 | 
							 * enable it.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		if (!IS_ERR(max98095->mclk)) {
 | 
							if (IS_ERR(max98095->mclk))
 | 
				
			||||||
			if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
 | 
								break;
 | 
				
			||||||
				clk_disable_unprepare(max98095->mclk);
 | 
					
 | 
				
			||||||
			else
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON)
 | 
				
			||||||
				clk_prepare_enable(max98095->mclk);
 | 
								clk_disable_unprepare(max98095->mclk);
 | 
				
			||||||
		}
 | 
							else
 | 
				
			||||||
 | 
								clk_prepare_enable(max98095->mclk);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regcache_sync(max98095->regmap);
 | 
								ret = regcache_sync(max98095->regmap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (ret != 0) {
 | 
								if (ret != 0) {
 | 
				
			||||||
| 
						 | 
					@ -1678,7 +1679,6 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		regcache_mark_dirty(max98095->regmap);
 | 
							regcache_mark_dirty(max98095->regmap);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2198,7 +2198,7 @@ static int max98095_suspend(struct snd_soc_codec *codec)
 | 
				
			||||||
	if (max98095->headphone_jack || max98095->mic_jack)
 | 
						if (max98095->headphone_jack || max98095->mic_jack)
 | 
				
			||||||
		max98095_jack_detect_disable(codec);
 | 
							max98095_jack_detect_disable(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2208,7 +2208,7 @@ static int max98095_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
	struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
 | 
						struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct i2c_client *client = to_i2c_client(codec->dev);
 | 
						struct i2c_client *client = to_i2c_client(codec->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (max98095->headphone_jack || max98095->mic_jack) {
 | 
						if (max98095->headphone_jack || max98095->mic_jack) {
 | 
				
			||||||
		max98095_jack_detect_enable(codec);
 | 
							max98095_jack_detect_enable(codec);
 | 
				
			||||||
| 
						 | 
					@ -2301,8 +2301,8 @@ static int max98095_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		/* register an audio interrupt */
 | 
							/* register an audio interrupt */
 | 
				
			||||||
		ret = request_threaded_irq(client->irq, NULL,
 | 
							ret = request_threaded_irq(client->irq, NULL,
 | 
				
			||||||
			max98095_report_jack,
 | 
								max98095_report_jack,
 | 
				
			||||||
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
 | 
								IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
 | 
				
			||||||
			"max98095", codec);
 | 
								IRQF_ONESHOT, "max98095", codec);
 | 
				
			||||||
		if (ret) {
 | 
							if (ret) {
 | 
				
			||||||
			dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
 | 
								dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
 | 
				
			||||||
			goto err_access;
 | 
								goto err_access;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,13 +60,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct gpio_desc *sdmode;
 | 
						struct gpio_desc *sdmode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sdmode = devm_gpiod_get(codec->dev, "sdmode");
 | 
						sdmode = devm_gpiod_get(codec->dev, "sdmode", GPIOD_OUT_LOW);
 | 
				
			||||||
	if (IS_ERR(sdmode)) {
 | 
						if (IS_ERR(sdmode)) {
 | 
				
			||||||
		dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n",
 | 
							dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n",
 | 
				
			||||||
				__func__, PTR_ERR(sdmode));
 | 
									__func__, PTR_ERR(sdmode));
 | 
				
			||||||
		return PTR_ERR(sdmode);
 | 
							return PTR_ERR(sdmode);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gpiod_direction_output(sdmode, 0);
 | 
					 | 
				
			||||||
	snd_soc_codec_set_drvdata(codec, sdmode);
 | 
						snd_soc_codec_set_drvdata(codec, sdmode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,7 +252,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regcache_sync(max9850->regmap);
 | 
								ret = regcache_sync(max9850->regmap);
 | 
				
			||||||
			if (ret) {
 | 
								if (ret) {
 | 
				
			||||||
				dev_err(codec->dev,
 | 
									dev_err(codec->dev,
 | 
				
			||||||
| 
						 | 
					@ -264,7 +264,6 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -523,7 +523,7 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		/* VMID ON */
 | 
							/* VMID ON */
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
 | 
								snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
 | 
				
			||||||
					    ML26124_VMID, ML26124_VMID);
 | 
										    ML26124_VMID, ML26124_VMID);
 | 
				
			||||||
			msleep(500);
 | 
								msleep(500);
 | 
				
			||||||
| 
						 | 
					@ -536,7 +536,6 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				    ML26124_VMID, 0);
 | 
									    ML26124_VMID, 0);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,7 +242,7 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
						struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
				
			||||||
	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
						struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (codec->dapm.bias_level) {
 | 
						switch (snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -270,7 +270,7 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
						struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
				
			||||||
	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
						struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (codec->dapm.bias_level) {
 | 
						switch (snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -298,7 +298,7 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
						struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
 | 
				
			||||||
	struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
						struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (codec->dapm.bias_level) {
 | 
						switch (snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -641,8 +641,6 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,6 +301,7 @@ static int rt286_support_power_controls[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 | 
					static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm;
 | 
				
			||||||
	unsigned int val, buf;
 | 
						unsigned int val, buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*hp = false;
 | 
						*hp = false;
 | 
				
			||||||
| 
						 | 
					@ -308,6 +309,9 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!rt286->codec)
 | 
						if (!rt286->codec)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dapm = snd_soc_codec_get_dapm(rt286->codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rt286->pdata.cbj_en) {
 | 
						if (rt286->pdata.cbj_en) {
 | 
				
			||||||
		regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
 | 
							regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
 | 
				
			||||||
		*hp = buf & 0x80000000;
 | 
							*hp = buf & 0x80000000;
 | 
				
			||||||
| 
						 | 
					@ -316,14 +320,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 | 
				
			||||||
			regmap_update_bits(rt286->regmap,
 | 
								regmap_update_bits(rt286->regmap,
 | 
				
			||||||
				RT286_DC_GAIN, 0x200, 0x200);
 | 
									RT286_DC_GAIN, 0x200, 0x200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
 | 
								snd_soc_dapm_force_enable_pin(dapm, "HV");
 | 
				
			||||||
							"HV");
 | 
								snd_soc_dapm_force_enable_pin(dapm, "VREF");
 | 
				
			||||||
			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
 | 
					 | 
				
			||||||
							"VREF");
 | 
					 | 
				
			||||||
			/* power LDO1 */
 | 
								/* power LDO1 */
 | 
				
			||||||
			snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
 | 
								snd_soc_dapm_force_enable_pin(dapm, "LDO1");
 | 
				
			||||||
							"LDO1");
 | 
								snd_soc_dapm_sync(dapm);
 | 
				
			||||||
			snd_soc_dapm_sync(&rt286->codec->dapm);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
 | 
								regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
 | 
				
			||||||
			msleep(50);
 | 
								msleep(50);
 | 
				
			||||||
| 
						 | 
					@ -360,11 +361,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
 | 
				
			||||||
		*mic = buf & 0x80000000;
 | 
							*mic = buf & 0x80000000;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV");
 | 
						snd_soc_dapm_disable_pin(dapm, "HV");
 | 
				
			||||||
	snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF");
 | 
						snd_soc_dapm_disable_pin(dapm, "VREF");
 | 
				
			||||||
	if (!*hp)
 | 
						if (!*hp)
 | 
				
			||||||
		snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1");
 | 
							snd_soc_dapm_disable_pin(dapm, "LDO1");
 | 
				
			||||||
	snd_soc_dapm_sync(&rt286->codec->dapm);
 | 
						snd_soc_dapm_sync(dapm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -391,6 +392,7 @@ static void rt286_jack_detect_work(struct work_struct *work)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 | 
					int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt286->jack = jack;
 | 
						rt286->jack = jack;
 | 
				
			||||||
| 
						 | 
					@ -398,7 +400,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 | 
				
			||||||
	if (jack) {
 | 
						if (jack) {
 | 
				
			||||||
		/* enable IRQ */
 | 
							/* enable IRQ */
 | 
				
			||||||
		if (rt286->jack->status & SND_JACK_HEADPHONE)
 | 
							if (rt286->jack->status & SND_JACK_HEADPHONE)
 | 
				
			||||||
			snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1");
 | 
								snd_soc_dapm_force_enable_pin(dapm, "LDO1");
 | 
				
			||||||
		regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
 | 
							regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
 | 
				
			||||||
		/* Send an initial empty report */
 | 
							/* Send an initial empty report */
 | 
				
			||||||
		snd_soc_jack_report(rt286->jack, rt286->jack->status,
 | 
							snd_soc_jack_report(rt286->jack, rt286->jack->status,
 | 
				
			||||||
| 
						 | 
					@ -406,9 +408,9 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* disable IRQ */
 | 
							/* disable IRQ */
 | 
				
			||||||
		regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0);
 | 
							regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0);
 | 
				
			||||||
		snd_soc_dapm_disable_pin(&codec->dapm, "LDO1");
 | 
							snd_soc_dapm_disable_pin(dapm, "LDO1");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	snd_soc_dapm_sync(&codec->dapm);
 | 
						snd_soc_dapm_sync(dapm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -985,7 +987,7 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (level) {
 | 
						switch (level) {
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
 | 
							if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
			snd_soc_write(codec,
 | 
								snd_soc_write(codec,
 | 
				
			||||||
				RT286_SET_AUDIO_POWER, AC_PWRST_D0);
 | 
									RT286_SET_AUDIO_POWER, AC_PWRST_D0);
 | 
				
			||||||
			snd_soc_update_bits(codec,
 | 
								snd_soc_update_bits(codec,
 | 
				
			||||||
| 
						 | 
					@ -1012,7 +1014,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1546,7 +1546,7 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
 | 
								snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
 | 
				
			||||||
				RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
 | 
									RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
 | 
				
			||||||
				RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
 | 
									RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
 | 
				
			||||||
| 
						 | 
					@ -1569,7 +1569,6 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1615,7 +1614,7 @@ static int rt5631_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
			RT5631_DMIC_R_CH_LATCH_RISING);
 | 
								RT5631_DMIC_R_CH_LATCH_RISING);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
 | 
						snd_soc_codec_init_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1870,7 +1870,7 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (level) {
 | 
						switch (level) {
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
 | 
							if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
			snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
 | 
								snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
 | 
				
			||||||
				RT5640_PWR_VREF1 | RT5640_PWR_MB |
 | 
									RT5640_PWR_VREF1 | RT5640_PWR_MB |
 | 
				
			||||||
				RT5640_PWR_BG | RT5640_PWR_VREF2,
 | 
									RT5640_PWR_BG | RT5640_PWR_VREF2,
 | 
				
			||||||
| 
						 | 
					@ -1902,7 +1902,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1935,11 +1934,12 @@ EXPORT_SYMBOL_GPL(rt5640_dmic_enable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rt5640_probe(struct snd_soc_codec *codec)
 | 
					static int rt5640_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5640->codec = codec;
 | 
						rt5640->codec = codec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
 | 
						snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
 | 
				
			||||||
	snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
 | 
						snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
 | 
				
			||||||
| 
						 | 
					@ -1951,18 +1951,18 @@ static int rt5640_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		snd_soc_add_codec_controls(codec,
 | 
							snd_soc_add_codec_controls(codec,
 | 
				
			||||||
			rt5640_specific_snd_controls,
 | 
								rt5640_specific_snd_controls,
 | 
				
			||||||
			ARRAY_SIZE(rt5640_specific_snd_controls));
 | 
								ARRAY_SIZE(rt5640_specific_snd_controls));
 | 
				
			||||||
		snd_soc_dapm_new_controls(&codec->dapm,
 | 
							snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			rt5640_specific_dapm_widgets,
 | 
								rt5640_specific_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(rt5640_specific_dapm_widgets));
 | 
								ARRAY_SIZE(rt5640_specific_dapm_widgets));
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5640_specific_dapm_routes,
 | 
								rt5640_specific_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(rt5640_specific_dapm_routes));
 | 
								ARRAY_SIZE(rt5640_specific_dapm_routes));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case RT5640_ID_5639:
 | 
						case RT5640_ID_5639:
 | 
				
			||||||
		snd_soc_dapm_new_controls(&codec->dapm,
 | 
							snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			rt5639_specific_dapm_widgets,
 | 
								rt5639_specific_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(rt5639_specific_dapm_widgets));
 | 
								ARRAY_SIZE(rt5639_specific_dapm_widgets));
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5639_specific_dapm_routes,
 | 
								rt5639_specific_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(rt5639_specific_dapm_routes));
 | 
								ARRAY_SIZE(rt5639_specific_dapm_routes));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					@ -1991,7 +1991,7 @@ static int rt5640_suspend(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
				
			||||||
	rt5640_reset(codec);
 | 
						rt5640_reset(codec);
 | 
				
			||||||
	regcache_cache_only(rt5640->regmap, true);
 | 
						regcache_cache_only(rt5640->regmap, true);
 | 
				
			||||||
	regcache_mark_dirty(rt5640->regmap);
 | 
						regcache_mark_dirty(rt5640->regmap);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -105,6 +105,7 @@
 | 
				
			||||||
#define RT5645_TDM_CTRL_1			0x77
 | 
					#define RT5645_TDM_CTRL_1			0x77
 | 
				
			||||||
#define RT5645_TDM_CTRL_2			0x78
 | 
					#define RT5645_TDM_CTRL_2			0x78
 | 
				
			||||||
#define RT5645_TDM_CTRL_3			0x79
 | 
					#define RT5645_TDM_CTRL_3			0x79
 | 
				
			||||||
 | 
					#define RT5650_TDM_CTRL_4			0x7a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Function - Analog */
 | 
					/* Function - Analog */
 | 
				
			||||||
#define RT5645_GLB_CLK				0x80
 | 
					#define RT5645_GLB_CLK				0x80
 | 
				
			||||||
| 
						 | 
					@ -942,10 +943,6 @@
 | 
				
			||||||
#define RT5645_I2S2_SDI_I2S2			(0x1 << 6)
 | 
					#define RT5645_I2S2_SDI_I2S2			(0x1 << 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ADC/DAC Clock Control 1 (0x73) */
 | 
					/* ADC/DAC Clock Control 1 (0x73) */
 | 
				
			||||||
#define RT5645_I2S_BCLK_MS1_MASK		(0x1 << 15)
 | 
					 | 
				
			||||||
#define RT5645_I2S_BCLK_MS1_SFT			15
 | 
					 | 
				
			||||||
#define RT5645_I2S_BCLK_MS1_32			(0x0 << 15)
 | 
					 | 
				
			||||||
#define RT5645_I2S_BCLK_MS1_64			(0x1 << 15)
 | 
					 | 
				
			||||||
#define RT5645_I2S_PD1_MASK			(0x7 << 12)
 | 
					#define RT5645_I2S_PD1_MASK			(0x7 << 12)
 | 
				
			||||||
#define RT5645_I2S_PD1_SFT			12
 | 
					#define RT5645_I2S_PD1_SFT			12
 | 
				
			||||||
#define RT5645_I2S_PD1_1			(0x0 << 12)
 | 
					#define RT5645_I2S_PD1_1			(0x0 << 12)
 | 
				
			||||||
| 
						 | 
					@ -1067,13 +1064,14 @@
 | 
				
			||||||
#define RT5645_SCLK_SRC_SFT			14
 | 
					#define RT5645_SCLK_SRC_SFT			14
 | 
				
			||||||
#define RT5645_SCLK_SRC_MCLK			(0x0 << 14)
 | 
					#define RT5645_SCLK_SRC_MCLK			(0x0 << 14)
 | 
				
			||||||
#define RT5645_SCLK_SRC_PLL1			(0x1 << 14)
 | 
					#define RT5645_SCLK_SRC_PLL1			(0x1 << 14)
 | 
				
			||||||
#define RT5645_SCLK_SRC_RCCLK			(0x2 << 14) /* 15MHz */
 | 
					#define RT5645_SCLK_SRC_RCCLK			(0x2 << 14)
 | 
				
			||||||
#define RT5645_PLL1_SRC_MASK			(0x3 << 12)
 | 
					#define RT5645_PLL1_SRC_MASK			(0x7 << 11)
 | 
				
			||||||
#define RT5645_PLL1_SRC_SFT			12
 | 
					#define RT5645_PLL1_SRC_SFT			11
 | 
				
			||||||
#define RT5645_PLL1_SRC_MCLK			(0x0 << 12)
 | 
					#define RT5645_PLL1_SRC_MCLK			(0x0 << 11)
 | 
				
			||||||
#define RT5645_PLL1_SRC_BCLK1			(0x1 << 12)
 | 
					#define RT5645_PLL1_SRC_BCLK1			(0x1 << 11)
 | 
				
			||||||
#define RT5645_PLL1_SRC_BCLK2			(0x2 << 12)
 | 
					#define RT5645_PLL1_SRC_BCLK2			(0x2 << 11)
 | 
				
			||||||
#define RT5645_PLL1_SRC_BCLK3			(0x3 << 12)
 | 
					#define RT5645_PLL1_SRC_BCLK3			(0x3 << 11)
 | 
				
			||||||
 | 
					#define RT5645_PLL1_SRC_RCCLK			(0x4 << 11)
 | 
				
			||||||
#define RT5645_PLL1_PD_MASK			(0x1 << 3)
 | 
					#define RT5645_PLL1_PD_MASK			(0x1 << 3)
 | 
				
			||||||
#define RT5645_PLL1_PD_SFT			3
 | 
					#define RT5645_PLL1_PD_SFT			3
 | 
				
			||||||
#define RT5645_PLL1_PD_1			(0x0 << 3)
 | 
					#define RT5645_PLL1_PD_1			(0x0 << 3)
 | 
				
			||||||
| 
						 | 
					@ -2147,6 +2145,7 @@ enum {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
 | 
						RT5645_DMIC1_DISABLE,
 | 
				
			||||||
	RT5645_DMIC_DATA_IN2P,
 | 
						RT5645_DMIC_DATA_IN2P,
 | 
				
			||||||
	RT5645_DMIC_DATA_GPIO6,
 | 
						RT5645_DMIC_DATA_GPIO6,
 | 
				
			||||||
	RT5645_DMIC_DATA_GPIO10,
 | 
						RT5645_DMIC_DATA_GPIO10,
 | 
				
			||||||
| 
						 | 
					@ -2154,6 +2153,7 @@ enum {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
 | 
						RT5645_DMIC2_DISABLE,
 | 
				
			||||||
	RT5645_DMIC_DATA_IN2N,
 | 
						RT5645_DMIC_DATA_IN2N,
 | 
				
			||||||
	RT5645_DMIC_DATA_GPIO5,
 | 
						RT5645_DMIC_DATA_GPIO5,
 | 
				
			||||||
	RT5645_DMIC_DATA_GPIO11,
 | 
						RT5645_DMIC_DATA_GPIO11,
 | 
				
			||||||
| 
						 | 
					@ -2184,6 +2184,7 @@ struct rt5645_priv {
 | 
				
			||||||
	struct i2c_client *i2c;
 | 
						struct i2c_client *i2c;
 | 
				
			||||||
	struct snd_soc_jack *hp_jack;
 | 
						struct snd_soc_jack *hp_jack;
 | 
				
			||||||
	struct snd_soc_jack *mic_jack;
 | 
						struct snd_soc_jack *mic_jack;
 | 
				
			||||||
 | 
						struct snd_soc_jack *btn_jack;
 | 
				
			||||||
	struct delayed_work jack_detect_work;
 | 
						struct delayed_work jack_detect_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int codec_type;
 | 
						int codec_type;
 | 
				
			||||||
| 
						 | 
					@ -2196,9 +2197,12 @@ struct rt5645_priv {
 | 
				
			||||||
	int pll_src;
 | 
						int pll_src;
 | 
				
			||||||
	int pll_in;
 | 
						int pll_in;
 | 
				
			||||||
	int pll_out;
 | 
						int pll_out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int jack_type;
 | 
				
			||||||
 | 
						bool en_button_func;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rt5645_set_jack_detect(struct snd_soc_codec *codec,
 | 
					int rt5645_set_jack_detect(struct snd_soc_codec *codec,
 | 
				
			||||||
	struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
 | 
						struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
 | 
				
			||||||
 | 
						struct snd_soc_jack *btn_jack);
 | 
				
			||||||
#endif /* __RT5645_H__ */
 | 
					#endif /* __RT5645_H__ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1571,7 +1571,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch (level) {
 | 
						switch (level) {
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
 | 
							if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
			snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
 | 
								snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
 | 
				
			||||||
				RT5651_PWR_VREF1 | RT5651_PWR_MB |
 | 
									RT5651_PWR_VREF1 | RT5651_PWR_MB |
 | 
				
			||||||
				RT5651_PWR_BG | RT5651_PWR_VREF2,
 | 
									RT5651_PWR_BG | RT5651_PWR_VREF2,
 | 
				
			||||||
| 
						 | 
					@ -1604,7 +1604,6 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1625,7 +1624,7 @@ static int rt5651_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		RT5651_PWR_FV1 | RT5651_PWR_FV2,
 | 
							RT5651_PWR_FV1 | RT5651_PWR_FV2,
 | 
				
			||||||
		RT5651_PWR_FV1 | RT5651_PWR_FV2);
 | 
							RT5651_PWR_FV1 | RT5651_PWR_FV2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5651_set_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -416,12 +416,12 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
 | 
				
			||||||
static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 | 
					static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (jack_insert) {
 | 
						if (jack_insert) {
 | 
				
			||||||
		snd_soc_dapm_force_enable_pin(&codec->dapm,
 | 
							snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
 | 
				
			||||||
						       "Mic Det Power");
 | 
							snd_soc_dapm_sync(dapm);
 | 
				
			||||||
		snd_soc_dapm_sync(&codec->dapm);
 | 
					 | 
				
			||||||
		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
 | 
							snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
 | 
				
			||||||
		snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
 | 
							snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
 | 
				
			||||||
			RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
 | 
								RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
 | 
				
			||||||
| 
						 | 
					@ -447,15 +447,15 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
 | 
								snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
 | 
				
			||||||
			rt5670->jack_type = SND_JACK_HEADPHONE;
 | 
								rt5670->jack_type = SND_JACK_HEADPHONE;
 | 
				
			||||||
			snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
 | 
								snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 | 
				
			||||||
			snd_soc_dapm_sync(&codec->dapm);
 | 
								snd_soc_dapm_sync(dapm);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
 | 
							snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
 | 
				
			||||||
		snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
 | 
							snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
 | 
				
			||||||
		rt5670->jack_type = 0;
 | 
							rt5670->jack_type = 0;
 | 
				
			||||||
		snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
 | 
							snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
 | 
				
			||||||
		snd_soc_dapm_sync(&codec->dapm);
 | 
							snd_soc_dapm_sync(dapm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rt5670->jack_type;
 | 
						return rt5670->jack_type;
 | 
				
			||||||
| 
						 | 
					@ -2603,7 +2603,7 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (level) {
 | 
						switch (level) {
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) {
 | 
							if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
			snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
 | 
								snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
 | 
				
			||||||
				RT5670_PWR_VREF1 | RT5670_PWR_MB |
 | 
									RT5670_PWR_VREF1 | RT5670_PWR_MB |
 | 
				
			||||||
				RT5670_PWR_BG | RT5670_PWR_VREF2,
 | 
									RT5670_PWR_BG | RT5670_PWR_VREF2,
 | 
				
			||||||
| 
						 | 
					@ -2647,30 +2647,30 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rt5670_probe(struct snd_soc_codec *codec)
 | 
					static int rt5670_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
 | 
						switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
 | 
				
			||||||
	case RT5670_ID_5670:
 | 
						case RT5670_ID_5670:
 | 
				
			||||||
	case RT5670_ID_5671:
 | 
						case RT5670_ID_5671:
 | 
				
			||||||
		snd_soc_dapm_new_controls(&codec->dapm,
 | 
							snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			rt5670_specific_dapm_widgets,
 | 
								rt5670_specific_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(rt5670_specific_dapm_widgets));
 | 
								ARRAY_SIZE(rt5670_specific_dapm_widgets));
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5670_specific_dapm_routes,
 | 
								rt5670_specific_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(rt5670_specific_dapm_routes));
 | 
								ARRAY_SIZE(rt5670_specific_dapm_routes));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case RT5670_ID_5672:
 | 
						case RT5670_ID_5672:
 | 
				
			||||||
		snd_soc_dapm_new_controls(&codec->dapm,
 | 
							snd_soc_dapm_new_controls(dapm,
 | 
				
			||||||
			rt5672_specific_dapm_widgets,
 | 
								rt5672_specific_dapm_widgets,
 | 
				
			||||||
			ARRAY_SIZE(rt5672_specific_dapm_widgets));
 | 
								ARRAY_SIZE(rt5672_specific_dapm_widgets));
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5672_specific_dapm_routes,
 | 
								rt5672_specific_dapm_routes,
 | 
				
			||||||
			ARRAY_SIZE(rt5672_specific_dapm_routes));
 | 
								ARRAY_SIZE(rt5672_specific_dapm_routes));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -820,7 +820,7 @@ static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
 | 
						rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
						if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
		rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en);
 | 
							rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -1060,6 +1060,7 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
 | 
				
			||||||
	unsigned int asrc5_mask = 0, asrc5_value = 0;
 | 
						unsigned int asrc5_mask = 0, asrc5_value = 0;
 | 
				
			||||||
	unsigned int asrc6_mask = 0, asrc6_value = 0;
 | 
						unsigned int asrc6_mask = 0, asrc6_value = 0;
 | 
				
			||||||
	unsigned int asrc7_mask = 0, asrc7_value = 0;
 | 
						unsigned int asrc7_mask = 0, asrc7_value = 0;
 | 
				
			||||||
 | 
						unsigned int asrc8_mask = 0, asrc8_value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (clk_src) {
 | 
						switch (clk_src) {
 | 
				
			||||||
	case RT5677_CLK_SEL_SYS:
 | 
						case RT5677_CLK_SEL_SYS:
 | 
				
			||||||
| 
						 | 
					@ -1196,10 +1197,108 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
 | 
				
			||||||
		regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask,
 | 
							regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask,
 | 
				
			||||||
			asrc7_value);
 | 
								asrc7_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* ASRC 8 */
 | 
				
			||||||
 | 
						if (filter_mask & RT5677_I2S1_SOURCE) {
 | 
				
			||||||
 | 
							asrc8_mask |= RT5677_I2S1_CLK_SEL_MASK;
 | 
				
			||||||
 | 
							asrc8_value = (asrc8_value & ~RT5677_I2S1_CLK_SEL_MASK)
 | 
				
			||||||
 | 
								| ((clk_src - 1) << RT5677_I2S1_CLK_SEL_SFT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (filter_mask & RT5677_I2S2_SOURCE) {
 | 
				
			||||||
 | 
							asrc8_mask |= RT5677_I2S2_CLK_SEL_MASK;
 | 
				
			||||||
 | 
							asrc8_value = (asrc8_value & ~RT5677_I2S2_CLK_SEL_MASK)
 | 
				
			||||||
 | 
								| ((clk_src - 1) << RT5677_I2S2_CLK_SEL_SFT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (filter_mask & RT5677_I2S3_SOURCE) {
 | 
				
			||||||
 | 
							asrc8_mask |= RT5677_I2S3_CLK_SEL_MASK;
 | 
				
			||||||
 | 
							asrc8_value = (asrc8_value & ~RT5677_I2S3_CLK_SEL_MASK)
 | 
				
			||||||
 | 
								| ((clk_src - 1) << RT5677_I2S3_CLK_SEL_SFT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (filter_mask & RT5677_I2S4_SOURCE) {
 | 
				
			||||||
 | 
							asrc8_mask |= RT5677_I2S4_CLK_SEL_MASK;
 | 
				
			||||||
 | 
							asrc8_value = (asrc8_value & ~RT5677_I2S4_CLK_SEL_MASK)
 | 
				
			||||||
 | 
								| ((clk_src - 1) << RT5677_I2S4_CLK_SEL_SFT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (asrc8_mask)
 | 
				
			||||||
 | 
							regmap_update_bits(rt5677->regmap, RT5677_ASRC_8, asrc8_mask,
 | 
				
			||||||
 | 
								asrc8_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
 | 
					EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source,
 | 
				
			||||||
 | 
								 struct snd_soc_dapm_widget *sink)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
 | 
				
			||||||
 | 
						struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						unsigned int asrc_setting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (source->shift) {
 | 
				
			||||||
 | 
						case 11:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_STO1_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
									RT5677_AD_STO1_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 10:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_STO2_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
									RT5677_AD_STO2_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 9:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_STO3_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
									RT5677_AD_STO3_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 8:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_STO4_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
								RT5677_AD_STO4_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 7:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_MONOL_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
								RT5677_AD_MONOL_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case 6:
 | 
				
			||||||
 | 
							regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting);
 | 
				
			||||||
 | 
							asrc_setting = (asrc_setting & RT5677_AD_MONOR_CLK_SEL_MASK) >>
 | 
				
			||||||
 | 
								RT5677_AD_MONOR_CLK_SEL_SFT;
 | 
				
			||||||
 | 
							if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
 | 
				
			||||||
 | 
								asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Digital Mixer */
 | 
					/* Digital Mixer */
 | 
				
			||||||
static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
 | 
					static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
 | 
				
			||||||
	SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
 | 
						SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
 | 
				
			||||||
| 
						 | 
					@ -2479,7 +2578,7 @@ static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (event) {
 | 
						switch (event) {
 | 
				
			||||||
	case SND_SOC_DAPM_POST_PMU:
 | 
						case SND_SOC_DAPM_POST_PMU:
 | 
				
			||||||
		if (codec->dapm.bias_level != SND_SOC_BIAS_ON &&
 | 
							if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_ON &&
 | 
				
			||||||
			!rt5677->is_vref_slow) {
 | 
								!rt5677->is_vref_slow) {
 | 
				
			||||||
			mdelay(20);
 | 
								mdelay(20);
 | 
				
			||||||
			regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
 | 
								regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
 | 
				
			||||||
| 
						 | 
					@ -3057,12 +3156,12 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 | 
					static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
 | 
				
			||||||
	{ "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc },
 | 
						{ "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc },
 | 
						{ "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc },
 | 
						{ "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc },
 | 
						{ "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc },
 | 
						{ "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc },
 | 
						{ "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", rt5677_dmic_use_asrc },
 | 
				
			||||||
	{ "I2S1", NULL, "I2S1 ASRC", can_use_asrc},
 | 
						{ "I2S1", NULL, "I2S1 ASRC", can_use_asrc},
 | 
				
			||||||
	{ "I2S2", NULL, "I2S2 ASRC", can_use_asrc},
 | 
						{ "I2S2", NULL, "I2S2 ASRC", can_use_asrc},
 | 
				
			||||||
	{ "I2S3", NULL, "I2S3 ASRC", can_use_asrc},
 | 
						{ "I2S3", NULL, "I2S3 ASRC", can_use_asrc},
 | 
				
			||||||
| 
						 | 
					@ -4353,7 +4452,7 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
 | 
				
			||||||
			rt5677_set_dsp_vad(codec, false);
 | 
								rt5677_set_dsp_vad(codec, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
 | 
								regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
 | 
				
			||||||
| 
						 | 
					@ -4395,7 +4494,6 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4606,22 +4704,23 @@ static void rt5677_free_gpio(struct i2c_client *i2c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rt5677_probe(struct snd_soc_codec *codec)
 | 
					static int rt5677_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5677->codec = codec;
 | 
						rt5677->codec = codec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
 | 
						if (rt5677->pdata.dmic2_clk_pin == RT5677_DMIC_CLK2) {
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5677_dmic2_clk_2,
 | 
								rt5677_dmic2_clk_2,
 | 
				
			||||||
			ARRAY_SIZE(rt5677_dmic2_clk_2));
 | 
								ARRAY_SIZE(rt5677_dmic2_clk_2));
 | 
				
			||||||
	} else { /*use dmic1 clock by default*/
 | 
						} else { /*use dmic1 clock by default*/
 | 
				
			||||||
		snd_soc_dapm_add_routes(&codec->dapm,
 | 
							snd_soc_dapm_add_routes(dapm,
 | 
				
			||||||
			rt5677_dmic2_clk_1,
 | 
								rt5677_dmic2_clk_1,
 | 
				
			||||||
			ARRAY_SIZE(rt5677_dmic2_clk_1));
 | 
								ARRAY_SIZE(rt5677_dmic2_clk_1));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5677_set_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
 | 
						regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
 | 
				
			||||||
	regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
 | 
						regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
 | 
				
			||||||
| 
						 | 
					@ -4667,6 +4766,8 @@ static int rt5677_remove(struct snd_soc_codec *codec)
 | 
				
			||||||
	regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
 | 
						regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
 | 
				
			||||||
	if (gpio_is_valid(rt5677->pow_ldo2))
 | 
						if (gpio_is_valid(rt5677->pow_ldo2))
 | 
				
			||||||
		gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
 | 
							gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
 | 
				
			||||||
 | 
						if (gpio_is_valid(rt5677->reset_pin))
 | 
				
			||||||
 | 
							gpio_set_value_cansleep(rt5677->reset_pin, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4682,6 +4783,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (gpio_is_valid(rt5677->pow_ldo2))
 | 
							if (gpio_is_valid(rt5677->pow_ldo2))
 | 
				
			||||||
			gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
 | 
								gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
 | 
				
			||||||
 | 
							if (gpio_is_valid(rt5677->reset_pin))
 | 
				
			||||||
 | 
								gpio_set_value_cansleep(rt5677->reset_pin, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					@ -4692,10 +4795,13 @@ static int rt5677_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
	struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
 | 
						struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!rt5677->dsp_vad_en) {
 | 
						if (!rt5677->dsp_vad_en) {
 | 
				
			||||||
		if (gpio_is_valid(rt5677->pow_ldo2)) {
 | 
							if (gpio_is_valid(rt5677->pow_ldo2))
 | 
				
			||||||
			gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
 | 
								gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
 | 
				
			||||||
 | 
							if (gpio_is_valid(rt5677->reset_pin))
 | 
				
			||||||
 | 
								gpio_set_value_cansleep(rt5677->reset_pin, 1);
 | 
				
			||||||
 | 
							if (gpio_is_valid(rt5677->pow_ldo2) ||
 | 
				
			||||||
 | 
							    gpio_is_valid(rt5677->reset_pin))
 | 
				
			||||||
			msleep(10);
 | 
								msleep(10);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		regcache_cache_only(rt5677->regmap, false);
 | 
							regcache_cache_only(rt5677->regmap, false);
 | 
				
			||||||
		regcache_sync(rt5677->regmap);
 | 
							regcache_sync(rt5677->regmap);
 | 
				
			||||||
| 
						 | 
					@ -4933,6 +5039,8 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rt5677->pow_ldo2 = of_get_named_gpio(np,
 | 
						rt5677->pow_ldo2 = of_get_named_gpio(np,
 | 
				
			||||||
					"realtek,pow-ldo2-gpio", 0);
 | 
										"realtek,pow-ldo2-gpio", 0);
 | 
				
			||||||
 | 
						rt5677->reset_pin = of_get_named_gpio(np,
 | 
				
			||||||
 | 
										"realtek,reset-gpio", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * POW_LDO2 is optional (it may be statically tied on the board).
 | 
						 * POW_LDO2 is optional (it may be statically tied on the board).
 | 
				
			||||||
| 
						 | 
					@ -4943,6 +5051,9 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 | 
				
			||||||
	if (!gpio_is_valid(rt5677->pow_ldo2) &&
 | 
						if (!gpio_is_valid(rt5677->pow_ldo2) &&
 | 
				
			||||||
			(rt5677->pow_ldo2 != -ENOENT))
 | 
								(rt5677->pow_ldo2 != -ENOENT))
 | 
				
			||||||
		return rt5677->pow_ldo2;
 | 
							return rt5677->pow_ldo2;
 | 
				
			||||||
 | 
						if (!gpio_is_valid(rt5677->reset_pin) &&
 | 
				
			||||||
 | 
								(rt5677->reset_pin != -ENOENT))
 | 
				
			||||||
 | 
							return rt5677->reset_pin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	of_property_read_u8_array(np, "realtek,gpio-config",
 | 
						of_property_read_u8_array(np, "realtek,gpio-config",
 | 
				
			||||||
		rt5677->pdata.gpio_config, RT5677_GPIO_NUM);
 | 
							rt5677->pdata.gpio_config, RT5677_GPIO_NUM);
 | 
				
			||||||
| 
						 | 
					@ -5044,6 +5155,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		rt5677->pow_ldo2 = -EINVAL;
 | 
							rt5677->pow_ldo2 = -EINVAL;
 | 
				
			||||||
 | 
							rt5677->reset_pin = -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (gpio_is_valid(rt5677->pow_ldo2)) {
 | 
						if (gpio_is_valid(rt5677->pow_ldo2)) {
 | 
				
			||||||
| 
						 | 
					@ -5055,6 +5167,21 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
				rt5677->pow_ldo2, ret);
 | 
									rt5677->pow_ldo2, ret);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gpio_is_valid(rt5677->reset_pin)) {
 | 
				
			||||||
 | 
							ret = devm_gpio_request_one(&i2c->dev, rt5677->reset_pin,
 | 
				
			||||||
 | 
										    GPIOF_OUT_INIT_HIGH,
 | 
				
			||||||
 | 
										    "RT5677 RESET");
 | 
				
			||||||
 | 
							if (ret < 0) {
 | 
				
			||||||
 | 
								dev_err(&i2c->dev, "Failed to request RESET %d: %d\n",
 | 
				
			||||||
 | 
									rt5677->reset_pin, ret);
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gpio_is_valid(rt5677->pow_ldo2) ||
 | 
				
			||||||
 | 
						    gpio_is_valid(rt5677->reset_pin)) {
 | 
				
			||||||
		/* Wait a while until I2C bus becomes available. The datasheet
 | 
							/* Wait a while until I2C bus becomes available. The datasheet
 | 
				
			||||||
		 * does not specify the exact we should wait but startup
 | 
							 * does not specify the exact we should wait but startup
 | 
				
			||||||
		 * sequence mentiones at least a few milliseconds.
 | 
							 * sequence mentiones at least a few milliseconds.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1446,6 +1446,16 @@
 | 
				
			||||||
#define RT5677_DSP_OB_4_7_CLK_SEL_MASK		(0xf << 8)
 | 
					#define RT5677_DSP_OB_4_7_CLK_SEL_MASK		(0xf << 8)
 | 
				
			||||||
#define RT5677_DSP_OB_4_7_CLK_SEL_SFT		8
 | 
					#define RT5677_DSP_OB_4_7_CLK_SEL_SFT		8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ASRC Control 8 (0x8a) */
 | 
				
			||||||
 | 
					#define RT5677_I2S1_CLK_SEL_MASK		(0xf << 12)
 | 
				
			||||||
 | 
					#define RT5677_I2S1_CLK_SEL_SFT			12
 | 
				
			||||||
 | 
					#define RT5677_I2S2_CLK_SEL_MASK		(0xf << 8)
 | 
				
			||||||
 | 
					#define RT5677_I2S2_CLK_SEL_SFT			8
 | 
				
			||||||
 | 
					#define RT5677_I2S3_CLK_SEL_MASK		(0xf << 4)
 | 
				
			||||||
 | 
					#define RT5677_I2S3_CLK_SEL_SFT			4
 | 
				
			||||||
 | 
					#define RT5677_I2S4_CLK_SEL_MASK		(0xf)
 | 
				
			||||||
 | 
					#define RT5677_I2S4_CLK_SEL_SFT			0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* VAD Function Control 4 (0x9f) */
 | 
					/* VAD Function Control 4 (0x9f) */
 | 
				
			||||||
#define RT5677_VAD_SRC_MASK			(0x7 << 8)
 | 
					#define RT5677_VAD_SRC_MASK			(0x7 << 8)
 | 
				
			||||||
#define RT5677_VAD_SRC_SFT			8
 | 
					#define RT5677_VAD_SRC_SFT			8
 | 
				
			||||||
| 
						 | 
					@ -1744,6 +1754,10 @@ enum {
 | 
				
			||||||
	RT5677_AD_MONO_R_FILTER = (0x1 << 12),
 | 
						RT5677_AD_MONO_R_FILTER = (0x1 << 12),
 | 
				
			||||||
	RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
 | 
						RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
 | 
				
			||||||
	RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
 | 
						RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
 | 
				
			||||||
 | 
						RT5677_I2S1_SOURCE = (0x1 << 15),
 | 
				
			||||||
 | 
						RT5677_I2S2_SOURCE = (0x1 << 16),
 | 
				
			||||||
 | 
						RT5677_I2S3_SOURCE = (0x1 << 17),
 | 
				
			||||||
 | 
						RT5677_I2S4_SOURCE = (0x1 << 18),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rt5677_priv {
 | 
					struct rt5677_priv {
 | 
				
			||||||
| 
						 | 
					@ -1762,6 +1776,7 @@ struct rt5677_priv {
 | 
				
			||||||
	int pll_in;
 | 
						int pll_in;
 | 
				
			||||||
	int pll_out;
 | 
						int pll_out;
 | 
				
			||||||
	int pow_ldo2; /* POW_LDO2 pin */
 | 
						int pow_ldo2; /* POW_LDO2 pin */
 | 
				
			||||||
 | 
						int reset_pin; /* RESET pin */
 | 
				
			||||||
	enum rt5677_type type;
 | 
						enum rt5677_type type;
 | 
				
			||||||
#ifdef CONFIG_GPIOLIB
 | 
					#ifdef CONFIG_GPIOLIB
 | 
				
			||||||
	struct gpio_chip gpio_chip;
 | 
						struct gpio_chip gpio_chip;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -948,7 +948,7 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regulator_bulk_enable(
 | 
								ret = regulator_bulk_enable(
 | 
				
			||||||
						ARRAY_SIZE(sgtl5000->supplies),
 | 
											ARRAY_SIZE(sgtl5000->supplies),
 | 
				
			||||||
						sgtl5000->supplies);
 | 
											sgtl5000->supplies);
 | 
				
			||||||
| 
						 | 
					@ -979,7 +979,6 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1091,6 +1090,19 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This precalculated table contains all (vag_val * 100 / lo_calcntrl) results
 | 
				
			||||||
 | 
					 * to select an appropriate lo_vol_* in SGTL5000_CHIP_LINE_OUT_VOL
 | 
				
			||||||
 | 
					 * The calculatation was done for all possible register values which
 | 
				
			||||||
 | 
					 * is the array index and the following formula: 10^((idx−15)/40) * 100
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const u8 vol_quot_table[] = {
 | 
				
			||||||
 | 
						42, 45, 47, 50, 53, 56, 60, 63,
 | 
				
			||||||
 | 
						67, 71, 75, 79, 84, 89, 94, 100,
 | 
				
			||||||
 | 
						106, 112, 119, 126, 133, 141, 150, 158,
 | 
				
			||||||
 | 
						168, 178, 188, 200, 211, 224, 237, 251
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * sgtl5000 has 3 internal power supplies:
 | 
					 * sgtl5000 has 3 internal power supplies:
 | 
				
			||||||
 * 1. VAG, normally set to vdda/2
 | 
					 * 1. VAG, normally set to vdda/2
 | 
				
			||||||
| 
						 | 
					@ -1111,6 +1123,10 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 | 
				
			||||||
	u16 ana_pwr;
 | 
						u16 ana_pwr;
 | 
				
			||||||
	u16 lreg_ctrl;
 | 
						u16 lreg_ctrl;
 | 
				
			||||||
	int vag;
 | 
						int vag;
 | 
				
			||||||
 | 
						int lo_vag;
 | 
				
			||||||
 | 
						int vol_quot;
 | 
				
			||||||
 | 
						int lo_vol;
 | 
				
			||||||
 | 
						size_t i;
 | 
				
			||||||
	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
 | 
						struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vdda  = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
 | 
						vdda  = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer);
 | 
				
			||||||
| 
						 | 
					@ -1198,23 +1214,45 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec)
 | 
				
			||||||
			SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
 | 
								SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
 | 
						/* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */
 | 
				
			||||||
	vag = vddio / 2;
 | 
						lo_vag = vddio / 2;
 | 
				
			||||||
	if (vag <= SGTL5000_LINE_OUT_GND_BASE)
 | 
						if (lo_vag <= SGTL5000_LINE_OUT_GND_BASE)
 | 
				
			||||||
		vag = 0;
 | 
							lo_vag = 0;
 | 
				
			||||||
	else if (vag >= SGTL5000_LINE_OUT_GND_BASE +
 | 
						else if (lo_vag >= SGTL5000_LINE_OUT_GND_BASE +
 | 
				
			||||||
		SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
 | 
							SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX)
 | 
				
			||||||
		vag = SGTL5000_LINE_OUT_GND_MAX;
 | 
							lo_vag = SGTL5000_LINE_OUT_GND_MAX;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		vag = (vag - SGTL5000_LINE_OUT_GND_BASE) /
 | 
							lo_vag = (lo_vag - SGTL5000_LINE_OUT_GND_BASE) /
 | 
				
			||||||
		    SGTL5000_LINE_OUT_GND_STP;
 | 
							    SGTL5000_LINE_OUT_GND_STP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
 | 
						snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL,
 | 
				
			||||||
			SGTL5000_LINE_OUT_CURRENT_MASK |
 | 
								SGTL5000_LINE_OUT_CURRENT_MASK |
 | 
				
			||||||
			SGTL5000_LINE_OUT_GND_MASK,
 | 
								SGTL5000_LINE_OUT_GND_MASK,
 | 
				
			||||||
			vag << SGTL5000_LINE_OUT_GND_SHIFT |
 | 
								lo_vag << SGTL5000_LINE_OUT_GND_SHIFT |
 | 
				
			||||||
			SGTL5000_LINE_OUT_CURRENT_360u <<
 | 
								SGTL5000_LINE_OUT_CURRENT_360u <<
 | 
				
			||||||
				SGTL5000_LINE_OUT_CURRENT_SHIFT);
 | 
									SGTL5000_LINE_OUT_CURRENT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Set lineout output level in range (0..31)
 | 
				
			||||||
 | 
						 * the same value is used for right and left channel
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Searching for a suitable index solving this formula:
 | 
				
			||||||
 | 
						 * idx = 40 * log10(vag_val / lo_cagcntrl) + 15
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						vol_quot = (vag * 100) / lo_vag;
 | 
				
			||||||
 | 
						lo_vol = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(vol_quot_table); i++) {
 | 
				
			||||||
 | 
							if (vol_quot >= vol_quot_table[i])
 | 
				
			||||||
 | 
								lo_vol = i;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL,
 | 
				
			||||||
 | 
							SGTL5000_LINE_OUT_VOL_RIGHT_MASK |
 | 
				
			||||||
 | 
							SGTL5000_LINE_OUT_VOL_LEFT_MASK,
 | 
				
			||||||
 | 
							lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT |
 | 
				
			||||||
 | 
							lo_vol << SGTL5000_LINE_OUT_VOL_LEFT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -395,7 +395,7 @@ struct snd_soc_dai_driver sirf_audio_codec_dai = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
 | 
					static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_enable(codec->dev);
 | 
						pm_runtime_enable(codec->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,7 +194,7 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
 | 
				
			||||||
			pr_debug("vaud_bias powering up pll\n");
 | 
								pr_debug("vaud_bias powering up pll\n");
 | 
				
			||||||
			/* power up the pll */
 | 
								/* power up the pll */
 | 
				
			||||||
			snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
 | 
								snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
 | 
				
			||||||
| 
						 | 
					@ -205,17 +205,22 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							switch (snd_soc_codec_get_bias_level(codec)) {
 | 
				
			||||||
 | 
							case SND_SOC_BIAS_OFF:
 | 
				
			||||||
			pr_debug("vaud_bias power up rail\n");
 | 
								pr_debug("vaud_bias power up rail\n");
 | 
				
			||||||
			/* power up the rail */
 | 
								/* power up the rail */
 | 
				
			||||||
			snd_soc_write(codec, SN95031_VAUD,
 | 
								snd_soc_write(codec, SN95031_VAUD,
 | 
				
			||||||
					BIT(2)|BIT(1)|BIT(0));
 | 
										BIT(2)|BIT(1)|BIT(0));
 | 
				
			||||||
			msleep(1);
 | 
								msleep(1);
 | 
				
			||||||
		} else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
 | 
								break;
 | 
				
			||||||
 | 
							case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
			/* turn off pcm */
 | 
								/* turn off pcm */
 | 
				
			||||||
			pr_debug("vaud_bias power dn pcm\n");
 | 
								pr_debug("vaud_bias power dn pcm\n");
 | 
				
			||||||
			snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
 | 
								snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
 | 
				
			||||||
			snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
 | 
								snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -226,7 +231,6 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -510,7 +510,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			ret = ssm2518_set_power(ssm2518, true);
 | 
								ret = ssm2518_set_power(ssm2518, true);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
| 
						 | 
					@ -518,12 +518,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret)
 | 
						return ret;
 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 | 
					static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -473,7 +473,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -524,8 +523,8 @@ static int ssm2602_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ssm2602_codec_probe(struct snd_soc_codec *codec)
 | 
					static int ssm2602_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
 | 
						struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
					 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V,
 | 
						regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V,
 | 
				
			||||||
| 
						 | 
					@ -549,7 +548,7 @@ static int ssm2602_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ssm2604_codec_probe(struct snd_soc_codec *codec)
 | 
					static int ssm2604_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm = &codec->dapm;
 | 
						struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
 | 
						ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -353,7 +353,7 @@ static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
	case SND_SOC_BIAS_PREPARE:
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			ret = ssm4567_set_power(ssm4567, true);
 | 
								ret = ssm4567_set_power(ssm4567, true);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_OFF:
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
| 
						 | 
					@ -361,12 +361,7 @@ static int ssm4567_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret)
 | 
						return ret;
 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dai_ops ssm4567_dai_ops = {
 | 
					static const struct snd_soc_dai_ops ssm4567_dai_ops = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -819,7 +819,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
 | 
								ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
 | 
				
			||||||
						    sta32x->supplies);
 | 
											    sta32x->supplies);
 | 
				
			||||||
			if (ret != 0) {
 | 
								if (ret != 0) {
 | 
				
			||||||
| 
						 | 
					@ -854,7 +854,6 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				       sta32x->supplies);
 | 
									       sta32x->supplies);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -970,7 +969,7 @@ static int sta32x_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	if (sta32x->pdata->needs_esd_watchdog)
 | 
						if (sta32x->pdata->needs_esd_watchdog)
 | 
				
			||||||
		INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
 | 
							INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
				
			||||||
	/* Bias level configuration will have done an extra enable */
 | 
						/* Bias level configuration will have done an extra enable */
 | 
				
			||||||
	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 | 
						regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1096,16 +1095,10 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* GPIOs */
 | 
						/* GPIOs */
 | 
				
			||||||
	sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset");
 | 
						sta32x->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",
 | 
				
			||||||
	if (IS_ERR(sta32x->gpiod_nreset)) {
 | 
											       GPIOD_OUT_LOW);
 | 
				
			||||||
		ret = PTR_ERR(sta32x->gpiod_nreset);
 | 
						if (IS_ERR(sta32x->gpiod_nreset))
 | 
				
			||||||
		if (ret != -ENOENT && ret != -ENOSYS)
 | 
							return PTR_ERR(sta32x->gpiod_nreset);
 | 
				
			||||||
			return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sta32x->gpiod_nreset = NULL;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		gpiod_direction_output(sta32x->gpiod_nreset, 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* regulators */
 | 
						/* regulators */
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
 | 
						for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -853,7 +853,7 @@ static int sta350_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
 | 
				
			||||||
			ret = regulator_bulk_enable(
 | 
								ret = regulator_bulk_enable(
 | 
				
			||||||
				ARRAY_SIZE(sta350->supplies),
 | 
									ARRAY_SIZE(sta350->supplies),
 | 
				
			||||||
				sta350->supplies);
 | 
									sta350->supplies);
 | 
				
			||||||
| 
						 | 
					@ -890,7 +890,6 @@ static int sta350_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
				       sta350->supplies);
 | 
									       sta350->supplies);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1037,7 +1036,7 @@ static int sta350_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	sta350->coef_shadow[60] = 0x400000;
 | 
						sta350->coef_shadow[60] = 0x400000;
 | 
				
			||||||
	sta350->coef_shadow[61] = 0x400000;
 | 
						sta350->coef_shadow[61] = 0x400000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
						snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
 | 
				
			||||||
	/* Bias level configuration will have done an extra enable */
 | 
						/* Bias level configuration will have done an extra enable */
 | 
				
			||||||
	regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
 | 
						regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1218,8 +1217,8 @@ static int sta350_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
	if (IS_ERR(sta350->gpiod_nreset))
 | 
						if (IS_ERR(sta350->gpiod_nreset))
 | 
				
			||||||
		return PTR_ERR(sta350->gpiod_nreset);
 | 
							return PTR_ERR(sta350->gpiod_nreset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down",
 | 
						sta350->gpiod_power_down = devm_gpiod_get_optional(dev, "power-down",
 | 
				
			||||||
						  GPIOD_OUT_LOW);
 | 
												   GPIOD_OUT_LOW);
 | 
				
			||||||
	if (IS_ERR(sta350->gpiod_power_down))
 | 
						if (IS_ERR(sta350->gpiod_power_down))
 | 
				
			||||||
		return PTR_ERR(sta350->gpiod_power_down);
 | 
							return PTR_ERR(sta350->gpiod_power_down);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -165,7 +165,7 @@ static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
 | 
				
			||||||
				FFX_CLK_ENB);
 | 
									FFX_CLK_ENB);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_BIAS_STANDBY:
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
 | 
							if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
 | 
				
			||||||
			regcache_sync(sta529->regmap);
 | 
								regcache_sync(sta529->regmap);
 | 
				
			||||||
		snd_soc_update_bits(codec, STA529_FFXCFG0,
 | 
							snd_soc_update_bits(codec, STA529_FFXCFG0,
 | 
				
			||||||
					POWER_CNTLMSAK, POWER_STDBY);
 | 
										POWER_CNTLMSAK, POWER_STDBY);
 | 
				
			||||||
| 
						 | 
					@ -179,12 +179,6 @@ static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * store the label for powers down audio subsystem for suspend.This is
 | 
					 | 
				
			||||||
	 * used by soc core layer
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,7 +236,6 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
		stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
 | 
							stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	codec->dapm.bias_level = level;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
#include <sound/soc-dapm.h>
 | 
					#include <sound/soc-dapm.h>
 | 
				
			||||||
#include <sound/tlv.h>
 | 
					#include <sound/tlv.h>
 | 
				
			||||||
#include <sound/tas2552-plat.h>
 | 
					#include <sound/tas2552-plat.h>
 | 
				
			||||||
 | 
					#include <dt-bindings/sound/tas2552.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tas2552.h"
 | 
					#include "tas2552.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +46,7 @@ static struct reg_default tas2552_reg_defs[] = {
 | 
				
			||||||
	{TAS2552_PDM_CFG, 0x01},
 | 
						{TAS2552_PDM_CFG, 0x01},
 | 
				
			||||||
	{TAS2552_PGA_GAIN, 0x00},
 | 
						{TAS2552_PGA_GAIN, 0x00},
 | 
				
			||||||
	{TAS2552_BOOST_PT_CTRL, 0x0f},
 | 
						{TAS2552_BOOST_PT_CTRL, 0x0f},
 | 
				
			||||||
	{TAS2552_RESERVED_0D, 0x00},
 | 
						{TAS2552_RESERVED_0D, 0xbe},
 | 
				
			||||||
	{TAS2552_LIMIT_RATE_HYS, 0x08},
 | 
						{TAS2552_LIMIT_RATE_HYS, 0x08},
 | 
				
			||||||
	{TAS2552_CFG_2, 0xef},
 | 
						{TAS2552_CFG_2, 0xef},
 | 
				
			||||||
	{TAS2552_SER_CTRL_1, 0x00},
 | 
						{TAS2552_SER_CTRL_1, 0x00},
 | 
				
			||||||
| 
						 | 
					@ -75,20 +76,45 @@ struct tas2552_data {
 | 
				
			||||||
	struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
 | 
						struct regulator_bulk_data supplies[TAS2552_NUM_SUPPLIES];
 | 
				
			||||||
	struct gpio_desc *enable_gpio;
 | 
						struct gpio_desc *enable_gpio;
 | 
				
			||||||
	unsigned char regs[TAS2552_VBAT_DATA];
 | 
						unsigned char regs[TAS2552_VBAT_DATA];
 | 
				
			||||||
	unsigned int mclk;
 | 
						unsigned int pll_clkin;
 | 
				
			||||||
 | 
						unsigned int pdm_clk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned int dai_fmt;
 | 
				
			||||||
 | 
						unsigned int tdm_delay;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int tas2552_post_event(struct snd_soc_dapm_widget *w,
 | 
				
			||||||
 | 
								      struct snd_kcontrol *kcontrol, int event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (event) {
 | 
				
			||||||
 | 
						case SND_SOC_DAPM_POST_PMU:
 | 
				
			||||||
 | 
							snd_soc_write(codec, TAS2552_RESERVED_0D, 0xc0);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5),
 | 
				
			||||||
 | 
									    (1 << 5));
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 0);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS, 0);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAPM_POST_PMD:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_SWS,
 | 
				
			||||||
 | 
									    TAS2552_SWS);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_CFG_2, 1, 1);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, TAS2552_LIMIT_RATE_HYS, (1 << 5), 0);
 | 
				
			||||||
 | 
							snd_soc_write(codec, TAS2552_RESERVED_0D, 0xbe);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Input mux controls */
 | 
					/* Input mux controls */
 | 
				
			||||||
static const char *tas2552_input_texts[] = {
 | 
					static const char * const tas2552_input_texts[] = {
 | 
				
			||||||
	"Digital", "Analog"
 | 
						"Digital", "Analog" };
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
 | 
					static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
 | 
				
			||||||
			    tas2552_input_texts);
 | 
								    tas2552_input_texts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new tas2552_input_mux_control[] = {
 | 
					static const struct snd_kcontrol_new tas2552_input_mux_control =
 | 
				
			||||||
	SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum)
 | 
						SOC_DAPM_ENUM("Route", tas2552_input_mux_enum);
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
 | 
					static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -96,12 +122,13 @@ static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* MUX Controls */
 | 
						/* MUX Controls */
 | 
				
			||||||
	SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
 | 
						SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
 | 
				
			||||||
				tas2552_input_mux_control),
 | 
								 &tas2552_input_mux_control),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
 | 
						SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
	SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
 | 
						SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
	SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
 | 
						SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
 | 
				
			||||||
	SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
 | 
						SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_POST("Post Event", tas2552_post_event),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SND_SOC_DAPM_OUTPUT("OUT")
 | 
						SND_SOC_DAPM_OUTPUT("OUT")
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -118,15 +145,16 @@ static const struct snd_soc_dapm_route tas2552_audio_map[] = {
 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
 | 
					static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 cfg1_reg;
 | 
						u8 cfg1_reg = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!tas_data->codec)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sw_shutdown)
 | 
						if (sw_shutdown)
 | 
				
			||||||
		cfg1_reg = 0;
 | 
							cfg1_reg = TAS2552_SWS;
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		cfg1_reg = TAS2552_SWS_MASK;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1,
 | 
						snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, TAS2552_SWS,
 | 
				
			||||||
						 TAS2552_SWS_MASK, cfg1_reg);
 | 
								    cfg1_reg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,15 +166,92 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
 | 
						struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
 | 
				
			||||||
	int sample_rate, pll_clk;
 | 
						int sample_rate, pll_clk;
 | 
				
			||||||
	int d;
 | 
						int d;
 | 
				
			||||||
 | 
						int cpf;
 | 
				
			||||||
	u8 p, j;
 | 
						u8 p, j;
 | 
				
			||||||
 | 
						u8 ser_ctrl1_reg, wclk_rate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!tas2552->mclk)
 | 
						switch (params_width(params)) {
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							ser_ctrl1_reg = TAS2552_WORDLENGTH_16BIT;
 | 
				
			||||||
 | 
							cpf = 32 + tas2552->tdm_delay;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 20:
 | 
				
			||||||
 | 
							ser_ctrl1_reg = TAS2552_WORDLENGTH_20BIT;
 | 
				
			||||||
 | 
							cpf = 64 + tas2552->tdm_delay;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 24:
 | 
				
			||||||
 | 
							ser_ctrl1_reg = TAS2552_WORDLENGTH_24BIT;
 | 
				
			||||||
 | 
							cpf = 64 + tas2552->tdm_delay;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 32:
 | 
				
			||||||
 | 
							ser_ctrl1_reg = TAS2552_WORDLENGTH_32BIT;
 | 
				
			||||||
 | 
							cpf = 64 + tas2552->tdm_delay;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Not supported sample size: %d\n",
 | 
				
			||||||
 | 
								params_width(params));
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cpf <= 32)
 | 
				
			||||||
 | 
							ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_32;
 | 
				
			||||||
 | 
						else if (cpf <= 64)
 | 
				
			||||||
 | 
							ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_64;
 | 
				
			||||||
 | 
						else if (cpf <= 128)
 | 
				
			||||||
 | 
							ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_128;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ser_ctrl1_reg |= TAS2552_CLKSPERFRAME_256;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snd_soc_update_bits(codec, TAS2552_SER_CTRL_1,
 | 
				
			||||||
 | 
								    TAS2552_WORDLENGTH_MASK | TAS2552_CLKSPERFRAME_MASK,
 | 
				
			||||||
 | 
								    ser_ctrl1_reg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (params_rate(params)) {
 | 
				
			||||||
 | 
						case 8000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_8KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 11025:
 | 
				
			||||||
 | 
						case 12000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_11_12KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 16000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_16KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 22050:
 | 
				
			||||||
 | 
						case 24000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_22_24KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 32000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_32KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 44100:
 | 
				
			||||||
 | 
						case 48000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_44_48KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 88200:
 | 
				
			||||||
 | 
						case 96000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_88_96KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 176400:
 | 
				
			||||||
 | 
						case 192000:
 | 
				
			||||||
 | 
							wclk_rate = TAS2552_WCLK_FREQ_176_192KHZ;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Not supported sample rate: %d\n",
 | 
				
			||||||
 | 
								params_rate(params));
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snd_soc_update_bits(codec, TAS2552_CFG_3, TAS2552_WCLK_FREQ_MASK,
 | 
				
			||||||
 | 
								    wclk_rate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!tas2552->pll_clkin)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
 | 
						snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tas2552->mclk == TAS2552_245MHZ_CLK ||
 | 
						if (tas2552->pll_clkin == TAS2552_245MHZ_CLK ||
 | 
				
			||||||
		tas2552->mclk == TAS2552_225MHZ_CLK) {
 | 
						    tas2552->pll_clkin == TAS2552_225MHZ_CLK) {
 | 
				
			||||||
		/* By pass the PLL configuration */
 | 
							/* By pass the PLL configuration */
 | 
				
			||||||
		snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
 | 
							snd_soc_update_bits(codec, TAS2552_PLL_CTRL_2,
 | 
				
			||||||
				    TAS2552_PLL_BYPASS_MASK,
 | 
									    TAS2552_PLL_BYPASS_MASK,
 | 
				
			||||||
| 
						 | 
					@ -170,8 +275,8 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		j = (pll_clk * 2 * (1 << p)) / tas2552->mclk;
 | 
							j = (pll_clk * 2 * (1 << p)) / tas2552->pll_clkin;
 | 
				
			||||||
		d = (pll_clk * 2 * (1 << p)) % tas2552->mclk;
 | 
							d = (pll_clk * 2 * (1 << p)) % tas2552->pll_clkin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
 | 
							snd_soc_update_bits(codec, TAS2552_PLL_CTRL_1,
 | 
				
			||||||
				TAS2552_PLL_J_MASK, j);
 | 
									TAS2552_PLL_J_MASK, j);
 | 
				
			||||||
| 
						 | 
					@ -185,56 +290,74 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TAS2552_DAI_FMT_MASK	(TAS2552_BCLKDIR | \
 | 
				
			||||||
 | 
									 TAS2552_WCLKDIR | \
 | 
				
			||||||
 | 
									 TAS2552_DATAFORMAT_MASK)
 | 
				
			||||||
 | 
					static int tas2552_prepare(struct snd_pcm_substream *substream,
 | 
				
			||||||
 | 
								   struct snd_soc_dai *dai)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int delay = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TDM slot selection only valid in DSP_A/_B mode */
 | 
				
			||||||
 | 
						if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_A)
 | 
				
			||||||
 | 
							delay += (tas2552->tdm_delay + 1);
 | 
				
			||||||
 | 
						else if (tas2552->dai_fmt == SND_SOC_DAIFMT_DSP_B)
 | 
				
			||||||
 | 
							delay += tas2552->tdm_delay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Configure data delay */
 | 
				
			||||||
 | 
						snd_soc_write(codec, TAS2552_SER_CTRL_2, delay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 | 
					static int tas2552_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = dai->codec;
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
 | 
				
			||||||
	u8 serial_format;
 | 
						u8 serial_format;
 | 
				
			||||||
	u8 serial_control_mask;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 | 
						switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 | 
				
			||||||
	case SND_SOC_DAIFMT_CBS_CFS:
 | 
						case SND_SOC_DAIFMT_CBS_CFS:
 | 
				
			||||||
		serial_format = 0x00;
 | 
							serial_format = 0x00;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_CBS_CFM:
 | 
						case SND_SOC_DAIFMT_CBS_CFM:
 | 
				
			||||||
		serial_format = TAS2552_WORD_CLK_MASK;
 | 
							serial_format = TAS2552_WCLKDIR;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_CBM_CFS:
 | 
						case SND_SOC_DAIFMT_CBM_CFS:
 | 
				
			||||||
		serial_format = TAS2552_BIT_CLK_MASK;
 | 
							serial_format = TAS2552_BCLKDIR;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_CBM_CFM:
 | 
						case SND_SOC_DAIFMT_CBM_CFM:
 | 
				
			||||||
		serial_format = (TAS2552_BIT_CLK_MASK | TAS2552_WORD_CLK_MASK);
 | 
							serial_format = (TAS2552_BCLKDIR | TAS2552_WCLKDIR);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		dev_vdbg(codec->dev, "DAI Format master is not found\n");
 | 
							dev_vdbg(codec->dev, "DAI Format master is not found\n");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serial_control_mask = TAS2552_BIT_CLK_MASK | TAS2552_WORD_CLK_MASK;
 | 
						switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
 | 
				
			||||||
 | 
							       SND_SOC_DAIFMT_INV_MASK)) {
 | 
				
			||||||
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 | 
						case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
 | 
				
			||||||
	case SND_SOC_DAIFMT_I2S:
 | 
					 | 
				
			||||||
		serial_format &= TAS2552_DAIFMT_I2S_MASK;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_DSP_A:
 | 
						case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
 | 
				
			||||||
		serial_format |= TAS2552_DAIFMT_DSP;
 | 
						case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
 | 
				
			||||||
 | 
							serial_format |= TAS2552_DATAFORMAT_DSP;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_RIGHT_J:
 | 
						case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
 | 
				
			||||||
		serial_format |= TAS2552_DAIFMT_RIGHT_J;
 | 
							serial_format |= TAS2552_DATAFORMAT_RIGHT_J;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SND_SOC_DAIFMT_LEFT_J:
 | 
						case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
 | 
				
			||||||
		serial_format |= TAS2552_DAIFMT_LEFT_J;
 | 
							serial_format |= TAS2552_DATAFORMAT_LEFT_J;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		dev_vdbg(codec->dev, "DAI Format is not found\n");
 | 
							dev_vdbg(codec->dev, "DAI Format is not found\n");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						tas2552->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fmt & SND_SOC_DAIFMT_FORMAT_MASK)
 | 
						snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, TAS2552_DAI_FMT_MASK,
 | 
				
			||||||
		serial_control_mask |= TAS2552_DATA_FORMAT_MASK;
 | 
								    serial_format);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	snd_soc_update_bits(codec, TAS2552_SER_CTRL_1, serial_control_mask,
 | 
					 | 
				
			||||||
						serial_format);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,23 +366,75 @@ static int tas2552_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_codec *codec = dai->codec;
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
	struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
 | 
						struct tas2552_data *tas2552 = dev_get_drvdata(codec->dev);
 | 
				
			||||||
 | 
						u8 reg, mask, val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tas2552->mclk = freq;
 | 
						switch (clk_id) {
 | 
				
			||||||
 | 
						case TAS2552_PLL_CLKIN_MCLK:
 | 
				
			||||||
 | 
						case TAS2552_PLL_CLKIN_BCLK:
 | 
				
			||||||
 | 
						case TAS2552_PLL_CLKIN_IVCLKIN:
 | 
				
			||||||
 | 
						case TAS2552_PLL_CLKIN_1_8_FIXED:
 | 
				
			||||||
 | 
							mask = TAS2552_PLL_SRC_MASK;
 | 
				
			||||||
 | 
							val = (clk_id << 3) & mask; /* bit 4:5 in the register */
 | 
				
			||||||
 | 
							reg = TAS2552_CFG_1;
 | 
				
			||||||
 | 
							tas2552->pll_clkin = freq;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case TAS2552_PDM_CLK_PLL:
 | 
				
			||||||
 | 
						case TAS2552_PDM_CLK_IVCLKIN:
 | 
				
			||||||
 | 
						case TAS2552_PDM_CLK_BCLK:
 | 
				
			||||||
 | 
						case TAS2552_PDM_CLK_MCLK:
 | 
				
			||||||
 | 
							mask = TAS2552_PDM_CLK_SEL_MASK;
 | 
				
			||||||
 | 
							val = (clk_id >> 1) & mask; /* bit 0:1 in the register */
 | 
				
			||||||
 | 
							reg = TAS2552_PDM_CFG;
 | 
				
			||||||
 | 
							tas2552->pdm_clk = freq;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Invalid clk id: %d\n", clk_id);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						snd_soc_update_bits(codec, reg, mask, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int tas2552_set_dai_tdm_slot(struct snd_soc_dai *dai,
 | 
				
			||||||
 | 
									    unsigned int tx_mask, unsigned int rx_mask,
 | 
				
			||||||
 | 
									    int slots, int slot_width)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						unsigned int lsb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (unlikely(!tx_mask)) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "tx masks need to be non 0\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* TDM based on DSP mode requires slots to be adjacent */
 | 
				
			||||||
 | 
						lsb = __ffs(tx_mask);
 | 
				
			||||||
 | 
						if ((lsb + 1) != __fls(tx_mask)) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Invalid mask, slots must be adjacent\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tas2552->tdm_delay = lsb * slot_width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* DOUT in high-impedance on inactive bit clocks */
 | 
				
			||||||
 | 
						snd_soc_update_bits(codec, TAS2552_DOUT,
 | 
				
			||||||
 | 
								    TAS2552_SDOUT_TRISTATE, TAS2552_SDOUT_TRISTATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tas2552_mute(struct snd_soc_dai *dai, int mute)
 | 
					static int tas2552_mute(struct snd_soc_dai *dai, int mute)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 cfg1_reg;
 | 
						u8 cfg1_reg = 0;
 | 
				
			||||||
	struct snd_soc_codec *codec = dai->codec;
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mute)
 | 
						if (mute)
 | 
				
			||||||
		cfg1_reg = TAS2552_MUTE_MASK;
 | 
							cfg1_reg |= TAS2552_MUTE;
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		cfg1_reg = ~TAS2552_MUTE_MASK;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE_MASK, cfg1_reg);
 | 
						snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, cfg1_reg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -269,7 +444,7 @@ static int tas2552_runtime_suspend(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tas2552_data *tas2552 = dev_get_drvdata(dev);
 | 
						struct tas2552_data *tas2552 = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tas2552_sw_shutdown(tas2552, 0);
 | 
						tas2552_sw_shutdown(tas2552, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regcache_cache_only(tas2552->regmap, true);
 | 
						regcache_cache_only(tas2552->regmap, true);
 | 
				
			||||||
	regcache_mark_dirty(tas2552->regmap);
 | 
						regcache_mark_dirty(tas2552->regmap);
 | 
				
			||||||
| 
						 | 
					@ -287,7 +462,7 @@ static int tas2552_runtime_resume(struct device *dev)
 | 
				
			||||||
	if (tas2552->enable_gpio)
 | 
						if (tas2552->enable_gpio)
 | 
				
			||||||
		gpiod_set_value(tas2552->enable_gpio, 1);
 | 
							gpiod_set_value(tas2552->enable_gpio, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tas2552_sw_shutdown(tas2552, 1);
 | 
						tas2552_sw_shutdown(tas2552, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regcache_cache_only(tas2552->regmap, false);
 | 
						regcache_cache_only(tas2552->regmap, false);
 | 
				
			||||||
	regcache_sync(tas2552->regmap);
 | 
						regcache_sync(tas2552->regmap);
 | 
				
			||||||
| 
						 | 
					@ -303,8 +478,10 @@ static const struct dev_pm_ops tas2552_pm = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
 | 
					static struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
 | 
				
			||||||
	.hw_params	= tas2552_hw_params,
 | 
						.hw_params	= tas2552_hw_params,
 | 
				
			||||||
 | 
						.prepare	= tas2552_prepare,
 | 
				
			||||||
	.set_sysclk	= tas2552_set_dai_sysclk,
 | 
						.set_sysclk	= tas2552_set_dai_sysclk,
 | 
				
			||||||
	.set_fmt	= tas2552_set_dai_fmt,
 | 
						.set_fmt	= tas2552_set_dai_fmt,
 | 
				
			||||||
 | 
						.set_tdm_slot	= tas2552_set_dai_tdm_slot,
 | 
				
			||||||
	.digital_mute = tas2552_mute,
 | 
						.digital_mute = tas2552_mute,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,16 +507,11 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
 | 
					 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24);
 | 
					static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_kcontrol_new tas2552_snd_controls[] = {
 | 
					static const struct snd_kcontrol_new tas2552_snd_controls[] = {
 | 
				
			||||||
	SOC_SINGLE_TLV("Speaker Driver Playback Volume",
 | 
						SOC_SINGLE_TLV("Speaker Driver Playback Volume",
 | 
				
			||||||
			 TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv),
 | 
								 TAS2552_PGA_GAIN, 0, 0x1f, 0, dac_tlv),
 | 
				
			||||||
	SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0),
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct reg_default tas2552_init_regs[] = {
 | 
					 | 
				
			||||||
	{ TAS2552_RESERVED_0D, 0xc0 },
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tas2552_codec_probe(struct snd_soc_codec *codec)
 | 
					static int tas2552_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
| 
						 | 
					@ -368,31 +540,19 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
		goto probe_fail;
 | 
							goto probe_fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_soc_write(codec, TAS2552_CFG_1, TAS2552_MUTE_MASK |
 | 
						snd_soc_update_bits(codec, TAS2552_CFG_1, TAS2552_MUTE, TAS2552_MUTE);
 | 
				
			||||||
				TAS2552_PLL_SRC_BCLK);
 | 
					 | 
				
			||||||
	snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
 | 
						snd_soc_write(codec, TAS2552_CFG_3, TAS2552_I2S_OUT_SEL |
 | 
				
			||||||
				TAS2552_DIN_SRC_SEL_AVG_L_R | TAS2552_88_96KHZ);
 | 
										    TAS2552_DIN_SRC_SEL_AVG_L_R);
 | 
				
			||||||
	snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I);
 | 
						snd_soc_write(codec, TAS2552_DOUT, TAS2552_PDM_DATA_I);
 | 
				
			||||||
	snd_soc_write(codec, TAS2552_OUTPUT_DATA, TAS2552_PDM_DATA_V_I | 0x8);
 | 
						snd_soc_write(codec, TAS2552_OUTPUT_DATA, TAS2552_PDM_DATA_V_I | 0x8);
 | 
				
			||||||
	snd_soc_write(codec, TAS2552_PDM_CFG, TAS2552_PDM_BCLK_SEL);
 | 
					 | 
				
			||||||
	snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 |
 | 
						snd_soc_write(codec, TAS2552_BOOST_PT_CTRL, TAS2552_APT_DELAY_200 |
 | 
				
			||||||
				TAS2552_APT_THRESH_2_1_7);
 | 
									TAS2552_APT_THRESH_2_1_7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = regmap_register_patch(tas2552->regmap, tas2552_init_regs,
 | 
					 | 
				
			||||||
					    ARRAY_SIZE(tas2552_init_regs));
 | 
					 | 
				
			||||||
	if (ret != 0) {
 | 
					 | 
				
			||||||
		dev_err(codec->dev, "Failed to write init registers: %d\n",
 | 
					 | 
				
			||||||
			ret);
 | 
					 | 
				
			||||||
		goto patch_fail;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN |
 | 
						snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN |
 | 
				
			||||||
				  TAS2552_APT_EN | TAS2552_LIM_EN);
 | 
									  TAS2552_APT_EN | TAS2552_LIM_EN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
patch_fail:
 | 
					 | 
				
			||||||
	pm_runtime_put(codec->dev);
 | 
					 | 
				
			||||||
probe_fail:
 | 
					probe_fail:
 | 
				
			||||||
	if (tas2552->enable_gpio)
 | 
						if (tas2552->enable_gpio)
 | 
				
			||||||
		gpiod_set_value(tas2552->enable_gpio, 0);
 | 
							gpiod_set_value(tas2552->enable_gpio, 0);
 | 
				
			||||||
| 
						 | 
					@ -454,6 +614,8 @@ static struct snd_soc_codec_driver soc_codec_dev_tas2552 = {
 | 
				
			||||||
	.remove = tas2552_codec_remove,
 | 
						.remove = tas2552_codec_remove,
 | 
				
			||||||
	.suspend =	tas2552_suspend,
 | 
						.suspend =	tas2552_suspend,
 | 
				
			||||||
	.resume = tas2552_resume,
 | 
						.resume = tas2552_resume,
 | 
				
			||||||
 | 
						.ignore_pmdown_time = true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.controls = tas2552_snd_controls,
 | 
						.controls = tas2552_snd_controls,
 | 
				
			||||||
	.num_controls = ARRAY_SIZE(tas2552_snd_controls),
 | 
						.num_controls = ARRAY_SIZE(tas2552_snd_controls),
 | 
				
			||||||
	.dapm_widgets = tas2552_dapm_widgets,
 | 
						.dapm_widgets = tas2552_dapm_widgets,
 | 
				
			||||||
| 
						 | 
					@ -486,8 +648,12 @@ static int tas2552_probe(struct i2c_client *client,
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
 | 
						data->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
 | 
				
			||||||
	if (IS_ERR(data->enable_gpio))
 | 
						if (IS_ERR(data->enable_gpio)) {
 | 
				
			||||||
		return PTR_ERR(data->enable_gpio);
 | 
							if (PTR_ERR(data->enable_gpio) == -EPROBE_DEFER)
 | 
				
			||||||
 | 
								return -EPROBE_DEFER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data->enable_gpio = NULL;;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data->tas2552_client = client;
 | 
						data->tas2552_client = client;
 | 
				
			||||||
	data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
 | 
						data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,10 +45,14 @@
 | 
				
			||||||
#define TAS2552_MAX_REG			0x20
 | 
					#define TAS2552_MAX_REG			0x20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* CFG1 Register Masks */
 | 
					/* CFG1 Register Masks */
 | 
				
			||||||
#define TAS2552_MUTE_MASK		(1 << 2)
 | 
					#define TAS2552_DEV_RESET		(1 << 0)
 | 
				
			||||||
#define TAS2552_SWS_MASK		(1 << 1)
 | 
					#define TAS2552_SWS			(1 << 1)
 | 
				
			||||||
#define TAS2552_WCLK_MASK		0x07
 | 
					#define TAS2552_MUTE			(1 << 2)
 | 
				
			||||||
#define TAS2552_CLASSD_EN_MASK	(1 << 7)
 | 
					#define TAS2552_PLL_SRC_MCLK		(0x0 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_SRC_BCLK		(0x1 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_SRC_IVCLKIN		(0x2 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_SRC_1_8_FIXED 	(0x3 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_PLL_SRC_MASK	 	TAS2552_PLL_SRC_1_8_FIXED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* CFG2 Register Masks */
 | 
					/* CFG2 Register Masks */
 | 
				
			||||||
#define TAS2552_CLASSD_EN		(1 << 7)
 | 
					#define TAS2552_CLASSD_EN		(1 << 7)
 | 
				
			||||||
| 
						 | 
					@ -59,38 +63,44 @@
 | 
				
			||||||
#define TAS2552_IVSENSE_EN		(1 << 1)
 | 
					#define TAS2552_IVSENSE_EN		(1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* CFG3 Register Masks */
 | 
					/* CFG3 Register Masks */
 | 
				
			||||||
#define TAS2552_WORD_CLK_MASK		(1 << 7)
 | 
					#define TAS2552_WCLK_FREQ_8KHZ		(0x0 << 0)
 | 
				
			||||||
#define TAS2552_BIT_CLK_MASK		(1 << 6)
 | 
					#define TAS2552_WCLK_FREQ_11_12KHZ	(0x1 << 0)
 | 
				
			||||||
#define TAS2552_DATA_FORMAT_MASK	(0x11 << 2)
 | 
					#define TAS2552_WCLK_FREQ_16KHZ		(0x2 << 0)
 | 
				
			||||||
 | 
					#define TAS2552_WCLK_FREQ_22_24KHZ	(0x3 << 0)
 | 
				
			||||||
#define TAS2552_DAIFMT_I2S_MASK		0xf3
 | 
					#define TAS2552_WCLK_FREQ_32KHZ		(0x4 << 0)
 | 
				
			||||||
#define TAS2552_DAIFMT_DSP			(1 << 3)
 | 
					#define TAS2552_WCLK_FREQ_44_48KHZ	(0x5 << 0)
 | 
				
			||||||
#define TAS2552_DAIFMT_RIGHT_J		(1 << 4)
 | 
					#define TAS2552_WCLK_FREQ_88_96KHZ	(0x6 << 0)
 | 
				
			||||||
#define TAS2552_DAIFMT_LEFT_J		(0x11 << 3)
 | 
					#define TAS2552_WCLK_FREQ_176_192KHZ	(0x7 << 0)
 | 
				
			||||||
 | 
					#define TAS2552_WCLK_FREQ_MASK		TAS2552_WCLK_FREQ_176_192KHZ
 | 
				
			||||||
#define TAS2552_PLL_SRC_MCLK	0x00
 | 
					#define TAS2552_DIN_SRC_SEL_MUTED	(0x0 << 3)
 | 
				
			||||||
#define TAS2552_PLL_SRC_BCLK	(1 << 3)
 | 
					#define TAS2552_DIN_SRC_SEL_LEFT	(0x1 << 3)
 | 
				
			||||||
#define TAS2552_PLL_SRC_IVCLKIN	(1 << 4)
 | 
					#define TAS2552_DIN_SRC_SEL_RIGHT	(0x2 << 3)
 | 
				
			||||||
#define TAS2552_PLL_SRC_1_8_FIXED (0x11 << 3)
 | 
					#define TAS2552_DIN_SRC_SEL_AVG_L_R	(0x3 << 3)
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TAS2552_DIN_SRC_SEL_MUTED	0x00
 | 
					 | 
				
			||||||
#define TAS2552_DIN_SRC_SEL_LEFT	(1 << 4)
 | 
					 | 
				
			||||||
#define TAS2552_DIN_SRC_SEL_RIGHT	(1 << 5)
 | 
					 | 
				
			||||||
#define TAS2552_DIN_SRC_SEL_AVG_L_R	(0x11 << 4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define TAS2552_PDM_IN_SEL		(1 << 5)
 | 
					#define TAS2552_PDM_IN_SEL		(1 << 5)
 | 
				
			||||||
#define TAS2552_I2S_OUT_SEL		(1 << 6)
 | 
					#define TAS2552_I2S_OUT_SEL		(1 << 6)
 | 
				
			||||||
#define TAS2552_ANALOG_IN_SEL	(1 << 7)
 | 
					#define TAS2552_ANALOG_IN_SEL		(1 << 7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* CFG3 WCLK Dividers */
 | 
					/* DOUT Register Masks */
 | 
				
			||||||
#define TAS2552_8KHZ		0x00
 | 
					#define TAS2552_SDOUT_TRISTATE		(1 << 2)
 | 
				
			||||||
#define TAS2552_11_12KHZ	(1 << 1)
 | 
					
 | 
				
			||||||
#define TAS2552_16KHZ		(1 << 2)
 | 
					/* Serial Interface Control Register Masks */
 | 
				
			||||||
#define TAS2552_22_24KHZ	(1 << 3)
 | 
					#define TAS2552_WORDLENGTH_16BIT	(0x0 << 0)
 | 
				
			||||||
#define TAS2552_32KHZ		(1 << 4)
 | 
					#define TAS2552_WORDLENGTH_20BIT	(0x1 << 0)
 | 
				
			||||||
#define TAS2552_44_48KHZ	(1 << 5)
 | 
					#define TAS2552_WORDLENGTH_24BIT	(0x2 << 0)
 | 
				
			||||||
#define TAS2552_88_96KHZ	(1 << 6)
 | 
					#define TAS2552_WORDLENGTH_32BIT	(0x3 << 0)
 | 
				
			||||||
#define TAS2552_176_192KHZ	(1 << 7)
 | 
					#define TAS2552_WORDLENGTH_MASK		TAS2552_WORDLENGTH_32BIT
 | 
				
			||||||
 | 
					#define TAS2552_DATAFORMAT_I2S		(0x0 << 2)
 | 
				
			||||||
 | 
					#define TAS2552_DATAFORMAT_DSP		(0x1 << 2)
 | 
				
			||||||
 | 
					#define TAS2552_DATAFORMAT_RIGHT_J	(0x2 << 2)
 | 
				
			||||||
 | 
					#define TAS2552_DATAFORMAT_LEFT_J	(0x3 << 2)
 | 
				
			||||||
 | 
					#define TAS2552_DATAFORMAT_MASK		TAS2552_DATAFORMAT_LEFT_J
 | 
				
			||||||
 | 
					#define TAS2552_CLKSPERFRAME_32		(0x0 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_CLKSPERFRAME_64		(0x1 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_CLKSPERFRAME_128	(0x2 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_CLKSPERFRAME_256	(0x3 << 4)
 | 
				
			||||||
 | 
					#define TAS2552_CLKSPERFRAME_MASK	TAS2552_CLKSPERFRAME_256
 | 
				
			||||||
 | 
					#define TAS2552_BCLKDIR			(1 << 6)
 | 
				
			||||||
 | 
					#define TAS2552_WCLKDIR			(1 << 7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* OUTPUT_DATA register */
 | 
					/* OUTPUT_DATA register */
 | 
				
			||||||
#define TAS2552_PDM_DATA_I		0x00
 | 
					#define TAS2552_PDM_DATA_I		0x00
 | 
				
			||||||
| 
						 | 
					@ -99,12 +109,12 @@
 | 
				
			||||||
#define TAS2552_PDM_DATA_V_I	(0x11 << 6)
 | 
					#define TAS2552_PDM_DATA_V_I	(0x11 << 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* PDM CFG Register */
 | 
					/* PDM CFG Register */
 | 
				
			||||||
#define TAS2552_PDM_DATA_ES_RISE 0x4
 | 
					#define TAS2552_PDM_CLK_SEL_PLL		(0x0 << 0)
 | 
				
			||||||
 | 
					#define TAS2552_PDM_CLK_SEL_IVCLKIN	(0x1 << 0)
 | 
				
			||||||
#define TAS2552_PDM_PLL_CLK_SEL 0x00
 | 
					#define TAS2552_PDM_CLK_SEL_BCLK	(0x2 << 0)
 | 
				
			||||||
#define TAS2552_PDM_IV_CLK_SEL	(1 << 1)
 | 
					#define TAS2552_PDM_CLK_SEL_MCLK	(0x3 << 0)
 | 
				
			||||||
#define TAS2552_PDM_BCLK_SEL	(1 << 2)
 | 
					#define TAS2552_PDM_CLK_SEL_MASK	TAS2552_PDM_CLK_SEL_MCLK
 | 
				
			||||||
#define TAS2552_PDM_MCLK_SEL	(1 << 3)
 | 
					#define TAS2552_PDM_DATA_ES	 	(1 << 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Boost pass-through register */
 | 
					/* Boost pass-through register */
 | 
				
			||||||
#define TAS2552_APT_DELAY_50	0x00
 | 
					#define TAS2552_APT_DELAY_50	0x00
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue