sound updates for 3.17-rc1
There've been many updates in ASoC side at this time, especially the
 framework enhancement for multiple CODECs on a single DAI and more
 componentization works.  The only major change in ALSA core is the
 addition of timestamp type in sw_params field.  This should behave in
 backward compatible way.  Other than that, there are lots of small
 changes and new drivers in wide range, including a large code cut in
 HD-audio driver for deprecated static quirks.  Some highlights are
 below:
 
 ALSA Core:
 - Add the new timestamp type field to sw_params to choose
   MONOTONIC_RAW type
 
 HD-audio:
 - Continued conversion to standard printk macros, generic code
   cleanups
 - Removal of obsoleted static quirk codes for Conexant and C-Media
   codecs
 - Fixups for HP Envy TS, Dell XPS 15, HP and Dell mute/mic LED,
   Gigabyte BXBT-2807 mobo
 - Intel Braswell support
 
 ASoC:
 - Support for multiple CODECs attached to a single DAI, enabling
   systems with for example multiple DAC/speaker drivers on a single
  link, contributed by Benoit Cousson based on work from Misael Lopez
  Cruz
 - Support for byte controls larger than 256 bytes based on the use of
   TLVs contributed by Omair Mohammed Abdullah
 - More componentisation work from Lars-Peter Clausen
 - The remainder of the conversions of CODEC drivers to params_width()
   by Mark Brown
 - Drivers for Cirrus Logic CS4265, Freescale i.MX ASRC blocks, Realtek
   RT286 and RT5670, Rockchip RK3xxx I2S controllers and Texas
   Instruments TAS2552
 - Lots of updates and fixes, especially to the DaVinci, Intel,
   Freescale, Realtek, and rcar drivers
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJT4fj0AAoJEGwxgFQ9KSmkXQ0QAIiRmVg40aiJoEdOLGgzNZtq
 r/nXj69AuB6JSy0hKbFyyijjCcRpyCCGvjDYlogjT75M3c35Npz/m85oZHx2tajD
 SB5OA+QxO4EQ3C0GjITIRHJROm4MM8/rnbnNYTsWnEGRkobTFTl0rHbSkA85RGFt
 0zZqqs1R0s/nO9PMQ+5PA5x9xVFiZs2COeCK0CFA9s2ACf/hbxJBRIqYpIFWOo78
 9L41jBOFuC/hIb4qwjgmsCWbKe1KQysTAf+Wty0CKipJ6VhfCbPn1Qn1zXGeUOxc
 mj4eZ6LpJTrVMr/UN02c5vgPOiaBrQ7fWZo3dVHLlIjC6cEI1tUvNYAin7CMEzx8
 DUsvo9p30OheA+ijc9wKaYFY6YmmJZRtpnnMd39i0oPG+bhvoV7vjXjJSB1sLJt1
 o82xLpVL4Th8H+DMDVwA7UIBvvZGZBusw1qsNGfcOPrmExi4ScGhA0gSOO6W2y1z
 VQLRbiXB/HtJGxeqWL6RqJOcLBOlJNmsk4UZMOSCu2OZrWd5I8MuRrNWeHDqhX1H
 +VDEJVhFmM21vMpnobzEPxWsMgTVIAVf3Thh+WgaPxL4Krh0vkpZsgZk16VVmy/o
 OJJF3n41FND4n9zSjOe4MkuL8UCOUpKCaBdqj9K1s6UKwOEKuDNslyT/zqutRWK5
 x1uApU5y+E4iQT/b7cmA
 =RL72
 -----END PGP SIGNATURE-----
Merge tag 'sound-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
 "There've been many updates in ASoC side at this time, especially the
  framework enhancement for multiple CODECs on a single DAI and more
  componentization works.
  The only major change in ALSA core is the addition of timestamp type
  in sw_params field.  This should behave in backward compatible way.
  Other than that, there are lots of small changes and new drivers in
  wide range, including a large code cut in HD-audio driver for
  deprecated static quirks.  Some highlights are below:
  ALSA Core:
   - Add the new timestamp type field to sw_params to choose
     MONOTONIC_RAW type
  HD-audio:
   - Continued conversion to standard printk macros, generic code
     cleanups
   - Removal of obsoleted static quirk codes for Conexant and C-Media
     codecs
   - Fixups for HP Envy TS, Dell XPS 15, HP and Dell mute/mic LED,
     Gigabyte BXBT-2807 mobo
   - Intel Braswell support
  ASoC:
   - Support for multiple CODECs attached to a single DAI, enabling
     systems with for example multiple DAC/speaker drivers on a single
     link, contributed by Benoit Cousson based on work from Misael Lopez
     Cruz
   - Support for byte controls larger than 256 bytes based on the use of
     TLVs contributed by Omair Mohammed Abdullah
   - More componentisation work from Lars-Peter Clausen
   - The remainder of the conversions of CODEC drivers to params_width()
     by Mark Brown
   - Drivers for Cirrus Logic CS4265, Freescale i.MX ASRC blocks,
     Realtek RT286 and RT5670, Rockchip RK3xxx I2S controllers and Texas
     Instruments TAS2552
   - Lots of updates and fixes, especially to the DaVinci, Intel,
     Freescale, Realtek, and rcar drivers"
* tag 'sound-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (402 commits)
  ALSA: usb-audio: Whitespace cleanups for sound/usb/midi.*
  ALSA: usb-audio: Respond to suspend and resume callbacks for MIDI input
  sound/oss/pss: Remove typedefs pss_mixerdata and pss_confdata
  sound/oss/opl3: Remove typedef opl_devinfo
  ALSA: fireworks: fix specifiers in format strings for propper output
  ASoC: imx-audmux: Use uintptr_t for port numbers
  ASoC: davinci: Enable menuconfig entry for McASP
  ASoC: fsl_asrc: Don't access members of config before checking it
  ASoC: fsl_sarc_dma: Check pair before using it
  ASoC: adau1977: Fix truncation warning on 64 bit architectures
  ALSA: virtuoso: add Xonar Essence STX II support
  ALSA: riptide: fix %d confusingly prefixed with 0x in format strings
  ALSA: fireworks: fix %d confusingly prefixed with 0x in format strings
  ALSA: hda - add codec ID for Braswell display audio codec
  ALSA: hda - add PCI IDs for Intel Braswell
  ALSA: usb-audio: Adjust Gamecom 780 volume level
  ALSA: usb-audio: improve dmesg source grepability
  ASoC: rt5670: Fix duplicate const warnings
  ASoC: rt5670: Staticise non-exported symbols
  ASoC: Intel: update stream only on stream IPC msgs
  ...
	
	
This commit is contained in:
		
				commit
				
					
						930e0312bc
					
				
			
		
					 294 changed files with 17276 additions and 7474 deletions
				
			
		| 
						 | 
					@ -10,10 +10,14 @@ Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  - reset-gpio : a GPIO spec for the reset/power down pin.
 | 
					  - reset-gpio : a GPIO spec for the reset/power down pin.
 | 
				
			||||||
		 If specified, it will be deasserted at probe time.
 | 
							 If specified, it will be deasserted at probe time.
 | 
				
			||||||
 | 
					  - va-supply : a regulator spec, providing 5.0V
 | 
				
			||||||
 | 
					  - vd-supply : a regulator spec, providing 3.3V
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
spdif: ak5386@0 {
 | 
					spdif: ak5386@0 {
 | 
				
			||||||
	compatible = "asahi-kasei,ak5386";
 | 
						compatible = "asahi-kasei,ak5386";
 | 
				
			||||||
	reset-gpio = <&gpio0 23>;
 | 
						reset-gpio = <&gpio0 23>;
 | 
				
			||||||
 | 
						va-supply = <&vdd_5v0_reg>;
 | 
				
			||||||
 | 
						vd-supply = <&vdd_3v3_reg>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								Documentation/devicetree/bindings/sound/cs4265.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Documentation/devicetree/bindings/sound/cs4265.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					CS4265 audio CODEC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This device supports I2C only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - compatible : "cirrus,cs4265"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - reg : the I2C address of the device for I2C. The I2C address depends on
 | 
				
			||||||
 | 
					          the state of the AD0 pin.  If AD0 is high, the i2c address is 0x4f.
 | 
				
			||||||
 | 
					          If it is low, the i2c address is 0x4e.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - reset-gpios : a GPIO spec for the reset pin. If specified, it will be
 | 
				
			||||||
 | 
							 deasserted before communication to the codec starts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					codec_ad0_high: cs4265@4f { /* AD0 Pin is high */
 | 
				
			||||||
 | 
						compatible = "cirrus,cs4265";
 | 
				
			||||||
 | 
						reg = <0x4f>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					codec_ad0_low: cs4265@4e { /* AD0 Pin is low */
 | 
				
			||||||
 | 
						compatible = "cirrus,cs4265";
 | 
				
			||||||
 | 
						reg = <0x4e>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										60
									
								
								Documentation/devicetree/bindings/sound/fsl,asrc.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Documentation/devicetree/bindings/sound/fsl,asrc.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					Freescale Asynchronous Sample Rate Converter (ASRC) Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Asynchronous Sample Rate Converter (ASRC) converts the sampling rate of a
 | 
				
			||||||
 | 
					signal associated with an input clock into a signal associated with a different
 | 
				
			||||||
 | 
					output clock. The driver currently works as a Front End of DPCM with other Back
 | 
				
			||||||
 | 
					Ends Audio controller such as ESAI, SSI and SAI. It has three pairs to support
 | 
				
			||||||
 | 
					three substreams within totally 10 channels.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - compatible		: Contains "fsl,imx35-asrc" or "fsl,imx53-asrc".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - reg			: Offset and length of the register set for the device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - interrupts		: Contains the spdif interrupt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - dmas		: Generic dma devicetree binding as described in
 | 
				
			||||||
 | 
								  Documentation/devicetree/bindings/dma/dma.txt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - dma-names		: Contains "rxa", "rxb", "rxc", "txa", "txb" and "txc".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - clocks		: Contains an entry for each entry in clock-names.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - clock-names		: Contains the following entries
 | 
				
			||||||
 | 
						"mem"		  Peripheral access clock to access registers.
 | 
				
			||||||
 | 
						"ipg"		  Peripheral clock to driver module.
 | 
				
			||||||
 | 
						"asrck_<0-f>"	  Clock sources for input and output clock.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - big-endian		: If this property is absent, the little endian mode
 | 
				
			||||||
 | 
								  will be in use as default. Otherwise, the big endian
 | 
				
			||||||
 | 
								  mode will be in use for all the device registers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - fsl,asrc-rate	: Defines a mutual sample rate used by DPCM Back Ends.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - fsl,asrc-width	: Defines a mutual sample width used by DPCM Back Ends.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					asrc: asrc@02034000 {
 | 
				
			||||||
 | 
						compatible = "fsl,imx53-asrc";
 | 
				
			||||||
 | 
						reg = <0x02034000 0x4000>;
 | 
				
			||||||
 | 
						interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
 | 
						clocks = <&clks 107>, <&clks 107>, <&clks 0>,
 | 
				
			||||||
 | 
						       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
 | 
				
			||||||
 | 
						       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
 | 
				
			||||||
 | 
						       <&clks 0>, <&clks 0>, <&clks 0>, <&clks 0>,
 | 
				
			||||||
 | 
						       <&clks 107>, <&clks 0>, <&clks 0>;
 | 
				
			||||||
 | 
						clock-names = "mem", "ipg", "asrck0",
 | 
				
			||||||
 | 
							"asrck_1", "asrck_2", "asrck_3", "asrck_4",
 | 
				
			||||||
 | 
							"asrck_5", "asrck_6", "asrck_7", "asrck_8",
 | 
				
			||||||
 | 
							"asrck_9", "asrck_a", "asrck_b", "asrck_c",
 | 
				
			||||||
 | 
							"asrck_d", "asrck_e", "asrck_f";
 | 
				
			||||||
 | 
						dmas = <&sdma 17 23 1>, <&sdma 18 23 1>, <&sdma 19 23 1>,
 | 
				
			||||||
 | 
						     <&sdma 20 23 1>, <&sdma 21 23 1>, <&sdma 22 23 1>;
 | 
				
			||||||
 | 
						dma-names = "rxa", "rxb", "rxc",
 | 
				
			||||||
 | 
							"txa", "txb", "txc";
 | 
				
			||||||
 | 
						fsl,asrc-rate  = <48000>;
 | 
				
			||||||
 | 
						fsl,asrc-width = <16>;
 | 
				
			||||||
 | 
						status = "okay";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ This device supports I2C only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Required properties:
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- compatible : "maxim,max98090".
 | 
					- compatible : "maxim,max98090" or "maxim,max98091".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- reg : The I2C address of the device.
 | 
					- reg : The I2C address of the device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,9 @@ Required properties:
 | 
				
			||||||
- rcar_sound,src		: Should contain SRC feature.
 | 
					- rcar_sound,src		: Should contain SRC feature.
 | 
				
			||||||
				  The number of SRC subnode should be same as HW.
 | 
									  The number of SRC subnode should be same as HW.
 | 
				
			||||||
				  see below for detail.
 | 
									  see below for detail.
 | 
				
			||||||
 | 
					- rcar_sound,dvc		: Should contain DVC feature.
 | 
				
			||||||
 | 
									  The number of DVC subnode should be same as HW.
 | 
				
			||||||
 | 
									  see below for detail.
 | 
				
			||||||
- rcar_sound,dai		: DAI contents.
 | 
					- rcar_sound,dai		: DAI contents.
 | 
				
			||||||
				  The number of DAI subnode should be same as HW.
 | 
									  The number of DAI subnode should be same as HW.
 | 
				
			||||||
				  see below for detail.
 | 
									  see below for detail.
 | 
				
			||||||
| 
						 | 
					@ -21,6 +24,7 @@ SSI subnode properties:
 | 
				
			||||||
- interrupts			: Should contain SSI interrupt for PIO transfer
 | 
					- interrupts			: Should contain SSI interrupt for PIO transfer
 | 
				
			||||||
- shared-pin			: if shared clock pin
 | 
					- shared-pin			: if shared clock pin
 | 
				
			||||||
- pio-transfer			: use PIO transfer mode
 | 
					- pio-transfer			: use PIO transfer mode
 | 
				
			||||||
 | 
					- no-busif			: BUSIF is not ussed when [mem -> SSI] via DMA case
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SRC subnode properties:
 | 
					SRC subnode properties:
 | 
				
			||||||
no properties at this point
 | 
					no properties at this point
 | 
				
			||||||
| 
						 | 
					@ -39,6 +43,11 @@ rcar_sound: rcar_sound@0xffd90000 {
 | 
				
			||||||
		<0 0xec540000 0 0x1000>, /* SSIU */
 | 
							<0 0xec540000 0 0x1000>, /* SSIU */
 | 
				
			||||||
		<0 0xec541000 0 0x1280>; /* SSI */
 | 
							<0 0xec541000 0 0x1280>; /* SSI */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rcar_sound,dvc {
 | 
				
			||||||
 | 
							dvc0: dvc@0 { };
 | 
				
			||||||
 | 
							dvc1: dvc@1 { };
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcar_sound,src {
 | 
						rcar_sound,src {
 | 
				
			||||||
		src0: src@0 { };
 | 
							src0: src@0 { };
 | 
				
			||||||
		src1: src@1 { };
 | 
							src1: src@1 { };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										37
									
								
								Documentation/devicetree/bindings/sound/rockchip-i2s.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Documentation/devicetree/bindings/sound/rockchip-i2s.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					* Rockchip I2S controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The I2S bus (Inter-IC sound bus) is a serial link for digital
 | 
				
			||||||
 | 
					audio data transfer between devices in the system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- compatible: should be one of the followings
 | 
				
			||||||
 | 
					   - "rockchip,rk3066-i2s": for rk3066
 | 
				
			||||||
 | 
					   - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
 | 
				
			||||||
 | 
					   - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288
 | 
				
			||||||
 | 
					- reg: physical base address of the controller and length of memory mapped
 | 
				
			||||||
 | 
					  region.
 | 
				
			||||||
 | 
					- interrupts: should contain the I2S interrupt.
 | 
				
			||||||
 | 
					- #address-cells: should be 1.
 | 
				
			||||||
 | 
					- #size-cells: should be 0.
 | 
				
			||||||
 | 
					- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
 | 
				
			||||||
 | 
						Documentation/devicetree/bindings/dma/dma.txt
 | 
				
			||||||
 | 
					- dma-names: should include "tx" and "rx".
 | 
				
			||||||
 | 
					- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
 | 
				
			||||||
 | 
					- clock-names: should contain followings:
 | 
				
			||||||
 | 
					   - "i2s_hclk": clock for I2S BUS
 | 
				
			||||||
 | 
					   - "i2s_clk" : clock for I2S controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example for rk3288 I2S controller:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i2s@ff890000 {
 | 
				
			||||||
 | 
						compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
 | 
				
			||||||
 | 
						reg = <0xff890000 0x10000>;
 | 
				
			||||||
 | 
						interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 | 
				
			||||||
 | 
						#address-cells = <1>;
 | 
				
			||||||
 | 
						#size-cells = <0>;
 | 
				
			||||||
 | 
						dmas = <&pdma1 0>, <&pdma1 1>;
 | 
				
			||||||
 | 
						dma-names = "rx", "tx";
 | 
				
			||||||
 | 
						clock-names = "i2s_hclk", "i2s_clk";
 | 
				
			||||||
 | 
						clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					Samsung Exynos Odroid X2/U3 audio complex with MAX98090 codec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					 - compatible : "samsung,odroidx2-audio" - for Odroid X2 board,
 | 
				
			||||||
 | 
							"samsung,odroidu3-audio" - for Odroid U3 board
 | 
				
			||||||
 | 
					 - samsung,model : the user-visible name of this sound complex
 | 
				
			||||||
 | 
					 - samsung,i2s-controller : the phandle of the I2S controller
 | 
				
			||||||
 | 
					 - samsung,audio-codec : the phandle of the MAX98090 audio codec
 | 
				
			||||||
 | 
					 - samsung,audio-routing : a list of the connections between audio
 | 
				
			||||||
 | 
					   components;  each entry is a pair of strings, the first being the
 | 
				
			||||||
 | 
					   connection's sink, the second being the connection's source;
 | 
				
			||||||
 | 
					   valid names for sources and sinks are the MAX98090's pins (as
 | 
				
			||||||
 | 
					   documented in its binding), and the jacks on the board
 | 
				
			||||||
 | 
					   For Odroid X2:
 | 
				
			||||||
 | 
					     * Headphone Jack
 | 
				
			||||||
 | 
					     * Mic Jack
 | 
				
			||||||
 | 
					     * DMIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   For Odroid U3:
 | 
				
			||||||
 | 
					     * Headphone Jack
 | 
				
			||||||
 | 
					     * Speakers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sound {
 | 
				
			||||||
 | 
						compatible = "samsung,odroidu3-audio";
 | 
				
			||||||
 | 
						samsung,i2s-controller = <&i2s0>;
 | 
				
			||||||
 | 
						samsung,audio-codec = <&max98090>;
 | 
				
			||||||
 | 
						samsung,model = "Odroid-X2";
 | 
				
			||||||
 | 
						samsung,audio-routing =
 | 
				
			||||||
 | 
							"Headphone Jack", "HPL",
 | 
				
			||||||
 | 
							"Headphone Jack", "HPR",
 | 
				
			||||||
 | 
							"IN1", "Mic Jack",
 | 
				
			||||||
 | 
							"Mic Jack", "MICBIAS";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										27
									
								
								Documentation/devicetree/bindings/sound/sirf-usp.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Documentation/devicetree/bindings/sound/sirf-usp.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					* SiRF SoC USP module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					- compatible: "sirf,prima2-usp-pcm"
 | 
				
			||||||
 | 
					- reg: Base address and size entries:
 | 
				
			||||||
 | 
					- dmas: List of DMA controller phandle and DMA request line ordered pairs.
 | 
				
			||||||
 | 
					- dma-names: Identifier string for each DMA request line in the dmas property.
 | 
				
			||||||
 | 
					  These strings correspond 1:1 with the ordered pairs in dmas.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  One of the DMA channels will be responsible for transmission (should be
 | 
				
			||||||
 | 
					  named "tx") and one for reception (should be named "rx").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- clocks: USP controller clock source
 | 
				
			||||||
 | 
					- pinctrl-names: Must contain a "default" entry.
 | 
				
			||||||
 | 
					- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					usp0: usp@b0080000 {
 | 
				
			||||||
 | 
						compatible = "sirf,prima2-usp-pcm";
 | 
				
			||||||
 | 
						reg = <0xb0080000 0x10000>;
 | 
				
			||||||
 | 
						clocks = <&clks 28>;
 | 
				
			||||||
 | 
						dmas = <&dmac1 1>, <&dmac1 2>;
 | 
				
			||||||
 | 
						dma-names = "rx", "tx";
 | 
				
			||||||
 | 
						pinctrl-names = "default";
 | 
				
			||||||
 | 
						pinctrl-0 = <&usp0_only_utfs_pins_a>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,15 +3,20 @@ Audio Binding for Snow boards
 | 
				
			||||||
Required properties:
 | 
					Required properties:
 | 
				
			||||||
- compatible : Can be one of the following,
 | 
					- compatible : Can be one of the following,
 | 
				
			||||||
			"google,snow-audio-max98090" or
 | 
								"google,snow-audio-max98090" or
 | 
				
			||||||
 | 
								"google,snow-audio-max98091" or
 | 
				
			||||||
			"google,snow-audio-max98095"
 | 
								"google,snow-audio-max98095"
 | 
				
			||||||
- samsung,i2s-controller: The phandle of the Samsung I2S controller
 | 
					- samsung,i2s-controller: The phandle of the Samsung I2S controller
 | 
				
			||||||
- samsung,audio-codec: The phandle of the audio codec
 | 
					- samsung,audio-codec: The phandle of the audio codec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional:
 | 
				
			||||||
 | 
					- samsung,model: The name of the sound-card
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sound {
 | 
					sound {
 | 
				
			||||||
		compatible = "google,snow-audio-max98095";
 | 
							compatible = "google,snow-audio-max98095";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							samsung,model = "Snow-I2S-MAX98095";
 | 
				
			||||||
		samsung,i2s-controller = <&i2s0>;
 | 
							samsung,i2s-controller = <&i2s0>;
 | 
				
			||||||
		samsung,audio-codec = <&max98095>;
 | 
							samsung,audio-codec = <&max98095>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								Documentation/devicetree/bindings/sound/tas2552.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Documentation/devicetree/bindings/sound/tas2552.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					Texas Instruments - tas2552 Codec module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The tas2552 serial control bus communicates through I2C protocols
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
						- compatible - One of:
 | 
				
			||||||
 | 
							"ti,tas2552" - TAS2552
 | 
				
			||||||
 | 
						- reg -  I2C slave address
 | 
				
			||||||
 | 
						- supply-*: Required supply regulators are:
 | 
				
			||||||
 | 
							"vbat"		battery voltage
 | 
				
			||||||
 | 
							"iovdd"		I/O Voltage
 | 
				
			||||||
 | 
							"avdd"		Analog DAC Voltage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional properties:
 | 
				
			||||||
 | 
						- enable-gpio - gpio pin to enable/disable the device
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tas2552: tas2552@41 {
 | 
				
			||||||
 | 
						compatible = "ti,tas2552";
 | 
				
			||||||
 | 
						reg = <0x41>;
 | 
				
			||||||
 | 
						enable-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more product information please see the link below:
 | 
				
			||||||
 | 
					http://www.ti.com/product/TAS2552
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,9 @@ Optional properties:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Most systems should not set any of these properties.
 | 
								Most systems should not set any of these properties.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 - avdd-supply:         Power supply for AVDD, providing 3.3V
 | 
				
			||||||
 | 
					 - dvdd-supply:         Power supply for DVDD, providing 3.3V
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Examples:
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i2c_bus {
 | 
						i2c_bus {
 | 
				
			||||||
| 
						 | 
					@ -39,5 +42,7 @@ Examples:
 | 
				
			||||||
			reg = <0x1b>;
 | 
								reg = <0x1b>;
 | 
				
			||||||
			reset-gpio = <&gpio 23 0>;
 | 
								reset-gpio = <&gpio 23 0>;
 | 
				
			||||||
			ti,charge-period = <156000>;
 | 
								ti,charge-period = <156000>;
 | 
				
			||||||
 | 
								avdd-supply = <&vdd_3v3_reg>;
 | 
				
			||||||
 | 
								dvdd-supply = <&vdd_3v3_reg>;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										33
									
								
								Documentation/devicetree/bindings/sound/wm8904.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Documentation/devicetree/bindings/sound/wm8904.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					WM8904 audio CODEC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This device supports I2C only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					  - compatible: "wlf,wm8904"
 | 
				
			||||||
 | 
					  - reg: the I2C address of the device.
 | 
				
			||||||
 | 
					  - clock-names: "mclk"
 | 
				
			||||||
 | 
					  - clocks: reference to
 | 
				
			||||||
 | 
					    <Documentation/devicetree/bindings/clock/clock-bindings.txt>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pins on the device (for linking into audio routes):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * IN1L
 | 
				
			||||||
 | 
					  * IN1R
 | 
				
			||||||
 | 
					  * IN2L
 | 
				
			||||||
 | 
					  * IN2R
 | 
				
			||||||
 | 
					  * IN3L
 | 
				
			||||||
 | 
					  * IN3R
 | 
				
			||||||
 | 
					  * HPOUTL
 | 
				
			||||||
 | 
					  * HPOUTR
 | 
				
			||||||
 | 
					  * LINEOUTL
 | 
				
			||||||
 | 
					  * LINEOUTR
 | 
				
			||||||
 | 
					  * MICBIAS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					codec: wm8904@1a {
 | 
				
			||||||
 | 
						compatible = "wlf,wm8904";
 | 
				
			||||||
 | 
						reg = <0x1a>;
 | 
				
			||||||
 | 
						clocks = <&pck0>;
 | 
				
			||||||
 | 
						clock-names = "mclk";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -2026,8 +2026,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 | 
				
			||||||
  -------------------
 | 
					  -------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Module for sound cards based on the Asus AV66/AV100/AV200 chips,
 | 
					    Module for sound cards based on the Asus AV66/AV100/AV200 chips,
 | 
				
			||||||
    i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), Essence STX,
 | 
					    i.e., Xonar D1, DX, D2, D2X, DS, DSX, Essence ST (Deluxe),
 | 
				
			||||||
    HDAV1.3 (Deluxe), and HDAV1.3 Slim.
 | 
					    Essence STX (II), HDAV1.3 (Deluxe), and HDAV1.3 Slim.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This module supports autoprobe and multiple cards.
 | 
					    This module supports autoprobe and multiple cards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -284,6 +284,11 @@ STAC92HD83*
 | 
				
			||||||
  hp-zephyr	HP Zephyr
 | 
					  hp-zephyr	HP Zephyr
 | 
				
			||||||
  hp-led	HP with broken BIOS for mute LED
 | 
					  hp-led	HP with broken BIOS for mute LED
 | 
				
			||||||
  hp-inv-led	HP with broken BIOS for inverted mute LED
 | 
					  hp-inv-led	HP with broken BIOS for inverted mute LED
 | 
				
			||||||
 | 
					  hp-mic-led	HP with mic-mute LED
 | 
				
			||||||
 | 
					  headset-jack	Dell Latitude with a 4-pin headset jack
 | 
				
			||||||
 | 
					  hp-envy-bass	Pin fixup for HP Envy bass speaker (NID 0x0f)
 | 
				
			||||||
 | 
					  hp-envy-ts-bass Pin fixup for HP Envy TS bass speaker (NID 0x10)
 | 
				
			||||||
 | 
					  hp-bnb13-eq	Hardware equalizer setup for HP laptops
 | 
				
			||||||
  auto		BIOS setup (default)
 | 
					  auto		BIOS setup (default)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
STAC92HD95
 | 
					STAC92HD95
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7526,6 +7526,13 @@ F:	drivers/rtc/
 | 
				
			||||||
F:	include/linux/rtc.h
 | 
					F:	include/linux/rtc.h
 | 
				
			||||||
F:	include/uapi/linux/rtc.h
 | 
					F:	include/uapi/linux/rtc.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REALTEK AUDIO CODECS
 | 
				
			||||||
 | 
					M:	Bard Liao <bardliao@realtek.com>
 | 
				
			||||||
 | 
					M:	Oder Chiou <oder_chiou@realtek.com>
 | 
				
			||||||
 | 
					S:	Maintained
 | 
				
			||||||
 | 
					F:	sound/soc/codecs/rt*
 | 
				
			||||||
 | 
					F:	include/sound/rt*.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
REISERFS FILE SYSTEM
 | 
					REISERFS FILE SYSTEM
 | 
				
			||||||
L:	reiserfs-devel@vger.kernel.org
 | 
					L:	reiserfs-devel@vger.kernel.org
 | 
				
			||||||
S:	Supported
 | 
					S:	Supported
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -998,6 +998,8 @@ static struct platform_device fsi_wm8978_device = {
 | 
				
			||||||
	.id	= 0,
 | 
						.id	= 0,
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi_wm8978_info,
 | 
							.platform_data	= &fsi_wm8978_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_wm8978_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1021,6 +1023,8 @@ static struct platform_device fsi_hdmi_device = {
 | 
				
			||||||
	.id	= 1,
 | 
						.id	= 1,
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi2_hdmi_info,
 | 
							.platform_data	= &fsi2_hdmi_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_hdmi_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -603,6 +603,8 @@ static struct platform_device fsi_ak4648_device = {
 | 
				
			||||||
	.name	= "asoc-simple-card",
 | 
						.name	= "asoc-simple-card",
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi2_ak4648_info,
 | 
							.platform_data	= &fsi2_ak4648_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_ak4648_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -523,6 +523,8 @@ static struct platform_device fsi_hdmi_device = {
 | 
				
			||||||
	.id	= 1,
 | 
						.id	= 1,
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi2_hdmi_info,
 | 
							.platform_data	= &fsi2_hdmi_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_hdmi_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -919,6 +921,8 @@ static struct platform_device fsi_ak4643_device = {
 | 
				
			||||||
	.name	= "asoc-simple-card",
 | 
						.name	= "asoc-simple-card",
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi2_ak4643_info,
 | 
							.platform_data	= &fsi2_ak4643_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_ak4643_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -874,6 +874,8 @@ static struct platform_device fsi_da7210_device = {
 | 
				
			||||||
	.name	= "asoc-simple-card",
 | 
						.name	= "asoc-simple-card",
 | 
				
			||||||
	.dev	= {
 | 
						.dev	= {
 | 
				
			||||||
		.platform_data	= &fsi_da7210_info,
 | 
							.platform_data	= &fsi_da7210_info,
 | 
				
			||||||
 | 
							.coherent_dma_mask = DMA_BIT_MASK(32),
 | 
				
			||||||
 | 
							.dma_mask = &fsi_da7210_device.dev.coherent_dma_mask,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										78
									
								
								arch/x86/include/asm/platform_sst_audio.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								arch/x86/include/asm/platform_sst_audio.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,78 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * platform_sst_audio.h:  sst audio platform data header file
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2012-14 Intel Corporation
 | 
				
			||||||
 | 
					 * Author: Jeeja KP <jeeja.kp@intel.com>
 | 
				
			||||||
 | 
					 * 	Omair Mohammed Abdullah <omair.m.abdullah@intel.com>
 | 
				
			||||||
 | 
					 *	Vinod Koul ,vinod.koul@intel.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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; version 2
 | 
				
			||||||
 | 
					 * of the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#ifndef _PLATFORM_SST_AUDIO_H_
 | 
				
			||||||
 | 
					#define _PLATFORM_SST_AUDIO_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/sfi.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum sst_audio_task_id_mrfld {
 | 
				
			||||||
 | 
						SST_TASK_ID_NONE = 0,
 | 
				
			||||||
 | 
						SST_TASK_ID_SBA = 1,
 | 
				
			||||||
 | 
						SST_TASK_ID_MEDIA = 3,
 | 
				
			||||||
 | 
						SST_TASK_ID_MAX = SST_TASK_ID_MEDIA,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Device IDs for Merrifield are Pipe IDs,
 | 
				
			||||||
 | 
					 * ref: DSP spec v0.75 */
 | 
				
			||||||
 | 
					enum sst_audio_device_id_mrfld {
 | 
				
			||||||
 | 
						/* Output pipeline IDs */
 | 
				
			||||||
 | 
						PIPE_ID_OUT_START = 0x0,
 | 
				
			||||||
 | 
						PIPE_CODEC_OUT0 = 0x2,
 | 
				
			||||||
 | 
						PIPE_CODEC_OUT1 = 0x3,
 | 
				
			||||||
 | 
						PIPE_SPROT_LOOP_OUT = 0x4,
 | 
				
			||||||
 | 
						PIPE_MEDIA_LOOP1_OUT = 0x5,
 | 
				
			||||||
 | 
						PIPE_MEDIA_LOOP2_OUT = 0x6,
 | 
				
			||||||
 | 
						PIPE_VOIP_OUT = 0xC,
 | 
				
			||||||
 | 
						PIPE_PCM0_OUT = 0xD,
 | 
				
			||||||
 | 
						PIPE_PCM1_OUT = 0xE,
 | 
				
			||||||
 | 
						PIPE_PCM2_OUT = 0xF,
 | 
				
			||||||
 | 
						PIPE_MEDIA0_OUT = 0x12,
 | 
				
			||||||
 | 
						PIPE_MEDIA1_OUT = 0x13,
 | 
				
			||||||
 | 
					/* Input Pipeline IDs */
 | 
				
			||||||
 | 
						PIPE_ID_IN_START = 0x80,
 | 
				
			||||||
 | 
						PIPE_CODEC_IN0 = 0x82,
 | 
				
			||||||
 | 
						PIPE_CODEC_IN1 = 0x83,
 | 
				
			||||||
 | 
						PIPE_SPROT_LOOP_IN = 0x84,
 | 
				
			||||||
 | 
						PIPE_MEDIA_LOOP1_IN = 0x85,
 | 
				
			||||||
 | 
						PIPE_MEDIA_LOOP2_IN = 0x86,
 | 
				
			||||||
 | 
						PIPE_VOIP_IN = 0x8C,
 | 
				
			||||||
 | 
						PIPE_PCM0_IN = 0x8D,
 | 
				
			||||||
 | 
						PIPE_PCM1_IN = 0x8E,
 | 
				
			||||||
 | 
						PIPE_MEDIA0_IN = 0x8F,
 | 
				
			||||||
 | 
						PIPE_MEDIA1_IN = 0x90,
 | 
				
			||||||
 | 
						PIPE_MEDIA2_IN = 0x91,
 | 
				
			||||||
 | 
						PIPE_RSVD = 0xFF,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* The stream map for each platform consists of an array of the below
 | 
				
			||||||
 | 
					 * stream map structure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct sst_dev_stream_map {
 | 
				
			||||||
 | 
						u8 dev_num;		/* device id */
 | 
				
			||||||
 | 
						u8 subdev_num;		/* substream */
 | 
				
			||||||
 | 
						u8 direction;
 | 
				
			||||||
 | 
						u8 device_id;		/* fw id */
 | 
				
			||||||
 | 
						u8 task_id;		/* fw task */
 | 
				
			||||||
 | 
						u8 status;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sst_platform_data {
 | 
				
			||||||
 | 
						/* Intel software platform id*/
 | 
				
			||||||
 | 
						struct sst_dev_stream_map *pdev_strm_map;
 | 
				
			||||||
 | 
						unsigned int strm_map_size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int add_sst_platform_device(void);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -982,6 +982,7 @@ static void __init edma_chan_init(struct edma_cc *ecc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
 | 
					#define EDMA_DMA_BUSWIDTHS	(BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
 | 
				
			||||||
				 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
 | 
									 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
 | 
				
			||||||
 | 
									 BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \
 | 
				
			||||||
				 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
 | 
									 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int edma_dma_device_slave_caps(struct dma_chan *dchan,
 | 
					static int edma_dma_device_slave_caps(struct dma_chan *dchan,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,16 +83,26 @@ EXPORT_SYMBOL(ssc_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct atmel_ssc_platform_data at91rm9200_config = {
 | 
					static struct atmel_ssc_platform_data at91rm9200_config = {
 | 
				
			||||||
	.use_dma = 0,
 | 
						.use_dma = 0,
 | 
				
			||||||
 | 
						.has_fslen_ext = 0,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct atmel_ssc_platform_data at91sam9rl_config = {
 | 
				
			||||||
 | 
						.use_dma = 0,
 | 
				
			||||||
 | 
						.has_fslen_ext = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct atmel_ssc_platform_data at91sam9g45_config = {
 | 
					static struct atmel_ssc_platform_data at91sam9g45_config = {
 | 
				
			||||||
	.use_dma = 1,
 | 
						.use_dma = 1,
 | 
				
			||||||
 | 
						.has_fslen_ext = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct platform_device_id atmel_ssc_devtypes[] = {
 | 
					static const struct platform_device_id atmel_ssc_devtypes[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.name = "at91rm9200_ssc",
 | 
							.name = "at91rm9200_ssc",
 | 
				
			||||||
		.driver_data = (unsigned long) &at91rm9200_config,
 | 
							.driver_data = (unsigned long) &at91rm9200_config,
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							.name = "at91sam9rl_ssc",
 | 
				
			||||||
 | 
							.driver_data = (unsigned long) &at91sam9rl_config,
 | 
				
			||||||
	}, {
 | 
						}, {
 | 
				
			||||||
		.name = "at91sam9g45_ssc",
 | 
							.name = "at91sam9g45_ssc",
 | 
				
			||||||
		.driver_data = (unsigned long) &at91sam9g45_config,
 | 
							.driver_data = (unsigned long) &at91sam9g45_config,
 | 
				
			||||||
| 
						 | 
					@ -106,6 +116,9 @@ static const struct of_device_id atmel_ssc_dt_ids[] = {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		.compatible = "atmel,at91rm9200-ssc",
 | 
							.compatible = "atmel,at91rm9200-ssc",
 | 
				
			||||||
		.data = &at91rm9200_config,
 | 
							.data = &at91rm9200_config,
 | 
				
			||||||
 | 
						}, {
 | 
				
			||||||
 | 
							.compatible = "atmel,at91sam9rl-ssc",
 | 
				
			||||||
 | 
							.data = &at91sam9rl_config,
 | 
				
			||||||
	}, {
 | 
						}, {
 | 
				
			||||||
		.compatible = "atmel,at91sam9g45-ssc",
 | 
							.compatible = "atmel,at91sam9g45-ssc",
 | 
				
			||||||
		.data = &at91sam9g45_config,
 | 
							.data = &at91sam9g45_config,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct atmel_ssc_platform_data {
 | 
					struct atmel_ssc_platform_data {
 | 
				
			||||||
	int			use_dma;
 | 
						int			use_dma;
 | 
				
			||||||
 | 
						int			has_fslen_ext;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ssc_device {
 | 
					struct ssc_device {
 | 
				
			||||||
| 
						 | 
					@ -71,6 +72,12 @@ void ssc_free(struct ssc_device *ssc);
 | 
				
			||||||
#define SSC_RFMR_DATNB_OFFSET			 8
 | 
					#define SSC_RFMR_DATNB_OFFSET			 8
 | 
				
			||||||
#define SSC_RFMR_FSEDGE_SIZE			 1
 | 
					#define SSC_RFMR_FSEDGE_SIZE			 1
 | 
				
			||||||
#define SSC_RFMR_FSEDGE_OFFSET			24
 | 
					#define SSC_RFMR_FSEDGE_OFFSET			24
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The FSLEN_EXT exist on at91sam9rl, at91sam9g10,
 | 
				
			||||||
 | 
					 * at91sam9g20, and at91sam9g45 and newer SoCs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SSC_RFMR_FSLEN_EXT_SIZE			 4
 | 
				
			||||||
 | 
					#define SSC_RFMR_FSLEN_EXT_OFFSET		28
 | 
				
			||||||
#define SSC_RFMR_FSLEN_SIZE			 4
 | 
					#define SSC_RFMR_FSLEN_SIZE			 4
 | 
				
			||||||
#define SSC_RFMR_FSLEN_OFFSET			16
 | 
					#define SSC_RFMR_FSLEN_OFFSET			16
 | 
				
			||||||
#define SSC_RFMR_FSOS_SIZE			 4
 | 
					#define SSC_RFMR_FSOS_SIZE			 4
 | 
				
			||||||
| 
						 | 
					@ -109,6 +116,12 @@ void ssc_free(struct ssc_device *ssc);
 | 
				
			||||||
#define SSC_TFMR_FSDEN_OFFSET			23
 | 
					#define SSC_TFMR_FSDEN_OFFSET			23
 | 
				
			||||||
#define SSC_TFMR_FSEDGE_SIZE			 1
 | 
					#define SSC_TFMR_FSEDGE_SIZE			 1
 | 
				
			||||||
#define SSC_TFMR_FSEDGE_OFFSET			24
 | 
					#define SSC_TFMR_FSEDGE_OFFSET			24
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The FSLEN_EXT exist on at91sam9rl, at91sam9g10,
 | 
				
			||||||
 | 
					 * at91sam9g20, and at91sam9g45 and newer SoCs
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SSC_TFMR_FSLEN_EXT_SIZE			 4
 | 
				
			||||||
 | 
					#define SSC_TFMR_FSLEN_EXT_OFFSET		28
 | 
				
			||||||
#define SSC_TFMR_FSLEN_SIZE			 4
 | 
					#define SSC_TFMR_FSLEN_SIZE			 4
 | 
				
			||||||
#define SSC_TFMR_FSLEN_OFFSET			16
 | 
					#define SSC_TFMR_FSLEN_OFFSET			16
 | 
				
			||||||
#define SSC_TFMR_FSOS_SIZE			 3
 | 
					#define SSC_TFMR_FSOS_SIZE			 3
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -299,6 +299,7 @@ enum dma_slave_buswidth {
 | 
				
			||||||
	DMA_SLAVE_BUSWIDTH_UNDEFINED = 0,
 | 
						DMA_SLAVE_BUSWIDTH_UNDEFINED = 0,
 | 
				
			||||||
	DMA_SLAVE_BUSWIDTH_1_BYTE = 1,
 | 
						DMA_SLAVE_BUSWIDTH_1_BYTE = 1,
 | 
				
			||||||
	DMA_SLAVE_BUSWIDTH_2_BYTES = 2,
 | 
						DMA_SLAVE_BUSWIDTH_2_BYTES = 2,
 | 
				
			||||||
 | 
						DMA_SLAVE_BUSWIDTH_3_BYTES = 3,
 | 
				
			||||||
	DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
 | 
						DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
 | 
				
			||||||
	DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
 | 
						DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,6 +110,12 @@ struct arizona {
 | 
				
			||||||
	int clk32k_ref;
 | 
						int clk32k_ref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm;
 | 
						struct snd_soc_dapm_context *dapm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int tdm_width[ARIZONA_MAX_AIF];
 | 
				
			||||||
 | 
						int tdm_slots[ARIZONA_MAX_AIF];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint16_t dac_comp_coeff;
 | 
				
			||||||
 | 
						uint8_t dac_comp_enabled;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arizona_clk32k_enable(struct arizona *arizona);
 | 
					int arizona_clk32k_enable(struct arizona *arizona);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,15 +15,6 @@
 | 
				
			||||||
#define S3C64XX_AC97_GPE  1
 | 
					#define S3C64XX_AC97_GPE  1
 | 
				
			||||||
extern void s3c64xx_ac97_setup_gpio(int);
 | 
					extern void s3c64xx_ac97_setup_gpio(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * The machine init code calls s5p*_spdif_setup_gpio with
 | 
					 | 
				
			||||||
 * one of these defines in order to select appropriate bank
 | 
					 | 
				
			||||||
 * of GPIO for S/PDIF pins
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define S5PC100_SPDIF_GPD  0
 | 
					 | 
				
			||||||
#define S5PC100_SPDIF_GPG3 1
 | 
					 | 
				
			||||||
extern void s5pc100_spdif_setup_gpio(int);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct samsung_i2s {
 | 
					struct samsung_i2s {
 | 
				
			||||||
/* If the Primary DAI has 5.1 Channels */
 | 
					/* If the Primary DAI has 5.1 Channels */
 | 
				
			||||||
#define QUIRK_PRI_6CHAN		(1 << 0)
 | 
					#define QUIRK_PRI_6CHAN		(1 << 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,7 @@ enum imx_dma_prio {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct imx_dma_data {
 | 
					struct imx_dma_data {
 | 
				
			||||||
	int dma_request; /* DMA request line */
 | 
						int dma_request; /* DMA request line */
 | 
				
			||||||
 | 
						int dma_request2; /* secondary DMA request line */
 | 
				
			||||||
	enum sdma_peripheral_type peripheral_type;
 | 
						enum sdma_peripheral_type peripheral_type;
 | 
				
			||||||
	int priority;
 | 
						int priority;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,10 +31,15 @@ typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ct
 | 
				
			||||||
typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
 | 
					typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
 | 
				
			||||||
typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
 | 
					typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
 | 
				
			||||||
typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
 | 
					typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
				    int op_flag, /* 0=read,1=write,-1=command */
 | 
									    int op_flag, /* SNDRV_CTL_TLV_OP_XXX */
 | 
				
			||||||
				    unsigned int size,
 | 
									    unsigned int size,
 | 
				
			||||||
				    unsigned int __user *tlv);
 | 
									    unsigned int __user *tlv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SNDRV_CTL_TLV_OP_READ = 0,
 | 
				
			||||||
 | 
						SNDRV_CTL_TLV_OP_WRITE = 1,
 | 
				
			||||||
 | 
						SNDRV_CTL_TLV_OP_CMD = -1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_kcontrol_new {
 | 
					struct snd_kcontrol_new {
 | 
				
			||||||
	snd_ctl_elem_iface_t iface;	/* interface identifier */
 | 
						snd_ctl_elem_iface_t iface;	/* interface identifier */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -931,10 +931,17 @@ void snd_pcm_timer_done(struct snd_pcm_substream *substream);
 | 
				
			||||||
static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
 | 
					static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
 | 
				
			||||||
				   struct timespec *tv)
 | 
									   struct timespec *tv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (runtime->tstamp_type == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
 | 
						switch (runtime->tstamp_type) {
 | 
				
			||||||
 | 
						case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
 | 
				
			||||||
		ktime_get_ts(tv);
 | 
							ktime_get_ts(tv);
 | 
				
			||||||
	else
 | 
							break;
 | 
				
			||||||
 | 
						case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
 | 
				
			||||||
 | 
							getrawmonotonic(tv);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
		getnstimeofday(tv);
 | 
							getnstimeofday(tv);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,7 @@
 | 
				
			||||||
 * B : SSI direction
 | 
					 * B : SSI direction
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define RSND_SSI_CLK_PIN_SHARE		(1 << 31)
 | 
					#define RSND_SSI_CLK_PIN_SHARE		(1 << 31)
 | 
				
			||||||
 | 
					#define RSND_SSI_NO_BUSIF		(1 << 30) /* SSI+DMA without BUSIF */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RSND_SSI(_dma_id, _pio_irq, _flags)		\
 | 
					#define RSND_SSI(_dma_id, _pio_irq, _flags)		\
 | 
				
			||||||
{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
 | 
					{ .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								include/sound/rt286.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								include/sound/rt286.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * linux/sound/rt286.h -- Platform data for RT286
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2013 Realtek Microelectronics
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __LINUX_SND_RT286_H
 | 
				
			||||||
 | 
					#define __LINUX_SND_RT286_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rt286_platform_data {
 | 
				
			||||||
 | 
						bool cbj_en; /*combo jack enable*/
 | 
				
			||||||
 | 
						bool gpio2_en; /*GPIO2 enable*/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										27
									
								
								include/sound/rt5670.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								include/sound/rt5670.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * linux/sound/rt5670.h -- Platform data for RT5670
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2014 Realtek Microelectronics
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __LINUX_SND_RT5670_H
 | 
				
			||||||
 | 
					#define __LINUX_SND_RT5670_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rt5670_platform_data {
 | 
				
			||||||
 | 
						int jd_mode;
 | 
				
			||||||
 | 
						bool in2_diff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool dmic_en;
 | 
				
			||||||
 | 
						unsigned int dmic1_data_pin;
 | 
				
			||||||
 | 
						/* 0 = GPIO6; 1 = IN2P; 3 = GPIO7*/
 | 
				
			||||||
 | 
						unsigned int dmic2_data_pin;
 | 
				
			||||||
 | 
						/* 0 = GPIO8; 1 = IN3N; */
 | 
				
			||||||
 | 
						unsigned int dmic3_data_pin;
 | 
				
			||||||
 | 
						/* 0 = GPIO9; 1 = GPIO10; 2 = GPIO5*/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -257,7 +257,6 @@ struct snd_soc_dai {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_dapm_widget *playback_widget;
 | 
						struct snd_soc_dapm_widget *playback_widget;
 | 
				
			||||||
	struct snd_soc_dapm_widget *capture_widget;
 | 
						struct snd_soc_dapm_widget *capture_widget;
 | 
				
			||||||
	struct snd_soc_dapm_context dapm;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* DAI DMA data */
 | 
						/* DAI DMA data */
 | 
				
			||||||
	void *playback_dma_data;
 | 
						void *playback_dma_data;
 | 
				
			||||||
| 
						 | 
					@ -273,6 +272,10 @@ struct snd_soc_dai {
 | 
				
			||||||
	struct snd_soc_codec *codec;
 | 
						struct snd_soc_codec *codec;
 | 
				
			||||||
	struct snd_soc_component *component;
 | 
						struct snd_soc_component *component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* CODEC TDM slot masks and params (for fixup) */
 | 
				
			||||||
 | 
						unsigned int tx_mask;
 | 
				
			||||||
 | 
						unsigned int rx_mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_card *card;
 | 
						struct snd_soc_card *card;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -431,7 +431,7 @@ int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
					   const char *pin);
 | 
										   const char *pin);
 | 
				
			||||||
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 | 
					int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
				const char *pin);
 | 
									const char *pin);
 | 
				
			||||||
void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec);
 | 
					void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mostly internal - should not normally be used */
 | 
					/* Mostly internal - should not normally be used */
 | 
				
			||||||
void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm);
 | 
					void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm);
 | 
				
			||||||
| 
						 | 
					@ -441,6 +441,8 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
 | 
				
			||||||
	struct snd_soc_dapm_widget_list **list);
 | 
						struct snd_soc_dapm_widget_list **list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol);
 | 
					struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol);
 | 
				
			||||||
 | 
					struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
 | 
				
			||||||
 | 
						struct snd_kcontrol *kcontrol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* dapm widget types */
 | 
					/* dapm widget types */
 | 
				
			||||||
enum snd_soc_dapm_type {
 | 
					enum snd_soc_dapm_type {
 | 
				
			||||||
| 
						 | 
					@ -524,7 +526,6 @@ struct snd_soc_dapm_widget {
 | 
				
			||||||
	const char *name;		/* widget name */
 | 
						const char *name;		/* widget name */
 | 
				
			||||||
	const char *sname;	/* stream name */
 | 
						const char *sname;	/* stream name */
 | 
				
			||||||
	struct snd_soc_codec *codec;
 | 
						struct snd_soc_codec *codec;
 | 
				
			||||||
	struct snd_soc_platform *platform;
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm;
 | 
						struct snd_soc_dapm_context *dapm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,7 +594,6 @@ struct snd_soc_dapm_context {
 | 
				
			||||||
	struct device *dev; /* from parent - for debug */
 | 
						struct device *dev; /* from parent - for debug */
 | 
				
			||||||
	struct snd_soc_component *component; /* parent component */
 | 
						struct snd_soc_component *component; /* parent component */
 | 
				
			||||||
	struct snd_soc_codec *codec; /* parent codec */
 | 
						struct snd_soc_codec *codec; /* parent codec */
 | 
				
			||||||
	struct snd_soc_platform *platform; /* parent platform */
 | 
					 | 
				
			||||||
	struct snd_soc_card *card; /* parent card */
 | 
						struct snd_soc_card *card; /* parent card */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* used during DAPM updates */
 | 
						/* used during DAPM updates */
 | 
				
			||||||
| 
						 | 
					@ -601,6 +601,8 @@ struct snd_soc_dapm_context {
 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 | 
						int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 | 
				
			||||||
 | 
						int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
 | 
				
			||||||
 | 
								      enum snd_soc_bias_level level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	struct dentry *debugfs_dapm;
 | 
						struct dentry *debugfs_dapm;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,6 +248,8 @@
 | 
				
			||||||
	.info = snd_soc_info_enum_double, \
 | 
						.info = snd_soc_info_enum_double, \
 | 
				
			||||||
	.get = xhandler_get, .put = xhandler_put, \
 | 
						.get = xhandler_get, .put = xhandler_put, \
 | 
				
			||||||
	.private_value = (unsigned long)&xenum }
 | 
						.private_value = (unsigned long)&xenum }
 | 
				
			||||||
 | 
					#define SOC_VALUE_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
 | 
				
			||||||
 | 
						SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SND_SOC_BYTES(xname, xbase, xregs)		      \
 | 
					#define SND_SOC_BYTES(xname, xbase, xregs)		      \
 | 
				
			||||||
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
 | 
					{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
 | 
				
			||||||
| 
						 | 
					@ -270,7 +272,14 @@
 | 
				
			||||||
	.get = xhandler_get, .put = xhandler_put, \
 | 
						.get = xhandler_get, .put = xhandler_put, \
 | 
				
			||||||
	.private_value = (unsigned long)&(struct soc_bytes_ext) \
 | 
						.private_value = (unsigned long)&(struct soc_bytes_ext) \
 | 
				
			||||||
		{.max = xcount} }
 | 
							{.max = xcount} }
 | 
				
			||||||
 | 
					#define SND_SOC_BYTES_TLV(xname, xcount, xhandler_get, xhandler_put) \
 | 
				
			||||||
 | 
					{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 | 
				
			||||||
 | 
						.access = SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE | \
 | 
				
			||||||
 | 
							  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
 | 
				
			||||||
 | 
						.tlv.c = (snd_soc_bytes_tlv_callback), \
 | 
				
			||||||
 | 
						.info = snd_soc_info_bytes_ext, \
 | 
				
			||||||
 | 
						.private_value = (unsigned long)&(struct soc_bytes_ext) \
 | 
				
			||||||
 | 
							{.max = xcount, .get = xhandler_get, .put = xhandler_put, } }
 | 
				
			||||||
#define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
 | 
					#define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
 | 
				
			||||||
		xmin, xmax, xinvert) \
 | 
							xmin, xmax, xinvert) \
 | 
				
			||||||
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 | 
					{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 | 
				
			||||||
| 
						 | 
					@ -436,6 +445,10 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
 | 
				
			||||||
int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
 | 
					int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
 | 
				
			||||||
		int cmd, struct snd_soc_platform *platform);
 | 
							int cmd, struct snd_soc_platform *platform);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int soc_dai_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
 | 
							      struct snd_pcm_hw_params *params,
 | 
				
			||||||
 | 
							      struct snd_soc_dai *dai);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Jack reporting */
 | 
					/* Jack reporting */
 | 
				
			||||||
int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
 | 
					int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
 | 
				
			||||||
		     struct snd_soc_jack *jack);
 | 
							     struct snd_soc_jack *jack);
 | 
				
			||||||
| 
						 | 
					@ -503,10 +516,12 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
 | 
				
			||||||
				  const char *prefix);
 | 
									  const char *prefix);
 | 
				
			||||||
struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
 | 
					struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
 | 
				
			||||||
					       const char *name);
 | 
										       const char *name);
 | 
				
			||||||
 | 
					int snd_soc_add_component_controls(struct snd_soc_component *component,
 | 
				
			||||||
 | 
						const struct snd_kcontrol_new *controls, unsigned int num_controls);
 | 
				
			||||||
int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
 | 
					int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
 | 
				
			||||||
	const struct snd_kcontrol_new *controls, int num_controls);
 | 
						const struct snd_kcontrol_new *controls, unsigned int num_controls);
 | 
				
			||||||
int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
 | 
					int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
 | 
				
			||||||
	const struct snd_kcontrol_new *controls, int num_controls);
 | 
						const struct snd_kcontrol_new *controls, unsigned int num_controls);
 | 
				
			||||||
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
 | 
					int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
 | 
				
			||||||
	const struct snd_kcontrol_new *controls, int num_controls);
 | 
						const struct snd_kcontrol_new *controls, int num_controls);
 | 
				
			||||||
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
 | 
					int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
 | 
				
			||||||
| 
						 | 
					@ -552,6 +567,8 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
		      struct snd_ctl_elem_value *ucontrol);
 | 
							      struct snd_ctl_elem_value *ucontrol);
 | 
				
			||||||
int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
 | 
					int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_ctl_elem_info *ucontrol);
 | 
						struct snd_ctl_elem_info *ucontrol);
 | 
				
			||||||
 | 
					int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag,
 | 
				
			||||||
 | 
						unsigned int size, unsigned int __user *tlv);
 | 
				
			||||||
int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
 | 
					int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
	struct snd_ctl_elem_info *uinfo);
 | 
						struct snd_ctl_elem_info *uinfo);
 | 
				
			||||||
int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
 | 
					int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
| 
						 | 
					@ -677,12 +694,17 @@ struct snd_soc_component_driver {
 | 
				
			||||||
	int (*of_xlate_dai_name)(struct snd_soc_component *component,
 | 
						int (*of_xlate_dai_name)(struct snd_soc_component *component,
 | 
				
			||||||
				 struct of_phandle_args *args,
 | 
									 struct of_phandle_args *args,
 | 
				
			||||||
				 const char **dai_name);
 | 
									 const char **dai_name);
 | 
				
			||||||
 | 
						void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
 | 
				
			||||||
 | 
							int subseq);
 | 
				
			||||||
 | 
						int (*stream_event)(struct snd_soc_component *, int event);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_soc_component {
 | 
					struct snd_soc_component {
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	int id;
 | 
						int id;
 | 
				
			||||||
 | 
						const char *name_prefix;
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
 | 
						struct snd_soc_card *card;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int active;
 | 
						unsigned int active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -705,18 +727,18 @@ struct snd_soc_component {
 | 
				
			||||||
	int val_bytes;
 | 
						int val_bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mutex io_mutex;
 | 
						struct mutex io_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Don't use these, use snd_soc_component_get_dapm() */
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context dapm;
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm_ptr;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SoC Audio Codec device */
 | 
					/* SoC Audio Codec device */
 | 
				
			||||||
struct snd_soc_codec {
 | 
					struct snd_soc_codec {
 | 
				
			||||||
	const char *name;
 | 
					 | 
				
			||||||
	const char *name_prefix;
 | 
					 | 
				
			||||||
	int id;
 | 
					 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
	const struct snd_soc_codec_driver *driver;
 | 
						const struct snd_soc_codec_driver *driver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct mutex mutex;
 | 
						struct mutex mutex;
 | 
				
			||||||
	struct snd_soc_card *card;
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
	struct list_head card_list;
 | 
						struct list_head card_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -790,9 +812,6 @@ struct snd_soc_codec_driver {
 | 
				
			||||||
	void (*seq_notifier)(struct snd_soc_dapm_context *,
 | 
						void (*seq_notifier)(struct snd_soc_dapm_context *,
 | 
				
			||||||
			     enum snd_soc_dapm_type, int);
 | 
								     enum snd_soc_dapm_type, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* codec stream completion event */
 | 
					 | 
				
			||||||
	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
 | 
						bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* probe ordering - for components with runtime dependencies */
 | 
						/* probe ordering - for components with runtime dependencies */
 | 
				
			||||||
| 
						 | 
					@ -834,9 +853,6 @@ struct snd_soc_platform_driver {
 | 
				
			||||||
	/* platform stream compress ops */
 | 
						/* platform stream compress ops */
 | 
				
			||||||
	const struct snd_compr_ops *compr_ops;
 | 
						const struct snd_compr_ops *compr_ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* platform stream completion event */
 | 
					 | 
				
			||||||
	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* probe ordering - for components with runtime dependencies */
 | 
						/* probe ordering - for components with runtime dependencies */
 | 
				
			||||||
	int probe_order;
 | 
						int probe_order;
 | 
				
			||||||
	int remove_order;
 | 
						int remove_order;
 | 
				
			||||||
| 
						 | 
					@ -847,23 +863,23 @@ struct snd_soc_platform_driver {
 | 
				
			||||||
	int (*bespoke_trigger)(struct snd_pcm_substream *, int);
 | 
						int (*bespoke_trigger)(struct snd_pcm_substream *, int);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_soc_platform {
 | 
					struct snd_soc_dai_link_component {
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	int id;
 | 
						const struct device_node *of_node;
 | 
				
			||||||
 | 
						const char *dai_name;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct snd_soc_platform {
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
	const struct snd_soc_platform_driver *driver;
 | 
						const struct snd_soc_platform_driver *driver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int suspended:1; /* platform is suspended */
 | 
						unsigned int suspended:1; /* platform is suspended */
 | 
				
			||||||
	unsigned int probed:1;
 | 
						unsigned int probed:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_card *card;
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
	struct list_head card_list;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_component component;
 | 
						struct snd_soc_component component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct snd_soc_dapm_context dapm;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	struct dentry *debugfs_platform_root;
 | 
						struct dentry *debugfs_platform_root;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -896,6 +912,10 @@ struct snd_soc_dai_link {
 | 
				
			||||||
	const struct device_node *codec_of_node;
 | 
						const struct device_node *codec_of_node;
 | 
				
			||||||
	/* You MUST specify the DAI name within the codec */
 | 
						/* You MUST specify the DAI name within the codec */
 | 
				
			||||||
	const char *codec_dai_name;
 | 
						const char *codec_dai_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct snd_soc_dai_link_component *codecs;
 | 
				
			||||||
 | 
						unsigned int num_codecs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * You MAY specify the link's platform/PCM/DMA driver, either by
 | 
						 * You MAY specify the link's platform/PCM/DMA driver, either by
 | 
				
			||||||
	 * device name, or by DT/OF node, but not both. Some forms of link
 | 
						 * device name, or by DT/OF node, but not both. Some forms of link
 | 
				
			||||||
| 
						 | 
					@ -1047,7 +1067,6 @@ struct snd_soc_card {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* lists of probed devices belonging to this card */
 | 
						/* lists of probed devices belonging to this card */
 | 
				
			||||||
	struct list_head codec_dev_list;
 | 
						struct list_head codec_dev_list;
 | 
				
			||||||
	struct list_head platform_dev_list;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct list_head widgets;
 | 
						struct list_head widgets;
 | 
				
			||||||
	struct list_head paths;
 | 
						struct list_head paths;
 | 
				
			||||||
| 
						 | 
					@ -1094,6 +1113,9 @@ struct snd_soc_pcm_runtime {
 | 
				
			||||||
	struct snd_soc_dai *codec_dai;
 | 
						struct snd_soc_dai *codec_dai;
 | 
				
			||||||
	struct snd_soc_dai *cpu_dai;
 | 
						struct snd_soc_dai *cpu_dai;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct snd_soc_dai **codec_dais;
 | 
				
			||||||
 | 
						unsigned int num_codecs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct delayed_work delayed_work;
 | 
						struct delayed_work delayed_work;
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
	struct dentry *debugfs_dpcm_root;
 | 
						struct dentry *debugfs_dpcm_root;
 | 
				
			||||||
| 
						 | 
					@ -1119,6 +1141,9 @@ struct soc_bytes {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct soc_bytes_ext {
 | 
					struct soc_bytes_ext {
 | 
				
			||||||
	int max;
 | 
						int max;
 | 
				
			||||||
 | 
						/* used for TLV byte control */
 | 
				
			||||||
 | 
						int (*get)(unsigned int __user *bytes, unsigned int size);
 | 
				
			||||||
 | 
						int (*put)(const unsigned int __user *bytes, unsigned int size);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* multi register control */
 | 
					/* multi register control */
 | 
				
			||||||
| 
						 | 
					@ -1164,6 +1189,21 @@ static inline struct snd_soc_platform *snd_soc_component_to_platform(
 | 
				
			||||||
	return container_of(component, struct snd_soc_platform, component);
 | 
						return container_of(component, struct snd_soc_platform, component);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
 | 
				
			||||||
 | 
					 *  embedded in
 | 
				
			||||||
 | 
					 * @dapm: The DAPM context to cast to the component
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This function must only be used on DAPM contexts that are known to be part of
 | 
				
			||||||
 | 
					 * a component (e.g. in a component driver). Otherwise the behavior is
 | 
				
			||||||
 | 
					 * undefined.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline struct snd_soc_component *snd_soc_dapm_to_component(
 | 
				
			||||||
 | 
						struct snd_soc_dapm_context *dapm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return container_of(dapm, struct snd_soc_component, dapm);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
 | 
					 * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
 | 
				
			||||||
 * @dapm: The DAPM context to cast to the CODEC
 | 
					 * @dapm: The DAPM context to cast to the CODEC
 | 
				
			||||||
| 
						 | 
					@ -1188,7 +1228,18 @@ static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
 | 
				
			||||||
static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
 | 
					static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
 | 
				
			||||||
	struct snd_soc_dapm_context *dapm)
 | 
						struct snd_soc_dapm_context *dapm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return container_of(dapm, struct snd_soc_platform, dapm);
 | 
						return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
 | 
				
			||||||
 | 
					 *  component
 | 
				
			||||||
 | 
					 * @component: The component for which to get the DAPM context
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
 | 
				
			||||||
 | 
						struct snd_soc_component *component)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return component->dapm_ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* codec IO */
 | 
					/* codec IO */
 | 
				
			||||||
| 
						 | 
					@ -1261,7 +1312,6 @@ static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd)
 | 
				
			||||||
static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
 | 
					static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	INIT_LIST_HEAD(&card->codec_dev_list);
 | 
						INIT_LIST_HEAD(&card->codec_dev_list);
 | 
				
			||||||
	INIT_LIST_HEAD(&card->platform_dev_list);
 | 
					 | 
				
			||||||
	INIT_LIST_HEAD(&card->widgets);
 | 
						INIT_LIST_HEAD(&card->widgets);
 | 
				
			||||||
	INIT_LIST_HEAD(&card->paths);
 | 
						INIT_LIST_HEAD(&card->paths);
 | 
				
			||||||
	INIT_LIST_HEAD(&card->dapm_list);
 | 
						INIT_LIST_HEAD(&card->dapm_list);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								include/sound/tas2552-plat.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								include/sound/tas2552-plat.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * TAS2552 driver platform header
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2014 Texas Instruments Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Author: Dan Murphy <dmurphy@ti.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 TAS2552_PLAT_H
 | 
				
			||||||
 | 
					#define TAS2552_PLAT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct tas2552_platform_data {
 | 
				
			||||||
 | 
						int enable_gpio;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#define WM8962_GPIO_FN_MICSCD          22
 | 
					#define WM8962_GPIO_FN_MICSCD          22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wm8962_pdata {
 | 
					struct wm8962_pdata {
 | 
				
			||||||
 | 
						struct clk *mclk;
 | 
				
			||||||
	int gpio_base;
 | 
						int gpio_base;
 | 
				
			||||||
	u32 gpio_init[WM8962_MAX_GPIO];
 | 
						u32 gpio_init[WM8962_MAX_GPIO];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,17 +296,17 @@ TRACE_EVENT(snd_soc_cache_sync,
 | 
				
			||||||
	TP_ARGS(codec, type, status),
 | 
						TP_ARGS(codec, type, status),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TP_STRUCT__entry(
 | 
						TP_STRUCT__entry(
 | 
				
			||||||
		__string(	name,		codec->name	)
 | 
							__string(	name,		codec->component.name)
 | 
				
			||||||
		__string(	status,		status		)
 | 
							__string(	status,		status		)
 | 
				
			||||||
		__string(	type,		type		)
 | 
							__string(	type,		type		)
 | 
				
			||||||
		__field(	int,		id		)
 | 
							__field(	int,		id		)
 | 
				
			||||||
	),
 | 
						),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TP_fast_assign(
 | 
						TP_fast_assign(
 | 
				
			||||||
		__assign_str(name, codec->name);
 | 
							__assign_str(name, codec->component.name);
 | 
				
			||||||
		__assign_str(status, status);
 | 
							__assign_str(status, status);
 | 
				
			||||||
		__assign_str(type, type);
 | 
							__assign_str(type, type);
 | 
				
			||||||
		__entry->id = codec->id;
 | 
							__entry->id = codec->component.id;
 | 
				
			||||||
	),
 | 
						),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TP_printk("codec=%s.%d type=%s status=%s", __get_str(name),
 | 
						TP_printk("codec=%s.%d type=%s status=%s", __get_str(name),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,7 +139,7 @@ struct snd_hwdep_dsp_image {
 | 
				
			||||||
 *                                                                           *
 | 
					 *                                                                           *
 | 
				
			||||||
 *****************************************************************************/
 | 
					 *****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 11)
 | 
					#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef unsigned long snd_pcm_uframes_t;
 | 
					typedef unsigned long snd_pcm_uframes_t;
 | 
				
			||||||
typedef signed long snd_pcm_sframes_t;
 | 
					typedef signed long snd_pcm_sframes_t;
 | 
				
			||||||
| 
						 | 
					@ -391,7 +391,9 @@ struct snd_pcm_sw_params {
 | 
				
			||||||
	snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
 | 
						snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
 | 
				
			||||||
	snd_pcm_uframes_t silence_size;		/* silence block size */
 | 
						snd_pcm_uframes_t silence_size;		/* silence block size */
 | 
				
			||||||
	snd_pcm_uframes_t boundary;		/* pointers wrap point */
 | 
						snd_pcm_uframes_t boundary;		/* pointers wrap point */
 | 
				
			||||||
	unsigned char reserved[64];		/* reserved for future */
 | 
						unsigned int proto;			/* protocol version */
 | 
				
			||||||
 | 
						unsigned int tstamp_type;		/* timestamp type (req. proto >= 2.0.12) */
 | 
				
			||||||
 | 
						unsigned char reserved[56];		/* reserved for future */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct snd_pcm_channel_info {
 | 
					struct snd_pcm_channel_info {
 | 
				
			||||||
| 
						 | 
					@ -462,7 +464,8 @@ struct snd_xfern {
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,	/* gettimeofday equivalent */
 | 
						SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,	/* gettimeofday equivalent */
 | 
				
			||||||
	SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,	/* posix_clock_monotonic equivalent */
 | 
						SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,	/* posix_clock_monotonic equivalent */
 | 
				
			||||||
	SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
 | 
						SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW,    /* monotonic_raw (no NTP) */
 | 
				
			||||||
 | 
						SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* channel positions */
 | 
					/* channel positions */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,15 +47,11 @@ static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
 | 
				
			||||||
	/* We use the PCI APIs for now until the generic one gets fixed
 | 
						/* We use the PCI APIs for now until the generic one gets fixed
 | 
				
			||||||
	 * enough or until we get some macio-specific versions
 | 
						 * enough or until we get some macio-specific versions
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	r->space = dma_alloc_coherent(
 | 
						r->space = dma_zalloc_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
 | 
				
			||||||
			&macio_get_pci_dev(i2sdev->macio)->dev,
 | 
									       r->size, &r->bus_addr, GFP_KERNEL);
 | 
				
			||||||
			r->size,
 | 
						if (!r->space)
 | 
				
			||||||
			&r->bus_addr,
 | 
							return -ENOMEM;
 | 
				
			||||||
			GFP_KERNEL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!r->space) return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memset(r->space, 0, r->size);
 | 
					 | 
				
			||||||
	r->cmds = (void*)DBDMA_ALIGN(r->space);
 | 
						r->cmds = (void*)DBDMA_ALIGN(r->space);
 | 
				
			||||||
	r->bus_cmd_start = r->bus_addr +
 | 
						r->bus_cmd_start = r->bus_addr +
 | 
				
			||||||
			   (dma_addr_t)((char*)r->cmds - (char*)r->space);
 | 
								   (dma_addr_t)((char*)r->cmds - (char*)r->space);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,9 +152,9 @@ static inline void pxa_ac97_cold_pxa27x(void)
 | 
				
			||||||
	gsr_bits = 0;
 | 
						gsr_bits = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* PXA27x Developers Manual section 13.5.2.2.1 */
 | 
						/* PXA27x Developers Manual section 13.5.2.2.1 */
 | 
				
			||||||
	clk_enable(ac97conf_clk);
 | 
						clk_prepare_enable(ac97conf_clk);
 | 
				
			||||||
	udelay(5);
 | 
						udelay(5);
 | 
				
			||||||
	clk_disable(ac97conf_clk);
 | 
						clk_disable_unprepare(ac97conf_clk);
 | 
				
			||||||
	GCR = GCR_COLD_RST | GCR_WARM_RST;
 | 
						GCR = GCR_COLD_RST | GCR_WARM_RST;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -299,14 +299,14 @@ static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id)
 | 
				
			||||||
int pxa2xx_ac97_hw_suspend(void)
 | 
					int pxa2xx_ac97_hw_suspend(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GCR |= GCR_ACLINK_OFF;
 | 
						GCR |= GCR_ACLINK_OFF;
 | 
				
			||||||
	clk_disable(ac97_clk);
 | 
						clk_disable_unprepare(ac97_clk);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
 | 
					EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pxa2xx_ac97_hw_resume(void)
 | 
					int pxa2xx_ac97_hw_resume(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	clk_enable(ac97_clk);
 | 
						clk_prepare_enable(ac97_clk);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
 | 
					EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
 | 
				
			||||||
| 
						 | 
					@ -368,7 +368,7 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
 | 
				
			||||||
		goto err_clk;
 | 
							goto err_clk;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = clk_enable(ac97_clk);
 | 
						ret = clk_prepare_enable(ac97_clk);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto err_clk2;
 | 
							goto err_clk2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -403,7 +403,7 @@ void pxa2xx_ac97_hw_remove(struct platform_device *dev)
 | 
				
			||||||
		clk_put(ac97conf_clk);
 | 
							clk_put(ac97conf_clk);
 | 
				
			||||||
		ac97conf_clk = NULL;
 | 
							ac97conf_clk = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	clk_disable(ac97_clk);
 | 
						clk_disable_unprepare(ac97_clk);
 | 
				
			||||||
	clk_put(ac97_clk);
 | 
						clk_put(ac97_clk);
 | 
				
			||||||
	ac97_clk = NULL;
 | 
						ac97_clk = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -491,7 +491,7 @@ static int snd_compress_check_input(struct snd_compr_params *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* first let's check the buffer parameter's */
 | 
						/* first let's check the buffer parameter's */
 | 
				
			||||||
	if (params->buffer.fragment_size == 0 ||
 | 
						if (params->buffer.fragment_size == 0 ||
 | 
				
			||||||
			params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
 | 
						    params->buffer.fragments > INT_MAX / params->buffer.fragment_size)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* now codec parameters */
 | 
						/* now codec parameters */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1406,11 +1406,11 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
 | 
						case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
 | 
				
			||||||
		return snd_ctl_subscribe_events(ctl, ip);
 | 
							return snd_ctl_subscribe_events(ctl, ip);
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_TLV_READ:
 | 
						case SNDRV_CTL_IOCTL_TLV_READ:
 | 
				
			||||||
		return snd_ctl_tlv_ioctl(ctl, argp, 0);
 | 
							return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_TLV_WRITE:
 | 
						case SNDRV_CTL_IOCTL_TLV_WRITE:
 | 
				
			||||||
		return snd_ctl_tlv_ioctl(ctl, argp, 1);
 | 
							return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_TLV_COMMAND:
 | 
						case SNDRV_CTL_IOCTL_TLV_COMMAND:
 | 
				
			||||||
		return snd_ctl_tlv_ioctl(ctl, argp, -1);
 | 
							return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_POWER:
 | 
						case SNDRV_CTL_IOCTL_POWER:
 | 
				
			||||||
		return -ENOPROTOOPT;
 | 
							return -ENOPROTOOPT;
 | 
				
			||||||
	case SNDRV_CTL_IOCTL_POWER_STATE:
 | 
						case SNDRV_CTL_IOCTL_POWER_STATE:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,9 @@ struct snd_pcm_sw_params32 {
 | 
				
			||||||
	u32 silence_threshold;
 | 
						u32 silence_threshold;
 | 
				
			||||||
	u32 silence_size;
 | 
						u32 silence_size;
 | 
				
			||||||
	u32 boundary;
 | 
						u32 boundary;
 | 
				
			||||||
	unsigned char reserved[64];
 | 
						u32 proto;
 | 
				
			||||||
 | 
						u32 tstamp_type;
 | 
				
			||||||
 | 
						unsigned char reserved[56];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* recalcuate the boundary within 32bit */
 | 
					/* recalcuate the boundary within 32bit */
 | 
				
			||||||
| 
						 | 
					@ -133,7 +135,9 @@ static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,
 | 
				
			||||||
	    get_user(params.start_threshold, &src->start_threshold) ||
 | 
						    get_user(params.start_threshold, &src->start_threshold) ||
 | 
				
			||||||
	    get_user(params.stop_threshold, &src->stop_threshold) ||
 | 
						    get_user(params.stop_threshold, &src->stop_threshold) ||
 | 
				
			||||||
	    get_user(params.silence_threshold, &src->silence_threshold) ||
 | 
						    get_user(params.silence_threshold, &src->silence_threshold) ||
 | 
				
			||||||
	    get_user(params.silence_size, &src->silence_size))
 | 
						    get_user(params.silence_size, &src->silence_size) ||
 | 
				
			||||||
 | 
						    get_user(params.tstamp_type, &src->tstamp_type) ||
 | 
				
			||||||
 | 
						    get_user(params.proto, &src->proto))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Check silent_size parameter.  Since we have 64bit boundary,
 | 
						 * Check silent_size parameter.  Since we have 64bit boundary,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,13 +65,15 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
 | 
				
			||||||
	enum dma_slave_buswidth buswidth;
 | 
						enum dma_slave_buswidth buswidth;
 | 
				
			||||||
	int bits;
 | 
						int bits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bits = snd_pcm_format_physical_width(params_format(params));
 | 
						bits = params_physical_width(params);
 | 
				
			||||||
	if (bits < 8 || bits > 64)
 | 
						if (bits < 8 || bits > 64)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	else if (bits == 8)
 | 
						else if (bits == 8)
 | 
				
			||||||
		buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
 | 
							buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
 | 
				
			||||||
	else if (bits == 16)
 | 
						else if (bits == 16)
 | 
				
			||||||
		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
 | 
							buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
 | 
				
			||||||
 | 
						else if (bits == 24)
 | 
				
			||||||
 | 
							buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
 | 
				
			||||||
	else if (bits <= 32)
 | 
						else if (bits <= 32)
 | 
				
			||||||
		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
 | 
							buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -543,6 +543,9 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST)
 | 
						if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12) &&
 | 
				
			||||||
 | 
						    params->tstamp_type > SNDRV_PCM_TSTAMP_TYPE_LAST)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
	if (params->avail_min == 0)
 | 
						if (params->avail_min == 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	if (params->silence_size >= runtime->boundary) {
 | 
						if (params->silence_size >= runtime->boundary) {
 | 
				
			||||||
| 
						 | 
					@ -557,6 +560,8 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	err = 0;
 | 
						err = 0;
 | 
				
			||||||
	snd_pcm_stream_lock_irq(substream);
 | 
						snd_pcm_stream_lock_irq(substream);
 | 
				
			||||||
	runtime->tstamp_mode = params->tstamp_mode;
 | 
						runtime->tstamp_mode = params->tstamp_mode;
 | 
				
			||||||
 | 
						if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12))
 | 
				
			||||||
 | 
							runtime->tstamp_type = params->tstamp_type;
 | 
				
			||||||
	runtime->period_step = params->period_step;
 | 
						runtime->period_step = params->period_step;
 | 
				
			||||||
	runtime->control->avail_min = params->avail_min;
 | 
						runtime->control->avail_min = params->avail_min;
 | 
				
			||||||
	runtime->start_threshold = params->start_threshold;
 | 
						runtime->start_threshold = params->start_threshold;
 | 
				
			||||||
| 
						 | 
					@ -2540,9 +2545,7 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
 | 
						if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
 | 
						runtime->tstamp_type = arg;
 | 
				
			||||||
	if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
 | 
					 | 
				
			||||||
		runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,9 +101,9 @@ int snd_seq_dump_var_event(const struct snd_seq_event *event,
 | 
				
			||||||
			len -= size;
 | 
								len -= size;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	} if (! (event->data.ext.len & SNDRV_SEQ_EXT_CHAINED)) {
 | 
					 | 
				
			||||||
		return func(private_data, event->data.ext.ptr, len);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (!(event->data.ext.len & SNDRV_SEQ_EXT_CHAINED))
 | 
				
			||||||
 | 
							return func(private_data, event->data.ext.ptr, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cell = (struct snd_seq_event_cell *)event->data.ext.ptr;
 | 
						cell = (struct snd_seq_event_cell *)event->data.ext.ptr;
 | 
				
			||||||
	for (; len > 0 && cell; cell = cell->next) {
 | 
						for (; len > 0 && cell; cell = cell->next) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,8 +83,8 @@ config SND_BEBOB
 | 
				
			||||||
	  * Edirol FA-66/FA-101
 | 
						  * Edirol FA-66/FA-101
 | 
				
			||||||
	  * PreSonus FIREBOX/FIREPOD/FP10/Inspire1394
 | 
						  * PreSonus FIREBOX/FIREPOD/FP10/Inspire1394
 | 
				
			||||||
	  * BridgeCo RDAudio1/Audio5
 | 
						  * BridgeCo RDAudio1/Audio5
 | 
				
			||||||
	  * Mackie Onyx 1220/1620/1640 (Firewire I/O Card)
 | 
						  * Mackie Onyx 1220/1620/1640 (FireWire I/O Card)
 | 
				
			||||||
	  * Mackie d.2 (Firewire Option)
 | 
						  * Mackie d.2 (FireWire Option)
 | 
				
			||||||
	  * Stanton FinalScratch 2 (ScratchAmp)
 | 
						  * Stanton FinalScratch 2 (ScratchAmp)
 | 
				
			||||||
	  * Tascam IF-FW/DM
 | 
						  * Tascam IF-FW/DM
 | 
				
			||||||
	  * Behringer XENIX UFX 1204/1604
 | 
						  * Behringer XENIX UFX 1204/1604
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@ config SND_BEBOB
 | 
				
			||||||
	  * Apogee Rosetta 200/400 (X-FireWire card)
 | 
						  * Apogee Rosetta 200/400 (X-FireWire card)
 | 
				
			||||||
	  * Apogee DA/AD/DD-16X (X-FireWire card)
 | 
						  * Apogee DA/AD/DD-16X (X-FireWire card)
 | 
				
			||||||
	  * Apogee Ensemble
 | 
						  * Apogee Ensemble
 | 
				
			||||||
	  * ESI Quotafire610
 | 
						  * ESI QuataFire 610
 | 
				
			||||||
	  * AcousticReality eARMasterOne
 | 
						  * AcousticReality eARMasterOne
 | 
				
			||||||
	  * CME MatrixKFW
 | 
						  * CME MatrixKFW
 | 
				
			||||||
	  * Phonic Helix Board 12 MkII/18 MkII/24 MkII
 | 
						  * Phonic Helix Board 12 MkII/18 MkII/24 MkII
 | 
				
			||||||
| 
						 | 
					@ -101,13 +101,13 @@ config SND_BEBOB
 | 
				
			||||||
	  * ICON FireXon
 | 
						  * ICON FireXon
 | 
				
			||||||
	  * PrismSound Orpheus/ADA-8XR
 | 
						  * PrismSound Orpheus/ADA-8XR
 | 
				
			||||||
	  * TerraTec PHASE 24 FW/PHASE X24 FW/PHASE 88 Rack FW
 | 
						  * TerraTec PHASE 24 FW/PHASE X24 FW/PHASE 88 Rack FW
 | 
				
			||||||
	  * Terratec EWS MIC2/EWS MIC4
 | 
						  * TerraTec EWS MIC2/EWS MIC8
 | 
				
			||||||
	  * Terratec Aureon 7.1 Firewire
 | 
						  * TerraTec Aureon 7.1 FireWire
 | 
				
			||||||
	  * Yamaha GO44/GO46
 | 
						  * Yamaha GO44/GO46
 | 
				
			||||||
	  * Focusrite Saffire/Saffire LE/SaffirePro10 IO/SaffirePro26 IO
 | 
						  * Focusrite Saffire/Saffire LE/SaffirePro10 IO/SaffirePro26 IO
 | 
				
			||||||
	  * M-Audio Firewire410/AudioPhile/Solo
 | 
						  * M-Audio FireWire410/AudioPhile/Solo
 | 
				
			||||||
	  * M-Audio Ozonic/NRV10/ProfireLightBridge
 | 
						  * M-Audio Ozonic/NRV10/ProfireLightBridge
 | 
				
			||||||
	  * M-Audio Firewire 1814/ProjectMix IO
 | 
						  * M-Audio FireWire 1814/ProjectMix IO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          To compile this driver as a module, choose M here: the module
 | 
					          To compile this driver as a module, choose M here: the module
 | 
				
			||||||
          will be called snd-bebob.
 | 
					          will be called snd-bebob.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,7 @@ proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 | 
				
			||||||
		    hwinfo->phys_in_grp_count);
 | 
							    hwinfo->phys_in_grp_count);
 | 
				
			||||||
	for (i = 0; i < hwinfo->phys_in_grp_count; i++) {
 | 
						for (i = 0; i < hwinfo->phys_in_grp_count; i++) {
 | 
				
			||||||
		snd_iprintf(buffer,
 | 
							snd_iprintf(buffer,
 | 
				
			||||||
			    "phys in grp[0x%d]: type 0x%d, count 0x%d\n",
 | 
								    "phys in grp[%d]: type 0x%X, count 0x%X\n",
 | 
				
			||||||
			    i, hwinfo->phys_out_grps[i].type,
 | 
								    i, hwinfo->phys_out_grps[i].type,
 | 
				
			||||||
			    hwinfo->phys_out_grps[i].count);
 | 
								    hwinfo->phys_out_grps[i].count);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 | 
				
			||||||
		    hwinfo->phys_out_grp_count);
 | 
							    hwinfo->phys_out_grp_count);
 | 
				
			||||||
	for (i = 0; i < hwinfo->phys_out_grp_count; i++) {
 | 
						for (i = 0; i < hwinfo->phys_out_grp_count; i++) {
 | 
				
			||||||
		snd_iprintf(buffer,
 | 
							snd_iprintf(buffer,
 | 
				
			||||||
			    "phys out grps[0x%d]: type 0x%d, count 0x%d\n",
 | 
								    "phys out grps[%d]: type 0x%X, count 0x%X\n",
 | 
				
			||||||
			    i, hwinfo->phys_out_grps[i].type,
 | 
								    i, hwinfo->phys_out_grps[i].type,
 | 
				
			||||||
			    hwinfo->phys_out_grps[i].count);
 | 
								    hwinfo->phys_out_grps[i].count);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,6 +316,7 @@ static int mpu_input_scanner(struct mpu_config *devc, unsigned char midic)
 | 
				
			||||||
				case 0xf6:
 | 
									case 0xf6:
 | 
				
			||||||
					/* printk( "tune_request\n"); */
 | 
										/* printk( "tune_request\n"); */
 | 
				
			||||||
					devc->m_state = ST_INIT;
 | 
										devc->m_state = ST_INIT;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					/*
 | 
										/*
 | 
				
			||||||
					 *    Real time messages
 | 
										 *    Real time messages
 | 
				
			||||||
| 
						 | 
					@ -972,7 +973,6 @@ int attach_mpu401(struct address_info *hw_config, struct module *owner)
 | 
				
			||||||
	devc->m_busy = 0;
 | 
						devc->m_busy = 0;
 | 
				
			||||||
	devc->m_state = ST_INIT;
 | 
						devc->m_state = ST_INIT;
 | 
				
			||||||
	devc->shared_irq = hw_config->always_detect;
 | 
						devc->shared_irq = hw_config->always_detect;
 | 
				
			||||||
	devc->irq = hw_config->irq;
 | 
					 | 
				
			||||||
	spin_lock_init(&devc->lock);
 | 
						spin_lock_init(&devc->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (devc->irq < 0)
 | 
						if (devc->irq < 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ struct voice_info
 | 
				
			||||||
	int             panning;	/* 0xffff means not set */
 | 
						int             panning;	/* 0xffff means not set */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct opl_devinfo
 | 
					struct opl_devinfo
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int             base;
 | 
						int             base;
 | 
				
			||||||
	int             left_io, right_io;
 | 
						int             left_io, right_io;
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ typedef struct opl_devinfo
 | 
				
			||||||
	unsigned char   cmask;
 | 
						unsigned char   cmask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int             is_opl4;
 | 
						int             is_opl4;
 | 
				
			||||||
} opl_devinfo;
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct opl_devinfo *devc = NULL;
 | 
					static struct opl_devinfo *devc = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,25 +123,25 @@ static bool pss_mixer;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pss_mixerdata {
 | 
					struct pss_mixerdata {
 | 
				
			||||||
	unsigned int volume_l;
 | 
						unsigned int volume_l;
 | 
				
			||||||
	unsigned int volume_r;
 | 
						unsigned int volume_r;
 | 
				
			||||||
	unsigned int bass;
 | 
						unsigned int bass;
 | 
				
			||||||
	unsigned int treble;
 | 
						unsigned int treble;
 | 
				
			||||||
	unsigned int synth;
 | 
						unsigned int synth;
 | 
				
			||||||
} pss_mixerdata;
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct pss_confdata {
 | 
					struct pss_confdata {
 | 
				
			||||||
	int             base;
 | 
						int             base;
 | 
				
			||||||
	int             irq;
 | 
						int             irq;
 | 
				
			||||||
	int             dma;
 | 
						int             dma;
 | 
				
			||||||
	int            *osp;
 | 
						int            *osp;
 | 
				
			||||||
	pss_mixerdata   mixer;
 | 
						struct pss_mixerdata mixer;
 | 
				
			||||||
	int             ad_mixer_dev;
 | 
						int             ad_mixer_dev;
 | 
				
			||||||
} pss_confdata;
 | 
					};
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
static pss_confdata pss_data;
 | 
					static struct pss_confdata pss_data;
 | 
				
			||||||
static pss_confdata *devc = &pss_data;
 | 
					static struct pss_confdata *devc = &pss_data;
 | 
				
			||||||
static DEFINE_SPINLOCK(lock);
 | 
					static DEFINE_SPINLOCK(lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int      pss_initialized;
 | 
					static int      pss_initialized;
 | 
				
			||||||
| 
						 | 
					@ -150,7 +150,7 @@ static int	pss_cdrom_port = -1;	/* Parameter for the PSS cdrom port */
 | 
				
			||||||
static bool	pss_enable_joystick;    /* Parameter for enabling the joystick */
 | 
					static bool	pss_enable_joystick;    /* Parameter for enabling the joystick */
 | 
				
			||||||
static coproc_operations pss_coproc_operations;
 | 
					static coproc_operations pss_coproc_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pss_write(pss_confdata *devc, int data)
 | 
					static void pss_write(struct pss_confdata *devc, int data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long i, limit;
 | 
						unsigned long i, limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,7 +206,7 @@ static int __init probe_pss(struct address_info *hw_config)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_irq(pss_confdata * devc, int dev, int irq)
 | 
					static int set_irq(struct pss_confdata *devc, int dev, int irq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static unsigned short irq_bits[16] =
 | 
						static unsigned short irq_bits[16] =
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -232,7 +232,7 @@ static int set_irq(pss_confdata * devc, int dev, int irq)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void set_io_base(pss_confdata * devc, int dev, int base)
 | 
					static void set_io_base(struct pss_confdata *devc, int dev, int base)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned short  tmp = inw(REG(dev)) & 0x003f;
 | 
						unsigned short  tmp = inw(REG(dev)) & 0x003f;
 | 
				
			||||||
	unsigned short  bits = (base & 0x0ffc) << 4;
 | 
						unsigned short  bits = (base & 0x0ffc) << 4;
 | 
				
			||||||
| 
						 | 
					@ -240,7 +240,7 @@ static void set_io_base(pss_confdata * devc, int dev, int base)
 | 
				
			||||||
	outw(bits | tmp, REG(dev));
 | 
						outw(bits | tmp, REG(dev));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_dma(pss_confdata * devc, int dev, int dma)
 | 
					static int set_dma(struct pss_confdata *devc, int dev, int dma)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static unsigned short dma_bits[8] =
 | 
						static unsigned short dma_bits[8] =
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -264,7 +264,7 @@ static int set_dma(pss_confdata * devc, int dev, int dma)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pss_reset_dsp(pss_confdata * devc)
 | 
					static int pss_reset_dsp(struct pss_confdata *devc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long   i, limit = jiffies + HZ/10;
 | 
						unsigned long   i, limit = jiffies + HZ/10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,7 +275,7 @@ static int pss_reset_dsp(pss_confdata * devc)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pss_put_dspword(pss_confdata * devc, unsigned short word)
 | 
					static int pss_put_dspword(struct pss_confdata *devc, unsigned short word)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, val;
 | 
						int i, val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,7 +291,7 @@ static int pss_put_dspword(pss_confdata * devc, unsigned short word)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
 | 
					static int pss_get_dspword(struct pss_confdata *devc, unsigned short *word)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, val;
 | 
						int i, val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,7 +307,8 @@ static int pss_get_dspword(pss_confdata * devc, unsigned short *word)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size, int flags)
 | 
					static int pss_download_boot(struct pss_confdata *devc, unsigned char *block,
 | 
				
			||||||
 | 
								     int size, int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, val, count;
 | 
						int i, val, count;
 | 
				
			||||||
	unsigned long limit;
 | 
						unsigned long limit;
 | 
				
			||||||
| 
						 | 
					@ -397,7 +398,7 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Mixer */
 | 
					/* Mixer */
 | 
				
			||||||
static void set_master_volume(pss_confdata *devc, int left, int right)
 | 
					static void set_master_volume(struct pss_confdata *devc, int left, int right)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static unsigned char log_scale[101] =  {
 | 
						static unsigned char log_scale[101] =  {
 | 
				
			||||||
		0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
 | 
							0xdb, 0xe0, 0xe3, 0xe5, 0xe7, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xed, 0xee,
 | 
				
			||||||
| 
						 | 
					@ -416,7 +417,7 @@ static void set_master_volume(pss_confdata *devc, int left, int right)
 | 
				
			||||||
	pss_write(devc, log_scale[right] | 0x0100);
 | 
						pss_write(devc, log_scale[right] | 0x0100);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void set_synth_volume(pss_confdata *devc, int volume)
 | 
					static void set_synth_volume(struct pss_confdata *devc, int volume)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int vol = ((0x8000*volume)/100L);
 | 
						int vol = ((0x8000*volume)/100L);
 | 
				
			||||||
	pss_write(devc, 0x0080);
 | 
						pss_write(devc, 0x0080);
 | 
				
			||||||
| 
						 | 
					@ -425,21 +426,21 @@ static void set_synth_volume(pss_confdata *devc, int volume)
 | 
				
			||||||
	pss_write(devc, vol);
 | 
						pss_write(devc, vol);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void set_bass(pss_confdata *devc, int level)
 | 
					static void set_bass(struct pss_confdata *devc, int level)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
 | 
						int vol = (int)(((0xfd - 0xf0) * level)/100L) + 0xf0;
 | 
				
			||||||
	pss_write(devc, 0x0010);
 | 
						pss_write(devc, 0x0010);
 | 
				
			||||||
	pss_write(devc, vol | 0x0200);
 | 
						pss_write(devc, vol | 0x0200);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void set_treble(pss_confdata *devc, int level)
 | 
					static void set_treble(struct pss_confdata *devc, int level)
 | 
				
			||||||
{	
 | 
					{	
 | 
				
			||||||
	int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
 | 
						int vol = (((0xfd - 0xf0) * level)/100L) + 0xf0;
 | 
				
			||||||
	pss_write(devc, 0x0010);
 | 
						pss_write(devc, 0x0010);
 | 
				
			||||||
	pss_write(devc, vol | 0x0300);
 | 
						pss_write(devc, vol | 0x0300);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pss_mixer_reset(pss_confdata *devc)
 | 
					static void pss_mixer_reset(struct pss_confdata *devc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	set_master_volume(devc, 33, 33);
 | 
						set_master_volume(devc, 33, 33);
 | 
				
			||||||
	set_bass(devc, 50);
 | 
						set_bass(devc, 50);
 | 
				
			||||||
| 
						 | 
					@ -499,7 +500,8 @@ static int ret_vol_stereo(int left, int right)
 | 
				
			||||||
	return ((right << 8) | left);
 | 
						return ((right << 8) | left);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, void __user *arg)
 | 
					static int call_ad_mixer(struct pss_confdata *devc, unsigned int cmd,
 | 
				
			||||||
 | 
								 void __user *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (devc->ad_mixer_dev != NO_WSS_MIXER) 
 | 
						if (devc->ad_mixer_dev != NO_WSS_MIXER) 
 | 
				
			||||||
		return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
 | 
							return mixer_devs[devc->ad_mixer_dev]->ioctl(devc->ad_mixer_dev, cmd, arg);
 | 
				
			||||||
| 
						 | 
					@ -509,7 +511,7 @@ static int call_ad_mixer(pss_confdata *devc,unsigned int cmd, void __user *arg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
 | 
					static int pss_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pss_confdata *devc = mixer_devs[dev]->devc;
 | 
						struct pss_confdata *devc = mixer_devs[dev]->devc;
 | 
				
			||||||
	int cmdf = cmd & 0xff;
 | 
						int cmdf = cmd & 0xff;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
 | 
						if ((cmdf != SOUND_MIXER_VOLUME) && (cmdf != SOUND_MIXER_BASS) &&
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -858,8 +858,8 @@ config SND_VIRTUOSO
 | 
				
			||||||
	select SND_JACK if INPUT=y || INPUT=SND
 | 
						select SND_JACK if INPUT=y || INPUT=SND
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Say Y here to include support for sound cards based on the
 | 
						  Say Y here to include support for sound cards based on the
 | 
				
			||||||
	  Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
 | 
						  Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, DSX,
 | 
				
			||||||
	  Essence ST (Deluxe), and Essence STX.
 | 
						  Essence ST (Deluxe), and Essence STX (II).
 | 
				
			||||||
	  Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
 | 
						  Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
 | 
				
			||||||
	  for the Xense, missing.
 | 
						  for the Xense, missing.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1754,9 +1754,6 @@ static struct snd_kcontrol_new snd_echo_vumeters_switch = {
 | 
				
			||||||
static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
 | 
					static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
				  struct snd_ctl_elem_info *uinfo)
 | 
									  struct snd_ctl_elem_info *uinfo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct echoaudio *chip;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 | 
						uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 | 
				
			||||||
	uinfo->count = 96;
 | 
						uinfo->count = 96;
 | 
				
			||||||
	uinfo->value.integer.min = ECHOGAIN_MINOUT;
 | 
						uinfo->value.integer.min = ECHOGAIN_MINOUT;
 | 
				
			||||||
| 
						 | 
					@ -1798,9 +1795,6 @@ static struct snd_kcontrol_new snd_echo_vumeters = {
 | 
				
			||||||
static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol,
 | 
					static int snd_echo_channels_info_info(struct snd_kcontrol *kcontrol,
 | 
				
			||||||
				       struct snd_ctl_elem_info *uinfo)
 | 
									       struct snd_ctl_elem_info *uinfo)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct echoaudio *chip;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 | 
						uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 | 
				
			||||||
	uinfo->count = 6;
 | 
						uinfo->count = 6;
 | 
				
			||||||
	uinfo->value.integer.min = 0;
 | 
						uinfo->value.integer.min = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								sound/pci/hda/dell_wmi_helper.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								sound/pci/hda/dell_wmi_helper.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					/* Helper functions for Dell Mic Mute LED control;
 | 
				
			||||||
 | 
					 * to be included from codec driver
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if IS_ENABLED(CONFIG_LEDS_DELL_NETBOOKS)
 | 
				
			||||||
 | 
					#include <linux/dell-led.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dell_led_value;
 | 
				
			||||||
 | 
					static int (*dell_led_set_func)(int, int);
 | 
				
			||||||
 | 
					static void (*dell_old_cap_hook)(struct hda_codec *,
 | 
				
			||||||
 | 
								         struct snd_kcontrol *,
 | 
				
			||||||
 | 
									 struct snd_ctl_elem_value *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void update_dell_wmi_micmute_led(struct hda_codec *codec,
 | 
				
			||||||
 | 
									        struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
										struct snd_ctl_elem_value *ucontrol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dell_old_cap_hook)
 | 
				
			||||||
 | 
							dell_old_cap_hook(codec, kcontrol, ucontrol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ucontrol || !dell_led_set_func)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
 | 
				
			||||||
 | 
							/* TODO: How do I verify if it's a mono or stereo here? */
 | 
				
			||||||
 | 
							int val = (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) ? 0 : 1;
 | 
				
			||||||
 | 
							if (val == dell_led_value)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							dell_led_value = val;
 | 
				
			||||||
 | 
							if (dell_led_set_func)
 | 
				
			||||||
 | 
								dell_led_set_func(DELL_LED_MICMUTE, dell_led_value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void alc_fixup_dell_wmi(struct hda_codec *codec,
 | 
				
			||||||
 | 
								       const struct hda_fixup *fix, int action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct alc_spec *spec = codec->spec;
 | 
				
			||||||
 | 
						bool removefunc = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (action == HDA_FIXUP_ACT_PROBE) {
 | 
				
			||||||
 | 
							if (!dell_led_set_func)
 | 
				
			||||||
 | 
								dell_led_set_func = symbol_request(dell_app_wmi_led_set);
 | 
				
			||||||
 | 
							if (!dell_led_set_func) {
 | 
				
			||||||
 | 
								codec_warn(codec, "Failed to find dell wmi symbol dell_app_wmi_led_set\n");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							removefunc = true;
 | 
				
			||||||
 | 
							if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) {
 | 
				
			||||||
 | 
								dell_led_value = 0;
 | 
				
			||||||
 | 
								if (spec->gen.num_adc_nids > 1)
 | 
				
			||||||
 | 
									codec_dbg(codec, "Skipping micmute LED control due to several ADCs");
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									dell_old_cap_hook = spec->gen.cap_sync_hook;
 | 
				
			||||||
 | 
									spec->gen.cap_sync_hook = update_dell_wmi_micmute_led;
 | 
				
			||||||
 | 
									removefunc = false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (dell_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
 | 
				
			||||||
 | 
							symbol_put(dell_app_wmi_led_set);
 | 
				
			||||||
 | 
							dell_led_set_func = NULL;
 | 
				
			||||||
 | 
							dell_old_cap_hook = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else /* CONFIG_LEDS_DELL_NETBOOKS */
 | 
				
			||||||
 | 
					static void alc_fixup_dell_wmi(struct hda_codec *codec,
 | 
				
			||||||
 | 
								       const struct hda_fixup *fix, int action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* CONFIG_LEDS_DELL_NETBOOKS */
 | 
				
			||||||
| 
						 | 
					@ -17,8 +17,6 @@
 | 
				
			||||||
#include "hda_local.h"
 | 
					#include "hda_local.h"
 | 
				
			||||||
#include "hda_auto_parser.h"
 | 
					#include "hda_auto_parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SFX	"hda_codec: "
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Helper for automatic pin configuration
 | 
					 * Helper for automatic pin configuration
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -856,7 +854,7 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct snd_hda_pin_quirk *pq;
 | 
						const struct snd_hda_pin_quirk *pq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (codec->fixup_forced)
 | 
						if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (pq = pin_quirk; pq->subvendor; pq++) {
 | 
						for (pq = pin_quirk; pq->subvendor; pq++) {
 | 
				
			||||||
| 
						 | 
					@ -882,14 +880,17 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
 | 
				
			||||||
			const struct hda_fixup *fixlist)
 | 
								const struct hda_fixup *fixlist)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct snd_pci_quirk *q;
 | 
						const struct snd_pci_quirk *q;
 | 
				
			||||||
	int id = -1;
 | 
						int id = HDA_FIXUP_ID_NOT_SET;
 | 
				
			||||||
	const char *name = NULL;
 | 
						const char *name = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* when model=nofixup is given, don't pick up any fixups */
 | 
						/* when model=nofixup is given, don't pick up any fixups */
 | 
				
			||||||
	if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
 | 
						if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
 | 
				
			||||||
		codec->fixup_list = NULL;
 | 
							codec->fixup_list = NULL;
 | 
				
			||||||
		codec->fixup_id = -1;
 | 
							codec->fixup_name = NULL;
 | 
				
			||||||
		codec->fixup_forced = 1;
 | 
							codec->fixup_id = HDA_FIXUP_ID_NO_FIXUP;
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -899,13 +900,12 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
 | 
				
			||||||
				codec->fixup_id = models->id;
 | 
									codec->fixup_id = models->id;
 | 
				
			||||||
				codec->fixup_name = models->name;
 | 
									codec->fixup_name = models->name;
 | 
				
			||||||
				codec->fixup_list = fixlist;
 | 
									codec->fixup_list = fixlist;
 | 
				
			||||||
				codec->fixup_forced = 1;
 | 
					 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			models++;
 | 
								models++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (id < 0 && quirk) {
 | 
						if (quirk) {
 | 
				
			||||||
		q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
 | 
							q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
 | 
				
			||||||
		if (q) {
 | 
							if (q) {
 | 
				
			||||||
			id = q->value;
 | 
								id = q->value;
 | 
				
			||||||
| 
						 | 
					@ -929,7 +929,6 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	codec->fixup_forced = 0;
 | 
					 | 
				
			||||||
	codec->fixup_id = id;
 | 
						codec->fixup_id = id;
 | 
				
			||||||
	if (id >= 0) {
 | 
						if (id >= 0) {
 | 
				
			||||||
		codec->fixup_list = fixlist;
 | 
							codec->fixup_list = fixlist;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1476,6 +1476,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
 | 
						INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
 | 
				
			||||||
	codec->depop_delay = -1;
 | 
						codec->depop_delay = -1;
 | 
				
			||||||
 | 
						codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
	spin_lock_init(&codec->power_lock);
 | 
						spin_lock_init(&codec->power_lock);
 | 
				
			||||||
| 
						 | 
					@ -2727,7 +2728,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
 | 
					typedef int (*map_slave_func_t)(struct hda_codec *, void *, struct snd_kcontrol *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* apply the function to all matching slave ctls in the mixer list */
 | 
					/* apply the function to all matching slave ctls in the mixer list */
 | 
				
			||||||
static int map_slaves(struct hda_codec *codec, const char * const *slaves,
 | 
					static int map_slaves(struct hda_codec *codec, const char * const *slaves,
 | 
				
			||||||
| 
						 | 
					@ -2751,7 +2752,7 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
 | 
				
			||||||
				name = tmpname;
 | 
									name = tmpname;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (!strcmp(sctl->id.name, name)) {
 | 
								if (!strcmp(sctl->id.name, name)) {
 | 
				
			||||||
				err = func(data, sctl);
 | 
									err = func(codec, data, sctl);
 | 
				
			||||||
				if (err)
 | 
									if (err)
 | 
				
			||||||
					return err;
 | 
										return err;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					@ -2761,13 +2762,15 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int check_slave_present(void *data, struct snd_kcontrol *sctl)
 | 
					static int check_slave_present(struct hda_codec *codec,
 | 
				
			||||||
 | 
								       void *data, struct snd_kcontrol *sctl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* guess the value corresponding to 0dB */
 | 
					/* guess the value corresponding to 0dB */
 | 
				
			||||||
static int get_kctl_0dB_offset(struct snd_kcontrol *kctl, int *step_to_check)
 | 
					static int get_kctl_0dB_offset(struct hda_codec *codec,
 | 
				
			||||||
 | 
								       struct snd_kcontrol *kctl, int *step_to_check)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int _tlv[4];
 | 
						int _tlv[4];
 | 
				
			||||||
	const int *tlv = NULL;
 | 
						const int *tlv = NULL;
 | 
				
			||||||
| 
						 | 
					@ -2788,7 +2791,7 @@ static int get_kctl_0dB_offset(struct snd_kcontrol *kctl, int *step_to_check)
 | 
				
			||||||
		if (!step)
 | 
							if (!step)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		if (*step_to_check && *step_to_check != step) {
 | 
							if (*step_to_check && *step_to_check != step) {
 | 
				
			||||||
			snd_printk(KERN_ERR "hda_codec: Mismatching dB step for vmaster slave (%d!=%d)\n",
 | 
								codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n",
 | 
				
			||||||
-				   *step_to_check, step);
 | 
					-				   *step_to_check, step);
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -2813,20 +2816,28 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* initialize the slave volume with 0dB */
 | 
					/* initialize the slave volume with 0dB */
 | 
				
			||||||
static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
 | 
					static int init_slave_0dB(struct hda_codec *codec,
 | 
				
			||||||
 | 
								  void *data, struct snd_kcontrol *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int offset = get_kctl_0dB_offset(slave, data);
 | 
						int offset = get_kctl_0dB_offset(codec, slave, data);
 | 
				
			||||||
	if (offset > 0)
 | 
						if (offset > 0)
 | 
				
			||||||
		put_kctl_with_value(slave, offset);
 | 
							put_kctl_with_value(slave, offset);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* unmute the slave */
 | 
					/* unmute the slave */
 | 
				
			||||||
static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
 | 
					static int init_slave_unmute(struct hda_codec *codec,
 | 
				
			||||||
 | 
								     void *data, struct snd_kcontrol *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return put_kctl_with_value(slave, 1);
 | 
						return put_kctl_with_value(slave, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int add_slave(struct hda_codec *codec,
 | 
				
			||||||
 | 
							     void *data, struct snd_kcontrol *slave)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return snd_ctl_add_slave(data, slave);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * snd_hda_add_vmaster - create a virtual master control and add slaves
 | 
					 * snd_hda_add_vmaster - create a virtual master control and add slaves
 | 
				
			||||||
 * @codec: HD-audio codec
 | 
					 * @codec: HD-audio codec
 | 
				
			||||||
| 
						 | 
					@ -2869,8 +2880,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = map_slaves(codec, slaves, suffix,
 | 
						err = map_slaves(codec, slaves, suffix, add_slave, kctl);
 | 
				
			||||||
			 (map_slave_func_t)snd_ctl_add_slave, kctl);
 | 
					 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4280,6 +4290,7 @@ static struct hda_rate_tbl rate_bits[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * snd_hda_calc_stream_format - calculate format bitset
 | 
					 * snd_hda_calc_stream_format - calculate format bitset
 | 
				
			||||||
 | 
					 * @codec: HD-audio codec
 | 
				
			||||||
 * @rate: the sample rate
 | 
					 * @rate: the sample rate
 | 
				
			||||||
 * @channels: the number of channels
 | 
					 * @channels: the number of channels
 | 
				
			||||||
 * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
 | 
					 * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
 | 
				
			||||||
| 
						 | 
					@ -4289,7 +4300,8 @@ static struct hda_rate_tbl rate_bits[] = {
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Return zero if invalid.
 | 
					 * Return zero if invalid.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
unsigned int snd_hda_calc_stream_format(unsigned int rate,
 | 
					unsigned int snd_hda_calc_stream_format(struct hda_codec *codec,
 | 
				
			||||||
 | 
										unsigned int rate,
 | 
				
			||||||
					unsigned int channels,
 | 
										unsigned int channels,
 | 
				
			||||||
					unsigned int format,
 | 
										unsigned int format,
 | 
				
			||||||
					unsigned int maxbps,
 | 
										unsigned int maxbps,
 | 
				
			||||||
| 
						 | 
					@ -4304,12 +4316,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	if (!rate_bits[i].hz) {
 | 
						if (!rate_bits[i].hz) {
 | 
				
			||||||
		snd_printdd("invalid rate %d\n", rate);
 | 
							codec_dbg(codec, "invalid rate %d\n", rate);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (channels == 0 || channels > 8) {
 | 
						if (channels == 0 || channels > 8) {
 | 
				
			||||||
		snd_printdd("invalid channels %d\n", channels);
 | 
							codec_dbg(codec, "invalid channels %d\n", channels);
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	val |= channels - 1;
 | 
						val |= channels - 1;
 | 
				
			||||||
| 
						 | 
					@ -4332,7 +4344,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
 | 
				
			||||||
			val |= AC_FMT_BITS_20;
 | 
								val |= AC_FMT_BITS_20;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		snd_printdd("invalid format width %d\n",
 | 
							codec_dbg(codec, "invalid format width %d\n",
 | 
				
			||||||
			  snd_pcm_format_width(format));
 | 
								  snd_pcm_format_width(format));
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -5670,12 +5682,13 @@ EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl);
 | 
				
			||||||
 * suffix is appended to the label.  This label index number is stored
 | 
					 * suffix is appended to the label.  This label index number is stored
 | 
				
			||||||
 * to type_idx when non-NULL pointer is given.
 | 
					 * to type_idx when non-NULL pointer is given.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
 | 
					int snd_hda_add_imux_item(struct hda_codec *codec,
 | 
				
			||||||
 | 
								  struct hda_input_mux *imux, const char *label,
 | 
				
			||||||
			  int index, int *type_idx)
 | 
								  int index, int *type_idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, label_idx = 0;
 | 
						int i, label_idx = 0;
 | 
				
			||||||
	if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
 | 
						if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
 | 
				
			||||||
		snd_printd(KERN_ERR "hda_codec: Too many imux items!\n");
 | 
							codec_err(codec, "hda_codec: Too many imux items!\n");
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for (i = 0; i < imux->num_items; i++) {
 | 
						for (i = 0; i < imux->num_items; i++) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -402,7 +402,6 @@ struct hda_codec {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* fix-up list */
 | 
						/* fix-up list */
 | 
				
			||||||
	int fixup_id;
 | 
						int fixup_id;
 | 
				
			||||||
	unsigned int fixup_forced:1; /* fixup explicitly set by user */
 | 
					 | 
				
			||||||
	const struct hda_fixup *fixup_list;
 | 
						const struct hda_fixup *fixup_list;
 | 
				
			||||||
	const char *fixup_name;
 | 
						const char *fixup_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -538,7 +537,8 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
 | 
				
			||||||
				    int do_now);
 | 
									    int do_now);
 | 
				
			||||||
#define snd_hda_codec_cleanup_stream(codec, nid) \
 | 
					#define snd_hda_codec_cleanup_stream(codec, nid) \
 | 
				
			||||||
	__snd_hda_codec_cleanup_stream(codec, nid, 0)
 | 
						__snd_hda_codec_cleanup_stream(codec, nid, 0)
 | 
				
			||||||
unsigned int snd_hda_calc_stream_format(unsigned int rate,
 | 
					unsigned int snd_hda_calc_stream_format(struct hda_codec *codec,
 | 
				
			||||||
 | 
										unsigned int rate,
 | 
				
			||||||
					unsigned int channels,
 | 
										unsigned int channels,
 | 
				
			||||||
					unsigned int format,
 | 
										unsigned int format,
 | 
				
			||||||
					unsigned int maxbps,
 | 
										unsigned int maxbps,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/pm_runtime.h>
 | 
					#include <linux/pm_runtime.h>
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
 | 
					#include <linux/reboot.h>
 | 
				
			||||||
#include <sound/core.h>
 | 
					#include <sound/core.h>
 | 
				
			||||||
#include <sound/initval.h>
 | 
					#include <sound/initval.h>
 | 
				
			||||||
#include "hda_priv.h"
 | 
					#include "hda_priv.h"
 | 
				
			||||||
| 
						 | 
					@ -152,11 +153,11 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
		      upper_32_bits(azx_dev->bdl.addr));
 | 
							      upper_32_bits(azx_dev->bdl.addr));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* enable the position buffer */
 | 
						/* enable the position buffer */
 | 
				
			||||||
	if (chip->position_fix[0] != POS_FIX_LPIB ||
 | 
						if (chip->get_position[0] != azx_get_pos_lpib ||
 | 
				
			||||||
	    chip->position_fix[1] != POS_FIX_LPIB) {
 | 
						    chip->get_position[1] != azx_get_pos_lpib) {
 | 
				
			||||||
		if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
 | 
							if (!(azx_readl(chip, DPLBASE) & AZX_DPLBASE_ENABLE))
 | 
				
			||||||
			azx_writel(chip, DPLBASE,
 | 
								azx_writel(chip, DPLBASE,
 | 
				
			||||||
				(u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
 | 
									(u32)chip->posbuf.addr | AZX_DPLBASE_ENABLE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set the interrupt enable bits in the descriptor control register */
 | 
						/* set the interrupt enable bits in the descriptor control register */
 | 
				
			||||||
| 
						 | 
					@ -482,7 +483,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	azx_stream_reset(chip, azx_dev);
 | 
						azx_stream_reset(chip, azx_dev);
 | 
				
			||||||
	format_val = snd_hda_calc_stream_format(runtime->rate,
 | 
						format_val = snd_hda_calc_stream_format(apcm->codec,
 | 
				
			||||||
 | 
											runtime->rate,
 | 
				
			||||||
						runtime->channels,
 | 
											runtime->channels,
 | 
				
			||||||
						runtime->format,
 | 
											runtime->format,
 | 
				
			||||||
						hinfo->maxbps,
 | 
											hinfo->maxbps,
 | 
				
			||||||
| 
						 | 
					@ -673,125 +675,40 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* get the current DMA position with correction on VIA chips */
 | 
					unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
static unsigned int azx_via_get_position(struct azx *chip,
 | 
					 | 
				
			||||||
					 struct azx_dev *azx_dev)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int link_pos, mini_pos, bound_pos;
 | 
						return azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
				
			||||||
	unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
 | 
					 | 
				
			||||||
	unsigned int fifo_size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
					 | 
				
			||||||
	if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 | 
					 | 
				
			||||||
		/* Playback, no problem using link position */
 | 
					 | 
				
			||||||
		return link_pos;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Capture */
 | 
					 | 
				
			||||||
	/* For new chipset,
 | 
					 | 
				
			||||||
	 * use mod to get the DMA position just like old chipset
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
 | 
					 | 
				
			||||||
	mod_dma_pos %= azx_dev->period_bytes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* azx_dev->fifo_size can't get FIFO size of in stream.
 | 
					 | 
				
			||||||
	 * Get from base address + offset.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (azx_dev->insufficient) {
 | 
					 | 
				
			||||||
		/* Link position never gather than FIFO size */
 | 
					 | 
				
			||||||
		if (link_pos <= fifo_size)
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		azx_dev->insufficient = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (link_pos <= fifo_size)
 | 
					 | 
				
			||||||
		mini_pos = azx_dev->bufsize + link_pos - fifo_size;
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		mini_pos = link_pos - fifo_size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Find nearest previous boudary */
 | 
					 | 
				
			||||||
	mod_mini_pos = mini_pos % azx_dev->period_bytes;
 | 
					 | 
				
			||||||
	mod_link_pos = link_pos % azx_dev->period_bytes;
 | 
					 | 
				
			||||||
	if (mod_link_pos >= fifo_size)
 | 
					 | 
				
			||||||
		bound_pos = link_pos - mod_link_pos;
 | 
					 | 
				
			||||||
	else if (mod_dma_pos >= mod_mini_pos)
 | 
					 | 
				
			||||||
		bound_pos = mini_pos - mod_mini_pos;
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
 | 
					 | 
				
			||||||
		if (bound_pos >= azx_dev->bufsize)
 | 
					 | 
				
			||||||
			bound_pos = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Calculate real DMA position we want */
 | 
					 | 
				
			||||||
	return bound_pos + mod_dma_pos;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(azx_get_pos_lpib);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return le32_to_cpu(*azx_dev->posbuf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(azx_get_pos_posbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int azx_get_position(struct azx *chip,
 | 
					unsigned int azx_get_position(struct azx *chip,
 | 
				
			||||||
			      struct azx_dev *azx_dev,
 | 
								      struct azx_dev *azx_dev)
 | 
				
			||||||
			      bool with_check)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_pcm_substream *substream = azx_dev->substream;
 | 
						struct snd_pcm_substream *substream = azx_dev->substream;
 | 
				
			||||||
	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 | 
					 | 
				
			||||||
	unsigned int pos;
 | 
						unsigned int pos;
 | 
				
			||||||
	int stream = substream->stream;
 | 
						int stream = substream->stream;
 | 
				
			||||||
	struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
 | 
					 | 
				
			||||||
	int delay = 0;
 | 
						int delay = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (chip->position_fix[stream]) {
 | 
						if (chip->get_position[stream])
 | 
				
			||||||
	case POS_FIX_LPIB:
 | 
							pos = chip->get_position[stream](chip, azx_dev);
 | 
				
			||||||
		/* read LPIB */
 | 
						else /* use the position buffer as default */
 | 
				
			||||||
		pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
							pos = azx_get_pos_posbuf(chip, azx_dev);
 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case POS_FIX_VIACOMBO:
 | 
					 | 
				
			||||||
		pos = azx_via_get_position(chip, azx_dev);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		/* use the position buffer */
 | 
					 | 
				
			||||||
		pos = le32_to_cpu(*azx_dev->posbuf);
 | 
					 | 
				
			||||||
		if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) {
 | 
					 | 
				
			||||||
			if (!pos || pos == (u32)-1) {
 | 
					 | 
				
			||||||
				dev_info(chip->card->dev,
 | 
					 | 
				
			||||||
					 "Invalid position buffer, using LPIB read method instead.\n");
 | 
					 | 
				
			||||||
				chip->position_fix[stream] = POS_FIX_LPIB;
 | 
					 | 
				
			||||||
				pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
					 | 
				
			||||||
			} else
 | 
					 | 
				
			||||||
				chip->position_fix[stream] = POS_FIX_POSBUF;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pos >= azx_dev->bufsize)
 | 
						if (pos >= azx_dev->bufsize)
 | 
				
			||||||
		pos = 0;
 | 
							pos = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* calculate runtime delay from LPIB */
 | 
					 | 
				
			||||||
	if (substream->runtime &&
 | 
					 | 
				
			||||||
	    chip->position_fix[stream] == POS_FIX_POSBUF &&
 | 
					 | 
				
			||||||
	    (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
 | 
					 | 
				
			||||||
		unsigned int lpib_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
					 | 
				
			||||||
		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
 | 
					 | 
				
			||||||
			delay = pos - lpib_pos;
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			delay = lpib_pos - pos;
 | 
					 | 
				
			||||||
		if (delay < 0) {
 | 
					 | 
				
			||||||
			if (delay >= azx_dev->delay_negative_threshold)
 | 
					 | 
				
			||||||
				delay = 0;
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				delay += azx_dev->bufsize;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (delay >= azx_dev->period_bytes) {
 | 
					 | 
				
			||||||
			dev_info(chip->card->dev,
 | 
					 | 
				
			||||||
				 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
 | 
					 | 
				
			||||||
				 delay, azx_dev->period_bytes);
 | 
					 | 
				
			||||||
			delay = 0;
 | 
					 | 
				
			||||||
			chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		delay = bytes_to_frames(substream->runtime, delay);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (substream->runtime) {
 | 
						if (substream->runtime) {
 | 
				
			||||||
 | 
							struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 | 
				
			||||||
 | 
							struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (chip->get_delay[stream])
 | 
				
			||||||
 | 
								delay += chip->get_delay[stream](chip, azx_dev, pos);
 | 
				
			||||||
		if (hinfo->ops.get_delay)
 | 
							if (hinfo->ops.get_delay)
 | 
				
			||||||
			delay += hinfo->ops.get_delay(hinfo, apcm->codec,
 | 
								delay += hinfo->ops.get_delay(hinfo, apcm->codec,
 | 
				
			||||||
						      substream);
 | 
											      substream);
 | 
				
			||||||
| 
						 | 
					@ -809,7 +726,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
 | 
				
			||||||
	struct azx *chip = apcm->chip;
 | 
						struct azx *chip = apcm->chip;
 | 
				
			||||||
	struct azx_dev *azx_dev = get_azx_dev(substream);
 | 
						struct azx_dev *azx_dev = get_azx_dev(substream);
 | 
				
			||||||
	return bytes_to_frames(substream->runtime,
 | 
						return bytes_to_frames(substream->runtime,
 | 
				
			||||||
			       azx_get_position(chip, azx_dev, false));
 | 
								       azx_get_position(chip, azx_dev));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
 | 
					static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
 | 
				
			||||||
| 
						 | 
					@ -1059,10 +976,10 @@ static void azx_init_cmd_io(struct azx *chip)
 | 
				
			||||||
	azx_writew(chip, CORBWP, 0);
 | 
						azx_writew(chip, CORBWP, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reset the corb hw read pointer */
 | 
						/* reset the corb hw read pointer */
 | 
				
			||||||
	azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
 | 
						azx_writew(chip, CORBRP, AZX_CORBRP_RST);
 | 
				
			||||||
	if (!(chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)) {
 | 
						if (!(chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)) {
 | 
				
			||||||
		for (timeout = 1000; timeout > 0; timeout--) {
 | 
							for (timeout = 1000; timeout > 0; timeout--) {
 | 
				
			||||||
			if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST)
 | 
								if ((azx_readw(chip, CORBRP) & AZX_CORBRP_RST) == AZX_CORBRP_RST)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			udelay(1);
 | 
								udelay(1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -1082,7 +999,7 @@ static void azx_init_cmd_io(struct azx *chip)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* enable corb dma */
 | 
						/* enable corb dma */
 | 
				
			||||||
	azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
 | 
						azx_writeb(chip, CORBCTL, AZX_CORBCTL_RUN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* RIRB set up */
 | 
						/* RIRB set up */
 | 
				
			||||||
	chip->rirb.addr = chip->rb.addr + 2048;
 | 
						chip->rirb.addr = chip->rb.addr + 2048;
 | 
				
			||||||
| 
						 | 
					@ -1095,14 +1012,14 @@ static void azx_init_cmd_io(struct azx *chip)
 | 
				
			||||||
	/* set the rirb size to 256 entries (ULI requires explicitly) */
 | 
						/* set the rirb size to 256 entries (ULI requires explicitly) */
 | 
				
			||||||
	azx_writeb(chip, RIRBSIZE, 0x02);
 | 
						azx_writeb(chip, RIRBSIZE, 0x02);
 | 
				
			||||||
	/* reset the rirb hw write pointer */
 | 
						/* reset the rirb hw write pointer */
 | 
				
			||||||
	azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST);
 | 
						azx_writew(chip, RIRBWP, AZX_RIRBWP_RST);
 | 
				
			||||||
	/* set N=1, get RIRB response interrupt for new entry */
 | 
						/* set N=1, get RIRB response interrupt for new entry */
 | 
				
			||||||
	if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
 | 
						if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
 | 
				
			||||||
		azx_writew(chip, RINTCNT, 0xc0);
 | 
							azx_writew(chip, RINTCNT, 0xc0);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		azx_writew(chip, RINTCNT, 1);
 | 
							azx_writew(chip, RINTCNT, 1);
 | 
				
			||||||
	/* enable rirb dma and response irq */
 | 
						/* enable rirb dma and response irq */
 | 
				
			||||||
	azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN);
 | 
						azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
 | 
				
			||||||
	spin_unlock_irq(&chip->reg_lock);
 | 
						spin_unlock_irq(&chip->reg_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(azx_init_cmd_io);
 | 
					EXPORT_SYMBOL_GPL(azx_init_cmd_io);
 | 
				
			||||||
| 
						 | 
					@ -1146,7 +1063,7 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wp++;
 | 
						wp++;
 | 
				
			||||||
	wp %= ICH6_MAX_CORB_ENTRIES;
 | 
						wp %= AZX_MAX_CORB_ENTRIES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rp = azx_readw(chip, CORBRP);
 | 
						rp = azx_readw(chip, CORBRP);
 | 
				
			||||||
	if (wp == rp) {
 | 
						if (wp == rp) {
 | 
				
			||||||
| 
						 | 
					@ -1164,7 +1081,7 @@ static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICH6_RIRB_EX_UNSOL_EV	(1<<4)
 | 
					#define AZX_RIRB_EX_UNSOL_EV	(1<<4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* retrieve RIRB entry - called from interrupt handler */
 | 
					/* retrieve RIRB entry - called from interrupt handler */
 | 
				
			||||||
static void azx_update_rirb(struct azx *chip)
 | 
					static void azx_update_rirb(struct azx *chip)
 | 
				
			||||||
| 
						 | 
					@ -1185,7 +1102,7 @@ static void azx_update_rirb(struct azx *chip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (chip->rirb.rp != wp) {
 | 
						while (chip->rirb.rp != wp) {
 | 
				
			||||||
		chip->rirb.rp++;
 | 
							chip->rirb.rp++;
 | 
				
			||||||
		chip->rirb.rp %= ICH6_MAX_RIRB_ENTRIES;
 | 
							chip->rirb.rp %= AZX_MAX_RIRB_ENTRIES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
 | 
							rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
 | 
				
			||||||
		res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
 | 
							res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
 | 
				
			||||||
| 
						 | 
					@ -1196,8 +1113,7 @@ static void azx_update_rirb(struct azx *chip)
 | 
				
			||||||
				res, res_ex,
 | 
									res, res_ex,
 | 
				
			||||||
				chip->rirb.rp, wp);
 | 
									chip->rirb.rp, wp);
 | 
				
			||||||
			snd_BUG();
 | 
								snd_BUG();
 | 
				
			||||||
		}
 | 
							} else if (res_ex & AZX_RIRB_EX_UNSOL_EV)
 | 
				
			||||||
		else if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
 | 
					 | 
				
			||||||
			snd_hda_queue_unsol_event(chip->bus, res, res_ex);
 | 
								snd_hda_queue_unsol_event(chip->bus, res, res_ex);
 | 
				
			||||||
		else if (chip->rirb.cmds[addr]) {
 | 
							else if (chip->rirb.cmds[addr]) {
 | 
				
			||||||
			chip->rirb.res[addr] = res;
 | 
								chip->rirb.res[addr] = res;
 | 
				
			||||||
| 
						 | 
					@ -1305,7 +1221,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
 | 
				
			||||||
	/* release CORB/RIRB */
 | 
						/* release CORB/RIRB */
 | 
				
			||||||
	azx_free_cmd_io(chip);
 | 
						azx_free_cmd_io(chip);
 | 
				
			||||||
	/* disable unsolicited responses */
 | 
						/* disable unsolicited responses */
 | 
				
			||||||
	azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL);
 | 
						azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~AZX_GCTL_UNSOL);
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1326,7 +1242,7 @@ static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (timeout--) {
 | 
						while (timeout--) {
 | 
				
			||||||
		/* check IRV busy bit */
 | 
							/* check IRV busy bit */
 | 
				
			||||||
		if (azx_readw(chip, IRS) & ICH6_IRS_VALID) {
 | 
							if (azx_readw(chip, IRS) & AZX_IRS_VALID) {
 | 
				
			||||||
			/* reuse rirb.res as the response return value */
 | 
								/* reuse rirb.res as the response return value */
 | 
				
			||||||
			chip->rirb.res[addr] = azx_readl(chip, IR);
 | 
								chip->rirb.res[addr] = azx_readl(chip, IR);
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
| 
						 | 
					@ -1350,13 +1266,13 @@ static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
 | 
				
			||||||
	bus->rirb_error = 0;
 | 
						bus->rirb_error = 0;
 | 
				
			||||||
	while (timeout--) {
 | 
						while (timeout--) {
 | 
				
			||||||
		/* check ICB busy bit */
 | 
							/* check ICB busy bit */
 | 
				
			||||||
		if (!((azx_readw(chip, IRS) & ICH6_IRS_BUSY))) {
 | 
							if (!((azx_readw(chip, IRS) & AZX_IRS_BUSY))) {
 | 
				
			||||||
			/* Clear IRV valid bit */
 | 
								/* Clear IRV valid bit */
 | 
				
			||||||
			azx_writew(chip, IRS, azx_readw(chip, IRS) |
 | 
								azx_writew(chip, IRS, azx_readw(chip, IRS) |
 | 
				
			||||||
				   ICH6_IRS_VALID);
 | 
									   AZX_IRS_VALID);
 | 
				
			||||||
			azx_writel(chip, IC, val);
 | 
								azx_writel(chip, IC, val);
 | 
				
			||||||
			azx_writew(chip, IRS, azx_readw(chip, IRS) |
 | 
								azx_writew(chip, IRS, azx_readw(chip, IRS) |
 | 
				
			||||||
				   ICH6_IRS_BUSY);
 | 
									   AZX_IRS_BUSY);
 | 
				
			||||||
			return azx_single_wait_for_response(chip, addr);
 | 
								return azx_single_wait_for_response(chip, addr);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		udelay(1);
 | 
							udelay(1);
 | 
				
			||||||
| 
						 | 
					@ -1585,10 +1501,10 @@ void azx_enter_link_reset(struct azx *chip)
 | 
				
			||||||
	unsigned long timeout;
 | 
						unsigned long timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* reset controller */
 | 
						/* reset controller */
 | 
				
			||||||
	azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
 | 
						azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~AZX_GCTL_RESET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	timeout = jiffies + msecs_to_jiffies(100);
 | 
						timeout = jiffies + msecs_to_jiffies(100);
 | 
				
			||||||
	while ((azx_readb(chip, GCTL) & ICH6_GCTL_RESET) &&
 | 
						while ((azx_readb(chip, GCTL) & AZX_GCTL_RESET) &&
 | 
				
			||||||
			time_before(jiffies, timeout))
 | 
								time_before(jiffies, timeout))
 | 
				
			||||||
		usleep_range(500, 1000);
 | 
							usleep_range(500, 1000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1599,7 +1515,7 @@ static void azx_exit_link_reset(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long timeout;
 | 
						unsigned long timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
 | 
						azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | AZX_GCTL_RESET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	timeout = jiffies + msecs_to_jiffies(100);
 | 
						timeout = jiffies + msecs_to_jiffies(100);
 | 
				
			||||||
	while (!azx_readb(chip, GCTL) &&
 | 
						while (!azx_readb(chip, GCTL) &&
 | 
				
			||||||
| 
						 | 
					@ -1640,7 +1556,7 @@ static int azx_reset(struct azx *chip, bool full_reset)
 | 
				
			||||||
	/* Accept unsolicited responses */
 | 
						/* Accept unsolicited responses */
 | 
				
			||||||
	if (!chip->single_cmd)
 | 
						if (!chip->single_cmd)
 | 
				
			||||||
		azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
 | 
							azx_writel(chip, GCTL, azx_readl(chip, GCTL) |
 | 
				
			||||||
			   ICH6_GCTL_UNSOL);
 | 
								   AZX_GCTL_UNSOL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* detect codecs */
 | 
						/* detect codecs */
 | 
				
			||||||
	if (!chip->codec_mask) {
 | 
						if (!chip->codec_mask) {
 | 
				
			||||||
| 
						 | 
					@ -1657,7 +1573,7 @@ static void azx_int_enable(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* enable controller CIE and GIE */
 | 
						/* enable controller CIE and GIE */
 | 
				
			||||||
	azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
 | 
						azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
 | 
				
			||||||
		   ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN);
 | 
							   AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* disable interrupts */
 | 
					/* disable interrupts */
 | 
				
			||||||
| 
						 | 
					@ -1678,7 +1594,7 @@ static void azx_int_disable(struct azx *chip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* disable controller CIE and GIE */
 | 
						/* disable controller CIE and GIE */
 | 
				
			||||||
	azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
 | 
						azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) &
 | 
				
			||||||
		   ~(ICH6_INT_CTRL_EN | ICH6_INT_GLOBAL_EN));
 | 
							   ~(AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* clear interrupts */
 | 
					/* clear interrupts */
 | 
				
			||||||
| 
						 | 
					@ -1699,7 +1615,7 @@ static void azx_int_clear(struct azx *chip)
 | 
				
			||||||
	azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
 | 
						azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* clear int status */
 | 
						/* clear int status */
 | 
				
			||||||
	azx_writel(chip, INTSTS, ICH6_INT_CTRL_EN | ICH6_INT_ALL_STREAM);
 | 
						azx_writel(chip, INTSTS, AZX_INT_CTRL_EN | AZX_INT_ALL_STREAM);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -2031,5 +1947,30 @@ int azx_init_stream(struct azx *chip)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(azx_init_stream);
 | 
					EXPORT_SYMBOL_GPL(azx_init_stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * reboot notifier for hang-up problem at power-down
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct azx *chip = container_of(nb, struct azx, reboot_notifier);
 | 
				
			||||||
 | 
						snd_hda_bus_reboot_notify(chip->bus);
 | 
				
			||||||
 | 
						azx_stop_chip(chip);
 | 
				
			||||||
 | 
						return NOTIFY_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void azx_notifier_register(struct azx *chip)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						chip->reboot_notifier.notifier_call = azx_halt;
 | 
				
			||||||
 | 
						register_reboot_notifier(&chip->reboot_notifier);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(azx_notifier_register);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void azx_notifier_unregister(struct azx *chip)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (chip->reboot_notifier.notifier_call)
 | 
				
			||||||
 | 
							unregister_reboot_notifier(&chip->reboot_notifier);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(azx_notifier_unregister);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
MODULE_DESCRIPTION("Common HDA driver funcitons");
 | 
					MODULE_DESCRIPTION("Common HDA driver funcitons");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,9 +25,9 @@ static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return substream->runtime->private_data;
 | 
						return substream->runtime->private_data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
unsigned int azx_get_position(struct azx *chip,
 | 
					unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev);
 | 
				
			||||||
			      struct azx_dev *azx_dev,
 | 
					unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev);
 | 
				
			||||||
			      bool with_check);
 | 
					unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Stream control. */
 | 
					/* Stream control. */
 | 
				
			||||||
void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev);
 | 
					void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev);
 | 
				
			||||||
| 
						 | 
					@ -50,4 +50,7 @@ int azx_codec_configure(struct azx *chip);
 | 
				
			||||||
int azx_mixer_create(struct azx *chip);
 | 
					int azx_mixer_create(struct azx *chip);
 | 
				
			||||||
int azx_init_stream(struct azx *chip);
 | 
					int azx_init_stream(struct azx *chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void azx_notifier_register(struct azx *chip);
 | 
				
			||||||
 | 
					void azx_notifier_unregister(struct azx *chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __SOUND_HDA_CONTROLLER_H */
 | 
					#endif /* __SOUND_HDA_CONTROLLER_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,7 +167,8 @@ static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
 | 
				
			||||||
	(buf[byte] >> (lowbit)) & ((1 << (bits)) - 1);	\
 | 
						(buf[byte] >> (lowbit)) & ((1 << (bits)) - 1);	\
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hdmi_update_short_audio_desc(struct cea_sad *a,
 | 
					static void hdmi_update_short_audio_desc(struct hda_codec *codec,
 | 
				
			||||||
 | 
										 struct cea_sad *a,
 | 
				
			||||||
					 const unsigned char *buf)
 | 
										 const unsigned char *buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					@ -188,8 +189,7 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 | 
				
			||||||
	a->format = GRAB_BITS(buf, 0, 3, 4);
 | 
						a->format = GRAB_BITS(buf, 0, 3, 4);
 | 
				
			||||||
	switch (a->format) {
 | 
						switch (a->format) {
 | 
				
			||||||
	case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
 | 
						case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
 | 
				
			||||||
		snd_printd(KERN_INFO
 | 
							codec_info(codec, "HDMI: audio coding type 0 not expected\n");
 | 
				
			||||||
				"HDMI: audio coding type 0 not expected\n");
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AUDIO_CODING_TYPE_LPCM:
 | 
						case AUDIO_CODING_TYPE_LPCM:
 | 
				
			||||||
| 
						 | 
					@ -233,9 +233,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 | 
				
			||||||
		a->format = GRAB_BITS(buf, 2, 3, 5);
 | 
							a->format = GRAB_BITS(buf, 2, 3, 5);
 | 
				
			||||||
		if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
 | 
							if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
 | 
				
			||||||
		    a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
 | 
							    a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
 | 
				
			||||||
			snd_printd(KERN_INFO
 | 
								codec_info(codec,
 | 
				
			||||||
				"HDMI: audio coding xtype %d not expected\n",
 | 
									   "HDMI: audio coding xtype %d not expected\n",
 | 
				
			||||||
				a->format);
 | 
									   a->format);
 | 
				
			||||||
			a->format = 0;
 | 
								a->format = 0;
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			a->format += AUDIO_CODING_TYPE_HE_AAC -
 | 
								a->format += AUDIO_CODING_TYPE_HE_AAC -
 | 
				
			||||||
| 
						 | 
					@ -247,7 +247,7 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Be careful, ELD buf could be totally rubbish!
 | 
					 * Be careful, ELD buf could be totally rubbish!
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e,
 | 
					int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e,
 | 
				
			||||||
			  const unsigned char *buf, int size)
 | 
								  const unsigned char *buf, int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int mnl;
 | 
						int mnl;
 | 
				
			||||||
| 
						 | 
					@ -256,8 +256,7 @@ int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e,
 | 
				
			||||||
	e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
 | 
						e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
 | 
				
			||||||
	if (e->eld_ver != ELD_VER_CEA_861D &&
 | 
						if (e->eld_ver != ELD_VER_CEA_861D &&
 | 
				
			||||||
	    e->eld_ver != ELD_VER_PARTIAL) {
 | 
						    e->eld_ver != ELD_VER_PARTIAL) {
 | 
				
			||||||
		snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
 | 
							codec_info(codec, "HDMI: Unknown ELD version %d\n", e->eld_ver);
 | 
				
			||||||
								e->eld_ver);
 | 
					 | 
				
			||||||
		goto out_fail;
 | 
							goto out_fail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,20 +279,20 @@ int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e,
 | 
				
			||||||
	e->product_id	  = get_unaligned_le16(buf + 18);
 | 
						e->product_id	  = get_unaligned_le16(buf + 18);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (mnl > ELD_MAX_MNL) {
 | 
						if (mnl > ELD_MAX_MNL) {
 | 
				
			||||||
		snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
 | 
							codec_info(codec, "HDMI: MNL is reserved value %d\n", mnl);
 | 
				
			||||||
		goto out_fail;
 | 
							goto out_fail;
 | 
				
			||||||
	} else if (ELD_FIXED_BYTES + mnl > size) {
 | 
						} else if (ELD_FIXED_BYTES + mnl > size) {
 | 
				
			||||||
		snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
 | 
							codec_info(codec, "HDMI: out of range MNL %d\n", mnl);
 | 
				
			||||||
		goto out_fail;
 | 
							goto out_fail;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1);
 | 
							strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < e->sad_count; i++) {
 | 
						for (i = 0; i < e->sad_count; i++) {
 | 
				
			||||||
		if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
 | 
							if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
 | 
				
			||||||
			snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
 | 
								codec_info(codec, "HDMI: out of range SAD %d\n", i);
 | 
				
			||||||
			goto out_fail;
 | 
								goto out_fail;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		hdmi_update_short_audio_desc(e->sad + i,
 | 
							hdmi_update_short_audio_desc(codec, e->sad + i,
 | 
				
			||||||
					buf + ELD_FIXED_BYTES + mnl + 3 * i);
 | 
										buf + ELD_FIXED_BYTES + mnl + 3 * i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -394,7 +393,8 @@ static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SND_PRINT_RATES_ADVISED_BUFSIZE	80
 | 
					#define SND_PRINT_RATES_ADVISED_BUFSIZE	80
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hdmi_show_short_audio_desc(struct cea_sad *a)
 | 
					static void hdmi_show_short_audio_desc(struct hda_codec *codec,
 | 
				
			||||||
 | 
									       struct cea_sad *a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
 | 
						char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
 | 
				
			||||||
	char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
 | 
						char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
 | 
				
			||||||
| 
						 | 
					@ -412,12 +412,10 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		buf2[0] = '\0';
 | 
							buf2[0] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_snd_printd(SND_PR_VERBOSE, "HDMI: supports coding type %s:"
 | 
						codec_dbg(codec,
 | 
				
			||||||
			" channels = %d, rates =%s%s\n",
 | 
							  "HDMI: supports coding type %s: channels = %d, rates =%s%s\n",
 | 
				
			||||||
			cea_audio_coding_type_names[a->format],
 | 
							  cea_audio_coding_type_names[a->format],
 | 
				
			||||||
			a->channels,
 | 
							  a->channels, buf, buf2);
 | 
				
			||||||
			buf,
 | 
					 | 
				
			||||||
			buf2);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
 | 
					void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
 | 
				
			||||||
| 
						 | 
					@ -432,22 +430,22 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
 | 
				
			||||||
	buf[j] = '\0';	/* necessary when j == 0 */
 | 
						buf[j] = '\0';	/* necessary when j == 0 */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void snd_hdmi_show_eld(struct parsed_hdmi_eld *e)
 | 
					void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_snd_printd(SND_PR_VERBOSE, "HDMI: detected monitor %s at connection type %s\n",
 | 
						codec_dbg(codec, "HDMI: detected monitor %s at connection type %s\n",
 | 
				
			||||||
			e->monitor_name,
 | 
								e->monitor_name,
 | 
				
			||||||
			eld_connection_type_names[e->conn_type]);
 | 
								eld_connection_type_names[e->conn_type]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (e->spk_alloc) {
 | 
						if (e->spk_alloc) {
 | 
				
			||||||
		char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
 | 
							char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
 | 
				
			||||||
		snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
 | 
							snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
 | 
				
			||||||
		_snd_printd(SND_PR_VERBOSE, "HDMI: available speakers:%s\n", buf);
 | 
							codec_dbg(codec, "HDMI: available speakers:%s\n", buf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < e->sad_count; i++)
 | 
						for (i = 0; i < e->sad_count; i++)
 | 
				
			||||||
		hdmi_show_short_audio_desc(e->sad + i);
 | 
							hdmi_show_short_audio_desc(codec, e->sad + i);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PROC_FS
 | 
					#ifdef CONFIG_PROC_FS
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -350,16 +350,16 @@ static void print_nid_path(struct hda_codec *codec,
 | 
				
			||||||
			   const char *pfx, struct nid_path *path)
 | 
								   const char *pfx, struct nid_path *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[40];
 | 
						char buf[40];
 | 
				
			||||||
 | 
						char *pos = buf;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*pos = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < path->depth; i++)
 | 
				
			||||||
 | 
							pos += scnprintf(pos, sizeof(buf) - (pos - buf), "%s%02x",
 | 
				
			||||||
 | 
									 pos != buf ? ":" : "",
 | 
				
			||||||
 | 
									 path->path[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf[0] = 0;
 | 
						codec_dbg(codec, "%s path: depth=%d '%s'\n", pfx, path->depth, buf);
 | 
				
			||||||
	for (i = 0; i < path->depth; i++) {
 | 
					 | 
				
			||||||
		char tmp[4];
 | 
					 | 
				
			||||||
		sprintf(tmp, ":%02x", path->path[i]);
 | 
					 | 
				
			||||||
		strlcat(buf, tmp, sizeof(buf));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	codec_dbg(codec, "%s path: depth=%d %s\n", pfx, path->depth, buf);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* called recursively */
 | 
					/* called recursively */
 | 
				
			||||||
| 
						 | 
					@ -1700,9 +1700,11 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
 | 
				
			||||||
#define DEBUG_BADNESS
 | 
					#define DEBUG_BADNESS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG_BADNESS
 | 
					#ifdef DEBUG_BADNESS
 | 
				
			||||||
#define debug_badness(fmt, args...)	codec_dbg(codec, fmt, ##args)
 | 
					#define debug_badness(fmt, ...)						\
 | 
				
			||||||
 | 
						codec_dbg(codec, fmt, ##__VA_ARGS__)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define debug_badness(...)
 | 
					#define debug_badness(fmt, ...)						\
 | 
				
			||||||
 | 
						do { if (0) codec_dbg(codec, fmt, ##__VA_ARGS__); } while (0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef DEBUG_BADNESS
 | 
					#ifdef DEBUG_BADNESS
 | 
				
			||||||
| 
						 | 
					@ -3054,7 +3056,7 @@ static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin,
 | 
				
			||||||
			if (spec->hp_mic_pin == pin)
 | 
								if (spec->hp_mic_pin == pin)
 | 
				
			||||||
				spec->hp_mic_mux_idx = imux->num_items;
 | 
									spec->hp_mic_mux_idx = imux->num_items;
 | 
				
			||||||
			spec->imux_pins[imux->num_items] = pin;
 | 
								spec->imux_pins[imux->num_items] = pin;
 | 
				
			||||||
			snd_hda_add_imux_item(imux, label, cfg_idx, NULL);
 | 
								snd_hda_add_imux_item(codec, imux, label, cfg_idx, NULL);
 | 
				
			||||||
			imux_added = true;
 | 
								imux_added = true;
 | 
				
			||||||
			if (spec->dyn_adc_switch)
 | 
								if (spec->dyn_adc_switch)
 | 
				
			||||||
				spec->dyn_adc_idx[imux_idx] = c;
 | 
									spec->dyn_adc_idx[imux_idx] = c;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,8 +28,8 @@
 | 
				
			||||||
 * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
 | 
					 * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N
 | 
				
			||||||
 * The values will be lost when the display power well is disabled.
 | 
					 * The values will be lost when the display power well is disabled.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define ICH6_REG_EM4			0x100c
 | 
					#define AZX_REG_EM4			0x100c
 | 
				
			||||||
#define ICH6_REG_EM5			0x1010
 | 
					#define AZX_REG_EM5			0x1010
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int (*get_power)(void);
 | 
					static int (*get_power)(void);
 | 
				
			||||||
static int (*put_power)(void);
 | 
					static int (*put_power)(void);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,6 @@
 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/pci.h>
 | 
					#include <linux/pci.h>
 | 
				
			||||||
#include <linux/mutex.h>
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <linux/reboot.h>
 | 
					 | 
				
			||||||
#include <linux/io.h>
 | 
					#include <linux/io.h>
 | 
				
			||||||
#include <linux/pm_runtime.h>
 | 
					#include <linux/pm_runtime.h>
 | 
				
			||||||
#include <linux/clocksource.h>
 | 
					#include <linux/clocksource.h>
 | 
				
			||||||
| 
						 | 
					@ -66,6 +65,52 @@
 | 
				
			||||||
#include "hda_priv.h"
 | 
					#include "hda_priv.h"
 | 
				
			||||||
#include "hda_i915.h"
 | 
					#include "hda_i915.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* position fix mode */
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						POS_FIX_AUTO,
 | 
				
			||||||
 | 
						POS_FIX_LPIB,
 | 
				
			||||||
 | 
						POS_FIX_POSBUF,
 | 
				
			||||||
 | 
						POS_FIX_VIACOMBO,
 | 
				
			||||||
 | 
						POS_FIX_COMBO,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Defines for ATI HD Audio support in SB450 south bridge */
 | 
				
			||||||
 | 
					#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
 | 
				
			||||||
 | 
					#define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Defines for Nvidia HDA support */
 | 
				
			||||||
 | 
					#define NVIDIA_HDA_TRANSREG_ADDR      0x4e
 | 
				
			||||||
 | 
					#define NVIDIA_HDA_ENABLE_COHBITS     0x0f
 | 
				
			||||||
 | 
					#define NVIDIA_HDA_ISTRM_COH          0x4d
 | 
				
			||||||
 | 
					#define NVIDIA_HDA_OSTRM_COH          0x4c
 | 
				
			||||||
 | 
					#define NVIDIA_HDA_ENABLE_COHBIT      0x01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Defines for Intel SCH HDA snoop control */
 | 
				
			||||||
 | 
					#define INTEL_SCH_HDA_DEVC      0x78
 | 
				
			||||||
 | 
					#define INTEL_SCH_HDA_DEVC_NOSNOOP       (0x1<<11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Define IN stream 0 FIFO size offset in VIA controller */
 | 
				
			||||||
 | 
					#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET	0x90
 | 
				
			||||||
 | 
					/* Define VIA HD Audio Device ID*/
 | 
				
			||||||
 | 
					#define VIA_HDAC_DEVICE_ID		0x3288
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* max number of SDs */
 | 
				
			||||||
 | 
					/* ICH, ATI and VIA have 4 playback and 4 capture */
 | 
				
			||||||
 | 
					#define ICH6_NUM_CAPTURE	4
 | 
				
			||||||
 | 
					#define ICH6_NUM_PLAYBACK	4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ULI has 6 playback and 5 capture */
 | 
				
			||||||
 | 
					#define ULI_NUM_CAPTURE		5
 | 
				
			||||||
 | 
					#define ULI_NUM_PLAYBACK	6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ATI HDMI may have up to 8 playbacks and 0 capture */
 | 
				
			||||||
 | 
					#define ATIHDMI_NUM_CAPTURE	0
 | 
				
			||||||
 | 
					#define ATIHDMI_NUM_PLAYBACK	8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TERA has 4 playback and 3 capture */
 | 
				
			||||||
 | 
					#define TERA_NUM_CAPTURE	3
 | 
				
			||||||
 | 
					#define TERA_NUM_PLAYBACK	4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 | 
					static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 | 
				
			||||||
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 | 
					static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 | 
				
			||||||
| 
						 | 
					@ -290,8 +335,28 @@ static char *driver_short_names[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct hda_intel {
 | 
					struct hda_intel {
 | 
				
			||||||
	struct azx chip;
 | 
						struct azx chip;
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* for pending irqs */
 | 
				
			||||||
 | 
						struct work_struct irq_pending_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* sync probing */
 | 
				
			||||||
 | 
						struct completion probe_wait;
 | 
				
			||||||
 | 
						struct work_struct probe_work;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* card list (for power_save trigger) */
 | 
				
			||||||
 | 
						struct list_head list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* extra flags */
 | 
				
			||||||
 | 
						unsigned int irq_pending_warned:1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* VGA-switcheroo setup */
 | 
				
			||||||
 | 
						unsigned int use_vga_switcheroo:1;
 | 
				
			||||||
 | 
						unsigned int vga_switcheroo_registered:1;
 | 
				
			||||||
 | 
						unsigned int init_failed:1; /* delayed init failed */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* secondary power domain for hdmi audio under vga device */
 | 
				
			||||||
 | 
						struct dev_pm_domain hdmi_pm_domain;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_X86
 | 
					#ifdef CONFIG_X86
 | 
				
			||||||
static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
 | 
					static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
 | 
				
			||||||
| 
						 | 
					@ -373,7 +438,7 @@ static void azx_init_pci(struct azx *chip)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
 | 
						if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
 | 
				
			||||||
		dev_dbg(chip->card->dev, "Clearing TCSEL\n");
 | 
							dev_dbg(chip->card->dev, "Clearing TCSEL\n");
 | 
				
			||||||
		update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
 | 
							update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
 | 
						/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
 | 
				
			||||||
| 
						 | 
					@ -421,11 +486,44 @@ static void azx_init_pci(struct azx *chip)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* calculate runtime delay from LPIB */
 | 
				
			||||||
 | 
					static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
 | 
				
			||||||
 | 
									   unsigned int pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_pcm_substream *substream = azx_dev->substream;
 | 
				
			||||||
 | 
						int stream = substream->stream;
 | 
				
			||||||
 | 
						unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
 | 
				
			||||||
 | 
						int delay;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (stream == SNDRV_PCM_STREAM_PLAYBACK)
 | 
				
			||||||
 | 
							delay = pos - lpib_pos;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							delay = lpib_pos - pos;
 | 
				
			||||||
 | 
						if (delay < 0) {
 | 
				
			||||||
 | 
							if (delay >= azx_dev->delay_negative_threshold)
 | 
				
			||||||
 | 
								delay = 0;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								delay += azx_dev->bufsize;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (delay >= azx_dev->period_bytes) {
 | 
				
			||||||
 | 
							dev_info(chip->card->dev,
 | 
				
			||||||
 | 
								 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
 | 
				
			||||||
 | 
								 delay, azx_dev->period_bytes);
 | 
				
			||||||
 | 
							delay = 0;
 | 
				
			||||||
 | 
							chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
 | 
				
			||||||
 | 
							chip->get_delay[stream] = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return bytes_to_frames(substream->runtime, delay);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
 | 
					static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* called from IRQ */
 | 
					/* called from IRQ */
 | 
				
			||||||
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
 | 
					static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	int ok;
 | 
						int ok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ok = azx_position_ok(chip, azx_dev);
 | 
						ok = azx_position_ok(chip, azx_dev);
 | 
				
			||||||
| 
						 | 
					@ -435,7 +533,7 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
	} else if (ok == 0 && chip->bus && chip->bus->workq) {
 | 
						} else if (ok == 0 && chip->bus && chip->bus->workq) {
 | 
				
			||||||
		/* bogus IRQ, process it later */
 | 
							/* bogus IRQ, process it later */
 | 
				
			||||||
		azx_dev->irq_pending = 1;
 | 
							azx_dev->irq_pending = 1;
 | 
				
			||||||
		queue_work(chip->bus->workq, &chip->irq_pending_work);
 | 
							queue_work(chip->bus->workq, &hda->irq_pending_work);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -451,6 +549,8 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 | 
					static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct snd_pcm_substream *substream = azx_dev->substream;
 | 
				
			||||||
 | 
						int stream = substream->stream;
 | 
				
			||||||
	u32 wallclk;
 | 
						u32 wallclk;
 | 
				
			||||||
	unsigned int pos;
 | 
						unsigned int pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -458,7 +558,25 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
	if (wallclk < (azx_dev->period_wallclk * 2) / 3)
 | 
						if (wallclk < (azx_dev->period_wallclk * 2) / 3)
 | 
				
			||||||
		return -1;	/* bogus (too early) interrupt */
 | 
							return -1;	/* bogus (too early) interrupt */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pos = azx_get_position(chip, azx_dev, true);
 | 
						if (chip->get_position[stream])
 | 
				
			||||||
 | 
							pos = chip->get_position[stream](chip, azx_dev);
 | 
				
			||||||
 | 
						else { /* use the position buffer as default */
 | 
				
			||||||
 | 
							pos = azx_get_pos_posbuf(chip, azx_dev);
 | 
				
			||||||
 | 
							if (!pos || pos == (u32)-1) {
 | 
				
			||||||
 | 
								dev_info(chip->card->dev,
 | 
				
			||||||
 | 
									 "Invalid position buffer, using LPIB read method instead.\n");
 | 
				
			||||||
 | 
								chip->get_position[stream] = azx_get_pos_lpib;
 | 
				
			||||||
 | 
								pos = azx_get_pos_lpib(chip, azx_dev);
 | 
				
			||||||
 | 
								chip->get_delay[stream] = NULL;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								chip->get_position[stream] = azx_get_pos_posbuf;
 | 
				
			||||||
 | 
								if (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)
 | 
				
			||||||
 | 
									chip->get_delay[stream] = azx_get_delay_from_lpib;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pos >= azx_dev->bufsize)
 | 
				
			||||||
 | 
							pos = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (WARN_ONCE(!azx_dev->period_bytes,
 | 
						if (WARN_ONCE(!azx_dev->period_bytes,
 | 
				
			||||||
		      "hda-intel: zero azx_dev->period_bytes"))
 | 
							      "hda-intel: zero azx_dev->period_bytes"))
 | 
				
			||||||
| 
						 | 
					@ -476,14 +594,15 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void azx_irq_pending_work(struct work_struct *work)
 | 
					static void azx_irq_pending_work(struct work_struct *work)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct azx *chip = container_of(work, struct azx, irq_pending_work);
 | 
						struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
 | 
				
			||||||
 | 
						struct azx *chip = &hda->chip;
 | 
				
			||||||
	int i, pending, ok;
 | 
						int i, pending, ok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!chip->irq_pending_warned) {
 | 
						if (!hda->irq_pending_warned) {
 | 
				
			||||||
		dev_info(chip->card->dev,
 | 
							dev_info(chip->card->dev,
 | 
				
			||||||
			 "IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
 | 
								 "IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
 | 
				
			||||||
			 chip->card->number);
 | 
								 chip->card->number);
 | 
				
			||||||
		chip->irq_pending_warned = 1;
 | 
							hda->irq_pending_warned = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;) {
 | 
						for (;;) {
 | 
				
			||||||
| 
						 | 
					@ -541,27 +660,86 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* get the current DMA position with correction on VIA chips */
 | 
				
			||||||
 | 
					static unsigned int azx_via_get_position(struct azx *chip,
 | 
				
			||||||
 | 
										 struct azx_dev *azx_dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int link_pos, mini_pos, bound_pos;
 | 
				
			||||||
 | 
						unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
 | 
				
			||||||
 | 
						unsigned int fifo_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link_pos = azx_sd_readl(chip, azx_dev, SD_LPIB);
 | 
				
			||||||
 | 
						if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 | 
				
			||||||
 | 
							/* Playback, no problem using link position */
 | 
				
			||||||
 | 
							return link_pos;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Capture */
 | 
				
			||||||
 | 
						/* For new chipset,
 | 
				
			||||||
 | 
						 * use mod to get the DMA position just like old chipset
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						mod_dma_pos = le32_to_cpu(*azx_dev->posbuf);
 | 
				
			||||||
 | 
						mod_dma_pos %= azx_dev->period_bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* azx_dev->fifo_size can't get FIFO size of in stream.
 | 
				
			||||||
 | 
						 * Get from base address + offset.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (azx_dev->insufficient) {
 | 
				
			||||||
 | 
							/* Link position never gather than FIFO size */
 | 
				
			||||||
 | 
							if (link_pos <= fifo_size)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							azx_dev->insufficient = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (link_pos <= fifo_size)
 | 
				
			||||||
 | 
							mini_pos = azx_dev->bufsize + link_pos - fifo_size;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							mini_pos = link_pos - fifo_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Find nearest previous boudary */
 | 
				
			||||||
 | 
						mod_mini_pos = mini_pos % azx_dev->period_bytes;
 | 
				
			||||||
 | 
						mod_link_pos = link_pos % azx_dev->period_bytes;
 | 
				
			||||||
 | 
						if (mod_link_pos >= fifo_size)
 | 
				
			||||||
 | 
							bound_pos = link_pos - mod_link_pos;
 | 
				
			||||||
 | 
						else if (mod_dma_pos >= mod_mini_pos)
 | 
				
			||||||
 | 
							bound_pos = mini_pos - mod_mini_pos;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes;
 | 
				
			||||||
 | 
							if (bound_pos >= azx_dev->bufsize)
 | 
				
			||||||
 | 
								bound_pos = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Calculate real DMA position we want */
 | 
				
			||||||
 | 
						return bound_pos + mod_dma_pos;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PM
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
static DEFINE_MUTEX(card_list_lock);
 | 
					static DEFINE_MUTEX(card_list_lock);
 | 
				
			||||||
static LIST_HEAD(card_list);
 | 
					static LIST_HEAD(card_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void azx_add_card_list(struct azx *chip)
 | 
					static void azx_add_card_list(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	mutex_lock(&card_list_lock);
 | 
						mutex_lock(&card_list_lock);
 | 
				
			||||||
	list_add(&chip->list, &card_list);
 | 
						list_add(&hda->list, &card_list);
 | 
				
			||||||
	mutex_unlock(&card_list_lock);
 | 
						mutex_unlock(&card_list_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void azx_del_card_list(struct azx *chip)
 | 
					static void azx_del_card_list(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	mutex_lock(&card_list_lock);
 | 
						mutex_lock(&card_list_lock);
 | 
				
			||||||
	list_del_init(&chip->list);
 | 
						list_del_init(&hda->list);
 | 
				
			||||||
	mutex_unlock(&card_list_lock);
 | 
						mutex_unlock(&card_list_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* trigger power-save check at writing parameter */
 | 
					/* trigger power-save check at writing parameter */
 | 
				
			||||||
static int param_set_xint(const char *val, const struct kernel_param *kp)
 | 
					static int param_set_xint(const char *val, const struct kernel_param *kp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
	struct azx *chip;
 | 
						struct azx *chip;
 | 
				
			||||||
	struct hda_codec *c;
 | 
						struct hda_codec *c;
 | 
				
			||||||
	int prev = power_save;
 | 
						int prev = power_save;
 | 
				
			||||||
| 
						 | 
					@ -571,7 +749,8 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutex_lock(&card_list_lock);
 | 
						mutex_lock(&card_list_lock);
 | 
				
			||||||
	list_for_each_entry(chip, &card_list, list) {
 | 
						list_for_each_entry(hda, &card_list, list) {
 | 
				
			||||||
 | 
							chip = &hda->chip;
 | 
				
			||||||
		if (!chip->bus || chip->disabled)
 | 
							if (!chip->bus || chip->disabled)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		list_for_each_entry(c, &chip->bus->codec_list, list)
 | 
							list_for_each_entry(c, &chip->bus->codec_list, list)
 | 
				
			||||||
| 
						 | 
					@ -593,10 +772,16 @@ static int azx_suspend(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pci_dev *pci = to_pci_dev(dev);
 | 
						struct pci_dev *pci = to_pci_dev(dev);
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
	struct azx_pcm *p;
 | 
						struct azx_pcm *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->disabled || chip->init_failed)
 | 
						if (!card)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip = card->private_data;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
						if (chip->disabled || hda->init_failed)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 | 
						snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 | 
				
			||||||
| 
						 | 
					@ -626,9 +811,15 @@ static int azx_resume(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pci_dev *pci = to_pci_dev(dev);
 | 
						struct pci_dev *pci = to_pci_dev(dev);
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->disabled || chip->init_failed)
 | 
						if (!card)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip = card->private_data;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
						if (chip->disabled || hda->init_failed)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
 | 
						if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
 | 
				
			||||||
| 
						 | 
					@ -663,9 +854,15 @@ static int azx_resume(struct device *dev)
 | 
				
			||||||
static int azx_runtime_suspend(struct device *dev)
 | 
					static int azx_runtime_suspend(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->disabled || chip->init_failed)
 | 
						if (!card)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip = card->private_data;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
						if (chip->disabled || hda->init_failed)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 | 
						if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 | 
				
			||||||
| 
						 | 
					@ -687,12 +884,18 @@ static int azx_runtime_suspend(struct device *dev)
 | 
				
			||||||
static int azx_runtime_resume(struct device *dev)
 | 
					static int azx_runtime_resume(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
	struct hda_bus *bus;
 | 
						struct hda_bus *bus;
 | 
				
			||||||
	struct hda_codec *codec;
 | 
						struct hda_codec *codec;
 | 
				
			||||||
	int status;
 | 
						int status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->disabled || chip->init_failed)
 | 
						if (!card)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip = card->private_data;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
						if (chip->disabled || hda->init_failed)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 | 
						if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 | 
				
			||||||
| 
						 | 
					@ -727,9 +930,15 @@ static int azx_runtime_resume(struct device *dev)
 | 
				
			||||||
static int azx_runtime_idle(struct device *dev)
 | 
					static int azx_runtime_idle(struct device *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->disabled || chip->init_failed)
 | 
						if (!card)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip = card->private_data;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
						if (chip->disabled || hda->init_failed)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!power_save_controller ||
 | 
						if (!power_save_controller ||
 | 
				
			||||||
| 
						 | 
					@ -753,29 +962,6 @@ static const struct dev_pm_ops azx_pm = {
 | 
				
			||||||
#endif /* CONFIG_PM */
 | 
					#endif /* CONFIG_PM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * reboot notifier for hang-up problem at power-down
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct azx *chip = container_of(nb, struct azx, reboot_notifier);
 | 
					 | 
				
			||||||
	snd_hda_bus_reboot_notify(chip->bus);
 | 
					 | 
				
			||||||
	azx_stop_chip(chip);
 | 
					 | 
				
			||||||
	return NOTIFY_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void azx_notifier_register(struct azx *chip)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	chip->reboot_notifier.notifier_call = azx_halt;
 | 
					 | 
				
			||||||
	register_reboot_notifier(&chip->reboot_notifier);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void azx_notifier_unregister(struct azx *chip)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (chip->reboot_notifier.notifier_call)
 | 
					 | 
				
			||||||
		unregister_reboot_notifier(&chip->reboot_notifier);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int azx_probe_continue(struct azx *chip);
 | 
					static int azx_probe_continue(struct azx *chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SUPPORT_VGA_SWITCHEROO
 | 
					#ifdef SUPPORT_VGA_SWITCHEROO
 | 
				
			||||||
| 
						 | 
					@ -786,10 +972,11 @@ static void azx_vs_set_state(struct pci_dev *pci,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_card *card = pci_get_drvdata(pci);
 | 
						struct snd_card *card = pci_get_drvdata(pci);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip = card->private_data;
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	bool disabled;
 | 
						bool disabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wait_for_completion(&chip->probe_wait);
 | 
						wait_for_completion(&hda->probe_wait);
 | 
				
			||||||
	if (chip->init_failed)
 | 
						if (hda->init_failed)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	disabled = (state == VGA_SWITCHEROO_OFF);
 | 
						disabled = (state == VGA_SWITCHEROO_OFF);
 | 
				
			||||||
| 
						 | 
					@ -803,7 +990,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
 | 
				
			||||||
				 "Start delayed initialization\n");
 | 
									 "Start delayed initialization\n");
 | 
				
			||||||
			if (azx_probe_continue(chip) < 0) {
 | 
								if (azx_probe_continue(chip) < 0) {
 | 
				
			||||||
				dev_err(chip->card->dev, "initialization error\n");
 | 
									dev_err(chip->card->dev, "initialization error\n");
 | 
				
			||||||
				chip->init_failed = true;
 | 
									hda->init_failed = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -833,9 +1020,10 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_card *card = pci_get_drvdata(pci);
 | 
						struct snd_card *card = pci_get_drvdata(pci);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip = card->private_data;
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wait_for_completion(&chip->probe_wait);
 | 
						wait_for_completion(&hda->probe_wait);
 | 
				
			||||||
	if (chip->init_failed)
 | 
						if (hda->init_failed)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	if (chip->disabled || !chip->bus)
 | 
						if (chip->disabled || !chip->bus)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
| 
						 | 
					@ -847,11 +1035,12 @@ static bool azx_vs_can_switch(struct pci_dev *pci)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void init_vga_switcheroo(struct azx *chip)
 | 
					static void init_vga_switcheroo(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	struct pci_dev *p = get_bound_vga(chip->pci);
 | 
						struct pci_dev *p = get_bound_vga(chip->pci);
 | 
				
			||||||
	if (p) {
 | 
						if (p) {
 | 
				
			||||||
		dev_info(chip->card->dev,
 | 
							dev_info(chip->card->dev,
 | 
				
			||||||
			 "Handle VGA-switcheroo audio client\n");
 | 
								 "Handle VGA-switcheroo audio client\n");
 | 
				
			||||||
		chip->use_vga_switcheroo = 1;
 | 
							hda->use_vga_switcheroo = 1;
 | 
				
			||||||
		pci_dev_put(p);
 | 
							pci_dev_put(p);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -863,9 +1052,10 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int register_vga_switcheroo(struct azx *chip)
 | 
					static int register_vga_switcheroo(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!chip->use_vga_switcheroo)
 | 
						if (!hda->use_vga_switcheroo)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	/* FIXME: currently only handling DIS controller
 | 
						/* FIXME: currently only handling DIS controller
 | 
				
			||||||
	 * is there any machine with two switchable HDMI audio controllers?
 | 
						 * is there any machine with two switchable HDMI audio controllers?
 | 
				
			||||||
| 
						 | 
					@ -875,11 +1065,11 @@ static int register_vga_switcheroo(struct azx *chip)
 | 
				
			||||||
						    chip->bus != NULL);
 | 
											    chip->bus != NULL);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	chip->vga_switcheroo_registered = 1;
 | 
						hda->vga_switcheroo_registered = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* register as an optimus hdmi audio power domain */
 | 
						/* register as an optimus hdmi audio power domain */
 | 
				
			||||||
	vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
 | 
						vga_switcheroo_init_domain_pm_optimus_hdmi_audio(chip->card->dev,
 | 
				
			||||||
							 &chip->hdmi_pm_domain);
 | 
												 &hda->hdmi_pm_domain);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -895,7 +1085,6 @@ static int azx_free(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pci_dev *pci = chip->pci;
 | 
						struct pci_dev *pci = chip->pci;
 | 
				
			||||||
	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
 | 
						if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
 | 
				
			||||||
| 
						 | 
					@ -906,13 +1095,13 @@ static int azx_free(struct azx *chip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	azx_notifier_unregister(chip);
 | 
						azx_notifier_unregister(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->init_failed = 1; /* to be sure */
 | 
						hda->init_failed = 1; /* to be sure */
 | 
				
			||||||
	complete_all(&chip->probe_wait);
 | 
						complete_all(&hda->probe_wait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (use_vga_switcheroo(chip)) {
 | 
						if (use_vga_switcheroo(hda)) {
 | 
				
			||||||
		if (chip->disabled && chip->bus)
 | 
							if (chip->disabled && chip->bus)
 | 
				
			||||||
			snd_hda_unlock_devices(chip->bus);
 | 
								snd_hda_unlock_devices(chip->bus);
 | 
				
			||||||
		if (chip->vga_switcheroo_registered)
 | 
							if (hda->vga_switcheroo_registered)
 | 
				
			||||||
			vga_switcheroo_unregister_client(chip->pci);
 | 
								vga_switcheroo_unregister_client(chip->pci);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1048,6 +1237,30 @@ static int check_position_fix(struct azx *chip, int fix)
 | 
				
			||||||
	return POS_FIX_AUTO;
 | 
						return POS_FIX_AUTO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void assign_position_fix(struct azx *chip, int fix)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static azx_get_pos_callback_t callbacks[] = {
 | 
				
			||||||
 | 
							[POS_FIX_AUTO] = NULL,
 | 
				
			||||||
 | 
							[POS_FIX_LPIB] = azx_get_pos_lpib,
 | 
				
			||||||
 | 
							[POS_FIX_POSBUF] = azx_get_pos_posbuf,
 | 
				
			||||||
 | 
							[POS_FIX_VIACOMBO] = azx_via_get_position,
 | 
				
			||||||
 | 
							[POS_FIX_COMBO] = azx_get_pos_lpib,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chip->get_position[0] = chip->get_position[1] = callbacks[fix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* combo mode uses LPIB only for playback */
 | 
				
			||||||
 | 
						if (fix == POS_FIX_COMBO)
 | 
				
			||||||
 | 
							chip->get_position[1] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fix == POS_FIX_POSBUF &&
 | 
				
			||||||
 | 
						    (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
 | 
				
			||||||
 | 
							chip->get_delay[0] = chip->get_delay[1] =
 | 
				
			||||||
 | 
								azx_get_delay_from_lpib;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * black-lists for probe_mask
 | 
					 * black-lists for probe_mask
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -1173,7 +1386,8 @@ static void azx_check_snoop_available(struct azx *chip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void azx_probe_work(struct work_struct *work)
 | 
					static void azx_probe_work(struct work_struct *work)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	azx_probe_continue(container_of(work, struct azx, probe_work));
 | 
						struct hda_intel *hda = container_of(work, struct hda_intel, probe_work);
 | 
				
			||||||
 | 
						azx_probe_continue(&hda->chip);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -1216,19 +1430,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 | 
				
			||||||
	check_msi(chip);
 | 
						check_msi(chip);
 | 
				
			||||||
	chip->dev_index = dev;
 | 
						chip->dev_index = dev;
 | 
				
			||||||
	chip->jackpoll_ms = jackpoll_ms;
 | 
						chip->jackpoll_ms = jackpoll_ms;
 | 
				
			||||||
	INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
 | 
					 | 
				
			||||||
	INIT_LIST_HEAD(&chip->pcm_list);
 | 
						INIT_LIST_HEAD(&chip->pcm_list);
 | 
				
			||||||
	INIT_LIST_HEAD(&chip->list);
 | 
						INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&hda->list);
 | 
				
			||||||
	init_vga_switcheroo(chip);
 | 
						init_vga_switcheroo(chip);
 | 
				
			||||||
	init_completion(&chip->probe_wait);
 | 
						init_completion(&hda->probe_wait);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->position_fix[0] = chip->position_fix[1] =
 | 
						assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
 | 
				
			||||||
		check_position_fix(chip, position_fix[dev]);
 | 
					 | 
				
			||||||
	/* combo mode uses LPIB for playback */
 | 
					 | 
				
			||||||
	if (chip->position_fix[0] == POS_FIX_COMBO) {
 | 
					 | 
				
			||||||
		chip->position_fix[0] = POS_FIX_LPIB;
 | 
					 | 
				
			||||||
		chip->position_fix[1] = POS_FIX_AUTO;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	check_probe_mask(chip, dev);
 | 
						check_probe_mask(chip, dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1257,7 +1465,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* continue probing in work context as may trigger request module */
 | 
						/* continue probing in work context as may trigger request module */
 | 
				
			||||||
	INIT_WORK(&chip->probe_work, azx_probe_work);
 | 
						INIT_WORK(&hda->probe_work, azx_probe_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*rchip = chip;
 | 
						*rchip = chip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1315,7 +1523,7 @@ static int azx_first_init(struct azx *chip)
 | 
				
			||||||
					 NULL);
 | 
										 NULL);
 | 
				
			||||||
		if (p_smbus) {
 | 
							if (p_smbus) {
 | 
				
			||||||
			if (p_smbus->revision < 0x30)
 | 
								if (p_smbus->revision < 0x30)
 | 
				
			||||||
				gcap &= ~ICH6_GCAP_64OK;
 | 
									gcap &= ~AZX_GCAP_64OK;
 | 
				
			||||||
			pci_dev_put(p_smbus);
 | 
								pci_dev_put(p_smbus);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1323,7 +1531,7 @@ static int azx_first_init(struct azx *chip)
 | 
				
			||||||
	/* disable 64bit DMA address on some devices */
 | 
						/* disable 64bit DMA address on some devices */
 | 
				
			||||||
	if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
 | 
						if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
 | 
				
			||||||
		dev_dbg(card->dev, "Disabling 64bit DMA\n");
 | 
							dev_dbg(card->dev, "Disabling 64bit DMA\n");
 | 
				
			||||||
		gcap &= ~ICH6_GCAP_64OK;
 | 
							gcap &= ~AZX_GCAP_64OK;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* disable buffer size rounding to 128-byte multiples if supported */
 | 
						/* disable buffer size rounding to 128-byte multiples if supported */
 | 
				
			||||||
| 
						 | 
					@ -1339,7 +1547,7 @@ static int azx_first_init(struct azx *chip)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* allow 64bit DMA address if supported by H/W */
 | 
						/* allow 64bit DMA address if supported by H/W */
 | 
				
			||||||
	if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
 | 
						if ((gcap & AZX_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
 | 
				
			||||||
		pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
 | 
							pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		pci_set_dma_mask(pci, DMA_BIT_MASK(32));
 | 
							pci_set_dma_mask(pci, DMA_BIT_MASK(32));
 | 
				
			||||||
| 
						 | 
					@ -1583,6 +1791,7 @@ static int azx_probe(struct pci_dev *pci,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static int dev;
 | 
						static int dev;
 | 
				
			||||||
	struct snd_card *card;
 | 
						struct snd_card *card;
 | 
				
			||||||
 | 
						struct hda_intel *hda;
 | 
				
			||||||
	struct azx *chip;
 | 
						struct azx *chip;
 | 
				
			||||||
	bool schedule_probe;
 | 
						bool schedule_probe;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
| 
						 | 
					@ -1606,6 +1815,7 @@ static int azx_probe(struct pci_dev *pci,
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		goto out_free;
 | 
							goto out_free;
 | 
				
			||||||
	card->private_data = chip;
 | 
						card->private_data = chip;
 | 
				
			||||||
 | 
						hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_set_drvdata(pci, card);
 | 
						pci_set_drvdata(pci, card);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1642,11 +1852,11 @@ static int azx_probe(struct pci_dev *pci,
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (schedule_probe)
 | 
						if (schedule_probe)
 | 
				
			||||||
		schedule_work(&chip->probe_work);
 | 
							schedule_work(&hda->probe_work);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev++;
 | 
						dev++;
 | 
				
			||||||
	if (chip->disabled)
 | 
						if (chip->disabled)
 | 
				
			||||||
		complete_all(&chip->probe_wait);
 | 
							complete_all(&hda->probe_wait);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_free:
 | 
					out_free:
 | 
				
			||||||
| 
						 | 
					@ -1662,6 +1872,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int azx_probe_continue(struct azx *chip)
 | 
					static int azx_probe_continue(struct azx *chip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
 | 
				
			||||||
	struct pci_dev *pci = chip->pci;
 | 
						struct pci_dev *pci = chip->pci;
 | 
				
			||||||
	int dev = chip->dev_index;
 | 
						int dev = chip->dev_index;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
| 
						 | 
					@ -1735,13 +1946,13 @@ static int azx_probe_continue(struct azx *chip)
 | 
				
			||||||
	power_down_all_codecs(chip);
 | 
						power_down_all_codecs(chip);
 | 
				
			||||||
	azx_notifier_register(chip);
 | 
						azx_notifier_register(chip);
 | 
				
			||||||
	azx_add_card_list(chip);
 | 
						azx_add_card_list(chip);
 | 
				
			||||||
	if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || chip->use_vga_switcheroo)
 | 
						if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || hda->use_vga_switcheroo)
 | 
				
			||||||
		pm_runtime_put_noidle(&pci->dev);
 | 
							pm_runtime_put_noidle(&pci->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_free:
 | 
					out_free:
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		chip->init_failed = 1;
 | 
							hda->init_failed = 1;
 | 
				
			||||||
	complete_all(&chip->probe_wait);
 | 
						complete_all(&hda->probe_wait);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1806,6 +2017,9 @@ static const struct pci_device_id azx_ids[] = {
 | 
				
			||||||
	/* BayTrail */
 | 
						/* BayTrail */
 | 
				
			||||||
	{ PCI_DEVICE(0x8086, 0x0f04),
 | 
						{ PCI_DEVICE(0x8086, 0x0f04),
 | 
				
			||||||
	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
 | 
						  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
 | 
				
			||||||
 | 
						/* Braswell */
 | 
				
			||||||
 | 
						{ PCI_DEVICE(0x8086, 0x2284),
 | 
				
			||||||
 | 
						  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
 | 
				
			||||||
	/* ICH */
 | 
						/* ICH */
 | 
				
			||||||
	{ PCI_DEVICE(0x8086, 0x2668),
 | 
						{ PCI_DEVICE(0x8086, 0x2668),
 | 
				
			||||||
	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
 | 
						  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,7 +268,8 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
 | 
				
			||||||
			  const struct hda_input_mux *imux,
 | 
								  const struct hda_input_mux *imux,
 | 
				
			||||||
			  struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
 | 
								  struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
 | 
				
			||||||
			  unsigned int *cur_val);
 | 
								  unsigned int *cur_val);
 | 
				
			||||||
int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
 | 
					int snd_hda_add_imux_item(struct hda_codec *codec,
 | 
				
			||||||
 | 
								  struct hda_input_mux *imux, const char *label,
 | 
				
			||||||
			  int index, int *type_index_ret);
 | 
								  int index, int *type_index_ret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -437,6 +438,8 @@ struct snd_hda_pin_quirk {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HDA_FIXUP_ID_NOT_SET -1
 | 
				
			||||||
 | 
					#define HDA_FIXUP_ID_NO_FIXUP -2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* fixup types */
 | 
					/* fixup types */
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
| 
						 | 
					@ -773,9 +776,9 @@ struct hdmi_eld {
 | 
				
			||||||
int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
 | 
					int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
 | 
				
			||||||
int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
 | 
					int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
 | 
				
			||||||
		     unsigned char *buf, int *eld_size);
 | 
							     unsigned char *buf, int *eld_size);
 | 
				
			||||||
int snd_hdmi_parse_eld(struct parsed_hdmi_eld *e,
 | 
					int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e,
 | 
				
			||||||
		       const unsigned char *buf, int size);
 | 
							       const unsigned char *buf, int size);
 | 
				
			||||||
void snd_hdmi_show_eld(struct parsed_hdmi_eld *e);
 | 
					void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e);
 | 
				
			||||||
void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
 | 
					void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
 | 
				
			||||||
			      struct hda_pcm_stream *hinfo);
 | 
								      struct hda_pcm_stream *hinfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,107 +22,87 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * registers
 | 
					 * registers
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define ICH6_REG_GCAP			0x00
 | 
					#define AZX_REG_GCAP			0x00
 | 
				
			||||||
#define   ICH6_GCAP_64OK	(1 << 0)   /* 64bit address support */
 | 
					#define   AZX_GCAP_64OK		(1 << 0)   /* 64bit address support */
 | 
				
			||||||
#define   ICH6_GCAP_NSDO	(3 << 1)   /* # of serial data out signals */
 | 
					#define   AZX_GCAP_NSDO		(3 << 1)   /* # of serial data out signals */
 | 
				
			||||||
#define   ICH6_GCAP_BSS		(31 << 3)  /* # of bidirectional streams */
 | 
					#define   AZX_GCAP_BSS		(31 << 3)  /* # of bidirectional streams */
 | 
				
			||||||
#define   ICH6_GCAP_ISS		(15 << 8)  /* # of input streams */
 | 
					#define   AZX_GCAP_ISS		(15 << 8)  /* # of input streams */
 | 
				
			||||||
#define   ICH6_GCAP_OSS		(15 << 12) /* # of output streams */
 | 
					#define   AZX_GCAP_OSS		(15 << 12) /* # of output streams */
 | 
				
			||||||
#define ICH6_REG_VMIN			0x02
 | 
					#define AZX_REG_VMIN			0x02
 | 
				
			||||||
#define ICH6_REG_VMAJ			0x03
 | 
					#define AZX_REG_VMAJ			0x03
 | 
				
			||||||
#define ICH6_REG_OUTPAY			0x04
 | 
					#define AZX_REG_OUTPAY			0x04
 | 
				
			||||||
#define ICH6_REG_INPAY			0x06
 | 
					#define AZX_REG_INPAY			0x06
 | 
				
			||||||
#define ICH6_REG_GCTL			0x08
 | 
					#define AZX_REG_GCTL			0x08
 | 
				
			||||||
#define   ICH6_GCTL_RESET	(1 << 0)   /* controller reset */
 | 
					#define   AZX_GCTL_RESET	(1 << 0)   /* controller reset */
 | 
				
			||||||
#define   ICH6_GCTL_FCNTRL	(1 << 1)   /* flush control */
 | 
					#define   AZX_GCTL_FCNTRL	(1 << 1)   /* flush control */
 | 
				
			||||||
#define   ICH6_GCTL_UNSOL	(1 << 8)   /* accept unsol. response enable */
 | 
					#define   AZX_GCTL_UNSOL	(1 << 8)   /* accept unsol. response enable */
 | 
				
			||||||
#define ICH6_REG_WAKEEN			0x0c
 | 
					#define AZX_REG_WAKEEN			0x0c
 | 
				
			||||||
#define ICH6_REG_STATESTS		0x0e
 | 
					#define AZX_REG_STATESTS		0x0e
 | 
				
			||||||
#define ICH6_REG_GSTS			0x10
 | 
					#define AZX_REG_GSTS			0x10
 | 
				
			||||||
#define   ICH6_GSTS_FSTS	(1 << 1)   /* flush status */
 | 
					#define   AZX_GSTS_FSTS		(1 << 1)   /* flush status */
 | 
				
			||||||
#define ICH6_REG_INTCTL			0x20
 | 
					#define AZX_REG_INTCTL			0x20
 | 
				
			||||||
#define ICH6_REG_INTSTS			0x24
 | 
					#define AZX_REG_INTSTS			0x24
 | 
				
			||||||
#define ICH6_REG_WALLCLK		0x30	/* 24Mhz source */
 | 
					#define AZX_REG_WALLCLK			0x30	/* 24Mhz source */
 | 
				
			||||||
#define ICH6_REG_OLD_SSYNC		0x34	/* SSYNC for old ICH */
 | 
					#define AZX_REG_OLD_SSYNC		0x34	/* SSYNC for old ICH */
 | 
				
			||||||
#define ICH6_REG_SSYNC			0x38
 | 
					#define AZX_REG_SSYNC			0x38
 | 
				
			||||||
#define ICH6_REG_CORBLBASE		0x40
 | 
					#define AZX_REG_CORBLBASE		0x40
 | 
				
			||||||
#define ICH6_REG_CORBUBASE		0x44
 | 
					#define AZX_REG_CORBUBASE		0x44
 | 
				
			||||||
#define ICH6_REG_CORBWP			0x48
 | 
					#define AZX_REG_CORBWP			0x48
 | 
				
			||||||
#define ICH6_REG_CORBRP			0x4a
 | 
					#define AZX_REG_CORBRP			0x4a
 | 
				
			||||||
#define   ICH6_CORBRP_RST	(1 << 15)  /* read pointer reset */
 | 
					#define   AZX_CORBRP_RST	(1 << 15)  /* read pointer reset */
 | 
				
			||||||
#define ICH6_REG_CORBCTL		0x4c
 | 
					#define AZX_REG_CORBCTL			0x4c
 | 
				
			||||||
#define   ICH6_CORBCTL_RUN	(1 << 1)   /* enable DMA */
 | 
					#define   AZX_CORBCTL_RUN	(1 << 1)   /* enable DMA */
 | 
				
			||||||
#define   ICH6_CORBCTL_CMEIE	(1 << 0)   /* enable memory error irq */
 | 
					#define   AZX_CORBCTL_CMEIE	(1 << 0)   /* enable memory error irq */
 | 
				
			||||||
#define ICH6_REG_CORBSTS		0x4d
 | 
					#define AZX_REG_CORBSTS			0x4d
 | 
				
			||||||
#define   ICH6_CORBSTS_CMEI	(1 << 0)   /* memory error indication */
 | 
					#define   AZX_CORBSTS_CMEI	(1 << 0)   /* memory error indication */
 | 
				
			||||||
#define ICH6_REG_CORBSIZE		0x4e
 | 
					#define AZX_REG_CORBSIZE		0x4e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICH6_REG_RIRBLBASE		0x50
 | 
					#define AZX_REG_RIRBLBASE		0x50
 | 
				
			||||||
#define ICH6_REG_RIRBUBASE		0x54
 | 
					#define AZX_REG_RIRBUBASE		0x54
 | 
				
			||||||
#define ICH6_REG_RIRBWP			0x58
 | 
					#define AZX_REG_RIRBWP			0x58
 | 
				
			||||||
#define   ICH6_RIRBWP_RST	(1 << 15)  /* write pointer reset */
 | 
					#define   AZX_RIRBWP_RST	(1 << 15)  /* write pointer reset */
 | 
				
			||||||
#define ICH6_REG_RINTCNT		0x5a
 | 
					#define AZX_REG_RINTCNT			0x5a
 | 
				
			||||||
#define ICH6_REG_RIRBCTL		0x5c
 | 
					#define AZX_REG_RIRBCTL			0x5c
 | 
				
			||||||
#define   ICH6_RBCTL_IRQ_EN	(1 << 0)   /* enable IRQ */
 | 
					#define   AZX_RBCTL_IRQ_EN	(1 << 0)   /* enable IRQ */
 | 
				
			||||||
#define   ICH6_RBCTL_DMA_EN	(1 << 1)   /* enable DMA */
 | 
					#define   AZX_RBCTL_DMA_EN	(1 << 1)   /* enable DMA */
 | 
				
			||||||
#define   ICH6_RBCTL_OVERRUN_EN	(1 << 2)   /* enable overrun irq */
 | 
					#define   AZX_RBCTL_OVERRUN_EN	(1 << 2)   /* enable overrun irq */
 | 
				
			||||||
#define ICH6_REG_RIRBSTS		0x5d
 | 
					#define AZX_REG_RIRBSTS			0x5d
 | 
				
			||||||
#define   ICH6_RBSTS_IRQ	(1 << 0)   /* response irq */
 | 
					#define   AZX_RBSTS_IRQ		(1 << 0)   /* response irq */
 | 
				
			||||||
#define   ICH6_RBSTS_OVERRUN	(1 << 2)   /* overrun irq */
 | 
					#define   AZX_RBSTS_OVERRUN	(1 << 2)   /* overrun irq */
 | 
				
			||||||
#define ICH6_REG_RIRBSIZE		0x5e
 | 
					#define AZX_REG_RIRBSIZE		0x5e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICH6_REG_IC			0x60
 | 
					#define AZX_REG_IC			0x60
 | 
				
			||||||
#define ICH6_REG_IR			0x64
 | 
					#define AZX_REG_IR			0x64
 | 
				
			||||||
#define ICH6_REG_IRS			0x68
 | 
					#define AZX_REG_IRS			0x68
 | 
				
			||||||
#define   ICH6_IRS_VALID	(1<<1)
 | 
					#define   AZX_IRS_VALID		(1<<1)
 | 
				
			||||||
#define   ICH6_IRS_BUSY		(1<<0)
 | 
					#define   AZX_IRS_BUSY		(1<<0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICH6_REG_DPLBASE		0x70
 | 
					#define AZX_REG_DPLBASE			0x70
 | 
				
			||||||
#define ICH6_REG_DPUBASE		0x74
 | 
					#define AZX_REG_DPUBASE			0x74
 | 
				
			||||||
#define   ICH6_DPLBASE_ENABLE	0x1	/* Enable position buffer */
 | 
					#define   AZX_DPLBASE_ENABLE	0x1	/* Enable position buffer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
 | 
					/* SD offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
 | 
				
			||||||
enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 | 
					enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* stream register offsets from stream base */
 | 
					/* stream register offsets from stream base */
 | 
				
			||||||
#define ICH6_REG_SD_CTL			0x00
 | 
					#define AZX_REG_SD_CTL			0x00
 | 
				
			||||||
#define ICH6_REG_SD_STS			0x03
 | 
					#define AZX_REG_SD_STS			0x03
 | 
				
			||||||
#define ICH6_REG_SD_LPIB		0x04
 | 
					#define AZX_REG_SD_LPIB			0x04
 | 
				
			||||||
#define ICH6_REG_SD_CBL			0x08
 | 
					#define AZX_REG_SD_CBL			0x08
 | 
				
			||||||
#define ICH6_REG_SD_LVI			0x0c
 | 
					#define AZX_REG_SD_LVI			0x0c
 | 
				
			||||||
#define ICH6_REG_SD_FIFOW		0x0e
 | 
					#define AZX_REG_SD_FIFOW		0x0e
 | 
				
			||||||
#define ICH6_REG_SD_FIFOSIZE		0x10
 | 
					#define AZX_REG_SD_FIFOSIZE		0x10
 | 
				
			||||||
#define ICH6_REG_SD_FORMAT		0x12
 | 
					#define AZX_REG_SD_FORMAT		0x12
 | 
				
			||||||
#define ICH6_REG_SD_BDLPL		0x18
 | 
					#define AZX_REG_SD_BDLPL		0x18
 | 
				
			||||||
#define ICH6_REG_SD_BDLPU		0x1c
 | 
					#define AZX_REG_SD_BDLPU		0x1c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* PCI space */
 | 
					/* PCI space */
 | 
				
			||||||
#define ICH6_PCIREG_TCSEL	0x44
 | 
					#define AZX_PCIREG_TCSEL		0x44
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * other constants
 | 
					 * other constants
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* max number of SDs */
 | 
					 | 
				
			||||||
/* ICH, ATI and VIA have 4 playback and 4 capture */
 | 
					 | 
				
			||||||
#define ICH6_NUM_CAPTURE	4
 | 
					 | 
				
			||||||
#define ICH6_NUM_PLAYBACK	4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ULI has 6 playback and 5 capture */
 | 
					 | 
				
			||||||
#define ULI_NUM_CAPTURE		5
 | 
					 | 
				
			||||||
#define ULI_NUM_PLAYBACK	6
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* ATI HDMI may have up to 8 playbacks and 0 capture */
 | 
					 | 
				
			||||||
#define ATIHDMI_NUM_CAPTURE	0
 | 
					 | 
				
			||||||
#define ATIHDMI_NUM_PLAYBACK	8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TERA has 4 playback and 3 capture */
 | 
					 | 
				
			||||||
#define TERA_NUM_CAPTURE	3
 | 
					 | 
				
			||||||
#define TERA_NUM_PLAYBACK	4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* this number is statically defined for simplicity */
 | 
					 | 
				
			||||||
#define MAX_AZX_DEV		16
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* max number of fragments - we may use more if allocating more pages for BDL */
 | 
					/* max number of fragments - we may use more if allocating more pages for BDL */
 | 
				
			||||||
#define BDL_SIZE		4096
 | 
					#define BDL_SIZE		4096
 | 
				
			||||||
#define AZX_MAX_BDL_ENTRIES	(BDL_SIZE / 16)
 | 
					#define AZX_MAX_BDL_ENTRIES	(BDL_SIZE / 16)
 | 
				
			||||||
| 
						 | 
					@ -160,13 +140,13 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 | 
				
			||||||
#define SD_STS_FIFO_READY	0x20	/* FIFO ready */
 | 
					#define SD_STS_FIFO_READY	0x20	/* FIFO ready */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* INTCTL and INTSTS */
 | 
					/* INTCTL and INTSTS */
 | 
				
			||||||
#define ICH6_INT_ALL_STREAM	0xff	   /* all stream interrupts */
 | 
					#define AZX_INT_ALL_STREAM	0xff	   /* all stream interrupts */
 | 
				
			||||||
#define ICH6_INT_CTRL_EN	0x40000000 /* controller interrupt enable bit */
 | 
					#define AZX_INT_CTRL_EN	0x40000000 /* controller interrupt enable bit */
 | 
				
			||||||
#define ICH6_INT_GLOBAL_EN	0x80000000 /* global interrupt enable bit */
 | 
					#define AZX_INT_GLOBAL_EN	0x80000000 /* global interrupt enable bit */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* below are so far hardcoded - should read registers in future */
 | 
					/* below are so far hardcoded - should read registers in future */
 | 
				
			||||||
#define ICH6_MAX_CORB_ENTRIES	256
 | 
					#define AZX_MAX_CORB_ENTRIES	256
 | 
				
			||||||
#define ICH6_MAX_RIRB_ENTRIES	256
 | 
					#define AZX_MAX_RIRB_ENTRIES	256
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* driver quirks (capabilities) */
 | 
					/* driver quirks (capabilities) */
 | 
				
			||||||
/* bits 0-7 are used for indicating driver type */
 | 
					/* bits 0-7 are used for indicating driver type */
 | 
				
			||||||
| 
						 | 
					@ -192,35 +172,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 | 
				
			||||||
#define AZX_DCAPS_I915_POWERWELL (1 << 27)	/* HSW i915 powerwell support */
 | 
					#define AZX_DCAPS_I915_POWERWELL (1 << 27)	/* HSW i915 powerwell support */
 | 
				
			||||||
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)	/* CORBRP clears itself after reset */
 | 
					#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)	/* CORBRP clears itself after reset */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* position fix mode */
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
	POS_FIX_AUTO,
 | 
					 | 
				
			||||||
	POS_FIX_LPIB,
 | 
					 | 
				
			||||||
	POS_FIX_POSBUF,
 | 
					 | 
				
			||||||
	POS_FIX_VIACOMBO,
 | 
					 | 
				
			||||||
	POS_FIX_COMBO,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Defines for ATI HD Audio support in SB450 south bridge */
 | 
					 | 
				
			||||||
#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
 | 
					 | 
				
			||||||
#define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Defines for Nvidia HDA support */
 | 
					 | 
				
			||||||
#define NVIDIA_HDA_TRANSREG_ADDR      0x4e
 | 
					 | 
				
			||||||
#define NVIDIA_HDA_ENABLE_COHBITS     0x0f
 | 
					 | 
				
			||||||
#define NVIDIA_HDA_ISTRM_COH          0x4d
 | 
					 | 
				
			||||||
#define NVIDIA_HDA_OSTRM_COH          0x4c
 | 
					 | 
				
			||||||
#define NVIDIA_HDA_ENABLE_COHBIT      0x01
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Defines for Intel SCH HDA snoop control */
 | 
					 | 
				
			||||||
#define INTEL_SCH_HDA_DEVC      0x78
 | 
					 | 
				
			||||||
#define INTEL_SCH_HDA_DEVC_NOSNOOP       (0x1<<11)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Define IN stream 0 FIFO size offset in VIA controller */
 | 
					 | 
				
			||||||
#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET	0x90
 | 
					 | 
				
			||||||
/* Define VIA HD Audio Device ID*/
 | 
					 | 
				
			||||||
#define VIA_HDAC_DEVICE_ID		0x3288
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* HD Audio class code */
 | 
					/* HD Audio class code */
 | 
				
			||||||
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO	0x0403
 | 
					#define PCI_CLASS_MULTIMEDIA_HD_AUDIO	0x0403
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -325,6 +276,9 @@ struct azx_pcm {
 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef unsigned int (*azx_get_pos_callback_t)(struct azx *, struct azx_dev *);
 | 
				
			||||||
 | 
					typedef int (*azx_get_delay_callback_t)(struct azx *, struct azx_dev *, unsigned int pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct azx {
 | 
					struct azx {
 | 
				
			||||||
	struct snd_card *card;
 | 
						struct snd_card *card;
 | 
				
			||||||
	struct pci_dev *pci;
 | 
						struct pci_dev *pci;
 | 
				
			||||||
| 
						 | 
					@ -343,6 +297,10 @@ struct azx {
 | 
				
			||||||
	/* Register interaction. */
 | 
						/* Register interaction. */
 | 
				
			||||||
	const struct hda_controller_ops *ops;
 | 
						const struct hda_controller_ops *ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* position adjustment callbacks */
 | 
				
			||||||
 | 
						azx_get_pos_callback_t get_position[2];
 | 
				
			||||||
 | 
						azx_get_delay_callback_t get_delay[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* pci resources */
 | 
						/* pci resources */
 | 
				
			||||||
	unsigned long addr;
 | 
						unsigned long addr;
 | 
				
			||||||
	void __iomem *remap_addr;
 | 
						void __iomem *remap_addr;
 | 
				
			||||||
| 
						 | 
					@ -351,7 +309,6 @@ struct azx {
 | 
				
			||||||
	/* locks */
 | 
						/* locks */
 | 
				
			||||||
	spinlock_t reg_lock;
 | 
						spinlock_t reg_lock;
 | 
				
			||||||
	struct mutex open_mutex; /* Prevents concurrent open/close operations */
 | 
						struct mutex open_mutex; /* Prevents concurrent open/close operations */
 | 
				
			||||||
	struct completion probe_wait;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* streams (x num_streams) */
 | 
						/* streams (x num_streams) */
 | 
				
			||||||
	struct azx_dev *azx_dev;
 | 
						struct azx_dev *azx_dev;
 | 
				
			||||||
| 
						 | 
					@ -378,7 +335,6 @@ struct azx {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* flags */
 | 
						/* flags */
 | 
				
			||||||
	int position_fix[2]; /* for both playback/capture streams */
 | 
					 | 
				
			||||||
	const int *bdl_pos_adj;
 | 
						const int *bdl_pos_adj;
 | 
				
			||||||
	int poll_count;
 | 
						int poll_count;
 | 
				
			||||||
	unsigned int running:1;
 | 
						unsigned int running:1;
 | 
				
			||||||
| 
						 | 
					@ -386,46 +342,23 @@ struct azx {
 | 
				
			||||||
	unsigned int single_cmd:1;
 | 
						unsigned int single_cmd:1;
 | 
				
			||||||
	unsigned int polling_mode:1;
 | 
						unsigned int polling_mode:1;
 | 
				
			||||||
	unsigned int msi:1;
 | 
						unsigned int msi:1;
 | 
				
			||||||
	unsigned int irq_pending_warned:1;
 | 
					 | 
				
			||||||
	unsigned int probing:1; /* codec probing phase */
 | 
						unsigned int probing:1; /* codec probing phase */
 | 
				
			||||||
	unsigned int snoop:1;
 | 
						unsigned int snoop:1;
 | 
				
			||||||
	unsigned int align_buffer_size:1;
 | 
						unsigned int align_buffer_size:1;
 | 
				
			||||||
	unsigned int region_requested:1;
 | 
						unsigned int region_requested:1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* VGA-switcheroo setup */
 | 
					 | 
				
			||||||
	unsigned int use_vga_switcheroo:1;
 | 
					 | 
				
			||||||
	unsigned int vga_switcheroo_registered:1;
 | 
					 | 
				
			||||||
	unsigned int init_failed:1; /* delayed init failed */
 | 
					 | 
				
			||||||
	unsigned int disabled:1; /* disabled by VGA-switcher */
 | 
						unsigned int disabled:1; /* disabled by VGA-switcher */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* for debugging */
 | 
						/* for debugging */
 | 
				
			||||||
	unsigned int last_cmd[AZX_MAX_CODECS];
 | 
						unsigned int last_cmd[AZX_MAX_CODECS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* for pending irqs */
 | 
					 | 
				
			||||||
	struct work_struct irq_pending_work;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct work_struct probe_work;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* reboot notifier (for mysterious hangup problem at power-down) */
 | 
						/* reboot notifier (for mysterious hangup problem at power-down) */
 | 
				
			||||||
	struct notifier_block reboot_notifier;
 | 
						struct notifier_block reboot_notifier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* card list (for power_save trigger) */
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_SND_HDA_DSP_LOADER
 | 
					#ifdef CONFIG_SND_HDA_DSP_LOADER
 | 
				
			||||||
	struct azx_dev saved_azx_dev;
 | 
						struct azx_dev saved_azx_dev;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* secondary power domain for hdmi audio under vga device */
 | 
					 | 
				
			||||||
	struct dev_pm_domain hdmi_pm_domain;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_SND_VERBOSE_PRINTK
 | 
					 | 
				
			||||||
#define SFX	/* nop */
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define SFX	"hda-intel "
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef CONFIG_X86
 | 
					#ifdef CONFIG_X86
 | 
				
			||||||
#define azx_snoop(chip)		((chip)->snoop)
 | 
					#define azx_snoop(chip)		((chip)->snoop)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					@ -437,29 +370,29 @@ struct azx {
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define azx_writel(chip, reg, value) \
 | 
					#define azx_writel(chip, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writel(value, (chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writel(value, (chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_readl(chip, reg) \
 | 
					#define azx_readl(chip, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readl((chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readl((chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_writew(chip, reg, value) \
 | 
					#define azx_writew(chip, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writew(value, (chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writew(value, (chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_readw(chip, reg) \
 | 
					#define azx_readw(chip, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readw((chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readw((chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_writeb(chip, reg, value) \
 | 
					#define azx_writeb(chip, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writeb(value, (chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writeb(value, (chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_readb(chip, reg) \
 | 
					#define azx_readb(chip, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readb((chip)->remap_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readb((chip)->remap_addr + AZX_REG_##reg))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define azx_sd_writel(chip, dev, reg, value) \
 | 
					#define azx_sd_writel(chip, dev, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writel(value, (dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writel(value, (dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_sd_readl(chip, dev, reg) \
 | 
					#define azx_sd_readl(chip, dev, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readl((dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readl((dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_sd_writew(chip, dev, reg, value) \
 | 
					#define azx_sd_writew(chip, dev, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writew(value, (dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writew(value, (dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_sd_readw(chip, dev, reg) \
 | 
					#define azx_sd_readw(chip, dev, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readw((dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readw((dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_sd_writeb(chip, dev, reg, value) \
 | 
					#define azx_sd_writeb(chip, dev, reg, value) \
 | 
				
			||||||
	((chip)->ops->reg_writeb(value, (dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_writeb(value, (dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
#define azx_sd_readb(chip, dev, reg) \
 | 
					#define azx_sd_readb(chip, dev, reg) \
 | 
				
			||||||
	((chip)->ops->reg_readb((dev)->sd_addr + ICH6_REG_##reg))
 | 
						((chip)->ops->reg_readb((dev)->sd_addr + AZX_REG_##reg))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __SOUND_HDA_PRIV_H */
 | 
					#endif /* __SOUND_HDA_PRIV_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,6 @@
 | 
				
			||||||
#include <linux/moduleparam.h>
 | 
					#include <linux/moduleparam.h>
 | 
				
			||||||
#include <linux/mutex.h>
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <linux/of_device.h>
 | 
					#include <linux/of_device.h>
 | 
				
			||||||
#include <linux/reboot.h>
 | 
					 | 
				
			||||||
#include <linux/slab.h>
 | 
					#include <linux/slab.h>
 | 
				
			||||||
#include <linux/time.h>
 | 
					#include <linux/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -272,13 +271,9 @@ static int hda_tegra_resume(struct device *dev)
 | 
				
			||||||
	struct snd_card *card = dev_get_drvdata(dev);
 | 
						struct snd_card *card = dev_get_drvdata(dev);
 | 
				
			||||||
	struct azx *chip = card->private_data;
 | 
						struct azx *chip = card->private_data;
 | 
				
			||||||
	struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
 | 
						struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
 | 
				
			||||||
	int status;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hda_tegra_enable_clocks(hda);
 | 
						hda_tegra_enable_clocks(hda);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Read STATESTS before controller reset */
 | 
					 | 
				
			||||||
	status = azx_readw(chip, STATESTS);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hda_tegra_init(hda);
 | 
						hda_tegra_init(hda);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	azx_init_chip(chip, 1);
 | 
						azx_init_chip(chip, 1);
 | 
				
			||||||
| 
						 | 
					@ -294,30 +289,6 @@ static const struct dev_pm_ops hda_tegra_pm = {
 | 
				
			||||||
	SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume)
 | 
						SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume)
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * reboot notifier for hang-up problem at power-down
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int hda_tegra_halt(struct notifier_block *nb, unsigned long event,
 | 
					 | 
				
			||||||
			  void *buf)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct azx *chip = container_of(nb, struct azx, reboot_notifier);
 | 
					 | 
				
			||||||
	snd_hda_bus_reboot_notify(chip->bus);
 | 
					 | 
				
			||||||
	azx_stop_chip(chip);
 | 
					 | 
				
			||||||
	return NOTIFY_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void hda_tegra_notifier_register(struct azx *chip)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	chip->reboot_notifier.notifier_call = hda_tegra_halt;
 | 
					 | 
				
			||||||
	register_reboot_notifier(&chip->reboot_notifier);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void hda_tegra_notifier_unregister(struct azx *chip)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (chip->reboot_notifier.notifier_call)
 | 
					 | 
				
			||||||
		unregister_reboot_notifier(&chip->reboot_notifier);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * destructor
 | 
					 * destructor
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -326,7 +297,7 @@ static int hda_tegra_dev_free(struct snd_device *device)
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	struct azx *chip = device->device_data;
 | 
						struct azx *chip = device->device_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hda_tegra_notifier_unregister(chip);
 | 
						azx_notifier_unregister(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->initialized) {
 | 
						if (chip->initialized) {
 | 
				
			||||||
		for (i = 0; i < chip->num_streams; i++)
 | 
							for (i = 0; i < chip->num_streams; i++)
 | 
				
			||||||
| 
						 | 
					@ -478,10 +449,7 @@ static int hda_tegra_create(struct snd_card *card,
 | 
				
			||||||
	chip->driver_type = driver_caps & 0xff;
 | 
						chip->driver_type = driver_caps & 0xff;
 | 
				
			||||||
	chip->dev_index = 0;
 | 
						chip->dev_index = 0;
 | 
				
			||||||
	INIT_LIST_HEAD(&chip->pcm_list);
 | 
						INIT_LIST_HEAD(&chip->pcm_list);
 | 
				
			||||||
	INIT_LIST_HEAD(&chip->list);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->position_fix[0] = POS_FIX_AUTO;
 | 
					 | 
				
			||||||
	chip->position_fix[1] = POS_FIX_AUTO;
 | 
					 | 
				
			||||||
	chip->codec_probe_mask = -1;
 | 
						chip->codec_probe_mask = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->single_cmd = false;
 | 
						chip->single_cmd = false;
 | 
				
			||||||
| 
						 | 
					@ -559,7 +527,7 @@ static int hda_tegra_probe(struct platform_device *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->running = 1;
 | 
						chip->running = 1;
 | 
				
			||||||
	power_down_all_codecs(chip);
 | 
						power_down_all_codecs(chip);
 | 
				
			||||||
	hda_tegra_notifier_register(chip);
 | 
						azx_notifier_register(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2046,14 +2046,14 @@ enum dma_state {
 | 
				
			||||||
	DMA_STATE_RUN   = 1
 | 
						DMA_STATE_RUN   = 1
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int dma_convert_to_hda_format(
 | 
					static int dma_convert_to_hda_format(struct hda_codec *codec,
 | 
				
			||||||
		unsigned int sample_rate,
 | 
							unsigned int sample_rate,
 | 
				
			||||||
		unsigned short channels,
 | 
							unsigned short channels,
 | 
				
			||||||
		unsigned short *hda_format)
 | 
							unsigned short *hda_format)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int format_val;
 | 
						unsigned int format_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	format_val = snd_hda_calc_stream_format(
 | 
						format_val = snd_hda_calc_stream_format(codec,
 | 
				
			||||||
				sample_rate,
 | 
									sample_rate,
 | 
				
			||||||
				channels,
 | 
									channels,
 | 
				
			||||||
				SNDRV_PCM_FORMAT_S32_LE,
 | 
									SNDRV_PCM_FORMAT_S32_LE,
 | 
				
			||||||
| 
						 | 
					@ -2452,7 +2452,7 @@ static int dspxfr_image(struct hda_codec *codec,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_engine->codec = codec;
 | 
						dma_engine->codec = codec;
 | 
				
			||||||
	dma_convert_to_hda_format(sample_rate, channels, &hda_format);
 | 
						dma_convert_to_hda_format(codec, sample_rate, channels, &hda_format);
 | 
				
			||||||
	dma_engine->m_converter_format = hda_format;
 | 
						dma_engine->m_converter_format = hda_format;
 | 
				
			||||||
	dma_engine->buf_size = (ovly ? DSP_DMA_WRITE_BUFLEN_OVLY :
 | 
						dma_engine->buf_size = (ovly ? DSP_DMA_WRITE_BUFLEN_OVLY :
 | 
				
			||||||
			DSP_DMA_WRITE_BUFLEN_INIT) * 2;
 | 
								DSP_DMA_WRITE_BUFLEN_INIT) * 2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -657,8 +657,10 @@ static void cs4208_fixup_mac(struct hda_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (action != HDA_FIXUP_ACT_PRE_PROBE)
 | 
						if (action != HDA_FIXUP_ACT_PRE_PROBE)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
 | 
				
			||||||
	snd_hda_pick_fixup(codec, NULL, cs4208_mac_fixup_tbl, cs4208_fixups);
 | 
						snd_hda_pick_fixup(codec, NULL, cs4208_mac_fixup_tbl, cs4208_fixups);
 | 
				
			||||||
	if (codec->fixup_id < 0 || codec->fixup_id == CS4208_MAC_AUTO)
 | 
						if (codec->fixup_id == HDA_FIXUP_ID_NOT_SET)
 | 
				
			||||||
		codec->fixup_id = CS4208_GPIO0; /* default fixup */
 | 
							codec->fixup_id = CS4208_GPIO0; /* default fixup */
 | 
				
			||||||
	snd_hda_apply_fixup(codec, action);
 | 
						snd_hda_apply_fixup(codec, action);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,549 +31,10 @@
 | 
				
			||||||
#include "hda_jack.h"
 | 
					#include "hda_jack.h"
 | 
				
			||||||
#include "hda_generic.h"
 | 
					#include "hda_generic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef ENABLE_CMI_STATIC_QUIRKS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef ENABLE_CMI_STATIC_QUIRKS
 | 
					 | 
				
			||||||
#define NUM_PINS	11
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* board config type */
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
	CMI_MINIMAL,	/* back 3-jack */
 | 
					 | 
				
			||||||
	CMI_MIN_FP,	/* back 3-jack + front-panel 2-jack */
 | 
					 | 
				
			||||||
	CMI_FULL,	/* back 6-jack + front-panel 2-jack */
 | 
					 | 
				
			||||||
	CMI_FULL_DIG,	/* back 6-jack + front-panel 2-jack + digital I/O */
 | 
					 | 
				
			||||||
	CMI_ALLOUT,	/* back 5-jack + front-panel 2-jack + digital out */
 | 
					 | 
				
			||||||
	CMI_AUTO,	/* let driver guess it */
 | 
					 | 
				
			||||||
	CMI_MODELS
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#endif /* ENABLE_CMI_STATIC_QUIRKS */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct cmi_spec {
 | 
					struct cmi_spec {
 | 
				
			||||||
	struct hda_gen_spec gen;
 | 
						struct hda_gen_spec gen;
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef ENABLE_CMI_STATIC_QUIRKS
 | 
					 | 
				
			||||||
	/* below are only for static models */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int board_config;
 | 
					 | 
				
			||||||
	unsigned int no_line_in: 1;	/* no line-in (5-jack) */
 | 
					 | 
				
			||||||
	unsigned int front_panel: 1;	/* has front-panel 2-jack */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* playback */
 | 
					 | 
				
			||||||
	struct hda_multi_out multiout;
 | 
					 | 
				
			||||||
	hda_nid_t dac_nids[AUTO_CFG_MAX_OUTS];	/* NID for each DAC */
 | 
					 | 
				
			||||||
	int num_dacs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* capture */
 | 
					 | 
				
			||||||
	const hda_nid_t *adc_nids;
 | 
					 | 
				
			||||||
	hda_nid_t dig_in_nid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* capture source */
 | 
					 | 
				
			||||||
	const struct hda_input_mux *input_mux;
 | 
					 | 
				
			||||||
	unsigned int cur_mux[2];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* channel mode */
 | 
					 | 
				
			||||||
	int num_channel_modes;
 | 
					 | 
				
			||||||
	const struct hda_channel_mode *channel_modes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct hda_pcm pcm_rec[2];	/* PCM information */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* pin default configuration */
 | 
					 | 
				
			||||||
	hda_nid_t pin_nid[NUM_PINS];
 | 
					 | 
				
			||||||
	unsigned int def_conf[NUM_PINS];
 | 
					 | 
				
			||||||
	unsigned int pin_def_confs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* multichannel pins */
 | 
					 | 
				
			||||||
	struct hda_verb multi_init[9];	/* 2 verbs for each pin + terminator */
 | 
					 | 
				
			||||||
#endif /* ENABLE_CMI_STATIC_QUIRKS */
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ENABLE_CMI_STATIC_QUIRKS
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * input MUX
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int cmi_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_input_mux_info(spec->input_mux, uinfo);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
 | 
					 | 
				
			||||||
				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * shared line-in, mic for surrounds
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 3-stack / 2 channel */
 | 
					 | 
				
			||||||
static const struct hda_verb cmi9880_ch2_init[] = {
 | 
					 | 
				
			||||||
	/* set line-in PIN for input */
 | 
					 | 
				
			||||||
	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 | 
					 | 
				
			||||||
	/* set mic PIN for input, also enable vref */
 | 
					 | 
				
			||||||
	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 | 
					 | 
				
			||||||
	/* route front PCM (DAC1) to HP */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 | 
					 | 
				
			||||||
	{}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 3-stack / 6 channel */
 | 
					 | 
				
			||||||
static const struct hda_verb cmi9880_ch6_init[] = {
 | 
					 | 
				
			||||||
	/* set line-in PIN for output */
 | 
					 | 
				
			||||||
	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 | 
					 | 
				
			||||||
	/* set mic PIN for output */
 | 
					 | 
				
			||||||
	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 | 
					 | 
				
			||||||
	/* route front PCM (DAC1) to HP */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 | 
					 | 
				
			||||||
	{}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* 3-stack+front / 8 channel */
 | 
					 | 
				
			||||||
static const struct hda_verb cmi9880_ch8_init[] = {
 | 
					 | 
				
			||||||
	/* set line-in PIN for output */
 | 
					 | 
				
			||||||
	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 | 
					 | 
				
			||||||
	/* set mic PIN for output */
 | 
					 | 
				
			||||||
	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 | 
					 | 
				
			||||||
	/* route rear-surround PCM (DAC4) to HP */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 },
 | 
					 | 
				
			||||||
	{}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_channel_mode cmi9880_channel_modes[3] = {
 | 
					 | 
				
			||||||
	{ 2, cmi9880_ch2_init },
 | 
					 | 
				
			||||||
	{ 6, cmi9880_ch6_init },
 | 
					 | 
				
			||||||
	{ 8, cmi9880_ch8_init },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_modes,
 | 
					 | 
				
			||||||
				    spec->num_channel_modes);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_modes,
 | 
					 | 
				
			||||||
				   spec->num_channel_modes, spec->multiout.max_channels);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_modes,
 | 
					 | 
				
			||||||
				   spec->num_channel_modes, &spec->multiout.max_channels);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct snd_kcontrol_new cmi9880_basic_mixer[] = {
 | 
					 | 
				
			||||||
	/* CMI9880 has no playback volumes! */
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE("Side Playback Switch", 0x06, 0x0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 | 
					 | 
				
			||||||
		/* The multiple "Capture Source" controls confuse alsamixer
 | 
					 | 
				
			||||||
		 * So call somewhat different..
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		/* .name = "Capture Source", */
 | 
					 | 
				
			||||||
		.name = "Input Source",
 | 
					 | 
				
			||||||
		.count = 2,
 | 
					 | 
				
			||||||
		.info = cmi_mux_enum_info,
 | 
					 | 
				
			||||||
		.get = cmi_mux_enum_get,
 | 
					 | 
				
			||||||
		.put = cmi_mux_enum_put,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0, HDA_INPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0, HDA_INPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE("Capture Switch", 0x08, 0, HDA_INPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0, HDA_INPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_VOLUME("Beep Playback Volume", 0x23, 0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	HDA_CODEC_MUTE("Beep Playback Switch", 0x23, 0, HDA_OUTPUT),
 | 
					 | 
				
			||||||
	{ } /* end */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * shared I/O pins
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 | 
					 | 
				
			||||||
		.name = "Channel Mode",
 | 
					 | 
				
			||||||
		.info = cmi_ch_mode_info,
 | 
					 | 
				
			||||||
		.get = cmi_ch_mode_get,
 | 
					 | 
				
			||||||
		.put = cmi_ch_mode_put,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	{ } /* end */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* AUD-in selections:
 | 
					 | 
				
			||||||
 * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct hda_input_mux cmi9880_basic_mux = {
 | 
					 | 
				
			||||||
	.num_items = 4,
 | 
					 | 
				
			||||||
	.items = {
 | 
					 | 
				
			||||||
		{ "Front Mic", 0x5 },
 | 
					 | 
				
			||||||
		{ "Rear Mic", 0x2 },
 | 
					 | 
				
			||||||
		{ "Line", 0x1 },
 | 
					 | 
				
			||||||
		{ "CD", 0x7 },
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_input_mux cmi9880_no_line_mux = {
 | 
					 | 
				
			||||||
	.num_items = 3,
 | 
					 | 
				
			||||||
	.items = {
 | 
					 | 
				
			||||||
		{ "Front Mic", 0x5 },
 | 
					 | 
				
			||||||
		{ "Rear Mic", 0x2 },
 | 
					 | 
				
			||||||
		{ "CD", 0x7 },
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* front, rear, clfe, rear_surr */
 | 
					 | 
				
			||||||
static const hda_nid_t cmi9880_dac_nids[4] = {
 | 
					 | 
				
			||||||
	0x03, 0x04, 0x05, 0x06
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
/* ADC0, ADC1 */
 | 
					 | 
				
			||||||
static const hda_nid_t cmi9880_adc_nids[2] = {
 | 
					 | 
				
			||||||
	0x08, 0x09
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CMI_DIG_OUT_NID	0x07
 | 
					 | 
				
			||||||
#define CMI_DIG_IN_NID	0x0a
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct hda_verb cmi9880_basic_init[] = {
 | 
					 | 
				
			||||||
	/* port-D for line out (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* port-E for HP out (front panel) */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* route front PCM to HP */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 | 
					 | 
				
			||||||
	/* port-A for surround (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* port-G for CLFE (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
 | 
					 | 
				
			||||||
	/* port-H for side (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
 | 
					 | 
				
			||||||
	/* port-C for line-in (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 | 
					 | 
				
			||||||
	/* port-B for mic-in (rear panel) with vref */
 | 
					 | 
				
			||||||
	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 | 
					 | 
				
			||||||
	/* port-F for mic-in (front panel) with vref */
 | 
					 | 
				
			||||||
	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 | 
					 | 
				
			||||||
	/* CD-in */
 | 
					 | 
				
			||||||
	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 | 
					 | 
				
			||||||
	/* route front mic to ADC1/2 */
 | 
					 | 
				
			||||||
	{ 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
 | 
					 | 
				
			||||||
	{ 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
 | 
					 | 
				
			||||||
	{} /* terminator */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_verb cmi9880_allout_init[] = {
 | 
					 | 
				
			||||||
	/* port-D for line out (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* port-E for HP out (front panel) */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* route front PCM to HP */
 | 
					 | 
				
			||||||
	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 | 
					 | 
				
			||||||
	/* port-A for side (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* port-G for CLFE (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
 | 
					 | 
				
			||||||
	/* port-H for side (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
 | 
					 | 
				
			||||||
	/* port-C for surround (rear panel) */
 | 
					 | 
				
			||||||
	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 | 
					 | 
				
			||||||
	/* port-B for mic-in (rear panel) with vref */
 | 
					 | 
				
			||||||
	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 | 
					 | 
				
			||||||
	/* port-F for mic-in (front panel) with vref */
 | 
					 | 
				
			||||||
	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 | 
					 | 
				
			||||||
	/* CD-in */
 | 
					 | 
				
			||||||
	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 | 
					 | 
				
			||||||
	/* route front mic to ADC1/2 */
 | 
					 | 
				
			||||||
	{ 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
 | 
					 | 
				
			||||||
	{ 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
 | 
					 | 
				
			||||||
	{} /* terminator */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int cmi9880_build_controls(struct hda_codec *codec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	struct snd_kcontrol *kctl;
 | 
					 | 
				
			||||||
	int i, err;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
 | 
					 | 
				
			||||||
	if (err < 0)
 | 
					 | 
				
			||||||
		return err;
 | 
					 | 
				
			||||||
	if (spec->channel_modes) {
 | 
					 | 
				
			||||||
		err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer);
 | 
					 | 
				
			||||||
		if (err < 0)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (spec->multiout.dig_out_nid) {
 | 
					 | 
				
			||||||
		err = snd_hda_create_spdif_out_ctls(codec,
 | 
					 | 
				
			||||||
						    spec->multiout.dig_out_nid,
 | 
					 | 
				
			||||||
						    spec->multiout.dig_out_nid);
 | 
					 | 
				
			||||||
		if (err < 0)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
		err = snd_hda_create_spdif_share_sw(codec,
 | 
					 | 
				
			||||||
						    &spec->multiout);
 | 
					 | 
				
			||||||
		if (err < 0)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
		spec->multiout.share_spdif = 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (spec->dig_in_nid) {
 | 
					 | 
				
			||||||
		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
 | 
					 | 
				
			||||||
		if (err < 0)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* assign Capture Source enums to NID */
 | 
					 | 
				
			||||||
	kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
 | 
					 | 
				
			||||||
	for (i = 0; kctl && i < kctl->count; i++) {
 | 
					 | 
				
			||||||
		err = snd_hda_add_nid(codec, kctl, i, spec->adc_nids[i]);
 | 
					 | 
				
			||||||
		if (err < 0)
 | 
					 | 
				
			||||||
			return err;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_init(struct hda_codec *codec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	if (spec->board_config == CMI_ALLOUT)
 | 
					 | 
				
			||||||
		snd_hda_sequence_write(codec, cmi9880_allout_init);
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		snd_hda_sequence_write(codec, cmi9880_basic_init);
 | 
					 | 
				
			||||||
	if (spec->board_config == CMI_AUTO)
 | 
					 | 
				
			||||||
		snd_hda_sequence_write(codec, spec->multi_init);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Analog playback callbacks
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
				     struct hda_codec *codec,
 | 
					 | 
				
			||||||
				     struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
 | 
					 | 
				
			||||||
					     hinfo);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
					struct hda_codec *codec,
 | 
					 | 
				
			||||||
					unsigned int stream_tag,
 | 
					 | 
				
			||||||
					unsigned int format,
 | 
					 | 
				
			||||||
					struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
 | 
					 | 
				
			||||||
						format, substream);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
				       struct hda_codec *codec,
 | 
					 | 
				
			||||||
				       struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Digital out
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
					 struct hda_codec *codec,
 | 
					 | 
				
			||||||
					 struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
					  struct hda_codec *codec,
 | 
					 | 
				
			||||||
					  struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
					    struct hda_codec *codec,
 | 
					 | 
				
			||||||
					    unsigned int stream_tag,
 | 
					 | 
				
			||||||
					    unsigned int format,
 | 
					 | 
				
			||||||
					    struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
 | 
					 | 
				
			||||||
					     format, substream);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Analog capture
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static int cmi9880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
				      struct hda_codec *codec,
 | 
					 | 
				
			||||||
				      unsigned int stream_tag,
 | 
					 | 
				
			||||||
				      unsigned int format,
 | 
					 | 
				
			||||||
				      struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
 | 
					 | 
				
			||||||
				   stream_tag, 0, format);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 | 
					 | 
				
			||||||
				      struct hda_codec *codec,
 | 
					 | 
				
			||||||
				      struct snd_pcm_substream *substream)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static const struct hda_pcm_stream cmi9880_pcm_analog_playback = {
 | 
					 | 
				
			||||||
	.substreams = 1,
 | 
					 | 
				
			||||||
	.channels_min = 2,
 | 
					 | 
				
			||||||
	.channels_max = 8,
 | 
					 | 
				
			||||||
	.nid = 0x03, /* NID to query formats and rates */
 | 
					 | 
				
			||||||
	.ops = {
 | 
					 | 
				
			||||||
		.open = cmi9880_playback_pcm_open,
 | 
					 | 
				
			||||||
		.prepare = cmi9880_playback_pcm_prepare,
 | 
					 | 
				
			||||||
		.cleanup = cmi9880_playback_pcm_cleanup
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_pcm_stream cmi9880_pcm_analog_capture = {
 | 
					 | 
				
			||||||
	.substreams = 2,
 | 
					 | 
				
			||||||
	.channels_min = 2,
 | 
					 | 
				
			||||||
	.channels_max = 2,
 | 
					 | 
				
			||||||
	.nid = 0x08, /* NID to query formats and rates */
 | 
					 | 
				
			||||||
	.ops = {
 | 
					 | 
				
			||||||
		.prepare = cmi9880_capture_pcm_prepare,
 | 
					 | 
				
			||||||
		.cleanup = cmi9880_capture_pcm_cleanup
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_pcm_stream cmi9880_pcm_digital_playback = {
 | 
					 | 
				
			||||||
	.substreams = 1,
 | 
					 | 
				
			||||||
	.channels_min = 2,
 | 
					 | 
				
			||||||
	.channels_max = 2,
 | 
					 | 
				
			||||||
	/* NID is set in cmi9880_build_pcms */
 | 
					 | 
				
			||||||
	.ops = {
 | 
					 | 
				
			||||||
		.open = cmi9880_dig_playback_pcm_open,
 | 
					 | 
				
			||||||
		.close = cmi9880_dig_playback_pcm_close,
 | 
					 | 
				
			||||||
		.prepare = cmi9880_dig_playback_pcm_prepare
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_pcm_stream cmi9880_pcm_digital_capture = {
 | 
					 | 
				
			||||||
	.substreams = 1,
 | 
					 | 
				
			||||||
	.channels_min = 2,
 | 
					 | 
				
			||||||
	.channels_max = 2,
 | 
					 | 
				
			||||||
	/* NID is set in cmi9880_build_pcms */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int cmi9880_build_pcms(struct hda_codec *codec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
					 | 
				
			||||||
	struct hda_pcm *info = spec->pcm_rec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->num_pcms = 1;
 | 
					 | 
				
			||||||
	codec->pcm_info = info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info->name = "CMI9880";
 | 
					 | 
				
			||||||
	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_analog_playback;
 | 
					 | 
				
			||||||
	info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_analog_capture;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
 | 
					 | 
				
			||||||
		codec->num_pcms++;
 | 
					 | 
				
			||||||
		info++;
 | 
					 | 
				
			||||||
		info->name = "CMI9880 Digital";
 | 
					 | 
				
			||||||
		info->pcm_type = HDA_PCM_TYPE_SPDIF;
 | 
					 | 
				
			||||||
		if (spec->multiout.dig_out_nid) {
 | 
					 | 
				
			||||||
			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback;
 | 
					 | 
				
			||||||
			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (spec->dig_in_nid) {
 | 
					 | 
				
			||||||
			info->stream[SNDRV_PCM_STREAM_CAPTURE] = cmi9880_pcm_digital_capture;
 | 
					 | 
				
			||||||
			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void cmi9880_free(struct hda_codec *codec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	kfree(codec->spec);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char * const cmi9880_models[CMI_MODELS] = {
 | 
					 | 
				
			||||||
	[CMI_MINIMAL]	= "minimal",
 | 
					 | 
				
			||||||
	[CMI_MIN_FP]	= "min_fp",
 | 
					 | 
				
			||||||
	[CMI_FULL]	= "full",
 | 
					 | 
				
			||||||
	[CMI_FULL_DIG]	= "full_dig",
 | 
					 | 
				
			||||||
	[CMI_ALLOUT]	= "allout",
 | 
					 | 
				
			||||||
	[CMI_AUTO]	= "auto",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct snd_pci_quirk cmi9880_cfg_tbl[] = {
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG),
 | 
					 | 
				
			||||||
	{} /* terminator */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct hda_codec_ops cmi9880_patch_ops = {
 | 
					 | 
				
			||||||
	.build_controls = cmi9880_build_controls,
 | 
					 | 
				
			||||||
	.build_pcms = cmi9880_build_pcms,
 | 
					 | 
				
			||||||
	.init = cmi9880_init,
 | 
					 | 
				
			||||||
	.free = cmi9880_free,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#endif /* ENABLE_CMI_STATIC_QUIRKS */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * stuff for auto-parser
 | 
					 * stuff for auto-parser
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -585,12 +46,18 @@ static const struct hda_codec_ops cmi_auto_patch_ops = {
 | 
				
			||||||
	.unsol_event = snd_hda_jack_unsol_event,
 | 
						.unsol_event = snd_hda_jack_unsol_event,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int cmi_parse_auto_config(struct hda_codec *codec)
 | 
					static int patch_cmi9880(struct hda_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct cmi_spec *spec = codec->spec;
 | 
						struct cmi_spec *spec;
 | 
				
			||||||
	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
 | 
						struct auto_pin_cfg *cfg;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 | 
				
			||||||
 | 
						if (spec == NULL)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codec->spec = spec;
 | 
				
			||||||
 | 
						cfg = &spec->gen.autocfg;
 | 
				
			||||||
	snd_hda_gen_spec_init(&spec->gen);
 | 
						snd_hda_gen_spec_init(&spec->gen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
 | 
						err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
 | 
				
			||||||
| 
						 | 
					@ -608,79 +75,6 @@ static int cmi_parse_auto_config(struct hda_codec *codec)
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
static int patch_cmi9880(struct hda_codec *codec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct cmi_spec *spec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 | 
					 | 
				
			||||||
	if (spec == NULL)
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->spec = spec;
 | 
					 | 
				
			||||||
#ifdef ENABLE_CMI_STATIC_QUIRKS
 | 
					 | 
				
			||||||
	spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS,
 | 
					 | 
				
			||||||
							cmi9880_models,
 | 
					 | 
				
			||||||
							cmi9880_cfg_tbl);
 | 
					 | 
				
			||||||
	if (spec->board_config < 0) {
 | 
					 | 
				
			||||||
		codec_dbg(codec, "%s: BIOS auto-probing.\n",
 | 
					 | 
				
			||||||
			    codec->chip_name);
 | 
					 | 
				
			||||||
		spec->board_config = CMI_AUTO; /* try everything */
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (spec->board_config == CMI_AUTO)
 | 
					 | 
				
			||||||
		return cmi_parse_auto_config(codec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* copy default DAC NIDs */
 | 
					 | 
				
			||||||
	memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
 | 
					 | 
				
			||||||
	spec->num_dacs = 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (spec->board_config) {
 | 
					 | 
				
			||||||
	case CMI_MINIMAL:
 | 
					 | 
				
			||||||
	case CMI_MIN_FP:
 | 
					 | 
				
			||||||
		spec->channel_modes = cmi9880_channel_modes;
 | 
					 | 
				
			||||||
		if (spec->board_config == CMI_MINIMAL)
 | 
					 | 
				
			||||||
			spec->num_channel_modes = 2;
 | 
					 | 
				
			||||||
		else {
 | 
					 | 
				
			||||||
			spec->front_panel = 1;
 | 
					 | 
				
			||||||
			spec->num_channel_modes = 3;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
 | 
					 | 
				
			||||||
		spec->input_mux = &cmi9880_basic_mux;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case CMI_FULL:
 | 
					 | 
				
			||||||
	case CMI_FULL_DIG:
 | 
					 | 
				
			||||||
		spec->front_panel = 1;
 | 
					 | 
				
			||||||
		spec->multiout.max_channels = 8;
 | 
					 | 
				
			||||||
		spec->input_mux = &cmi9880_basic_mux;
 | 
					 | 
				
			||||||
		if (spec->board_config == CMI_FULL_DIG) {
 | 
					 | 
				
			||||||
			spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
 | 
					 | 
				
			||||||
			spec->dig_in_nid = CMI_DIG_IN_NID;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case CMI_ALLOUT:
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		spec->front_panel = 1;
 | 
					 | 
				
			||||||
		spec->multiout.max_channels = 8;
 | 
					 | 
				
			||||||
		spec->no_line_in = 1;
 | 
					 | 
				
			||||||
		spec->input_mux = &cmi9880_no_line_mux;
 | 
					 | 
				
			||||||
		spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spec->multiout.num_dacs = spec->num_dacs;
 | 
					 | 
				
			||||||
	spec->multiout.dac_nids = spec->dac_nids;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	spec->adc_nids = cmi9880_adc_nids;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	codec->patch_ops = cmi9880_patch_ops;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	return cmi_parse_auto_config(codec);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * patch entries
 | 
					 * patch entries
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -648,7 +648,8 @@ static int get_channel_allocation_order(int ca)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * TODO: it could select the wrong CA from multiple candidates.
 | 
					 * TODO: it could select the wrong CA from multiple candidates.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
 | 
					static int hdmi_channel_allocation(struct hda_codec *codec,
 | 
				
			||||||
 | 
									   struct hdmi_eld *eld, int channels)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
	int ca = 0;
 | 
						int ca = 0;
 | 
				
			||||||
| 
						 | 
					@ -694,7 +695,7 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
 | 
						snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
 | 
				
			||||||
	snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
 | 
						codec_dbg(codec, "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
 | 
				
			||||||
		    ca, channels, buf);
 | 
							    ca, channels, buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ca;
 | 
						return ca;
 | 
				
			||||||
| 
						 | 
					@ -1131,7 +1132,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
 | 
				
			||||||
	if (!non_pcm && per_pin->chmap_set)
 | 
						if (!non_pcm && per_pin->chmap_set)
 | 
				
			||||||
		ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
 | 
							ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		ca = hdmi_channel_allocation(eld, channels);
 | 
							ca = hdmi_channel_allocation(codec, eld, channels);
 | 
				
			||||||
	if (ca < 0)
 | 
						if (ca < 0)
 | 
				
			||||||
		ca = 0;
 | 
							ca = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1557,13 +1558,13 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
 | 
				
			||||||
			eld->eld_valid = false;
 | 
								eld->eld_valid = false;
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			memset(&eld->info, 0, sizeof(struct parsed_hdmi_eld));
 | 
								memset(&eld->info, 0, sizeof(struct parsed_hdmi_eld));
 | 
				
			||||||
			if (snd_hdmi_parse_eld(&eld->info, eld->eld_buffer,
 | 
								if (snd_hdmi_parse_eld(codec, &eld->info, eld->eld_buffer,
 | 
				
			||||||
						    eld->eld_size) < 0)
 | 
											    eld->eld_size) < 0)
 | 
				
			||||||
				eld->eld_valid = false;
 | 
									eld->eld_valid = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (eld->eld_valid) {
 | 
							if (eld->eld_valid) {
 | 
				
			||||||
			snd_hdmi_show_eld(&eld->info);
 | 
								snd_hdmi_show_eld(codec, &eld->info);
 | 
				
			||||||
			update_eld = true;
 | 
								update_eld = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (repoll) {
 | 
							else if (repoll) {
 | 
				
			||||||
| 
						 | 
					@ -3355,6 +3356,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
 | 
				
			||||||
{ .id = 0x80862808, .name = "Broadwell HDMI",	.patch = patch_generic_hdmi },
 | 
					{ .id = 0x80862808, .name = "Broadwell HDMI",	.patch = patch_generic_hdmi },
 | 
				
			||||||
{ .id = 0x80862880, .name = "CedarTrail HDMI",	.patch = patch_generic_hdmi },
 | 
					{ .id = 0x80862880, .name = "CedarTrail HDMI",	.patch = patch_generic_hdmi },
 | 
				
			||||||
{ .id = 0x80862882, .name = "Valleyview2 HDMI",	.patch = patch_generic_hdmi },
 | 
					{ .id = 0x80862882, .name = "Valleyview2 HDMI",	.patch = patch_generic_hdmi },
 | 
				
			||||||
 | 
					{ .id = 0x80862883, .name = "Braswell HDMI",	.patch = patch_generic_hdmi },
 | 
				
			||||||
{ .id = 0x808629fb, .name = "Crestline HDMI",	.patch = patch_generic_hdmi },
 | 
					{ .id = 0x808629fb, .name = "Crestline HDMI",	.patch = patch_generic_hdmi },
 | 
				
			||||||
{} /* terminator */
 | 
					{} /* terminator */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -3414,6 +3416,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862807");
 | 
				
			||||||
MODULE_ALIAS("snd-hda-codec-id:80862808");
 | 
					MODULE_ALIAS("snd-hda-codec-id:80862808");
 | 
				
			||||||
MODULE_ALIAS("snd-hda-codec-id:80862880");
 | 
					MODULE_ALIAS("snd-hda-codec-id:80862880");
 | 
				
			||||||
MODULE_ALIAS("snd-hda-codec-id:80862882");
 | 
					MODULE_ALIAS("snd-hda-codec-id:80862882");
 | 
				
			||||||
 | 
					MODULE_ALIAS("snd-hda-codec-id:80862883");
 | 
				
			||||||
MODULE_ALIAS("snd-hda-codec-id:808629fb");
 | 
					MODULE_ALIAS("snd-hda-codec-id:808629fb");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_LICENSE("GPL");
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,6 +101,7 @@ struct alc_spec {
 | 
				
			||||||
	/* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
 | 
						/* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
 | 
				
			||||||
	int mute_led_polarity;
 | 
						int mute_led_polarity;
 | 
				
			||||||
	hda_nid_t mute_led_nid;
 | 
						hda_nid_t mute_led_nid;
 | 
				
			||||||
 | 
						hda_nid_t cap_mute_led_nid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
 | 
						unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3402,7 +3403,8 @@ static unsigned int led_power_filter(struct hda_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct alc_spec *spec = codec->spec;
 | 
						struct alc_spec *spec = codec->spec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid)
 | 
						if (power_state != AC_PWRST_D3 || nid == 0 ||
 | 
				
			||||||
 | 
						    (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
 | 
				
			||||||
		return power_state;
 | 
							return power_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Set pin ctl again, it might have just been set to 0 */
 | 
						/* Set pin ctl again, it might have just been set to 0 */
 | 
				
			||||||
| 
						 | 
					@ -3520,6 +3522,68 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* turn on/off mic-mute LED per capture hook */
 | 
				
			||||||
 | 
					static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
 | 
				
			||||||
 | 
										       struct snd_kcontrol *kcontrol,
 | 
				
			||||||
 | 
										       struct snd_ctl_elem_value *ucontrol)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct alc_spec *spec = codec->spec;
 | 
				
			||||||
 | 
						unsigned int pinval, enable, disable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
 | 
				
			||||||
 | 
						pinval &= ~AC_PINCTL_VREFEN;
 | 
				
			||||||
 | 
						enable  = pinval | AC_PINCTL_VREF_80;
 | 
				
			||||||
 | 
						disable = pinval | AC_PINCTL_VREF_HIZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ucontrol)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ucontrol->value.integer.value[0] ||
 | 
				
			||||||
 | 
						    ucontrol->value.integer.value[1])
 | 
				
			||||||
 | 
							pinval = disable;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							pinval = enable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (spec->cap_mute_led_nid)
 | 
				
			||||||
 | 
							snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
 | 
				
			||||||
 | 
									const struct hda_fixup *fix, int action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct alc_spec *spec = codec->spec;
 | 
				
			||||||
 | 
						static const struct hda_verb gpio_init[] = {
 | 
				
			||||||
 | 
							{ 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
 | 
				
			||||||
 | 
							{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
 | 
				
			||||||
 | 
							{}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (action == HDA_FIXUP_ACT_PRE_PROBE) {
 | 
				
			||||||
 | 
							spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
 | 
				
			||||||
 | 
							spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
 | 
				
			||||||
 | 
							spec->gpio_led = 0;
 | 
				
			||||||
 | 
							spec->cap_mute_led_nid = 0x18;
 | 
				
			||||||
 | 
							snd_hda_add_verbs(codec, gpio_init);
 | 
				
			||||||
 | 
							codec->power_filter = led_power_filter;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
 | 
				
			||||||
 | 
									const struct hda_fixup *fix, int action)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct alc_spec *spec = codec->spec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (action == HDA_FIXUP_ACT_PRE_PROBE) {
 | 
				
			||||||
 | 
							spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
 | 
				
			||||||
 | 
							spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
 | 
				
			||||||
 | 
							spec->mute_led_polarity = 0;
 | 
				
			||||||
 | 
							spec->mute_led_nid = 0x1a;
 | 
				
			||||||
 | 
							spec->cap_mute_led_nid = 0x18;
 | 
				
			||||||
 | 
							spec->gen.vmaster_mute_enum = 1;
 | 
				
			||||||
 | 
							codec->power_filter = led_power_filter;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void alc_headset_mode_unplugged(struct hda_codec *codec)
 | 
					static void alc_headset_mode_unplugged(struct hda_codec *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int val;
 | 
						int val;
 | 
				
			||||||
| 
						 | 
					@ -4231,6 +4295,9 @@ static void alc290_fixup_mono_speakers(struct hda_codec *codec,
 | 
				
			||||||
/* for hda_fixup_thinkpad_acpi() */
 | 
					/* for hda_fixup_thinkpad_acpi() */
 | 
				
			||||||
#include "thinkpad_helper.c"
 | 
					#include "thinkpad_helper.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* for dell wmi mic mute led */
 | 
				
			||||||
 | 
					#include "dell_wmi_helper.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	ALC269_FIXUP_SONY_VAIO,
 | 
						ALC269_FIXUP_SONY_VAIO,
 | 
				
			||||||
	ALC275_FIXUP_SONY_VAIO_GPIO2,
 | 
						ALC275_FIXUP_SONY_VAIO_GPIO2,
 | 
				
			||||||
| 
						 | 
					@ -4255,6 +4322,8 @@ enum {
 | 
				
			||||||
	ALC269_FIXUP_HP_MUTE_LED_MIC1,
 | 
						ALC269_FIXUP_HP_MUTE_LED_MIC1,
 | 
				
			||||||
	ALC269_FIXUP_HP_MUTE_LED_MIC2,
 | 
						ALC269_FIXUP_HP_MUTE_LED_MIC2,
 | 
				
			||||||
	ALC269_FIXUP_HP_GPIO_LED,
 | 
						ALC269_FIXUP_HP_GPIO_LED,
 | 
				
			||||||
 | 
						ALC269_FIXUP_HP_GPIO_MIC1_LED,
 | 
				
			||||||
 | 
						ALC269_FIXUP_HP_LINE1_MIC1_LED,
 | 
				
			||||||
	ALC269_FIXUP_INV_DMIC,
 | 
						ALC269_FIXUP_INV_DMIC,
 | 
				
			||||||
	ALC269_FIXUP_LENOVO_DOCK,
 | 
						ALC269_FIXUP_LENOVO_DOCK,
 | 
				
			||||||
	ALC269_FIXUP_NO_SHUTUP,
 | 
						ALC269_FIXUP_NO_SHUTUP,
 | 
				
			||||||
| 
						 | 
					@ -4292,6 +4361,8 @@ enum {
 | 
				
			||||||
	ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
 | 
						ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
 | 
				
			||||||
	ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
 | 
						ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
 | 
				
			||||||
	ALC292_FIXUP_TPT440_DOCK,
 | 
						ALC292_FIXUP_TPT440_DOCK,
 | 
				
			||||||
 | 
						ALC283_FIXUP_BXBT2807_MIC,
 | 
				
			||||||
 | 
						ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct hda_fixup alc269_fixups[] = {
 | 
					static const struct hda_fixup alc269_fixups[] = {
 | 
				
			||||||
| 
						 | 
					@ -4447,6 +4518,14 @@ static const struct hda_fixup alc269_fixups[] = {
 | 
				
			||||||
		.type = HDA_FIXUP_FUNC,
 | 
							.type = HDA_FIXUP_FUNC,
 | 
				
			||||||
		.v.func = alc269_fixup_hp_gpio_led,
 | 
							.v.func = alc269_fixup_hp_gpio_led,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						[ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_FUNC,
 | 
				
			||||||
 | 
							.v.func = alc269_fixup_hp_gpio_mic1_led,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						[ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_FUNC,
 | 
				
			||||||
 | 
							.v.func = alc269_fixup_hp_line1_mic1_led,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	[ALC269_FIXUP_INV_DMIC] = {
 | 
						[ALC269_FIXUP_INV_DMIC] = {
 | 
				
			||||||
		.type = HDA_FIXUP_FUNC,
 | 
							.type = HDA_FIXUP_FUNC,
 | 
				
			||||||
		.v.func = alc_fixup_inv_dmic_0x12,
 | 
							.v.func = alc_fixup_inv_dmic_0x12,
 | 
				
			||||||
| 
						 | 
					@ -4718,6 +4797,20 @@ static const struct hda_fixup alc269_fixups[] = {
 | 
				
			||||||
		.chained = true,
 | 
							.chained = true,
 | 
				
			||||||
		.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
 | 
							.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						[ALC283_FIXUP_BXBT2807_MIC] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_PINS,
 | 
				
			||||||
 | 
							.v.pins = (const struct hda_pintbl[]) {
 | 
				
			||||||
 | 
								{ 0x19, 0x04a110f0 },
 | 
				
			||||||
 | 
								{ },
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						[ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_FUNC,
 | 
				
			||||||
 | 
							.v.func = alc_fixup_dell_wmi,
 | 
				
			||||||
 | 
							.chained_before = true,
 | 
				
			||||||
 | 
							.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
					static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
| 
						 | 
					@ -4727,7 +4820,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
 | 
						SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
 | 
						SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
 | 
						SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
 | 
				
			||||||
	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
 | 
						SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
 | 
						SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
 | 
				
			||||||
| 
						 | 
					@ -4761,10 +4853,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
 | 
						SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 | 
				
			||||||
| 
						 | 
					@ -4782,6 +4876,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
 | 
						SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
 | 
				
			||||||
	/* ALC282 */
 | 
						/* ALC282 */
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x21f8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x220d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x220d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x220e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x220e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
| 
						 | 
					@ -4790,6 +4886,20 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2212, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2212, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2234, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2235, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x224a, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x224c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x224d, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
| 
						 | 
					@ -4814,13 +4924,43 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x22da, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x8004, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
	/* ALC290 */
 | 
						/* ALC290 */
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x221c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x221d, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2220, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2222, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2223, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2224, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2246, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2247, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2248, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2249, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2258, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2277, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
| 
						 | 
					@ -4843,7 +4983,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
						SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
 | 
				
			||||||
	SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
 | 
						SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
						SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
						SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
				
			||||||
| 
						 | 
					@ -4864,9 +5003,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
 | 
						SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
 | 
				
			||||||
	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
 | 
						SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
 | 
				
			||||||
	SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
 | 
						SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
 | 
				
			||||||
	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
 | 
						SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
 | 
				
			||||||
	SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
 | 
						SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
 | 
						SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
 | 
						SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
 | 
						SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
 | 
				
			||||||
| 
						 | 
					@ -4891,7 +5030,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
						SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
 | 
						SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
 | 
				
			||||||
	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 | 
						SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 | 
				
			||||||
	SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
 | 
					 | 
				
			||||||
	SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
 | 
						SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
| 
						 | 
					@ -4945,6 +5083,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
 | 
				
			||||||
 | 
						SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct hda_model_fixup alc269_fixup_models[] = {
 | 
					static const struct hda_model_fixup alc269_fixup_models[] = {
 | 
				
			||||||
	{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
 | 
						{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
 | 
				
			||||||
	{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
 | 
						{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
 | 
				
			||||||
| 
						 | 
					@ -5040,6 +5186,17 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
 | 
				
			||||||
		{0x1d, 0x40700001},
 | 
							{0x1d, 0x40700001},
 | 
				
			||||||
		{0x1e, 0x411111f0},
 | 
							{0x1e, 0x411111f0},
 | 
				
			||||||
		{0x21, 0x02211040}),
 | 
							{0x21, 0x02211040}),
 | 
				
			||||||
 | 
						SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
 | 
				
			||||||
 | 
							{0x12, 0x99a30130},
 | 
				
			||||||
 | 
							{0x14, 0x90170110},
 | 
				
			||||||
 | 
							{0x17, 0x40000000},
 | 
				
			||||||
 | 
							{0x18, 0x411111f0},
 | 
				
			||||||
 | 
							{0x19, 0x03a11020},
 | 
				
			||||||
 | 
							{0x1a, 0x411111f0},
 | 
				
			||||||
 | 
							{0x1b, 0x411111f0},
 | 
				
			||||||
 | 
							{0x1d, 0x40f41905},
 | 
				
			||||||
 | 
							{0x1e, 0x411111f0},
 | 
				
			||||||
 | 
							{0x21, 0x0321101f}),
 | 
				
			||||||
	SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
 | 
						SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
 | 
				
			||||||
		{0x12, 0x90a60130},
 | 
							{0x12, 0x90a60130},
 | 
				
			||||||
		{0x14, 0x90170110},
 | 
							{0x14, 0x90170110},
 | 
				
			||||||
| 
						 | 
					@ -5162,6 +5319,8 @@ static int patch_alc269(struct hda_codec *codec)
 | 
				
			||||||
	snd_hda_pick_fixup(codec, alc269_fixup_models,
 | 
						snd_hda_pick_fixup(codec, alc269_fixup_models,
 | 
				
			||||||
		       alc269_fixup_tbl, alc269_fixups);
 | 
							       alc269_fixup_tbl, alc269_fixups);
 | 
				
			||||||
	snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
 | 
						snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
 | 
				
			||||||
 | 
						snd_hda_pick_fixup(codec, NULL,	alc269_fixup_vendor_tbl,
 | 
				
			||||||
 | 
								   alc269_fixups);
 | 
				
			||||||
	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 | 
						snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	alc_auto_parse_customize_define(codec);
 | 
						alc_auto_parse_customize_define(codec);
 | 
				
			||||||
| 
						 | 
					@ -5858,6 +6017,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
 | 
				
			||||||
	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
 | 
						SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
 | 
						SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
	SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
						SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,7 @@ enum {
 | 
				
			||||||
	STAC_DELL_EQ,
 | 
						STAC_DELL_EQ,
 | 
				
			||||||
	STAC_ALIENWARE_M17X,
 | 
						STAC_ALIENWARE_M17X,
 | 
				
			||||||
	STAC_92HD89XX_HP_FRONT_JACK,
 | 
						STAC_92HD89XX_HP_FRONT_JACK,
 | 
				
			||||||
 | 
						STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK,
 | 
				
			||||||
	STAC_92HD73XX_MODELS
 | 
						STAC_92HD73XX_MODELS
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,6 +104,7 @@ enum {
 | 
				
			||||||
	STAC_92HD83XXX_HP,
 | 
						STAC_92HD83XXX_HP,
 | 
				
			||||||
	STAC_HP_ENVY_BASS,
 | 
						STAC_HP_ENVY_BASS,
 | 
				
			||||||
	STAC_HP_BNB13_EQ,
 | 
						STAC_HP_BNB13_EQ,
 | 
				
			||||||
 | 
						STAC_HP_ENVY_TS_BASS,
 | 
				
			||||||
	STAC_92HD83XXX_MODELS
 | 
						STAC_92HD83XXX_MODELS
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1017,7 +1019,7 @@ static int stac_create_spdif_mux_ctls(struct hda_codec *codec)
 | 
				
			||||||
	for (i = 0; i < num_cons; i++) {
 | 
						for (i = 0; i < num_cons; i++) {
 | 
				
			||||||
		if (snd_BUG_ON(!labels[i]))
 | 
							if (snd_BUG_ON(!labels[i]))
 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
		snd_hda_add_imux_item(&spec->spdif_mux, labels[i], i, NULL);
 | 
							snd_hda_add_imux_item(codec, &spec->spdif_mux, labels[i], i, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
 | 
						kctl = snd_hda_gen_add_kctl(&spec->gen, NULL, &stac_smux_mixer);
 | 
				
			||||||
| 
						 | 
					@ -1809,6 +1811,11 @@ static const struct hda_pintbl stac92hd89xx_hp_front_jack_pin_configs[] = {
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct hda_pintbl stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs[] = {
 | 
				
			||||||
 | 
						{ 0x0e, 0x400000f0 },
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
 | 
					static void stac92hd73xx_fixup_ref(struct hda_codec *codec,
 | 
				
			||||||
				   const struct hda_fixup *fix, int action)
 | 
									   const struct hda_fixup *fix, int action)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1931,6 +1938,10 @@ static const struct hda_fixup stac92hd73xx_fixups[] = {
 | 
				
			||||||
	[STAC_92HD89XX_HP_FRONT_JACK] = {
 | 
						[STAC_92HD89XX_HP_FRONT_JACK] = {
 | 
				
			||||||
		.type = HDA_FIXUP_PINS,
 | 
							.type = HDA_FIXUP_PINS,
 | 
				
			||||||
		.v.pins = stac92hd89xx_hp_front_jack_pin_configs,
 | 
							.v.pins = stac92hd89xx_hp_front_jack_pin_configs,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						[STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_PINS,
 | 
				
			||||||
 | 
							.v.pins = stac92hd89xx_hp_z1_g2_right_mic_jack_pin_configs,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1991,6 +2002,8 @@ static const struct snd_pci_quirk stac92hd73xx_fixup_tbl[] = {
 | 
				
			||||||
		      "Alienware M17x", STAC_ALIENWARE_M17X),
 | 
							      "Alienware M17x", STAC_ALIENWARE_M17X),
 | 
				
			||||||
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490,
 | 
				
			||||||
		      "Alienware M17x R3", STAC_DELL_EQ),
 | 
							      "Alienware M17x R3", STAC_DELL_EQ),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1927,
 | 
				
			||||||
 | 
									"HP Z1 G2", STAC_92HD89XX_HP_Z1_G2_RIGHT_MIC_JACK),
 | 
				
			||||||
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x2b17,
 | 
				
			||||||
				"unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
 | 
									"unknown HP", STAC_92HD89XX_HP_FRONT_JACK),
 | 
				
			||||||
	{} /* terminator */
 | 
						{} /* terminator */
 | 
				
			||||||
| 
						 | 
					@ -2668,6 +2681,13 @@ static const struct hda_fixup stac92hd83xxx_fixups[] = {
 | 
				
			||||||
		.chained = true,
 | 
							.chained = true,
 | 
				
			||||||
		.chain_id = STAC_92HD83XXX_HP_MIC_LED,
 | 
							.chain_id = STAC_92HD83XXX_HP_MIC_LED,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						[STAC_HP_ENVY_TS_BASS] = {
 | 
				
			||||||
 | 
							.type = HDA_FIXUP_PINS,
 | 
				
			||||||
 | 
							.v.pins = (const struct hda_pintbl[]) {
 | 
				
			||||||
 | 
								{ 0x10, 0x92170111 },
 | 
				
			||||||
 | 
								{}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct hda_model_fixup stac92hd83xxx_models[] = {
 | 
					static const struct hda_model_fixup stac92hd83xxx_models[] = {
 | 
				
			||||||
| 
						 | 
					@ -2684,6 +2704,7 @@ static const struct hda_model_fixup stac92hd83xxx_models[] = {
 | 
				
			||||||
	{ .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
 | 
						{ .id = STAC_92HD83XXX_HEADSET_JACK, .name = "headset-jack" },
 | 
				
			||||||
	{ .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
 | 
						{ .id = STAC_HP_ENVY_BASS, .name = "hp-envy-bass" },
 | 
				
			||||||
	{ .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
 | 
						{ .id = STAC_HP_BNB13_EQ, .name = "hp-bnb13-eq" },
 | 
				
			||||||
 | 
						{ .id = STAC_HP_ENVY_TS_BASS, .name = "hp-envy-ts-bass" },
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2739,6 +2760,8 @@ static const struct snd_pci_quirk stac92hd83xxx_fixup_tbl[] = {
 | 
				
			||||||
			  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
								  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
				
			||||||
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190A,
 | 
				
			||||||
			  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
								  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
				
			||||||
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x190e,
 | 
				
			||||||
 | 
								  "HP ENVY TS", STAC_HP_ENVY_TS_BASS),
 | 
				
			||||||
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1940,
 | 
				
			||||||
			  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
								  "HP bNB13", STAC_HP_BNB13_EQ),
 | 
				
			||||||
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
 | 
						SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1941,
 | 
				
			||||||
| 
						 | 
					@ -3438,9 +3461,11 @@ static void stac922x_fixup_intel_mac_auto(struct hda_codec *codec,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (action != HDA_FIXUP_ACT_PRE_PROBE)
 | 
						if (action != HDA_FIXUP_ACT_PRE_PROBE)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
 | 
				
			||||||
	snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
 | 
						snd_hda_pick_fixup(codec, NULL, stac922x_intel_mac_fixup_tbl,
 | 
				
			||||||
			   stac922x_fixups);
 | 
								   stac922x_fixups);
 | 
				
			||||||
	if (codec->fixup_id != STAC_INTEL_MAC_AUTO)
 | 
						if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
 | 
				
			||||||
		snd_hda_apply_fixup(codec, action);
 | 
							snd_hda_apply_fixup(codec, action);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,14 +41,17 @@
 | 
				
			||||||
#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
 | 
					#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICE1712_REG_CONTROL		0x00	/* byte */
 | 
					#define ICE1712_REG_CONTROL		0x00	/* byte */
 | 
				
			||||||
#define   ICE1712_RESET			0x80	/* reset whole chip */
 | 
					#define   ICE1712_RESET			0x80	/* soft reset whole chip */
 | 
				
			||||||
#define   ICE1712_SERR_LEVEL		0x04	/* SERR# level otherwise edge */
 | 
					#define   ICE1712_SERR_ASSERT_DS_DMA	0x40    /* disabled SERR# assertion for the DS DMA Ch-C irq otherwise enabled */
 | 
				
			||||||
 | 
					#define   ICE1712_DOS_VOL		0x10    /* DOS WT/FM volume control */
 | 
				
			||||||
 | 
					#define   ICE1712_SERR_LEVEL		0x08	/* SERR# level otherwise edge */
 | 
				
			||||||
 | 
					#define   ICE1712_SERR_ASSERT_SB	0x02	/* disabled SERR# assertion for SB irq otherwise enabled */
 | 
				
			||||||
#define   ICE1712_NATIVE		0x01	/* native mode otherwise SB */
 | 
					#define   ICE1712_NATIVE		0x01	/* native mode otherwise SB */
 | 
				
			||||||
#define ICE1712_REG_IRQMASK		0x01	/* byte */
 | 
					#define ICE1712_REG_IRQMASK		0x01	/* byte */
 | 
				
			||||||
#define   ICE1712_IRQ_MPU1		0x80
 | 
					#define   ICE1712_IRQ_MPU1		0x80	/* MIDI irq mask */
 | 
				
			||||||
#define   ICE1712_IRQ_TIMER		0x40
 | 
					#define   ICE1712_IRQ_TIMER		0x40	/* Timer mask */
 | 
				
			||||||
#define   ICE1712_IRQ_MPU2		0x20
 | 
					#define   ICE1712_IRQ_MPU2		0x20	/* Secondary MIDI irq mask */
 | 
				
			||||||
#define   ICE1712_IRQ_PROPCM		0x10
 | 
					#define   ICE1712_IRQ_PROPCM		0x10	/* professional multi-track */
 | 
				
			||||||
#define   ICE1712_IRQ_FM		0x08	/* FM/MIDI - legacy */
 | 
					#define   ICE1712_IRQ_FM		0x08	/* FM/MIDI - legacy */
 | 
				
			||||||
#define   ICE1712_IRQ_PBKDS		0x04	/* playback DS channels */
 | 
					#define   ICE1712_IRQ_PBKDS		0x04	/* playback DS channels */
 | 
				
			||||||
#define   ICE1712_IRQ_CONCAP		0x02	/* consumer capture */
 | 
					#define   ICE1712_IRQ_CONCAP		0x02	/* consumer capture */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,13 +151,11 @@ static int send_msg( struct mixart_mgr *mgr,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 headptr, tailptr;
 | 
						u32 headptr, tailptr;
 | 
				
			||||||
	u32 msg_frame_address;
 | 
						u32 msg_frame_address;
 | 
				
			||||||
	int err, i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (snd_BUG_ON(msg->size % 4))
 | 
						if (snd_BUG_ON(msg->size % 4))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* get message frame address */
 | 
						/* get message frame address */
 | 
				
			||||||
	tailptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
 | 
						tailptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
 | 
				
			||||||
	headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_HEAD));
 | 
						headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_HEAD));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,7 @@ static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
 | 
				
			||||||
	{ OXYGEN_PCI_SUBID(0x1043, 0x835e) },
 | 
						{ OXYGEN_PCI_SUBID(0x1043, 0x835e) },
 | 
				
			||||||
	{ OXYGEN_PCI_SUBID(0x1043, 0x838e) },
 | 
						{ OXYGEN_PCI_SUBID(0x1043, 0x838e) },
 | 
				
			||||||
	{ OXYGEN_PCI_SUBID(0x1043, 0x8522) },
 | 
						{ OXYGEN_PCI_SUBID(0x1043, 0x8522) },
 | 
				
			||||||
 | 
						{ OXYGEN_PCI_SUBID(0x1043, 0x85f4) },
 | 
				
			||||||
	{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },
 | 
						{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },
 | 
				
			||||||
	{ }
 | 
						{ }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,8 +100,8 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Xonar Essence ST (Deluxe)/STX
 | 
					 * Xonar Essence ST (Deluxe)/STX (II)
 | 
				
			||||||
 * -----------------------------
 | 
					 * ----------------------------------
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * CMI8788:
 | 
					 * CMI8788:
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -1138,6 +1138,14 @@ int get_xonar_pcm179x_model(struct oxygen *chip,
 | 
				
			||||||
		chip->model.resume = xonar_stx_resume;
 | 
							chip->model.resume = xonar_stx_resume;
 | 
				
			||||||
		chip->model.set_dac_params = set_pcm1796_params;
 | 
							chip->model.set_dac_params = set_pcm1796_params;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case 0x85f4:
 | 
				
			||||||
 | 
							chip->model = model_xonar_st;
 | 
				
			||||||
 | 
							/* TODO: daughterboard support */
 | 
				
			||||||
 | 
							chip->model.shortname = "Xonar STX II";
 | 
				
			||||||
 | 
							chip->model.init = xonar_stx_init;
 | 
				
			||||||
 | 
							chip->model.resume = xonar_stx_resume;
 | 
				
			||||||
 | 
							chip->model.set_dac_params = set_pcm1796_params;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -941,7 +941,7 @@ setmixer(struct cmdif *cif, short num, unsigned short rval, unsigned short lval)
 | 
				
			||||||
	union cmdret rptr = CMDRET_ZERO;
 | 
						union cmdret rptr = CMDRET_ZERO;
 | 
				
			||||||
	int i = 0;
 | 
						int i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_printdd("sent mixer %d: 0x%d 0x%d\n", num, rval, lval);
 | 
						snd_printdd("sent mixer %d: 0x%x 0x%x\n", num, rval, lval);
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		SEND_SDGV(cif, num, num, rval, lval);
 | 
							SEND_SDGV(cif, num, num, rval, lval);
 | 
				
			||||||
		SEND_RDGV(cif, num, num, &rptr);
 | 
							SEND_RDGV(cif, num, num, &rptr);
 | 
				
			||||||
| 
						 | 
					@ -1080,7 +1080,7 @@ getmixer(struct cmdif *cif, short num, unsigned short *rval,
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
	*rval = rptr.retwords[0];
 | 
						*rval = rptr.retwords[0];
 | 
				
			||||||
	*lval = rptr.retwords[1];
 | 
						*lval = rptr.retwords[1];
 | 
				
			||||||
	snd_printdd("got mixer %d: 0x%d 0x%d\n", num, *rval, *lval);
 | 
						snd_printdd("got mixer %d: 0x%x 0x%x\n", num, *rval, *lval);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3880,14 +3880,12 @@ void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voi
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long flags;
 | 
						unsigned long flags;
 | 
				
			||||||
	void (*private_free)(struct snd_trident_voice *);
 | 
						void (*private_free)(struct snd_trident_voice *);
 | 
				
			||||||
	void *private_data;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (voice == NULL || !voice->use)
 | 
						if (voice == NULL || !voice->use)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	snd_trident_clear_voices(trident, voice->number, voice->number);
 | 
						snd_trident_clear_voices(trident, voice->number, voice->number);
 | 
				
			||||||
	spin_lock_irqsave(&trident->voice_alloc, flags);
 | 
						spin_lock_irqsave(&trident->voice_alloc, flags);
 | 
				
			||||||
	private_free = voice->private_free;
 | 
						private_free = voice->private_free;
 | 
				
			||||||
	private_data = voice->private_data;
 | 
					 | 
				
			||||||
	voice->private_free = NULL;
 | 
						voice->private_free = NULL;
 | 
				
			||||||
	voice->private_data = NULL;
 | 
						voice->private_data = NULL;
 | 
				
			||||||
	if (voice->pcm)
 | 
						if (voice->pcm)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,12 +139,11 @@ static inline void *offset_ptr(struct snd_trident *trident, int offset)
 | 
				
			||||||
static struct snd_util_memblk *
 | 
					static struct snd_util_memblk *
 | 
				
			||||||
search_empty(struct snd_util_memhdr *hdr, int size)
 | 
					search_empty(struct snd_util_memhdr *hdr, int size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_util_memblk *blk, *prev;
 | 
						struct snd_util_memblk *blk;
 | 
				
			||||||
	int page, psize;
 | 
						int page, psize;
 | 
				
			||||||
	struct list_head *p;
 | 
						struct list_head *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	psize = get_aligned_page(size + ALIGN_PAGE_SIZE -1);
 | 
						psize = get_aligned_page(size + ALIGN_PAGE_SIZE -1);
 | 
				
			||||||
	prev = NULL;
 | 
					 | 
				
			||||||
	page = 0;
 | 
						page = 0;
 | 
				
			||||||
	list_for_each(p, &hdr->block) {
 | 
						list_for_each(p, &hdr->block) {
 | 
				
			||||||
		blk = list_entry(p, struct snd_util_memblk, list);
 | 
							blk = list_entry(p, struct snd_util_memblk, list);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ source "sound/soc/kirkwood/Kconfig"
 | 
				
			||||||
source "sound/soc/intel/Kconfig"
 | 
					source "sound/soc/intel/Kconfig"
 | 
				
			||||||
source "sound/soc/mxs/Kconfig"
 | 
					source "sound/soc/mxs/Kconfig"
 | 
				
			||||||
source "sound/soc/pxa/Kconfig"
 | 
					source "sound/soc/pxa/Kconfig"
 | 
				
			||||||
 | 
					source "sound/soc/rockchip/Kconfig"
 | 
				
			||||||
source "sound/soc/samsung/Kconfig"
 | 
					source "sound/soc/samsung/Kconfig"
 | 
				
			||||||
source "sound/soc/s6000/Kconfig"
 | 
					source "sound/soc/s6000/Kconfig"
 | 
				
			||||||
source "sound/soc/sh/Kconfig"
 | 
					source "sound/soc/sh/Kconfig"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@ obj-$(CONFIG_SND_SOC)	+= nuc900/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= omap/
 | 
					obj-$(CONFIG_SND_SOC)	+= omap/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= kirkwood/
 | 
					obj-$(CONFIG_SND_SOC)	+= kirkwood/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= pxa/
 | 
					obj-$(CONFIG_SND_SOC)	+= pxa/
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC)	+= rockchip/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= samsung/
 | 
					obj-$(CONFIG_SND_SOC)	+= samsung/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= s6000/
 | 
					obj-$(CONFIG_SND_SOC)	+= s6000/
 | 
				
			||||||
obj-$(CONFIG_SND_SOC)	+= sh/
 | 
					obj-$(CONFIG_SND_SOC)	+= sh/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -347,6 +347,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	u32 tfmr, rfmr, tcmr, rcmr;
 | 
						u32 tfmr, rfmr, tcmr, rcmr;
 | 
				
			||||||
	int start_event;
 | 
						int start_event;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
						int fslen, fslen_ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Currently, there is only one set of dma params for
 | 
						 * Currently, there is only one set of dma params for
 | 
				
			||||||
| 
						 | 
					@ -387,18 +388,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * The SSC only supports up to 16-bit samples in I2S format, due
 | 
					 | 
				
			||||||
	 * to the size of the Frame Mode Register FSLEN field.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
 | 
					 | 
				
			||||||
		&& bits > 16) {
 | 
					 | 
				
			||||||
		printk(KERN_WARNING
 | 
					 | 
				
			||||||
				"atmel_ssc_dai: sample size %d "
 | 
					 | 
				
			||||||
				"is too large for I2S\n", bits);
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Compute SSC register settings.
 | 
						 * Compute SSC register settings.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
| 
						 | 
					@ -413,6 +402,17 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
		 * from the MCK divider, and the BCLK signal
 | 
							 * from the MCK divider, and the BCLK signal
 | 
				
			||||||
		 * is output on the SSC TK line.
 | 
							 * is output on the SSC TK line.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (bits > 16 && !ssc->pdata->has_fslen_ext) {
 | 
				
			||||||
 | 
								dev_err(dai->dev,
 | 
				
			||||||
 | 
									"sample size %d is too large for SSC device\n",
 | 
				
			||||||
 | 
									bits);
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fslen_ext = (bits - 1) / 16;
 | 
				
			||||||
 | 
							fslen = (bits - 1) % 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rcmr =	  SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
 | 
							rcmr =	  SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
 | 
				
			||||||
			| SSC_BF(RCMR_STTDLY, START_DELAY)
 | 
								| SSC_BF(RCMR_STTDLY, START_DELAY)
 | 
				
			||||||
			| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
 | 
								| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
 | 
				
			||||||
| 
						 | 
					@ -420,9 +420,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
			| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
 | 
								| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
 | 
				
			||||||
			| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
 | 
								| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rfmr =	  SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 | 
							rfmr =    SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
 | 
				
			||||||
 | 
								| SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 | 
				
			||||||
			| SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
 | 
								| SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
 | 
				
			||||||
			| SSC_BF(RFMR_FSLEN, (bits - 1))
 | 
								| SSC_BF(RFMR_FSLEN, fslen)
 | 
				
			||||||
			| SSC_BF(RFMR_DATNB, (channels - 1))
 | 
								| SSC_BF(RFMR_DATNB, (channels - 1))
 | 
				
			||||||
			| SSC_BIT(RFMR_MSBF)
 | 
								| SSC_BIT(RFMR_MSBF)
 | 
				
			||||||
			| SSC_BF(RFMR_LOOP, 0)
 | 
								| SSC_BF(RFMR_LOOP, 0)
 | 
				
			||||||
| 
						 | 
					@ -435,10 +436,11 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
			| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
 | 
								| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
 | 
				
			||||||
			| SSC_BF(TCMR_CKS, SSC_CKS_DIV);
 | 
								| SSC_BF(TCMR_CKS, SSC_CKS_DIV);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		tfmr =	  SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 | 
							tfmr =    SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
 | 
				
			||||||
 | 
								| SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
 | 
				
			||||||
			| SSC_BF(TFMR_FSDEN, 0)
 | 
								| SSC_BF(TFMR_FSDEN, 0)
 | 
				
			||||||
			| SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
 | 
								| SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
 | 
				
			||||||
			| SSC_BF(TFMR_FSLEN, (bits - 1))
 | 
								| SSC_BF(TFMR_FSLEN, fslen)
 | 
				
			||||||
			| SSC_BF(TFMR_DATNB, (channels - 1))
 | 
								| SSC_BF(TFMR_DATNB, (channels - 1))
 | 
				
			||||||
			| SSC_BIT(TFMR_MSBF)
 | 
								| SSC_BIT(TFMR_MSBF)
 | 
				
			||||||
			| SSC_BF(TFMR_DATDEF, 0)
 | 
								| SSC_BF(TFMR_DATDEF, 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,10 +18,6 @@
 | 
				
			||||||
#include "../codecs/wm8904.h"
 | 
					#include "../codecs/wm8904.h"
 | 
				
			||||||
#include "atmel_ssc_dai.h"
 | 
					#include "atmel_ssc_dai.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MCLK_RATE 32768
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct clk *mclk;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct snd_soc_dapm_widget atmel_asoc_wm8904_dapm_widgets[] = {
 | 
					static const struct snd_soc_dapm_widget atmel_asoc_wm8904_dapm_widgets[] = {
 | 
				
			||||||
	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 | 
						SND_SOC_DAPM_HP("Headphone Jack", NULL),
 | 
				
			||||||
	SND_SOC_DAPM_MIC("Mic", NULL),
 | 
						SND_SOC_DAPM_MIC("Mic", NULL),
 | 
				
			||||||
| 
						 | 
					@ -61,26 +57,6 @@ static struct snd_soc_ops atmel_asoc_wm8904_ops = {
 | 
				
			||||||
	.hw_params = atmel_asoc_wm8904_hw_params,
 | 
						.hw_params = atmel_asoc_wm8904_hw_params,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atmel_set_bias_level(struct snd_soc_card *card,
 | 
					 | 
				
			||||||
		struct snd_soc_dapm_context *dapm,
 | 
					 | 
				
			||||||
		enum snd_soc_bias_level level)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
 | 
					 | 
				
			||||||
		switch (level) {
 | 
					 | 
				
			||||||
		case SND_SOC_BIAS_PREPARE:
 | 
					 | 
				
			||||||
			clk_prepare_enable(mclk);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SND_SOC_BIAS_OFF:
 | 
					 | 
				
			||||||
			clk_disable_unprepare(mclk);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
 | 
					static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
 | 
				
			||||||
	.name = "WM8904",
 | 
						.name = "WM8904",
 | 
				
			||||||
	.stream_name = "WM8904 PCM",
 | 
						.stream_name = "WM8904 PCM",
 | 
				
			||||||
| 
						 | 
					@ -94,7 +70,6 @@ static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
 | 
				
			||||||
static struct snd_soc_card atmel_asoc_wm8904_card = {
 | 
					static struct snd_soc_card atmel_asoc_wm8904_card = {
 | 
				
			||||||
	.name = "atmel_asoc_wm8904",
 | 
						.name = "atmel_asoc_wm8904",
 | 
				
			||||||
	.owner = THIS_MODULE,
 | 
						.owner = THIS_MODULE,
 | 
				
			||||||
	.set_bias_level = atmel_set_bias_level,
 | 
					 | 
				
			||||||
	.dai_link = &atmel_asoc_wm8904_dailink,
 | 
						.dai_link = &atmel_asoc_wm8904_dailink,
 | 
				
			||||||
	.num_links = 1,
 | 
						.num_links = 1,
 | 
				
			||||||
	.dapm_widgets = atmel_asoc_wm8904_dapm_widgets,
 | 
						.dapm_widgets = atmel_asoc_wm8904_dapm_widgets,
 | 
				
			||||||
| 
						 | 
					@ -153,7 +128,6 @@ static int atmel_asoc_wm8904_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct snd_soc_card *card = &atmel_asoc_wm8904_card;
 | 
						struct snd_soc_card *card = &atmel_asoc_wm8904_card;
 | 
				
			||||||
	struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
 | 
						struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
 | 
				
			||||||
	struct clk *clk_src;
 | 
					 | 
				
			||||||
	int id, ret;
 | 
						int id, ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	card->dev = &pdev->dev;
 | 
						card->dev = &pdev->dev;
 | 
				
			||||||
| 
						 | 
					@ -170,30 +144,6 @@ static int atmel_asoc_wm8904_probe(struct platform_device *pdev)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mclk = clk_get(NULL, "pck0");
 | 
					 | 
				
			||||||
	if (IS_ERR(mclk)) {
 | 
					 | 
				
			||||||
		dev_err(&pdev->dev, "failed to get pck0\n");
 | 
					 | 
				
			||||||
		ret = PTR_ERR(mclk);
 | 
					 | 
				
			||||||
		goto err_set_audio;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clk_src = clk_get(NULL, "clk32k");
 | 
					 | 
				
			||||||
	if (IS_ERR(clk_src)) {
 | 
					 | 
				
			||||||
		dev_err(&pdev->dev, "failed to get clk32k\n");
 | 
					 | 
				
			||||||
		ret = PTR_ERR(clk_src);
 | 
					 | 
				
			||||||
		goto err_set_audio;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = clk_set_parent(mclk, clk_src);
 | 
					 | 
				
			||||||
	clk_put(clk_src);
 | 
					 | 
				
			||||||
	if (ret != 0) {
 | 
					 | 
				
			||||||
		dev_err(&pdev->dev, "failed to set MCLK parent\n");
 | 
					 | 
				
			||||||
		goto err_set_audio;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dev_info(&pdev->dev, "setting pck0 to %dHz\n", MCLK_RATE);
 | 
					 | 
				
			||||||
	clk_set_rate(mclk, MCLK_RATE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = snd_soc_register_card(card);
 | 
						ret = snd_soc_register_card(card);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		dev_err(&pdev->dev, "snd_soc_register_card failed\n");
 | 
							dev_err(&pdev->dev, "snd_soc_register_card failed\n");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -290,19 +290,19 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
 | 
				
			||||||
	unsigned int sample_size = runtime->sample_bits / 8;
 | 
						unsigned int sample_size = runtime->sample_bits / 8;
 | 
				
			||||||
	void *buf = runtime->dma_area;
 | 
						void *buf = runtime->dma_area;
 | 
				
			||||||
	struct bf5xx_i2s_pcm_data *dma_data;
 | 
						struct bf5xx_i2s_pcm_data *dma_data;
 | 
				
			||||||
	unsigned int offset, size;
 | 
						unsigned int offset, samples;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 | 
						dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dma_data->tdm_mode) {
 | 
						if (dma_data->tdm_mode) {
 | 
				
			||||||
		offset = pos * 8 * sample_size;
 | 
							offset = pos * 8 * sample_size;
 | 
				
			||||||
		size = count * 8 * sample_size;
 | 
							samples = count * 8;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		offset = frames_to_bytes(runtime, pos);
 | 
							offset = frames_to_bytes(runtime, pos);
 | 
				
			||||||
		size = frames_to_bytes(runtime, count);
 | 
							samples = count * runtime->channels;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snd_pcm_format_set_silence(runtime->format, buf + offset, size);
 | 
						snd_pcm_format_set_silence(runtime->format, buf + offset, samples);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -945,11 +945,11 @@ static int pm860x_pcm_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	unsigned char inf = 0, mask = 0;
 | 
						unsigned char inf = 0, mask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* bit size */
 | 
						/* bit size */
 | 
				
			||||||
	switch (params_format(params)) {
 | 
						switch (params_width(params)) {
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S16_LE:
 | 
						case 16:
 | 
				
			||||||
		inf &= ~PCM_INF2_18WL;
 | 
							inf &= ~PCM_INF2_18WL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S18_3LE:
 | 
						case 18:
 | 
				
			||||||
		inf |= PCM_INF2_18WL;
 | 
							inf |= PCM_INF2_18WL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -1044,11 +1044,11 @@ static int pm860x_i2s_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	unsigned char inf;
 | 
						unsigned char inf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* bit size */
 | 
						/* bit size */
 | 
				
			||||||
	switch (params_format(params)) {
 | 
						switch (params_width(params)) {
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S16_LE:
 | 
						case 16:
 | 
				
			||||||
		inf = 0;
 | 
							inf = 0;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S18_3LE:
 | 
						case 18:
 | 
				
			||||||
		inf = PCM_INF2_18WL;
 | 
							inf = PCM_INF2_18WL;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_CS42L52 if I2C && INPUT
 | 
						select SND_SOC_CS42L52 if I2C && INPUT
 | 
				
			||||||
	select SND_SOC_CS42L56 if I2C && INPUT
 | 
						select SND_SOC_CS42L56 if I2C && INPUT
 | 
				
			||||||
	select SND_SOC_CS42L73 if I2C
 | 
						select SND_SOC_CS42L73 if I2C
 | 
				
			||||||
 | 
						select SND_SOC_CS4265 if I2C
 | 
				
			||||||
	select SND_SOC_CS4270 if I2C
 | 
						select SND_SOC_CS4270 if I2C
 | 
				
			||||||
	select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
 | 
						select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
 | 
				
			||||||
	select SND_SOC_CS42XX8_I2C if I2C
 | 
						select SND_SOC_CS42XX8_I2C if I2C
 | 
				
			||||||
| 
						 | 
					@ -74,10 +75,12 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_PCM3008
 | 
						select SND_SOC_PCM3008
 | 
				
			||||||
	select SND_SOC_PCM512x_I2C if I2C
 | 
						select SND_SOC_PCM512x_I2C if I2C
 | 
				
			||||||
	select SND_SOC_PCM512x_SPI if SPI_MASTER
 | 
						select SND_SOC_PCM512x_SPI if SPI_MASTER
 | 
				
			||||||
 | 
						select SND_SOC_RT286 if I2C
 | 
				
			||||||
	select SND_SOC_RT5631 if I2C
 | 
						select SND_SOC_RT5631 if I2C
 | 
				
			||||||
	select SND_SOC_RT5640 if I2C
 | 
						select SND_SOC_RT5640 if I2C
 | 
				
			||||||
	select SND_SOC_RT5645 if I2C
 | 
						select SND_SOC_RT5645 if I2C
 | 
				
			||||||
	select SND_SOC_RT5651 if I2C
 | 
						select SND_SOC_RT5651 if I2C
 | 
				
			||||||
 | 
						select SND_SOC_RT5670 if I2C
 | 
				
			||||||
	select SND_SOC_RT5677 if I2C
 | 
						select SND_SOC_RT5677 if I2C
 | 
				
			||||||
	select SND_SOC_SGTL5000 if I2C
 | 
						select SND_SOC_SGTL5000 if I2C
 | 
				
			||||||
	select SND_SOC_SI476X if MFD_SI476X_CORE
 | 
						select SND_SOC_SI476X if MFD_SI476X_CORE
 | 
				
			||||||
| 
						 | 
					@ -91,6 +94,7 @@ config SND_SOC_ALL_CODECS
 | 
				
			||||||
	select SND_SOC_STA350 if I2C
 | 
						select SND_SOC_STA350 if I2C
 | 
				
			||||||
	select SND_SOC_STA529 if I2C
 | 
						select SND_SOC_STA529 if I2C
 | 
				
			||||||
	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_TAS5086 if I2C
 | 
						select SND_SOC_TAS5086 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
 | 
				
			||||||
| 
						 | 
					@ -338,6 +342,11 @@ config SND_SOC_CS42L73
 | 
				
			||||||
	tristate "Cirrus Logic CS42L73 CODEC"
 | 
						tristate "Cirrus Logic CS42L73 CODEC"
 | 
				
			||||||
	depends on I2C
 | 
						depends on I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SND_SOC_CS4265
 | 
				
			||||||
 | 
						tristate "Cirrus Logic CS4265 CODEC"
 | 
				
			||||||
 | 
						depends on I2C
 | 
				
			||||||
 | 
						select REGMAP_I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Cirrus Logic CS4270 Codec
 | 
					# Cirrus Logic CS4270 Codec
 | 
				
			||||||
config SND_SOC_CS4270
 | 
					config SND_SOC_CS4270
 | 
				
			||||||
	tristate "Cirrus Logic CS4270 CODEC"
 | 
						tristate "Cirrus Logic CS4270 CODEC"
 | 
				
			||||||
| 
						 | 
					@ -445,9 +454,16 @@ config SND_SOC_RL6231
 | 
				
			||||||
	default y if SND_SOC_RT5640=y
 | 
						default y if SND_SOC_RT5640=y
 | 
				
			||||||
	default y if SND_SOC_RT5645=y
 | 
						default y if SND_SOC_RT5645=y
 | 
				
			||||||
	default y if SND_SOC_RT5651=y
 | 
						default y if SND_SOC_RT5651=y
 | 
				
			||||||
 | 
						default y if SND_SOC_RT5670=y
 | 
				
			||||||
 | 
						default y if SND_SOC_RT5677=y
 | 
				
			||||||
	default m if SND_SOC_RT5640=m
 | 
						default m if SND_SOC_RT5640=m
 | 
				
			||||||
	default m if SND_SOC_RT5645=m
 | 
						default m if SND_SOC_RT5645=m
 | 
				
			||||||
	default m if SND_SOC_RT5651=m
 | 
						default m if SND_SOC_RT5651=m
 | 
				
			||||||
 | 
						default m if SND_SOC_RT5670=m
 | 
				
			||||||
 | 
						default m if SND_SOC_RT5677=m
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SND_SOC_RT286
 | 
				
			||||||
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_RT5631
 | 
					config SND_SOC_RT5631
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
| 
						 | 
					@ -461,6 +477,9 @@ config SND_SOC_RT5645
 | 
				
			||||||
config SND_SOC_RT5651
 | 
					config SND_SOC_RT5651
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SND_SOC_RT5670
 | 
				
			||||||
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_RT5677
 | 
					config SND_SOC_RT5677
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -521,6 +540,10 @@ config SND_SOC_STA529
 | 
				
			||||||
config SND_SOC_STAC9766
 | 
					config SND_SOC_STAC9766
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SND_SOC_TAS2552
 | 
				
			||||||
 | 
						tristate "Texas Instruments TAS2552 Mono Audio amplifier"
 | 
				
			||||||
 | 
						depends on I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_TAS5086
 | 
					config SND_SOC_TAS5086
 | 
				
			||||||
	tristate "Texas Instruments TAS5086 speaker amplifier"
 | 
						tristate "Texas Instruments TAS5086 speaker amplifier"
 | 
				
			||||||
	depends on I2C
 | 
						depends on I2C
 | 
				
			||||||
| 
						 | 
					@ -541,7 +564,9 @@ config SND_SOC_TLV320AIC26
 | 
				
			||||||
	depends on SPI
 | 
						depends on SPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_TLV320AIC31XX
 | 
					config SND_SOC_TLV320AIC31XX
 | 
				
			||||||
        tristate
 | 
						tristate "Texas Instruments TLV320AIC31xx CODECs"
 | 
				
			||||||
 | 
						depends on I2C
 | 
				
			||||||
 | 
						select REGMAP_I2C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config SND_SOC_TLV320AIC32X4
 | 
					config SND_SOC_TLV320AIC32X4
 | 
				
			||||||
	tristate
 | 
						tristate
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@ snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
 | 
				
			||||||
snd-soc-cs42l52-objs := cs42l52.o
 | 
					snd-soc-cs42l52-objs := cs42l52.o
 | 
				
			||||||
snd-soc-cs42l56-objs := cs42l56.o
 | 
					snd-soc-cs42l56-objs := cs42l56.o
 | 
				
			||||||
snd-soc-cs42l73-objs := cs42l73.o
 | 
					snd-soc-cs42l73-objs := cs42l73.o
 | 
				
			||||||
 | 
					snd-soc-cs4265-objs := cs4265.o
 | 
				
			||||||
snd-soc-cs4270-objs := cs4270.o
 | 
					snd-soc-cs4270-objs := cs4270.o
 | 
				
			||||||
snd-soc-cs4271-objs := cs4271.o
 | 
					snd-soc-cs4271-objs := cs4271.o
 | 
				
			||||||
snd-soc-cs42xx8-objs := cs42xx8.o
 | 
					snd-soc-cs42xx8-objs := cs42xx8.o
 | 
				
			||||||
| 
						 | 
					@ -68,10 +69,12 @@ snd-soc-pcm512x-objs := pcm512x.o
 | 
				
			||||||
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 | 
					snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 | 
				
			||||||
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 | 
					snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 | 
				
			||||||
snd-soc-rl6231-objs := rl6231.o
 | 
					snd-soc-rl6231-objs := rl6231.o
 | 
				
			||||||
 | 
					snd-soc-rt286-objs := rt286.o
 | 
				
			||||||
snd-soc-rt5631-objs := rt5631.o
 | 
					snd-soc-rt5631-objs := rt5631.o
 | 
				
			||||||
snd-soc-rt5640-objs := rt5640.o
 | 
					snd-soc-rt5640-objs := rt5640.o
 | 
				
			||||||
snd-soc-rt5645-objs := rt5645.o
 | 
					snd-soc-rt5645-objs := rt5645.o
 | 
				
			||||||
snd-soc-rt5651-objs := rt5651.o
 | 
					snd-soc-rt5651-objs := rt5651.o
 | 
				
			||||||
 | 
					snd-soc-rt5670-objs := rt5670.o
 | 
				
			||||||
snd-soc-rt5677-objs := rt5677.o
 | 
					snd-soc-rt5677-objs := rt5677.o
 | 
				
			||||||
snd-soc-sgtl5000-objs := sgtl5000.o
 | 
					snd-soc-sgtl5000-objs := sgtl5000.o
 | 
				
			||||||
snd-soc-alc5623-objs := alc5623.o
 | 
					snd-soc-alc5623-objs := alc5623.o
 | 
				
			||||||
| 
						 | 
					@ -162,6 +165,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
 | 
				
			||||||
# Amp
 | 
					# Amp
 | 
				
			||||||
snd-soc-max9877-objs := max9877.o
 | 
					snd-soc-max9877-objs := max9877.o
 | 
				
			||||||
snd-soc-tpa6130a2-objs := tpa6130a2.o
 | 
					snd-soc-tpa6130a2-objs := tpa6130a2.o
 | 
				
			||||||
 | 
					snd-soc-tas2552-objs := tas2552.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_88PM860X)	+= snd-soc-88pm860x.o
 | 
					obj-$(CONFIG_SND_SOC_88PM860X)	+= snd-soc-88pm860x.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_AB8500_CODEC)	+= snd-soc-ab8500-codec.o
 | 
					obj-$(CONFIG_SND_SOC_AB8500_CODEC)	+= snd-soc-ab8500-codec.o
 | 
				
			||||||
| 
						 | 
					@ -204,6 +208,7 @@ obj-$(CONFIG_SND_SOC_CS42L51_I2C)	+= snd-soc-cs42l51-i2c.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS42L52)	+= snd-soc-cs42l52.o
 | 
					obj-$(CONFIG_SND_SOC_CS42L52)	+= snd-soc-cs42l52.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS42L56)	+= snd-soc-cs42l56.o
 | 
					obj-$(CONFIG_SND_SOC_CS42L56)	+= snd-soc-cs42l56.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS42L73)	+= snd-soc-cs42l73.o
 | 
					obj-$(CONFIG_SND_SOC_CS42L73)	+= snd-soc-cs42l73.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC_CS4265)	+= snd-soc-cs4265.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
 | 
					obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS4271)	+= snd-soc-cs4271.o
 | 
					obj-$(CONFIG_SND_SOC_CS4271)	+= snd-soc-cs4271.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_CS42XX8)	+= snd-soc-cs42xx8.o
 | 
					obj-$(CONFIG_SND_SOC_CS42XX8)	+= snd-soc-cs42xx8.o
 | 
				
			||||||
| 
						 | 
					@ -235,10 +240,12 @@ obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 | 
					obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 | 
					obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
 | 
					obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC_RT286)	+= snd-soc-rt286.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RT5631)	+= snd-soc-rt5631.o
 | 
					obj-$(CONFIG_SND_SOC_RT5631)	+= snd-soc-rt5631.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RT5640)	+= snd-soc-rt5640.o
 | 
					obj-$(CONFIG_SND_SOC_RT5640)	+= snd-soc-rt5640.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RT5645)	+= snd-soc-rt5645.o
 | 
					obj-$(CONFIG_SND_SOC_RT5645)	+= snd-soc-rt5645.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RT5651)	+= snd-soc-rt5651.o
 | 
					obj-$(CONFIG_SND_SOC_RT5651)	+= snd-soc-rt5651.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SND_SOC_RT5670)	+= snd-soc-rt5670.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_RT5677)	+= snd-soc-rt5677.o
 | 
					obj-$(CONFIG_SND_SOC_RT5677)	+= snd-soc-rt5677.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 | 
					obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_SIGMADSP)	+= snd-soc-sigmadsp.o
 | 
					obj-$(CONFIG_SND_SOC_SIGMADSP)	+= snd-soc-sigmadsp.o
 | 
				
			||||||
| 
						 | 
					@ -255,6 +262,7 @@ obj-$(CONFIG_SND_SOC_STA32X)   += snd-soc-sta32x.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_STA350)   += snd-soc-sta350.o
 | 
					obj-$(CONFIG_SND_SOC_STA350)   += snd-soc-sta350.o
 | 
				
			||||||
obj-$(CONFIG_SND_SOC_STA529)   += snd-soc-sta529.o
 | 
					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_TAS5086)	+= snd-soc-tas5086.o
 | 
					obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,8 +89,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* add codec as bus device for standard ac97 */
 | 
						/* add codec as bus device for standard ac97 */
 | 
				
			||||||
	ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL,
 | 
						ret = snd_ac97_bus(codec->component.card->snd_card, 0, soc_ac97_ops,
 | 
				
			||||||
			   &ac97_bus);
 | 
								   NULL, &ac97_bus);
 | 
				
			||||||
	if (ret < 0)
 | 
						if (ret < 0)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,8 +230,10 @@ static int adau1701_reg_read(void *context, unsigned int reg,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*value = 0;
 | 
						*value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < size; i++)
 | 
						for (i = 0; i < size; i++) {
 | 
				
			||||||
		*value |= recv_buf[i] << (i * 8);
 | 
							*value <<= 8;
 | 
				
			||||||
 | 
							*value |= recv_buf[i];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,14 +359,14 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
 | 
						if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (params_format(params)) {
 | 
						switch (params_width(params)) {
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S16_LE:
 | 
						case 16:
 | 
				
			||||||
		val = ADAU17X1_SERIAL_PORT1_DELAY16;
 | 
							val = ADAU17X1_SERIAL_PORT1_DELAY16;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S24_LE:
 | 
						case 24:
 | 
				
			||||||
		val = ADAU17X1_SERIAL_PORT1_DELAY8;
 | 
							val = ADAU17X1_SERIAL_PORT1_DELAY8;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case SNDRV_PCM_FORMAT_S32_LE:
 | 
						case 32:
 | 
				
			||||||
		val = ADAU17X1_SERIAL_PORT1_DELAY0;
 | 
							val = ADAU17X1_SERIAL_PORT1_DELAY0;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -968,7 +968,7 @@ int adau1977_probe(struct device *dev, struct regmap *regmap,
 | 
				
			||||||
	if (adau1977->dvdd_reg)
 | 
						if (adau1977->dvdd_reg)
 | 
				
			||||||
		power_off_mask = ~0;
 | 
							power_off_mask = ~0;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
 | 
							power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
 | 
						ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
 | 
				
			||||||
				power_off_mask, 0x00);
 | 
									power_off_mask, 0x00);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,7 +547,7 @@ static const struct ak4642_drvdata ak4648_drvdata = {
 | 
				
			||||||
	.extended_frequencies = 1,
 | 
						.extended_frequencies = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct of_device_id ak4642_of_match[];
 | 
					static const struct of_device_id ak4642_of_match[];
 | 
				
			||||||
static int ak4642_i2c_probe(struct i2c_client *i2c,
 | 
					static int ak4642_i2c_probe(struct i2c_client *i2c,
 | 
				
			||||||
			    const struct i2c_device_id *id)
 | 
								    const struct i2c_device_id *id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -593,7 +593,7 @@ static int ak4642_i2c_remove(struct i2c_client *client)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct of_device_id ak4642_of_match[] = {
 | 
					static const struct of_device_id ak4642_of_match[] = {
 | 
				
			||||||
	{ .compatible = "asahi-kasei,ak4642",	.data = &ak4642_drvdata},
 | 
						{ .compatible = "asahi-kasei,ak4642",	.data = &ak4642_drvdata},
 | 
				
			||||||
	{ .compatible = "asahi-kasei,ak4643",	.data = &ak4643_drvdata},
 | 
						{ .compatible = "asahi-kasei,ak4643",	.data = &ak4643_drvdata},
 | 
				
			||||||
	{ .compatible = "asahi-kasei,ak4648",	.data = &ak4648_drvdata},
 | 
						{ .compatible = "asahi-kasei,ak4648",	.data = &ak4648_drvdata},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,12 +14,18 @@
 | 
				
			||||||
#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 <sound/soc.h>
 | 
					#include <sound/soc.h>
 | 
				
			||||||
#include <sound/pcm.h>
 | 
					#include <sound/pcm.h>
 | 
				
			||||||
#include <sound/initval.h>
 | 
					#include <sound/initval.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const supply_names[] = {
 | 
				
			||||||
 | 
						"va", "vd"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ak5386_priv {
 | 
					struct ak5386_priv {
 | 
				
			||||||
	int reset_gpio;
 | 
						int reset_gpio;
 | 
				
			||||||
 | 
						struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct snd_soc_dapm_widget ak5386_dapm_widgets[] = {
 | 
					static const struct snd_soc_dapm_widget ak5386_dapm_widgets[] = {
 | 
				
			||||||
| 
						 | 
					@ -32,7 +38,42 @@ static const struct snd_soc_dapm_route ak5386_dapm_routes[] = {
 | 
				
			||||||
	{ "Capture", NULL, "AINR" },
 | 
						{ "Capture", NULL, "AINR" },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ak5386_soc_probe(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ak5386_soc_remove(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PM
 | 
				
			||||||
 | 
					static int ak5386_soc_suspend(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int ak5386_soc_resume(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						return regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define ak5386_soc_suspend	NULL
 | 
				
			||||||
 | 
					#define ak5386_soc_resume	NULL
 | 
				
			||||||
 | 
					#endif /* CONFIG_PM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct snd_soc_codec_driver soc_codec_ak5386 = {
 | 
					static struct snd_soc_codec_driver soc_codec_ak5386 = {
 | 
				
			||||||
 | 
						.probe = ak5386_soc_probe,
 | 
				
			||||||
 | 
						.remove = ak5386_soc_remove,
 | 
				
			||||||
 | 
						.suspend = ak5386_soc_suspend,
 | 
				
			||||||
 | 
						.resume = ak5386_soc_resume,
 | 
				
			||||||
	.dapm_widgets = ak5386_dapm_widgets,
 | 
						.dapm_widgets = ak5386_dapm_widgets,
 | 
				
			||||||
	.num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets),
 | 
						.num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets),
 | 
				
			||||||
	.dapm_routes = ak5386_dapm_routes,
 | 
						.dapm_routes = ak5386_dapm_routes,
 | 
				
			||||||
| 
						 | 
					@ -122,6 +163,7 @@ static int ak5386_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct device *dev = &pdev->dev;
 | 
						struct device *dev = &pdev->dev;
 | 
				
			||||||
	struct ak5386_priv *priv;
 | 
						struct ak5386_priv *priv;
 | 
				
			||||||
 | 
						int ret, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 | 
						priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 | 
				
			||||||
	if (!priv)
 | 
						if (!priv)
 | 
				
			||||||
| 
						 | 
					@ -130,6 +172,14 @@ static int ak5386_probe(struct platform_device *pdev)
 | 
				
			||||||
	priv->reset_gpio = -EINVAL;
 | 
						priv->reset_gpio = -EINVAL;
 | 
				
			||||||
	dev_set_drvdata(dev, priv);
 | 
						dev_set_drvdata(dev, priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 | 
				
			||||||
 | 
							priv->supplies[i].supply = supply_names[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies),
 | 
				
			||||||
 | 
									      priv->supplies);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (of_match_device(of_match_ptr(ak5386_dt_ids), dev))
 | 
						if (of_match_device(of_match_ptr(ak5386_dt_ids), dev))
 | 
				
			||||||
		priv->reset_gpio = of_get_named_gpio(dev->of_node,
 | 
							priv->reset_gpio = of_get_named_gpio(dev->of_node,
 | 
				
			||||||
						      "reset-gpio", 0);
 | 
											      "reset-gpio", 0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,6 +243,31 @@ int arizona_init_spk(struct snd_soc_codec *codec)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(arizona_init_spk);
 | 
					EXPORT_SYMBOL_GPL(arizona_init_spk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_dapm_route arizona_mono_routes[] = {
 | 
				
			||||||
 | 
						{ "OUT1R", NULL, "OUT1L" },
 | 
				
			||||||
 | 
						{ "OUT2R", NULL, "OUT2L" },
 | 
				
			||||||
 | 
						{ "OUT3R", NULL, "OUT3L" },
 | 
				
			||||||
 | 
						{ "OUT4R", NULL, "OUT4L" },
 | 
				
			||||||
 | 
						{ "OUT5R", NULL, "OUT5L" },
 | 
				
			||||||
 | 
						{ "OUT6R", NULL, "OUT6L" },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int arizona_init_mono(struct snd_soc_codec *codec)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
 | 
				
			||||||
 | 
							if (arizona->pdata.out_mono[i])
 | 
				
			||||||
 | 
								snd_soc_dapm_add_routes(&codec->dapm,
 | 
				
			||||||
 | 
											&arizona_mono_routes[i], 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					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 arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
| 
						 | 
					@ -1127,6 +1152,31 @@ static int arizona_startup(struct snd_pcm_substream *substream,
 | 
				
			||||||
					  constraint);
 | 
										  constraint);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
										unsigned int rate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						struct reg_default dac_comp[] = {
 | 
				
			||||||
 | 
							{ 0x80, 0x3 },
 | 
				
			||||||
 | 
							{ ARIZONA_DAC_COMP_1, 0 },
 | 
				
			||||||
 | 
							{ ARIZONA_DAC_COMP_2, 0 },
 | 
				
			||||||
 | 
							{ 0x80, 0x0 },
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_lock(&codec->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dac_comp[1].def = arizona->dac_comp_coeff;
 | 
				
			||||||
 | 
						if (rate >= 176400)
 | 
				
			||||||
 | 
							dac_comp[2].def = arizona->dac_comp_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_unlock(&codec->mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regmap_multi_reg_write(arizona->regmap,
 | 
				
			||||||
 | 
								       dac_comp,
 | 
				
			||||||
 | 
								       ARRAY_SIZE(dac_comp));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
					static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
				
			||||||
				  struct snd_pcm_hw_params *params,
 | 
									  struct snd_pcm_hw_params *params,
 | 
				
			||||||
				  struct snd_soc_dai *dai)
 | 
									  struct snd_soc_dai *dai)
 | 
				
			||||||
| 
						 | 
					@ -1153,6 +1203,15 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (dai_priv->clk) {
 | 
						switch (dai_priv->clk) {
 | 
				
			||||||
	case ARIZONA_CLK_SYSCLK:
 | 
						case ARIZONA_CLK_SYSCLK:
 | 
				
			||||||
 | 
							switch (priv->arizona->type) {
 | 
				
			||||||
 | 
							case WM5102:
 | 
				
			||||||
 | 
								arizona_wm5102_set_dac_comp(codec,
 | 
				
			||||||
 | 
											    params_rate(params));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
 | 
							snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
 | 
				
			||||||
				    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
 | 
									    ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
 | 
				
			||||||
		if (base)
 | 
							if (base)
 | 
				
			||||||
| 
						 | 
					@ -1175,6 +1234,27 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool arizona_aif_cfg_changed(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
									    int base, int bclk, int lrclk, int frame)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = snd_soc_read(codec, base + ARIZONA_AIF_BCLK_CTRL);
 | 
				
			||||||
 | 
						if (bclk != (val & ARIZONA_AIF1_BCLK_FREQ_MASK))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = snd_soc_read(codec, base + ARIZONA_AIF_TX_BCLK_RATE);
 | 
				
			||||||
 | 
						if (lrclk != (val & ARIZONA_AIF1TX_BCPF_MASK))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = snd_soc_read(codec, base + ARIZONA_AIF_FRAME_CTRL_1);
 | 
				
			||||||
 | 
						if (frame != (val & (ARIZONA_AIF1TX_WL_MASK |
 | 
				
			||||||
 | 
								     ARIZONA_AIF1TX_SLOT_LEN_MASK)))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int arizona_hw_params(struct snd_pcm_substream *substream,
 | 
					static int arizona_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
			     struct snd_pcm_hw_params *params,
 | 
								     struct snd_pcm_hw_params *params,
 | 
				
			||||||
			     struct snd_soc_dai *dai)
 | 
								     struct snd_soc_dai *dai)
 | 
				
			||||||
| 
						 | 
					@ -1185,26 +1265,40 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	int base = dai->driver->base;
 | 
						int base = dai->driver->base;
 | 
				
			||||||
	const int *rates;
 | 
						const int *rates;
 | 
				
			||||||
	int i, ret, val;
 | 
						int i, ret, val;
 | 
				
			||||||
 | 
						int channels = params_channels(params);
 | 
				
			||||||
	int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
 | 
						int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
 | 
				
			||||||
 | 
						int tdm_width = arizona->tdm_width[dai->id - 1];
 | 
				
			||||||
 | 
						int tdm_slots = arizona->tdm_slots[dai->id - 1];
 | 
				
			||||||
	int bclk, lrclk, wl, frame, bclk_target;
 | 
						int bclk, lrclk, wl, frame, bclk_target;
 | 
				
			||||||
 | 
						bool reconfig;
 | 
				
			||||||
 | 
						unsigned int aif_tx_state, aif_rx_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (params_rate(params) % 8000)
 | 
						if (params_rate(params) % 8000)
 | 
				
			||||||
		rates = &arizona_44k1_bclk_rates[0];
 | 
							rates = &arizona_44k1_bclk_rates[0];
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		rates = &arizona_48k_bclk_rates[0];
 | 
							rates = &arizona_48k_bclk_rates[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bclk_target = snd_soc_params_to_bclk(params);
 | 
						if (tdm_slots) {
 | 
				
			||||||
	if (chan_limit && chan_limit < params_channels(params)) {
 | 
							arizona_aif_dbg(dai, "Configuring for %d %d bit TDM slots\n",
 | 
				
			||||||
 | 
									tdm_slots, tdm_width);
 | 
				
			||||||
 | 
							bclk_target = tdm_slots * tdm_width * params_rate(params);
 | 
				
			||||||
 | 
							channels = tdm_slots;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							bclk_target = snd_soc_params_to_bclk(params);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (chan_limit && chan_limit < channels) {
 | 
				
			||||||
		arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
 | 
							arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
 | 
				
			||||||
		bclk_target /= params_channels(params);
 | 
							bclk_target /= channels;
 | 
				
			||||||
		bclk_target *= chan_limit;
 | 
							bclk_target *= chan_limit;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Force stereo for I2S mode */
 | 
						/* Force multiple of 2 channels for I2S mode */
 | 
				
			||||||
	val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
 | 
						val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT);
 | 
				
			||||||
	if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) {
 | 
						if ((channels & 1) && (val & ARIZONA_AIF1_FMT_MASK)) {
 | 
				
			||||||
		arizona_aif_dbg(dai, "Forcing stereo mode\n");
 | 
							arizona_aif_dbg(dai, "Forcing stereo mode\n");
 | 
				
			||||||
		bclk_target *= 2;
 | 
							bclk_target /= channels;
 | 
				
			||||||
 | 
							bclk_target *= channels + 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
 | 
						for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
 | 
				
			||||||
| 
						 | 
					@ -1228,28 +1322,56 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
	wl = snd_pcm_format_width(params_format(params));
 | 
						wl = snd_pcm_format_width(params_format(params));
 | 
				
			||||||
	frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
 | 
						frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reconfig = arizona_aif_cfg_changed(codec, base, bclk, lrclk, frame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (reconfig) {
 | 
				
			||||||
 | 
							/* Save AIF TX/RX state */
 | 
				
			||||||
 | 
							aif_tx_state = snd_soc_read(codec,
 | 
				
			||||||
 | 
										    base + ARIZONA_AIF_TX_ENABLES);
 | 
				
			||||||
 | 
							aif_rx_state = snd_soc_read(codec,
 | 
				
			||||||
 | 
										    base + ARIZONA_AIF_RX_ENABLES);
 | 
				
			||||||
 | 
							/* Disable AIF TX/RX before reconfiguring it */
 | 
				
			||||||
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
 | 
									    base + ARIZONA_AIF_TX_ENABLES, 0xff, 0x0);
 | 
				
			||||||
 | 
							regmap_update_bits(arizona->regmap,
 | 
				
			||||||
 | 
									    base + ARIZONA_AIF_RX_ENABLES, 0xff, 0x0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = arizona_hw_params_rate(substream, params, dai);
 | 
						ret = arizona_hw_params_rate(substream, params, dai);
 | 
				
			||||||
	if (ret != 0)
 | 
						if (ret != 0)
 | 
				
			||||||
		return ret;
 | 
							goto restore_aif;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap,
 | 
						if (reconfig) {
 | 
				
			||||||
				 base + ARIZONA_AIF_BCLK_CTRL,
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
				 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
 | 
										 base + ARIZONA_AIF_BCLK_CTRL,
 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap,
 | 
										 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
 | 
				
			||||||
				 base + ARIZONA_AIF_TX_BCLK_RATE,
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
				 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
 | 
										 base + ARIZONA_AIF_TX_BCLK_RATE,
 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap,
 | 
										 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
 | 
				
			||||||
				 base + ARIZONA_AIF_RX_BCLK_RATE,
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
				 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
 | 
										 base + ARIZONA_AIF_RX_BCLK_RATE,
 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap,
 | 
										 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
 | 
				
			||||||
				 base + ARIZONA_AIF_FRAME_CTRL_1,
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
				 ARIZONA_AIF1TX_WL_MASK |
 | 
										 base + ARIZONA_AIF_FRAME_CTRL_1,
 | 
				
			||||||
				 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
 | 
										 ARIZONA_AIF1TX_WL_MASK |
 | 
				
			||||||
	regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2,
 | 
										 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
 | 
				
			||||||
			   ARIZONA_AIF1RX_WL_MASK |
 | 
							regmap_update_bits(arizona->regmap,
 | 
				
			||||||
			   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
 | 
									   base + ARIZONA_AIF_FRAME_CTRL_2,
 | 
				
			||||||
 | 
									   ARIZONA_AIF1RX_WL_MASK |
 | 
				
			||||||
 | 
									   ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
					restore_aif:
 | 
				
			||||||
 | 
						if (reconfig) {
 | 
				
			||||||
 | 
							/* Restore AIF TX/RX state */
 | 
				
			||||||
 | 
							regmap_update_bits_async(arizona->regmap,
 | 
				
			||||||
 | 
										 base + ARIZONA_AIF_TX_ENABLES,
 | 
				
			||||||
 | 
										 0xff, aif_tx_state);
 | 
				
			||||||
 | 
							regmap_update_bits(arizona->regmap,
 | 
				
			||||||
 | 
									   base + ARIZONA_AIF_RX_ENABLES,
 | 
				
			||||||
 | 
									   0xff, aif_rx_state);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *arizona_dai_clk_str(int clk_id)
 | 
					static const char *arizona_dai_clk_str(int clk_id)
 | 
				
			||||||
| 
						 | 
					@ -1324,9 +1446,63 @@ static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
 | 
				
			||||||
				   ARIZONA_AIF1_TRI, reg);
 | 
									   ARIZONA_AIF1_TRI, reg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void arizona_set_channels_to_mask(struct snd_soc_dai *dai,
 | 
				
			||||||
 | 
										 unsigned int base,
 | 
				
			||||||
 | 
										 int channels, unsigned int mask)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						int slot, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < channels; ++i) {
 | 
				
			||||||
 | 
							slot = ffs(mask) - 1;
 | 
				
			||||||
 | 
							if (slot < 0)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							regmap_write(arizona->regmap, base + i, slot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mask &= ~(1 << slot);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mask)
 | 
				
			||||||
 | 
							arizona_aif_warn(dai, "Too many channels in TDM mask\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int arizona_set_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 arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						struct arizona *arizona = priv->arizona;
 | 
				
			||||||
 | 
						int base = dai->driver->base;
 | 
				
			||||||
 | 
						int rx_max_chan = dai->driver->playback.channels_max;
 | 
				
			||||||
 | 
						int tx_max_chan = dai->driver->capture.channels_max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Only support TDM for the physical AIFs */
 | 
				
			||||||
 | 
						if (dai->id > ARIZONA_MAX_AIF)
 | 
				
			||||||
 | 
							return -ENOTSUPP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (slots == 0) {
 | 
				
			||||||
 | 
							tx_mask = (1 << tx_max_chan) - 1;
 | 
				
			||||||
 | 
							rx_mask = (1 << rx_max_chan) - 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_3,
 | 
				
			||||||
 | 
									     tx_max_chan, tx_mask);
 | 
				
			||||||
 | 
						arizona_set_channels_to_mask(dai, base + ARIZONA_AIF_FRAME_CTRL_11,
 | 
				
			||||||
 | 
									     rx_max_chan, rx_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arizona->tdm_width[dai->id - 1] = slot_width;
 | 
				
			||||||
 | 
						arizona->tdm_slots[dai->id - 1] = slots;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct snd_soc_dai_ops arizona_dai_ops = {
 | 
					const struct snd_soc_dai_ops arizona_dai_ops = {
 | 
				
			||||||
	.startup = arizona_startup,
 | 
						.startup = arizona_startup,
 | 
				
			||||||
	.set_fmt = arizona_set_fmt,
 | 
						.set_fmt = arizona_set_fmt,
 | 
				
			||||||
 | 
						.set_tdm_slot = arizona_set_tdm_slot,
 | 
				
			||||||
	.hw_params = arizona_hw_params,
 | 
						.hw_params = arizona_hw_params,
 | 
				
			||||||
	.set_sysclk = arizona_dai_set_sysclk,
 | 
						.set_sysclk = arizona_dai_set_sysclk,
 | 
				
			||||||
	.set_tristate = arizona_set_tristate,
 | 
						.set_tristate = arizona_set_tristate,
 | 
				
			||||||
| 
						 | 
					@ -1400,6 +1576,12 @@ static int arizona_validate_fll(struct arizona_fll *fll,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned int Fvco_min;
 | 
						unsigned int Fvco_min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fll->fout && Fout != fll->fout) {
 | 
				
			||||||
 | 
							arizona_fll_err(fll,
 | 
				
			||||||
 | 
									"Can't change output on active FLL\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
 | 
						if (Fref / ARIZONA_FLL_MAX_REFDIV > ARIZONA_FLL_MAX_FREF) {
 | 
				
			||||||
		arizona_fll_err(fll,
 | 
							arizona_fll_err(fll,
 | 
				
			||||||
				"Can't scale %dMHz in to <=13.5MHz\n",
 | 
									"Can't scale %dMHz in to <=13.5MHz\n",
 | 
				
			||||||
| 
						 | 
					@ -1478,6 +1660,10 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
 | 
				
			||||||
	while (div <= ARIZONA_FLL_MAX_REFDIV) {
 | 
						while (div <= ARIZONA_FLL_MAX_REFDIV) {
 | 
				
			||||||
		for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
 | 
							for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
 | 
				
			||||||
		     ratio++) {
 | 
							     ratio++) {
 | 
				
			||||||
 | 
								if ((ARIZONA_FLL_VCO_CORNER / 2) /
 | 
				
			||||||
 | 
								    (fll->vco_mult * ratio) < Fref)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (target % (ratio * Fref)) {
 | 
								if (target % (ratio * Fref)) {
 | 
				
			||||||
				cfg->refdiv = refdiv;
 | 
									cfg->refdiv = refdiv;
 | 
				
			||||||
				cfg->fratio = ratio - 1;
 | 
									cfg->fratio = ratio - 1;
 | 
				
			||||||
| 
						 | 
					@ -1485,11 +1671,7 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (ratio = init_ratio - 1; ratio >= 0; ratio--) {
 | 
							for (ratio = init_ratio - 1; ratio > 0; ratio--) {
 | 
				
			||||||
			if (ARIZONA_FLL_VCO_CORNER / (fll->vco_mult * ratio) <
 | 
					 | 
				
			||||||
			    Fref)
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (target % (ratio * Fref)) {
 | 
								if (target % (ratio * Fref)) {
 | 
				
			||||||
				cfg->refdiv = refdiv;
 | 
									cfg->refdiv = refdiv;
 | 
				
			||||||
				cfg->fratio = ratio - 1;
 | 
									cfg->fratio = ratio - 1;
 | 
				
			||||||
| 
						 | 
					@ -1616,7 +1798,7 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
 | 
				
			||||||
				 ARIZONA_FLL1_CTRL_UPD | cfg->n);
 | 
									 ARIZONA_FLL1_CTRL_UPD | cfg->n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool arizona_is_enabled_fll(struct arizona_fll *fll)
 | 
					static int arizona_is_enabled_fll(struct arizona_fll *fll)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct arizona *arizona = fll->arizona;
 | 
						struct arizona *arizona = fll->arizona;
 | 
				
			||||||
	unsigned int reg;
 | 
						unsigned int reg;
 | 
				
			||||||
| 
						 | 
					@ -1632,13 +1814,26 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll)
 | 
				
			||||||
	return reg & ARIZONA_FLL1_ENA;
 | 
						return reg & ARIZONA_FLL1_ENA;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void arizona_enable_fll(struct arizona_fll *fll)
 | 
					static int arizona_enable_fll(struct arizona_fll *fll)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct arizona *arizona = fll->arizona;
 | 
						struct arizona *arizona = fll->arizona;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	bool use_sync = false;
 | 
						bool use_sync = false;
 | 
				
			||||||
 | 
						int already_enabled = arizona_is_enabled_fll(fll);
 | 
				
			||||||
	struct arizona_fll_cfg cfg;
 | 
						struct arizona_fll_cfg cfg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (already_enabled < 0)
 | 
				
			||||||
 | 
							return already_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (already_enabled) {
 | 
				
			||||||
 | 
							/* Facilitate smooth refclk across the transition */
 | 
				
			||||||
 | 
							regmap_update_bits_async(fll->arizona->regmap, fll->base + 0x7,
 | 
				
			||||||
 | 
										 ARIZONA_FLL1_GAIN_MASK, 0);
 | 
				
			||||||
 | 
							regmap_update_bits_async(fll->arizona->regmap, fll->base + 1,
 | 
				
			||||||
 | 
										 ARIZONA_FLL1_FREERUN,
 | 
				
			||||||
 | 
										 ARIZONA_FLL1_FREERUN);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If we have both REFCLK and SYNCCLK then enable both,
 | 
						 * If we have both REFCLK and SYNCCLK then enable both,
 | 
				
			||||||
	 * otherwise apply the SYNCCLK settings to REFCLK.
 | 
						 * otherwise apply the SYNCCLK settings to REFCLK.
 | 
				
			||||||
| 
						 | 
					@ -1666,7 +1861,7 @@ static void arizona_enable_fll(struct arizona_fll *fll)
 | 
				
			||||||
					 ARIZONA_FLL1_SYNC_ENA, 0);
 | 
										 ARIZONA_FLL1_SYNC_ENA, 0);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		arizona_fll_err(fll, "No clocks provided\n");
 | 
							arizona_fll_err(fll, "No clocks provided\n");
 | 
				
			||||||
		return;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -1681,14 +1876,12 @@ static void arizona_enable_fll(struct arizona_fll *fll)
 | 
				
			||||||
					 ARIZONA_FLL1_SYNC_BW,
 | 
										 ARIZONA_FLL1_SYNC_BW,
 | 
				
			||||||
					 ARIZONA_FLL1_SYNC_BW);
 | 
										 ARIZONA_FLL1_SYNC_BW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!arizona_is_enabled_fll(fll))
 | 
						if (!already_enabled)
 | 
				
			||||||
		pm_runtime_get(arizona->dev);
 | 
							pm_runtime_get(arizona->dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Clear any pending completions */
 | 
						/* Clear any pending completions */
 | 
				
			||||||
	try_wait_for_completion(&fll->ok);
 | 
						try_wait_for_completion(&fll->ok);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap, fll->base + 1,
 | 
					 | 
				
			||||||
				 ARIZONA_FLL1_FREERUN, 0);
 | 
					 | 
				
			||||||
	regmap_update_bits_async(arizona->regmap, fll->base + 1,
 | 
						regmap_update_bits_async(arizona->regmap, fll->base + 1,
 | 
				
			||||||
				 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
 | 
									 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
 | 
				
			||||||
	if (use_sync)
 | 
						if (use_sync)
 | 
				
			||||||
| 
						 | 
					@ -1696,10 +1889,16 @@ static void arizona_enable_fll(struct arizona_fll *fll)
 | 
				
			||||||
					 ARIZONA_FLL1_SYNC_ENA,
 | 
										 ARIZONA_FLL1_SYNC_ENA,
 | 
				
			||||||
					 ARIZONA_FLL1_SYNC_ENA);
 | 
										 ARIZONA_FLL1_SYNC_ENA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (already_enabled)
 | 
				
			||||||
 | 
							regmap_update_bits_async(arizona->regmap, fll->base + 1,
 | 
				
			||||||
 | 
										 ARIZONA_FLL1_FREERUN, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = wait_for_completion_timeout(&fll->ok,
 | 
						ret = wait_for_completion_timeout(&fll->ok,
 | 
				
			||||||
					  msecs_to_jiffies(250));
 | 
										  msecs_to_jiffies(250));
 | 
				
			||||||
	if (ret == 0)
 | 
						if (ret == 0)
 | 
				
			||||||
		arizona_fll_warn(fll, "Timed out waiting for lock\n");
 | 
							arizona_fll_warn(fll, "Timed out waiting for lock\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void arizona_disable_fll(struct arizona_fll *fll)
 | 
					static void arizona_disable_fll(struct arizona_fll *fll)
 | 
				
			||||||
| 
						 | 
					@ -1713,6 +1912,8 @@ static void arizona_disable_fll(struct arizona_fll *fll)
 | 
				
			||||||
				 ARIZONA_FLL1_ENA, 0, &change);
 | 
									 ARIZONA_FLL1_ENA, 0, &change);
 | 
				
			||||||
	regmap_update_bits(arizona->regmap, fll->base + 0x11,
 | 
						regmap_update_bits(arizona->regmap, fll->base + 0x11,
 | 
				
			||||||
			   ARIZONA_FLL1_SYNC_ENA, 0);
 | 
								   ARIZONA_FLL1_SYNC_ENA, 0);
 | 
				
			||||||
 | 
						regmap_update_bits_async(arizona->regmap, fll->base + 1,
 | 
				
			||||||
 | 
									 ARIZONA_FLL1_FREERUN, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (change)
 | 
						if (change)
 | 
				
			||||||
		pm_runtime_put_autosuspend(arizona->dev);
 | 
							pm_runtime_put_autosuspend(arizona->dev);
 | 
				
			||||||
| 
						 | 
					@ -1721,7 +1922,7 @@ static void arizona_disable_fll(struct arizona_fll *fll)
 | 
				
			||||||
int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 | 
					int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 | 
				
			||||||
			   unsigned int Fref, unsigned int Fout)
 | 
								   unsigned int Fref, unsigned int Fout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fll->ref_src == source && fll->ref_freq == Fref)
 | 
						if (fll->ref_src == source && fll->ref_freq == Fref)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -1736,17 +1937,17 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
 | 
				
			||||||
	fll->ref_freq = Fref;
 | 
						fll->ref_freq = Fref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fll->fout && Fref > 0) {
 | 
						if (fll->fout && Fref > 0) {
 | 
				
			||||||
		arizona_enable_fll(fll);
 | 
							ret = arizona_enable_fll(fll);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
 | 
					EXPORT_SYMBOL_GPL(arizona_set_fll_refclk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int arizona_set_fll(struct arizona_fll *fll, int source,
 | 
					int arizona_set_fll(struct arizona_fll *fll, int source,
 | 
				
			||||||
		    unsigned int Fref, unsigned int Fout)
 | 
							    unsigned int Fref, unsigned int Fout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fll->sync_src == source &&
 | 
						if (fll->sync_src == source &&
 | 
				
			||||||
	    fll->sync_freq == Fref && fll->fout == Fout)
 | 
						    fll->sync_freq == Fref && fll->fout == Fout)
 | 
				
			||||||
| 
						 | 
					@ -1768,13 +1969,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
 | 
				
			||||||
	fll->sync_freq = Fref;
 | 
						fll->sync_freq = Fref;
 | 
				
			||||||
	fll->fout = Fout;
 | 
						fll->fout = Fout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (Fout) {
 | 
						if (Fout)
 | 
				
			||||||
		arizona_enable_fll(fll);
 | 
							ret = arizona_enable_fll(fll);
 | 
				
			||||||
	} else {
 | 
						else
 | 
				
			||||||
		arizona_disable_fll(fll);
 | 
							arizona_disable_fll(fll);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(arizona_set_fll);
 | 
					EXPORT_SYMBOL_GPL(arizona_set_fll);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,6 +249,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int arizona_init_spk(struct snd_soc_codec *codec);
 | 
					extern int arizona_init_spk(struct snd_soc_codec *codec);
 | 
				
			||||||
extern int arizona_init_gpio(struct snd_soc_codec *codec);
 | 
					extern int arizona_init_gpio(struct snd_soc_codec *codec);
 | 
				
			||||||
 | 
					extern int arizona_init_mono(struct snd_soc_codec *codec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int arizona_init_dai(struct arizona_priv *priv, int dai);
 | 
					extern int arizona_init_dai(struct arizona_priv *priv, int dai);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										682
									
								
								sound/soc/codecs/cs4265.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										682
									
								
								sound/soc/codecs/cs4265.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,682 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * cs4265.c -- CS4265 ALSA SoC audio driver
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2014 Cirrus Logic, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Author: Paul Handrigan <paul.handrigan@cirrus.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/moduleparam.h>
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/gpio/consumer.h>
 | 
				
			||||||
 | 
					#include <linux/init.h>
 | 
				
			||||||
 | 
					#include <linux/delay.h>
 | 
				
			||||||
 | 
					#include <linux/i2c.h>
 | 
				
			||||||
 | 
					#include <linux/input.h>
 | 
				
			||||||
 | 
					#include <linux/regmap.h>
 | 
				
			||||||
 | 
					#include <linux/slab.h>
 | 
				
			||||||
 | 
					#include <linux/platform_device.h>
 | 
				
			||||||
 | 
					#include <sound/core.h>
 | 
				
			||||||
 | 
					#include <sound/pcm.h>
 | 
				
			||||||
 | 
					#include <sound/pcm_params.h>
 | 
				
			||||||
 | 
					#include <sound/soc.h>
 | 
				
			||||||
 | 
					#include <sound/soc-dapm.h>
 | 
				
			||||||
 | 
					#include <sound/initval.h>
 | 
				
			||||||
 | 
					#include <sound/tlv.h>
 | 
				
			||||||
 | 
					#include "cs4265.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cs4265_private {
 | 
				
			||||||
 | 
						struct device *dev;
 | 
				
			||||||
 | 
						struct regmap *regmap;
 | 
				
			||||||
 | 
						struct gpio_desc *reset_gpio;
 | 
				
			||||||
 | 
						u8 format;
 | 
				
			||||||
 | 
						u32 sysclk;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct reg_default cs4265_reg_defaults[] = {
 | 
				
			||||||
 | 
						{ CS4265_PWRCTL, 0x0F },
 | 
				
			||||||
 | 
						{ CS4265_DAC_CTL, 0x08 },
 | 
				
			||||||
 | 
						{ CS4265_ADC_CTL, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_MCLK_FREQ, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_SIG_SEL, 0x40 },
 | 
				
			||||||
 | 
						{ CS4265_CHB_PGA_CTL, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_CHA_PGA_CTL, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_ADC_CTL2, 0x19 },
 | 
				
			||||||
 | 
						{ CS4265_DAC_CHA_VOL, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_DAC_CHB_VOL, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_DAC_CTL2, 0xC0 },
 | 
				
			||||||
 | 
						{ CS4265_SPDIF_CTL1, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_SPDIF_CTL2, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_INT_MASK, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_STATUS_MODE_MSB, 0x00 },
 | 
				
			||||||
 | 
						{ CS4265_STATUS_MODE_LSB, 0x00 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool cs4265_readable_register(struct device *dev, unsigned int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (reg) {
 | 
				
			||||||
 | 
						case CS4265_PWRCTL:
 | 
				
			||||||
 | 
						case CS4265_DAC_CTL:
 | 
				
			||||||
 | 
						case CS4265_ADC_CTL:
 | 
				
			||||||
 | 
						case CS4265_MCLK_FREQ:
 | 
				
			||||||
 | 
						case CS4265_SIG_SEL:
 | 
				
			||||||
 | 
						case CS4265_CHB_PGA_CTL:
 | 
				
			||||||
 | 
						case CS4265_CHA_PGA_CTL:
 | 
				
			||||||
 | 
						case CS4265_ADC_CTL2:
 | 
				
			||||||
 | 
						case CS4265_DAC_CHA_VOL:
 | 
				
			||||||
 | 
						case CS4265_DAC_CHB_VOL:
 | 
				
			||||||
 | 
						case CS4265_DAC_CTL2:
 | 
				
			||||||
 | 
						case CS4265_SPDIF_CTL1:
 | 
				
			||||||
 | 
						case CS4265_SPDIF_CTL2:
 | 
				
			||||||
 | 
						case CS4265_INT_MASK:
 | 
				
			||||||
 | 
						case CS4265_STATUS_MODE_MSB:
 | 
				
			||||||
 | 
						case CS4265_STATUS_MODE_LSB:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool cs4265_volatile_register(struct device *dev, unsigned int reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (reg) {
 | 
				
			||||||
 | 
						case CS4265_INT_STATUS:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static DECLARE_TLV_DB_SCALE(pga_tlv, -1200, 50, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const digital_input_mux_text[] = {
 | 
				
			||||||
 | 
						"SDIN1", "SDIN2"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SOC_ENUM_SINGLE_DECL(digital_input_mux_enum, CS4265_SIG_SEL, 7,
 | 
				
			||||||
 | 
							digital_input_mux_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new digital_input_mux =
 | 
				
			||||||
 | 
						SOC_DAPM_ENUM("Digital Input Mux", digital_input_mux_enum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const mic_linein_text[] = {
 | 
				
			||||||
 | 
						"MIC", "LINEIN"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SOC_ENUM_SINGLE_DECL(mic_linein_enum, CS4265_ADC_CTL2, 0,
 | 
				
			||||||
 | 
							mic_linein_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const cam_mode_text[] = {
 | 
				
			||||||
 | 
						"One Byte", "Two Byte"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SOC_ENUM_SINGLE_DECL(cam_mode_enum, CS4265_SPDIF_CTL1, 5,
 | 
				
			||||||
 | 
							cam_mode_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const cam_mono_stereo_text[] = {
 | 
				
			||||||
 | 
						"Stereo", "Mono"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SOC_ENUM_SINGLE_DECL(spdif_mono_stereo_enum, CS4265_SPDIF_CTL2, 2,
 | 
				
			||||||
 | 
							cam_mono_stereo_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char * const mono_select_text[] = {
 | 
				
			||||||
 | 
						"Channel A", "Channel B"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SOC_ENUM_SINGLE_DECL(spdif_mono_select_enum, CS4265_SPDIF_CTL2, 0,
 | 
				
			||||||
 | 
							mono_select_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new mic_linein_mux =
 | 
				
			||||||
 | 
						SOC_DAPM_ENUM("ADC Input Capture Mux", mic_linein_enum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new loopback_ctl =
 | 
				
			||||||
 | 
						SOC_DAPM_SINGLE("Switch", CS4265_SIG_SEL, 1, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new spdif_switch =
 | 
				
			||||||
 | 
						SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new dac_switch =
 | 
				
			||||||
 | 
						SOC_DAPM_SINGLE("Switch", CS4265_PWRCTL, 1, 1, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_kcontrol_new cs4265_snd_controls[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SOC_DOUBLE_R_SX_TLV("PGA Volume", CS4265_CHA_PGA_CTL,
 | 
				
			||||||
 | 
								      CS4265_CHB_PGA_CTL, 0, 0x28, 0x30, pga_tlv),
 | 
				
			||||||
 | 
						SOC_DOUBLE_R_TLV("DAC Volume", CS4265_DAC_CHA_VOL,
 | 
				
			||||||
 | 
							      CS4265_DAC_CHB_VOL, 0, 0xFF, 1, dac_tlv),
 | 
				
			||||||
 | 
						SOC_SINGLE("De-emp 44.1kHz Switch", CS4265_DAC_CTL, 1,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("DAC INV Switch", CS4265_DAC_CTL2, 5,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("DAC Zero Cross Switch", CS4265_DAC_CTL2, 6,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("DAC Soft Ramp Switch", CS4265_DAC_CTL2, 7,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("ADC HPF Switch", CS4265_ADC_CTL, 1,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("ADC Zero Cross Switch", CS4265_ADC_CTL2, 3,
 | 
				
			||||||
 | 
									1, 1),
 | 
				
			||||||
 | 
						SOC_SINGLE("ADC Soft Ramp Switch", CS4265_ADC_CTL2, 7,
 | 
				
			||||||
 | 
									1, 0),
 | 
				
			||||||
 | 
						SOC_SINGLE("E to F Buffer Disable Switch", CS4265_SPDIF_CTL1,
 | 
				
			||||||
 | 
									6, 1, 0),
 | 
				
			||||||
 | 
						SOC_ENUM("C Data Access", cam_mode_enum),
 | 
				
			||||||
 | 
						SOC_SINGLE("Validity Bit Control Switch", CS4265_SPDIF_CTL2,
 | 
				
			||||||
 | 
									3, 1, 0),
 | 
				
			||||||
 | 
						SOC_ENUM("SPDIF Mono/Stereo", spdif_mono_stereo_enum),
 | 
				
			||||||
 | 
						SOC_SINGLE("MMTLR Data Switch", 0,
 | 
				
			||||||
 | 
									1, 1, 0),
 | 
				
			||||||
 | 
						SOC_ENUM("Mono Channel Select", spdif_mono_select_enum),
 | 
				
			||||||
 | 
						SND_SOC_BYTES("C Data Buffer", CS4265_C_DATA_BUFF, 24),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_dapm_widget cs4265_dapm_widgets[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_INPUT("LINEINL"),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_INPUT("LINEINR"),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_INPUT("MICL"),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_INPUT("MICR"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_AIF_OUT("DOUT", NULL,  0,
 | 
				
			||||||
 | 
								SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_AIF_OUT("SPDIFOUT", NULL,  0,
 | 
				
			||||||
 | 
								SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_MUX("ADC Mux", SND_SOC_NOPM, 0, 0, &mic_linein_mux),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_ADC("ADC", NULL, CS4265_PWRCTL, 2, 1),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_PGA("Pre-amp MIC", CS4265_PWRCTL, 3,
 | 
				
			||||||
 | 
								1, NULL, 0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM,
 | 
				
			||||||
 | 
								 0, 0, &digital_input_mux),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_MIXER("SDIN1 Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_MIXER("SDIN2 Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_MIXER("SPDIF Transmitter", SND_SOC_NOPM, 0, 0, NULL, 0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_SWITCH("Loopback", SND_SOC_NOPM, 0, 0,
 | 
				
			||||||
 | 
								&loopback_ctl),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_SWITCH("SPDIF", SND_SOC_NOPM, 0, 0,
 | 
				
			||||||
 | 
								&spdif_switch),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_SWITCH("DAC", CS4265_PWRCTL, 1, 1,
 | 
				
			||||||
 | 
								&dac_switch),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_AIF_IN("DIN1", NULL,  0,
 | 
				
			||||||
 | 
								SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_AIF_IN("DIN2", NULL,  0,
 | 
				
			||||||
 | 
								SND_SOC_NOPM, 0, 0),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_AIF_IN("TXIN", NULL,  0,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2, 5, 1),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SND_SOC_DAPM_OUTPUT("LINEOUTL"),
 | 
				
			||||||
 | 
						SND_SOC_DAPM_OUTPUT("LINEOUTR"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_dapm_route cs4265_audio_map[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{"DIN1", NULL, "DAI1 Playback"},
 | 
				
			||||||
 | 
						{"DIN2", NULL, "DAI2 Playback"},
 | 
				
			||||||
 | 
						{"SDIN1 Input Mixer", NULL, "DIN1"},
 | 
				
			||||||
 | 
						{"SDIN2 Input Mixer", NULL, "DIN2"},
 | 
				
			||||||
 | 
						{"Input Mux", "SDIN1", "SDIN1 Input Mixer"},
 | 
				
			||||||
 | 
						{"Input Mux", "SDIN2", "SDIN2 Input Mixer"},
 | 
				
			||||||
 | 
						{"DAC", "Switch", "Input Mux"},
 | 
				
			||||||
 | 
						{"SPDIF", "Switch", "Input Mux"},
 | 
				
			||||||
 | 
						{"LINEOUTL", NULL, "DAC"},
 | 
				
			||||||
 | 
						{"LINEOUTR", NULL, "DAC"},
 | 
				
			||||||
 | 
						{"SPDIFOUT", NULL, "SPDIF"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{"ADC Mux", "LINEIN", "LINEINL"},
 | 
				
			||||||
 | 
						{"ADC Mux", "LINEIN", "LINEINR"},
 | 
				
			||||||
 | 
						{"ADC Mux", "MIC", "MICL"},
 | 
				
			||||||
 | 
						{"ADC Mux", "MIC", "MICR"},
 | 
				
			||||||
 | 
						{"ADC", NULL, "ADC Mux"},
 | 
				
			||||||
 | 
						{"DOUT", NULL, "ADC"},
 | 
				
			||||||
 | 
						{"DAI1 Capture", NULL, "DOUT"},
 | 
				
			||||||
 | 
						{"DAI2 Capture", NULL, "DOUT"},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Loopback */
 | 
				
			||||||
 | 
						{"Loopback", "Switch", "ADC"},
 | 
				
			||||||
 | 
						{"DAC", NULL, "Loopback"},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cs4265_clk_para {
 | 
				
			||||||
 | 
						u32 mclk;
 | 
				
			||||||
 | 
						u32 rate;
 | 
				
			||||||
 | 
						u8 fm_mode; /* values 1, 2, or 4 */
 | 
				
			||||||
 | 
						u8 mclkdiv;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct cs4265_clk_para clk_map_table[] = {
 | 
				
			||||||
 | 
						/*32k*/
 | 
				
			||||||
 | 
						{8192000, 32000, 0, 0},
 | 
				
			||||||
 | 
						{12288000, 32000, 0, 1},
 | 
				
			||||||
 | 
						{16384000, 32000, 0, 2},
 | 
				
			||||||
 | 
						{24576000, 32000, 0, 3},
 | 
				
			||||||
 | 
						{32768000, 32000, 0, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*44.1k*/
 | 
				
			||||||
 | 
						{11289600, 44100, 0, 0},
 | 
				
			||||||
 | 
						{16934400, 44100, 0, 1},
 | 
				
			||||||
 | 
						{22579200, 44100, 0, 2},
 | 
				
			||||||
 | 
						{33868000, 44100, 0, 3},
 | 
				
			||||||
 | 
						{45158400, 44100, 0, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*48k*/
 | 
				
			||||||
 | 
						{12288000, 48000, 0, 0},
 | 
				
			||||||
 | 
						{18432000, 48000, 0, 1},
 | 
				
			||||||
 | 
						{24576000, 48000, 0, 2},
 | 
				
			||||||
 | 
						{36864000, 48000, 0, 3},
 | 
				
			||||||
 | 
						{49152000, 48000, 0, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*64k*/
 | 
				
			||||||
 | 
						{8192000, 64000, 1, 0},
 | 
				
			||||||
 | 
						{1228800, 64000, 1, 1},
 | 
				
			||||||
 | 
						{1693440, 64000, 1, 2},
 | 
				
			||||||
 | 
						{2457600, 64000, 1, 3},
 | 
				
			||||||
 | 
						{3276800, 64000, 1, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 88.2k */
 | 
				
			||||||
 | 
						{11289600, 88200, 1, 0},
 | 
				
			||||||
 | 
						{16934400, 88200, 1, 1},
 | 
				
			||||||
 | 
						{22579200, 88200, 1, 2},
 | 
				
			||||||
 | 
						{33868000, 88200, 1, 3},
 | 
				
			||||||
 | 
						{45158400, 88200, 1, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 96k */
 | 
				
			||||||
 | 
						{12288000, 96000, 1, 0},
 | 
				
			||||||
 | 
						{18432000, 96000, 1, 1},
 | 
				
			||||||
 | 
						{24576000, 96000, 1, 2},
 | 
				
			||||||
 | 
						{36864000, 96000, 1, 3},
 | 
				
			||||||
 | 
						{49152000, 96000, 1, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 128k */
 | 
				
			||||||
 | 
						{8192000, 128000, 2, 0},
 | 
				
			||||||
 | 
						{12288000, 128000, 2, 1},
 | 
				
			||||||
 | 
						{16934400, 128000, 2, 2},
 | 
				
			||||||
 | 
						{24576000, 128000, 2, 3},
 | 
				
			||||||
 | 
						{32768000, 128000, 2, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 176.4k */
 | 
				
			||||||
 | 
						{11289600, 176400, 2, 0},
 | 
				
			||||||
 | 
						{16934400, 176400, 2, 1},
 | 
				
			||||||
 | 
						{22579200, 176400, 2, 2},
 | 
				
			||||||
 | 
						{33868000, 176400, 2, 3},
 | 
				
			||||||
 | 
						{49152000, 176400, 2, 4},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 192k */
 | 
				
			||||||
 | 
						{12288000, 192000, 2, 0},
 | 
				
			||||||
 | 
						{18432000, 192000, 2, 1},
 | 
				
			||||||
 | 
						{24576000, 192000, 2, 2},
 | 
				
			||||||
 | 
						{36864000, 192000, 2, 3},
 | 
				
			||||||
 | 
						{49152000, 192000, 2, 4},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_get_clk_index(int mclk, int rate)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
 | 
				
			||||||
 | 
							if (clk_map_table[i].rate == rate &&
 | 
				
			||||||
 | 
									clk_map_table[i].mclk == mclk)
 | 
				
			||||||
 | 
								return i;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_set_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
 | 
				
			||||||
 | 
								unsigned int freq, int dir)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = codec_dai->codec;
 | 
				
			||||||
 | 
						struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (clk_id != 0) {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "Invalid clk_id %d\n", clk_id);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
 | 
				
			||||||
 | 
							if (clk_map_table[i].mclk == freq) {
 | 
				
			||||||
 | 
								cs4265->sysclk = freq;
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cs4265->sysclk = 0;
 | 
				
			||||||
 | 
						dev_err(codec->dev, "Invalid freq parameter %d\n", freq);
 | 
				
			||||||
 | 
						return -EINVAL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = codec_dai->codec;
 | 
				
			||||||
 | 
						struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						u8 iface = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_CBM_CFM:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
									CS4265_ADC_MASTER,
 | 
				
			||||||
 | 
									CS4265_ADC_MASTER);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_CBS_CFS:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
									CS4265_ADC_MASTER,
 | 
				
			||||||
 | 
									0);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						 /* interface format */
 | 
				
			||||||
 | 
						switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_I2S:
 | 
				
			||||||
 | 
							iface |= SND_SOC_DAIFMT_I2S;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_RIGHT_J:
 | 
				
			||||||
 | 
							iface |= SND_SOC_DAIFMT_RIGHT_J;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_LEFT_J:
 | 
				
			||||||
 | 
							iface |= SND_SOC_DAIFMT_LEFT_J;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cs4265->format = iface;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_digital_mute(struct snd_soc_dai *dai, int mute)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mute) {
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
								CS4265_DAC_CTL_MUTE,
 | 
				
			||||||
 | 
								CS4265_DAC_CTL_MUTE);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2_MUTE,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2_MUTE);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
								CS4265_DAC_CTL_MUTE,
 | 
				
			||||||
 | 
								0);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2_MUTE,
 | 
				
			||||||
 | 
								0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
 | 
				
			||||||
 | 
									     struct snd_pcm_hw_params *params,
 | 
				
			||||||
 | 
									     struct snd_soc_dai *dai)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct snd_soc_codec *codec = dai->codec;
 | 
				
			||||||
 | 
						struct cs4265_private *cs4265 = snd_soc_codec_get_drvdata(codec);
 | 
				
			||||||
 | 
						int index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
 | 
				
			||||||
 | 
							((cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK)
 | 
				
			||||||
 | 
							== SND_SOC_DAIFMT_RIGHT_J))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						index = cs4265_get_clk_index(cs4265->sysclk, params_rate(params));
 | 
				
			||||||
 | 
						if (index >= 0) {
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
								CS4265_ADC_FM, clk_map_table[index].fm_mode);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_MCLK_FREQ,
 | 
				
			||||||
 | 
								CS4265_MCLK_FREQ_MASK,
 | 
				
			||||||
 | 
								clk_map_table[index].mclkdiv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							dev_err(codec->dev, "can't get correct mclk\n");
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (cs4265->format & SND_SOC_DAIFMT_FORMAT_MASK) {
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_I2S:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
								CS4265_DAC_CTL_DIF, (1 << 4));
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
								CS4265_ADC_DIF, (1 << 4));
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2_DIF, (1 << 6));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_RIGHT_J:
 | 
				
			||||||
 | 
							if (params_width(params) == 16) {
 | 
				
			||||||
 | 
								snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
									CS4265_DAC_CTL_DIF, (1 << 5));
 | 
				
			||||||
 | 
								snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
									CS4265_SPDIF_CTL2_DIF, (1 << 7));
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
									CS4265_DAC_CTL_DIF, (3 << 5));
 | 
				
			||||||
 | 
								snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
									CS4265_SPDIF_CTL2_DIF, (1 << 7));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_DAIFMT_LEFT_J:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_DAC_CTL,
 | 
				
			||||||
 | 
								CS4265_DAC_CTL_DIF, 0);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
								CS4265_ADC_DIF, 0);
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_ADC_CTL,
 | 
				
			||||||
 | 
								CS4265_SPDIF_CTL2_DIF, (1 << 6));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_set_bias_level(struct snd_soc_codec *codec,
 | 
				
			||||||
 | 
										enum snd_soc_bias_level level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (level) {
 | 
				
			||||||
 | 
						case SND_SOC_BIAS_ON:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_BIAS_PREPARE:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_PWRCTL,
 | 
				
			||||||
 | 
								CS4265_PWRCTL_PDN, 0);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_BIAS_STANDBY:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_PWRCTL,
 | 
				
			||||||
 | 
								CS4265_PWRCTL_PDN,
 | 
				
			||||||
 | 
								CS4265_PWRCTL_PDN);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SND_SOC_BIAS_OFF:
 | 
				
			||||||
 | 
							snd_soc_update_bits(codec, CS4265_PWRCTL,
 | 
				
			||||||
 | 
								CS4265_PWRCTL_PDN,
 | 
				
			||||||
 | 
								CS4265_PWRCTL_PDN);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						codec->dapm.bias_level = level;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
 | 
				
			||||||
 | 
								SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
 | 
				
			||||||
 | 
								SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
 | 
				
			||||||
 | 
								SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
 | 
				
			||||||
 | 
								SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_dai_ops cs4265_ops = {
 | 
				
			||||||
 | 
						.hw_params	= cs4265_pcm_hw_params,
 | 
				
			||||||
 | 
						.digital_mute	= cs4265_digital_mute,
 | 
				
			||||||
 | 
						.set_fmt	= cs4265_set_fmt,
 | 
				
			||||||
 | 
						.set_sysclk	= cs4265_set_sysclk,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct snd_soc_dai_driver cs4265_dai[] = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.name = "cs4265-dai1",
 | 
				
			||||||
 | 
							.playback = {
 | 
				
			||||||
 | 
								.stream_name = "DAI1 Playback",
 | 
				
			||||||
 | 
								.channels_min = 1,
 | 
				
			||||||
 | 
								.channels_max = 2,
 | 
				
			||||||
 | 
								.rates = CS4265_RATES,
 | 
				
			||||||
 | 
								.formats = CS4265_FORMATS,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.capture = {
 | 
				
			||||||
 | 
								.stream_name = "DAI1 Capture",
 | 
				
			||||||
 | 
								.channels_min = 1,
 | 
				
			||||||
 | 
								.channels_max = 2,
 | 
				
			||||||
 | 
								.rates = CS4265_RATES,
 | 
				
			||||||
 | 
								.formats = CS4265_FORMATS,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.ops = &cs4265_ops,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.name = "cs4265-dai2",
 | 
				
			||||||
 | 
							.playback = {
 | 
				
			||||||
 | 
								.stream_name = "DAI2 Playback",
 | 
				
			||||||
 | 
								.channels_min = 1,
 | 
				
			||||||
 | 
								.channels_max = 2,
 | 
				
			||||||
 | 
								.rates = CS4265_RATES,
 | 
				
			||||||
 | 
								.formats = CS4265_FORMATS,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.capture = {
 | 
				
			||||||
 | 
								.stream_name = "DAI2 Capture",
 | 
				
			||||||
 | 
								.channels_min = 1,
 | 
				
			||||||
 | 
								.channels_max = 2,
 | 
				
			||||||
 | 
								.rates = CS4265_RATES,
 | 
				
			||||||
 | 
								.formats = CS4265_FORMATS,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							.ops = &cs4265_ops,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct snd_soc_codec_driver soc_codec_cs4265 = {
 | 
				
			||||||
 | 
						.set_bias_level = cs4265_set_bias_level,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.dapm_widgets = cs4265_dapm_widgets,
 | 
				
			||||||
 | 
						.num_dapm_widgets = ARRAY_SIZE(cs4265_dapm_widgets),
 | 
				
			||||||
 | 
						.dapm_routes = cs4265_audio_map,
 | 
				
			||||||
 | 
						.num_dapm_routes = ARRAY_SIZE(cs4265_audio_map),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.controls = cs4265_snd_controls,
 | 
				
			||||||
 | 
						.num_controls = ARRAY_SIZE(cs4265_snd_controls),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct regmap_config cs4265_regmap = {
 | 
				
			||||||
 | 
						.reg_bits = 8,
 | 
				
			||||||
 | 
						.val_bits = 8,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.max_register = CS4265_MAX_REGISTER,
 | 
				
			||||||
 | 
						.reg_defaults = cs4265_reg_defaults,
 | 
				
			||||||
 | 
						.num_reg_defaults = ARRAY_SIZE(cs4265_reg_defaults),
 | 
				
			||||||
 | 
						.readable_reg = cs4265_readable_register,
 | 
				
			||||||
 | 
						.volatile_reg = cs4265_volatile_register,
 | 
				
			||||||
 | 
						.cache_type = REGCACHE_RBTREE,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_i2c_probe(struct i2c_client *i2c_client,
 | 
				
			||||||
 | 
								     const struct i2c_device_id *id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cs4265_private *cs4265;
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
						unsigned int devid = 0;
 | 
				
			||||||
 | 
						unsigned int reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cs4265 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4265_private),
 | 
				
			||||||
 | 
								       GFP_KERNEL);
 | 
				
			||||||
 | 
						if (cs4265 == NULL)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
						cs4265->dev = &i2c_client->dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cs4265->regmap = devm_regmap_init_i2c(i2c_client, &cs4265_regmap);
 | 
				
			||||||
 | 
						if (IS_ERR(cs4265->regmap)) {
 | 
				
			||||||
 | 
							ret = PTR_ERR(cs4265->regmap);
 | 
				
			||||||
 | 
							dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cs4265->reset_gpio = devm_gpiod_get(&i2c_client->dev,
 | 
				
			||||||
 | 
							"reset-gpios");
 | 
				
			||||||
 | 
						if (IS_ERR(cs4265->reset_gpio)) {
 | 
				
			||||||
 | 
							ret = PTR_ERR(cs4265->reset_gpio);
 | 
				
			||||||
 | 
							if (ret != -ENOENT && ret != -ENOSYS)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cs4265->reset_gpio = NULL;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ret = gpiod_direction_output(cs4265->reset_gpio, 0);
 | 
				
			||||||
 | 
							if (ret)
 | 
				
			||||||
 | 
								return ret;
 | 
				
			||||||
 | 
							mdelay(1);
 | 
				
			||||||
 | 
							gpiod_set_value_cansleep(cs4265->reset_gpio, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i2c_set_clientdata(i2c_client, cs4265);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = regmap_read(cs4265->regmap, CS4265_CHIP_ID, ®);
 | 
				
			||||||
 | 
						devid = reg & CS4265_CHIP_ID_MASK;
 | 
				
			||||||
 | 
						if (devid != CS4265_CHIP_ID_VAL) {
 | 
				
			||||||
 | 
							ret = -ENODEV;
 | 
				
			||||||
 | 
							dev_err(&i2c_client->dev,
 | 
				
			||||||
 | 
								"CS4265 Device ID (%X). Expected %X\n",
 | 
				
			||||||
 | 
								devid, CS4265_CHIP_ID);
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dev_info(&i2c_client->dev,
 | 
				
			||||||
 | 
							"CS4265 Version %x\n",
 | 
				
			||||||
 | 
								reg & CS4265_REV_ID_MASK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret =  snd_soc_register_codec(&i2c_client->dev,
 | 
				
			||||||
 | 
								&soc_codec_cs4265, cs4265_dai,
 | 
				
			||||||
 | 
								ARRAY_SIZE(cs4265_dai));
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int cs4265_i2c_remove(struct i2c_client *client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						snd_soc_unregister_codec(&client->dev);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct of_device_id cs4265_of_match[] = {
 | 
				
			||||||
 | 
						{ .compatible = "cirrus,cs4265", },
 | 
				
			||||||
 | 
						{ }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					MODULE_DEVICE_TABLE(of, cs4265_of_match);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct i2c_device_id cs4265_id[] = {
 | 
				
			||||||
 | 
						{ "cs4265", 0 },
 | 
				
			||||||
 | 
						{ }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					MODULE_DEVICE_TABLE(i2c, cs4265_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct i2c_driver cs4265_i2c_driver = {
 | 
				
			||||||
 | 
						.driver = {
 | 
				
			||||||
 | 
							.name = "cs4265",
 | 
				
			||||||
 | 
							.owner = THIS_MODULE,
 | 
				
			||||||
 | 
							.of_match_table = cs4265_of_match,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.id_table = cs4265_id,
 | 
				
			||||||
 | 
						.probe =    cs4265_i2c_probe,
 | 
				
			||||||
 | 
						.remove =   cs4265_i2c_remove,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_i2c_driver(cs4265_i2c_driver);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODULE_DESCRIPTION("ASoC CS4265 driver");
 | 
				
			||||||
 | 
					MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <paul.handrigan@cirrus.com>");
 | 
				
			||||||
 | 
					MODULE_LICENSE("GPL");
 | 
				
			||||||
							
								
								
									
										64
									
								
								sound/soc/codecs/cs4265.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								sound/soc/codecs/cs4265.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,64 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * cs4265.h -- CS4265 ALSA SoC audio driver
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2014 Cirrus Logic, Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Author: Paul Handrigan <paul.handrigan@cirrus.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __CS4265_H__
 | 
				
			||||||
 | 
					#define __CS4265_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_CHIP_ID				0x1
 | 
				
			||||||
 | 
					#define CS4265_CHIP_ID_VAL			0xD0
 | 
				
			||||||
 | 
					#define CS4265_CHIP_ID_MASK			0xF0
 | 
				
			||||||
 | 
					#define CS4265_REV_ID_MASK			0x0F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_PWRCTL				0x02
 | 
				
			||||||
 | 
					#define CS4265_PWRCTL_PDN			1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_DAC_CTL				0x3
 | 
				
			||||||
 | 
					#define CS4265_DAC_CTL_MUTE			(1 << 2)
 | 
				
			||||||
 | 
					#define CS4265_DAC_CTL_DIF			(3 << 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_ADC_CTL				0x4
 | 
				
			||||||
 | 
					#define CS4265_ADC_MASTER			1
 | 
				
			||||||
 | 
					#define CS4265_ADC_DIF				(1 << 4)
 | 
				
			||||||
 | 
					#define CS4265_ADC_FM				(3 << 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_MCLK_FREQ			0x5
 | 
				
			||||||
 | 
					#define CS4265_MCLK_FREQ_MASK			(7 << 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_SIG_SEL				0x6
 | 
				
			||||||
 | 
					#define CS4265_SIG_SEL_LOOP			(1 << 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_CHB_PGA_CTL			0x7
 | 
				
			||||||
 | 
					#define CS4265_CHA_PGA_CTL			0x8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_ADC_CTL2				0x9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_DAC_CHA_VOL			0xA
 | 
				
			||||||
 | 
					#define CS4265_DAC_CHB_VOL			0xB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_DAC_CTL2				0xC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_INT_STATUS			0xD
 | 
				
			||||||
 | 
					#define CS4265_INT_MASK				0xE
 | 
				
			||||||
 | 
					#define CS4265_STATUS_MODE_MSB			0xF
 | 
				
			||||||
 | 
					#define CS4265_STATUS_MODE_LSB			0x10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_SPDIF_CTL1			0x11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_SPDIF_CTL2			0x12
 | 
				
			||||||
 | 
					#define CS4265_SPDIF_CTL2_MUTE			(1 << 4)
 | 
				
			||||||
 | 
					#define CS4265_SPDIF_CTL2_DIF			(3 << 6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CS4265_C_DATA_BUFF			0x13
 | 
				
			||||||
 | 
					#define CS4265_MAX_REGISTER			0x2A
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -664,10 +664,8 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
 | 
						cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
 | 
				
			||||||
			      GFP_KERNEL);
 | 
								      GFP_KERNEL);
 | 
				
			||||||
	if (!cs4270) {
 | 
						if (!cs4270)
 | 
				
			||||||
		dev_err(&i2c_client->dev, "could not allocate codec\n");
 | 
					 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* get the power supply regulators */
 | 
						/* get the power supply regulators */
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 | 
						for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
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