History

Merge tag 'sound-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai: "After a heavy storm by syzkaller in 4.5 cycle, we have relatively few changes in the core at this time while a lot of changes are found in the driver side, unsurprisingly. Below are some highlights: ALSA core: - A few more hardening in ALSA timer codes - An extension of sequencer API for advertising the card / pid - Small fixes in compress-offload and jack layers HD-audio: - Dynamic PCM assignment in HDMI/DP codec; preparation for upcoming DP-MST support - Lots of code refactoring for sharing with ASoC SKL driver - Regression fixes for Intel HDMI/DP - Fixups for CX20724 codec, Lenovo AiO USB-audio: - Add quirk_alias option to make quirk debugging easier - Fixes for possible Oops by malformed firmware Firewire: - Add support for FW-1804 in tascam driver - Improvements / changes in card registration, multi stream handling, etc for DICE - Lots of code refactoring ASoC: - Enhancements of still ongoing topology API - Lots of commits for Intel Skylake support including HDMI support - A few Intel Atom driver updates for recent devices - Lots of improvements to the Renesas drivers - Capture support for Qualcomm drivers - Support for TI DaVinci DRA7xxx devices - New machine drivers for Freescale systems with Cirrus CODECs, Mediatek systems with RT5650 CODECs - New CPU drivers for Allwinner S/PDIF controllers - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514" * tag 'sound-4.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (291 commits) ALSA: hda - Fix mutex deadlock at HDMI/DP hotplug ALSA: ctl: change return value in compatibility layer so that it's the same value in core implementation ALSA: mixart: silence an uninitialized variable warning ALSA: usb-audio: Add sanity checks for endpoint accesses ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk() ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk() ALSA: hda - Limit i915 HDMI binding only for HSW and later ALSA: hda - Fix unconditional GPIO toggle via automute ALSA: mixart: silence unitialized variable warnings ALSA: hda - Fixes double fault in nvhdmi_chmap_cea_alloc_validate_get_type ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41. ALSA: hda - Add new GPU codec ID 0x10de0082 to snd-hda ASoC: rsnd: add simplified module explanation ASoC: hdac_hdmi: Add broxton device ID ASoC: Intel: Bxtn: Add Broxton PCI ID ASoC: Intel: Skylake: Move Skylake dsp ops & loader ops ASoC: Intel: add dmabuffer to common sst_dsp ASoC: Intel: Skylake: Unstatify skl_dsp_enable_core ASoC: Intel: Skylake: Fix whitepsace issues ASoC: Intel: Skylake: Move module id defines ...

Linus Torvalds committed 10 years ago

Commit 021f1632 parents 9ea4463 222bde0202 files · +12770 −4360Browse files

Unified · Split

202 files
  1. Documentation/devicetree/bindings/sound/adi,adau17x1.txt +24 −0
  2. Documentation/devicetree/bindings/sound/fsl-asoc-card.txt +9 −0
  3. Documentation/devicetree/bindings/sound/max9867.txt +17 −0
  4. Documentation/devicetree/bindings/sound/max98926.txt +32 −0
  5. Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt +15 −0
  6. Documentation/devicetree/bindings/sound/mt8173-rt5650.txt +15 −0
  7. Documentation/devicetree/bindings/sound/pcm179x.txt +10 −1
  8. Documentation/devicetree/bindings/sound/renesas,rsnd.txt +340 −0
  9. Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +1 −0
  10. Documentation/devicetree/bindings/sound/rockchip-i2s.txt +1 −0
  11. Documentation/devicetree/bindings/sound/rockchip-spdif.txt +6 −2
  12. Documentation/devicetree/bindings/sound/rt5514.txt +25 −0
  13. Documentation/devicetree/bindings/sound/rt5616.txt +6 −0
  14. Documentation/devicetree/bindings/sound/rt5640.txt +3 −0
  15. Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt +39 −0
  16. Documentation/devicetree/bindings/sound/ti,ads117x.txt +11 −0
  17. Documentation/sound/alsa/ALSA-Configuration.txt +9 −0
  18. Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt +74 −0
  19. drivers/misc/atmel-ssc.c +1 −0
  20. include/drm/drm_edid.h +12 −0
  21. include/linux/platform_data/adau17x1.h +1 −1
  22. include/sound/hda_chmap.h +76 −0
  23. include/sound/hdaudio.h +2 −0
  24. include/sound/jack.h +14 −9
  25. include/sound/pcm.h +2 −0
  26. include/sound/soc-topology.h +10 −11
  27. include/sound/soc.h +1 −1
  28. include/uapi/sound/asequencer.h +4 −8
  29. include/uapi/sound/asound.h +4 −0
  30. sound/core/Kconfig +6 −3
  31. sound/core/compress_offload.c +8 −4
  32. sound/core/control_compat.c +1 −1
  33. sound/core/jack.c +20 −3
  34. sound/core/pcm_lib.c +1 −1
  35. sound/core/pcm_misc.c +30 −0
  36. sound/core/seq/seq_clientmgr.c +14 −0
  37. sound/core/seq/seq_clientmgr.h +2 −0
  38. sound/core/timer.c +123 −145
  39. sound/drivers/mts64.c +44 −52
  40. sound/drivers/portman2x4.c +43 −51
  41. sound/firewire/bebob/bebob.c +16 −5
  42. sound/firewire/bebob/bebob.h +1 −4
  43. sound/firewire/bebob/bebob_midi.c +12 −4
  44. sound/firewire/bebob/bebob_pcm.c +20 −8
  45. sound/firewire/bebob/bebob_stream.c +4 −54
  46. sound/firewire/dice/dice-midi.c +21 −10
  47. sound/firewire/dice/dice-pcm.c +113 −165
  48. sound/firewire/dice/dice-stream.c +285 −183
  49. sound/firewire/dice/dice-transaction.c +1 −55
  50. sound/firewire/dice/dice.c +44 −64
  51. sound/firewire/dice/dice.h +29 −12
  52. sound/firewire/fireworks/fireworks.c +3 −0
  53. sound/firewire/fireworks/fireworks_stream.c +2 −4
  54. sound/firewire/oxfw/oxfw-scs1x.c +25 −10
  55. sound/hda/Makefile +1 −1
  56. sound/hda/hdac_device.c +16 −0
  57. sound/hda/hdac_i915.c +12 −2
  58. sound/hda/hdac_regmap.c +46 −23
  59. sound/hda/hdmi_chmap.c +791 −0
  60. sound/mips/Kconfig +0 −12
  61. sound/mips/Makefile +0 −2
  62. sound/mips/au1x00.c +0 −734
  63. sound/pci/Kconfig +1 −1
  64. sound/pci/hda/Kconfig +1 −1
  65. sound/pci/hda/hda_eld.c +3 −28
  66. sound/pci/hda/hda_intel.c +1 −1
  67. sound/pci/hda/patch_cirrus.c +6 −2
  68. sound/pci/hda/patch_conexant.c +6 −1
  69. sound/pci/hda/patch_hdmi.c +630 −821
  70. sound/pci/hda/patch_realtek.c +1 −0
  71. sound/pci/hda/thinkpad_helper.c +2 −15
  72. sound/pci/intel8x0.c +1 −0
  73. sound/pci/mixart/mixart.c +1 −1
  74. sound/pci/mixart/mixart_mixer.c +2 −2
  75. sound/soc/Kconfig +1 −1
  76. sound/soc/atmel/atmel_ssc_dai.c +18 −9
  77. sound/soc/bcm/bcm2835-i2s.c +64 −220
  78. sound/soc/codecs/Kconfig +35 −3
  79. sound/soc/codecs/Makefile +10 −0
  80. sound/soc/codecs/ab8500-codec.c +0 −1
  81. sound/soc/codecs/adau1761-i2c.c +13 −1
  82. sound/soc/codecs/adau1761-spi.c +13 −1
  83. sound/soc/codecs/adau1761.c +9 −1
  84. sound/soc/codecs/adau1781-i2c.c +10 −0
  85. sound/soc/codecs/adau1781-spi.c +10 −0
  86. sound/soc/codecs/adau1781.c +1 −1
  87. sound/soc/codecs/ads117x.c +12 −0
  88. sound/soc/codecs/arizona.c +21 −50
  89. sound/soc/codecs/arizona.h +3 −1
  90. sound/soc/codecs/cs42xx8.c +8 −2
  91. sound/soc/codecs/cs47l24.c +118 −5
  92. sound/soc/codecs/hdac_hdmi.c +1096 −123
  93. sound/soc/codecs/hdac_hdmi.h +6 −0
  94. sound/soc/codecs/max9867.c +546 −0
  95. sound/soc/codecs/max9867.h +83 −0
  96. sound/soc/codecs/max98926.c +606 −0
  97. sound/soc/codecs/max98926.h +848 −0
  98. sound/soc/codecs/nau8825.c +126 −43
  99. sound/soc/codecs/nau8825.h +15 −1
  100. sound/soc/codecs/pcm179x-i2c.c +73 −0
  101. sound/soc/codecs/pcm179x-spi.c +72 −0
  102. sound/soc/codecs/pcm179x.c +14 −42
  103. sound/soc/codecs/pcm179x.h +5 −4
  104. sound/soc/codecs/pcm3168a.c +6 −2
  105. sound/soc/codecs/rt298.c +6 −1
  106. sound/soc/codecs/rt298.h +8 −0
  107. sound/soc/codecs/rt5514.c +982 −0
  108. sound/soc/codecs/rt5514.h +252 −0
  109. sound/soc/codecs/rt5616.c +228 −186
  110. sound/soc/codecs/rt5640.c +61 −30
  111. sound/soc/codecs/rt5640.h +2 −0
  112. sound/soc/codecs/rt5645.c +10 −5
  113. sound/soc/codecs/rt5659.c +1 −1
  114. sound/soc/codecs/ssm4567.c +5 −0
  115. sound/soc/codecs/wm5102.c +88 −5
  116. sound/soc/codecs/wm5110.c +64 −11
  117. sound/soc/codecs/wm8974.c +93 −0
  118. sound/soc/codecs/wm8997.c +1 −1
  119. sound/soc/codecs/wm8998.c +1 −1
  120. sound/soc/codecs/wm_adsp.c +71 −60
  121. sound/soc/codecs/wm_adsp.h +3 −5
  122. sound/soc/davinci/Kconfig +2 −1
  123. sound/soc/davinci/davinci-mcasp.c +12 −0
  124. sound/soc/fsl/Kconfig +2 −2
  125. sound/soc/fsl/fsl-asoc-card.c +22 −4
  126. sound/soc/fsl/fsl_sai.c +2 −1
  127. sound/soc/fsl/fsl_ssi.c +22 −20
  128. sound/soc/fsl/mpc5200_psc_ac97.c +2 −1
  129. sound/soc/intel/Kconfig +4 −0
  130. sound/soc/intel/atom/sst/sst_acpi.c +4 −0
  131. sound/soc/intel/atom/sst/sst_ipc.c +0 −2
  132. sound/soc/intel/boards/bytcr_rt5640.c +34 −16
  133. sound/soc/intel/boards/cht_bsw_max98090_ti.c +2 −15
  134. sound/soc/intel/boards/cht_bsw_rt5645.c +14 −14
  135. sound/soc/intel/boards/skl_nau88l25_max98357a.c +105 −17
  136. sound/soc/intel/boards/skl_nau88l25_ssm4567.c +112 −18
  137. sound/soc/intel/boards/skl_rt286.c +104 −9
  138. sound/soc/intel/common/sst-acpi.h +3 −0
  139. sound/soc/intel/common/sst-dsp-priv.h +1 −0
  140. sound/soc/intel/common/sst-match-acpi.c +40 −5
  141. sound/soc/intel/skylake/skl-messages.c +109 −15
  142. sound/soc/intel/skylake/skl-nhlt.c +34 −0
  143. sound/soc/intel/skylake/skl-pcm.c +98 −8
  144. sound/soc/intel/skylake/skl-sst-dsp.c +7 −7
  145. sound/soc/intel/skylake/skl-sst-dsp.h +6 −1
  146. sound/soc/intel/skylake/skl-sst.c +0 −3
  147. sound/soc/intel/skylake/skl-topology.c +203 −5
  148. sound/soc/intel/skylake/skl-topology.h +27 −0
  149. sound/soc/intel/skylake/skl-tplg-interface.h +2 −1
  150. sound/soc/intel/skylake/skl.c +88 −0
  151. sound/soc/intel/skylake/skl.h +14 −1
  152. sound/soc/mediatek/Kconfig +21 −1
  153. sound/soc/mediatek/Makefile +2 −0
  154. sound/soc/mediatek/mt8173-rt5650-rt5514.c +258 −0
  155. sound/soc/mediatek/mt8173-rt5650-rt5676.c +13 −5
  156. sound/soc/mediatek/mt8173-rt5650.c +236 −0
  157. sound/soc/mediatek/mtk-afe-common.h +1 −0
  158. sound/soc/mediatek/mtk-afe-pcm.c +38 −9
  159. sound/soc/mxs/mxs-saif.c +1 −1
  160. sound/soc/omap/omap-hdmi-audio.c +1 −0
  161. sound/soc/pxa/brownstone.c +0 −2
  162. sound/soc/qcom/Kconfig +5 −2
  163. sound/soc/qcom/apq8016_sbc.c +7 −3
  164. sound/soc/qcom/lpass-apq8016.c +24 −7
  165. sound/soc/qcom/lpass-cpu.c +114 −32
  166. sound/soc/qcom/lpass-ipq806x.c +9 −2
  167. sound/soc/qcom/lpass-lpaif-reg.h +83 −33
  168. sound/soc/qcom/lpass-platform.c +147 −97
  169. sound/soc/qcom/lpass.h +7 −3
  170. sound/soc/rockchip/rockchip_i2s.c +13 −0
  171. sound/soc/rockchip/rockchip_spdif.c +12 −5
  172. sound/soc/samsung/s3c-i2s-v2.c +1 −1
  173. sound/soc/samsung/s3c-i2s-v2.h +1 −1
  174. sound/soc/sh/rcar/adg.c +119 −99
  175. sound/soc/sh/rcar/cmd.c +12 −6
  176. sound/soc/sh/rcar/core.c +119 −41
  177. sound/soc/sh/rcar/ctu.c +272 −9
  178. sound/soc/sh/rcar/dma.c +29 −27
  179. sound/soc/sh/rcar/dvc.c +28 −5
  180. sound/soc/sh/rcar/gen.c +37 −19
  181. sound/soc/sh/rcar/mix.c +2 −2
  182. sound/soc/sh/rcar/rsnd.h +86 −29
  183. sound/soc/sh/rcar/rsrc-card.c +18 −9
  184. sound/soc/sh/rcar/src.c +70 −101
  185. sound/soc/sh/rcar/ssi.c +174 −160
  186. sound/soc/sh/rcar/ssiu.c +11 −9
  187. sound/soc/soc-core.c +4 −4
  188. sound/soc/soc-dapm.c +2 −2
  189. sound/soc/soc-pcm.c +12 −12
  190. sound/soc/soc-topology.c +154 −86
  191. sound/soc/sunxi/Kconfig +8 −0
  192. sound/soc/sunxi/Makefile +1 −0
  193. sound/soc/sunxi/sun4i-spdif.c +550 −0
  194. sound/usb/card.c +53 −3
  195. sound/usb/clock.c +2 −0
  196. sound/usb/endpoint.c +3 −0
  197. sound/usb/midi.c +9 −6
  198. sound/usb/midi.h +12 −2
  199. sound/usb/mixer_quirks.c +4 −0
  200. sound/usb/pcm.c +2 −0
  201. sound/usb/quirks.c +35 −23
  202. sound/usb/quirks.h +2 −1
Documentation/devicetree/bindings/sound/adi,adau17x1.txt+24−0
@@ -0,0 +1,24 @@
1Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781
2
3Required properties:
4
5 - compatible: Should contain one of the following:
6 "adi,adau1361"
7 "adi,adau1461"
8 "adi,adau1761"
9 "adi,adau1961"
10 "adi,adau1381"
11 "adi,adau1781"
12
13 - reg: The i2c address. Value depends on the state of ADDR0
14 and ADDR1, as wired in hardware.
15
16Examples:
17#include <dt-bindings/sound/adau17x1.h>
18
19 i2c_bus {
20 adau1361@38 {
21 compatible = "adi,adau1761";
22 reg = <0x38>;
23 };
24 };
Documentation/devicetree/bindings/sound/fsl-asoc-card.txt+9−0
@@ -24,6 +24,9 @@ The compatible list for this generic sound card currently: · 23 unmodified lines
24 24
25 "fsl,imx-audio-cs42888"25 "fsl,imx-audio-cs42888"
26 26
27 "fsl,imx-audio-cs427x"
28 (compatible with CS4271 and CS4272)
29
27 "fsl,imx-audio-wm8962"30 "fsl,imx-audio-wm8962"
28 (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt)31 (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt)
29 32
@@ -63,6 +66,12 @@ Optional properties: · 33 unmodified lines
63 - audio-asrc : The phandle of ASRC. It can be absent if there's no66 - audio-asrc : The phandle of ASRC. It can be absent if there's no
64 need to add ASRC support via DPCM.67 need to add ASRC support via DPCM.
65 68
69Optional unless SSI is selected as a CPU DAI:
70
71 - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
72
73 - mux-ext-port : The external port of the i.MX audio muxer
74
66Example:75Example:
67sound-cs42888 {76sound-cs42888 {
68 compatible = "fsl,imx-audio-cs42888";77 compatible = "fsl,imx-audio-cs42888";
Documentation/devicetree/bindings/sound/max9867.txt+17−0
@@ -0,0 +1,17 @@
1max9867 codec
2
3This device supports I2C mode only.
4
5Required properties:
6
7- compatible : "maxim,max9867"
8- reg : The chip select number on the I2C bus
9
10Example:
11
12&i2c {
13 max9867: max9867@0x18 {
14 compatible = "maxim,max9867";
15 reg = <0x18>;
16 };
17};
Documentation/devicetree/bindings/sound/max98926.txt+32−0
@@ -0,0 +1,32 @@
1max98926 audio CODEC
2
3This device supports I2C.
4
5Required properties:
6
7 - compatible : "maxim,max98926"
8
9 - vmon-slot-no : slot number used to send voltage information
10 or in inteleave mode this will be used as
11 interleave slot.
12
13 - imon-slot-no : slot number used to send current information
14
15 - interleave-mode : When using two MAX98926 in a system it is
16 possible to create ADC data that that will
17 overflow the frame size. Digital Audio Interleave
18 mode provides a means to output VMON and IMON data
19 from two devices on a single DOUT line when running
20 smaller frames sizes such as 32 BCLKS per LRCLK or
21 48 BCLKS per LRCLK.
22
23 - reg : the I2C address of the device for I2C
24
25Example:
26
27codec: max98926@1a {
28 compatible = "maxim,max98926";
29 vmon-slot-no = <0>;
30 imon-slot-no = <2>;
31 reg = <0x1a>;
32};
Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt+15−0
@@ -0,0 +1,15 @@
1MT8173 with RT5650 RT5514 CODECS
2
3Required properties:
4- compatible : "mediatek,mt8173-rt5650-rt5514"
5- mediatek,audio-codec: the phandles of rt5650 and rt5514 codecs
6- mediatek,platform: the phandle of MT8173 ASoC platform
7
8Example:
9
10 sound {
11 compatible = "mediatek,mt8173-rt5650-rt5514";
12 mediatek,audio-codec = <&rt5650 &rt5514>;
13 mediatek,platform = <&afe>;
14 };
15
Documentation/devicetree/bindings/sound/mt8173-rt5650.txt+15−0
@@ -0,0 +1,15 @@
1MT8173 with RT5650 CODECS
2
3Required properties:
4- compatible : "mediatek,mt8173-rt5650"
5- mediatek,audio-codec: the phandles of rt5650 codecs
6- mediatek,platform: the phandle of MT8173 ASoC platform
7
8Example:
9
10 sound {
11 compatible = "mediatek,mt8173-rt5650";
12 mediatek,audio-codec = <&rt5650>;
13 mediatek,platform = <&afe>;
14 };
15
Documentation/devicetree/bindings/sound/pcm179x.txt+10−1
@@ -1,6 +1,6 @@
1Texas Instruments pcm179x DT bindings1Texas Instruments pcm179x DT bindings
2 2
3This driver supports the SPI bus.3This driver supports both the I2C and SPI bus.
4 4
5Required properties:5Required properties:
6 6
@@ -9,6 +9,11 @@ Required properties: · 2 unmodified lines
9For required properties on SPI, please consult9For required properties on SPI, please consult
10Documentation/devicetree/bindings/spi/spi-bus.txt10Documentation/devicetree/bindings/spi/spi-bus.txt
11 11
12Required properties on I2C:
13
14 - reg: the I2C address
15
16
12Examples:17Examples:
13 18
14 codec_spi: 1792a@0 {19 codec_spi: 1792a@0 {
@@ -16,3 +21,7 @@ Examples: · 1 unmodified line
16 spi-max-frequency = <600000>;21 spi-max-frequency = <600000>;
17 };22 };
18 23
24 codec_i2c: 1792a@4c {
25 compatible = "ti,pcm1792a";
26 reg = <0x4c>;
27 };
Documentation/devicetree/bindings/sound/renesas,rsnd.txt+340−0
@@ -1,6 +1,337 @@
1Renesas R-Car sound1Renesas R-Car sound
2 2
3=============================================
4* Modules
5=============================================
6
7Renesas R-Car sound is constructed from below modules
8(for Gen2 or later)
9
10 SCU : Sampling Rate Converter Unit
11 - SRC : Sampling Rate Converter
12 - CMD
13 - CTU : Channel Transfer Unit
14 - MIX : Mixer
15 - DVC : Digital Volume and Mute Function
16 SSIU : Serial Sound Interface Unit
17 SSI : Serial Sound Interface
18
19See detail of each module's channels, connection, limitation on datasheet
20
21=============================================
22* Multi channel
23=============================================
24
25Multi channel is supported by Multi-SSI, or TDM-SSI.
26
27 Multi-SSI : 6ch case, you can use stereo x 3 SSI
28 TDM-SSI : 6ch case, you can use TDM
29
30=============================================
31* Enable/Disable each modules
32=============================================
33
34See datasheet to check SRC/CTU/MIX/DVC connect-limitation.
35DT controls enabling/disabling module.
36${LINUX}/arch/arm/boot/dts/r8a7790-lager.dts can be good example.
37This is example of
38
39Playback: [MEM] -> [SRC2] -> [DVC0] -> [SSIU0/SSI0] -> [codec]
40Capture: [MEM] <- [DVC1] <- [SRC3] <- [SSIU1/SSI1] <- [codec]
41
42 &rcar_sound {
43 ...
44 rcar_sound,dai {
45 dai0 {
46 playback = <&ssi0 &src2 &dvc0>;
47 capture = <&ssi1 &src3 &dvc1>;
48 };
49 };
50 };
51
52You can use below.
53${LINUX}/arch/arm/boot/dts/r8a7790.dts can be good example.
54
55 &src0 &ctu00 &mix0 &dvc0 &ssi0
56 &src1 &ctu01 &mix1 &dvc1 &ssi1
57 &src2 &ctu02 &ssi2
58 &src3 &ctu03 &ssi3
59 &src4 &ssi4
60 &src5 &ctu10 &ssi5
61 &src6 &ctu11 &ssi6
62 &src7 &ctu12 &ssi7
63 &src8 &ctu13 &ssi8
64 &src9 &ssi9
65
66=============================================
67* SRC (Sampling Rate Converter)
68=============================================
69
70 [xx]Hz [yy]Hz
71 ------> [SRC] ------>
72
73SRC can convert [xx]Hz to [yy]Hz. Then, it has below 2 modes
74
75 Asynchronous mode: input data / output data are based on different clocks.
76 you can use this mode on Playback / Capture
77 Synchronous mode: input data / output data are based on same clocks.
78 This mode will be used if system doesn't have its input clock,
79 for example digital TV case.
80 you can use this mode on Playback
81
82------------------
83** Asynchronous mode
84------------------
85
86You need to use "renesas,rsrc-card" sound card for it.
87example)
88
89 sound {
90 compatible = "renesas,rsrc-card";
91 ...
92 /*
93 * SRC Asynchronous mode setting
94 * Playback:
95 * All input data will be converted to 48kHz
96 * Capture:
97 * Inputed 48kHz data will be converted to
98 * system specified Hz
99 */
100 convert-rate = <48000>;
101 ...
102 cpu {
103 sound-dai = <&rcar_sound>;
104 };
105 codec {
106 ...
107 };
108 };
109
110------------------
111** Synchronous mode
112------------------
113
114 > amixer set "SRC Out Rate" on
115 > aplay xxxx.wav
116 > amixer set "SRC Out Rate" 48000
117 > amixer set "SRC Out Rate" 44100
118
119=============================================
120* CTU (Channel Transfer Unit)
121=============================================
122
123 [xx]ch [yy]ch
124 ------> [CTU] -------->
125
126CTU can convert [xx]ch to [yy]ch, or exchange outputed channel.
127CTU conversion needs matrix settings.
128For more detail information, see below
129
130 Renesas R-Car datasheet
131 - Sampling Rate Converter Unit (SCU)
132 - SCU Operation
133 - CMD Block
134 - Functional Blocks in CMD
135
136 Renesas R-Car datasheet
137 - Sampling Rate Converter Unit (SCU)
138 - Register Description
139 - CTUn Scale Value exx Register (CTUn_SVxxR)
140
141 ${LINUX}/sound/soc/sh/rcar/ctu.c
142 - comment of header
143
144You need to use "renesas,rsrc-card" sound card for it.
145example)
146
147 sound {
148 compatible = "renesas,rsrc-card";
149 ...
150 /*
151 * CTU setting
152 * All input data will be converted to 2ch
153 * as output data
154 */
155 convert-channels = <2>;
156 ...
157 cpu {
158 sound-dai = <&rcar_sound>;
159 };
160 codec {
161 ...
162 };
163 };
164
165Ex) Exchange output channel
166 Input -> Output
167 1ch -> 0ch
168 0ch -> 1ch
169
170 example of using matrix
171 output 0ch = (input 0ch x 0) + (input 1ch x 1)
172 output 1ch = (input 0ch x 1) + (input 1ch x 0)
173
174 amixer set "CTU Reset" on
175 amixer set "CTU Pass" 9,10
176 amixer set "CTU SV0" 0,4194304
177 amixer set "CTU SV1" 4194304,0
178
179 example of changing connection
180 amixer set "CTU Reset" on
181 amixer set "CTU Pass" 2,1
182
183=============================================
184* MIX (Mixer)
185=============================================
186
187MIX merges 2 sounds path. You can see 2 sound interface on system,
188and these sounds will be merged by MIX.
189
190 aplay -D plughw:0,0 xxxx.wav &
191 aplay -D plughw:0,1 yyyy.wav
192
193You need to use "renesas,rsrc-card" sound card for it.
194Ex)
195 [MEM] -> [SRC1] -> [CTU02] -+-> [MIX0] -> [DVC0] -> [SSI0]
196 |
197 [MEM] -> [SRC2] -> [CTU03] -+
198
199 sound {
200 compatible = "renesas,rsrc-card";
201 ...
202 cpu@0 {
203 sound-dai = <&rcar_sound 0>;
204 };
205 cpu@1 {
206 sound-dai = <&rcar_sound 1>;
207 };
208 codec {
209 ...
210 };
211 };
212
213 &rcar_sound {
214 ...
215 rcar_sound,dai {
216 dai0 {
217 playback = <&src1 &ctu02 &mix0 &dvc0 &ssi0>;
218 };
219 dai1 {
220 playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;
221 };
222 };
223 };
224
225=============================================
226* DVC (Digital Volume and Mute Function)
227=============================================
228
229DVC controls Playback/Capture volume.
230
231Playback Volume
232 amixer set "DVC Out" 100%
233
234Capture Volume
235 amixer set "DVC In" 100%
236
237Playback Mute
238 amixer set "DVC Out Mute" on
239
240Capture Mute
241 amixer set "DVC In Mute" on
242
243Volume Ramp
244 amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps"
245 amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
246 amixer set "DVC Out Ramp" on
247 aplay xxx.wav &
248 amixer set "DVC Out" 80% // Volume Down
249 amixer set "DVC Out" 100% // Volume Up
250
251=============================================
252* SSIU (Serial Sound Interface Unit)
253=============================================
254
255There is no DT settings for SSIU, because SSIU will be automatically
256selected via SSI.
257SSIU can avoid some under/over run error, because it has some buffer.
258But you can't use it if SSI was PIO mode.
259In DMA mode, you can select not to use SSIU by using "no-busif" on DT.
260
261 &ssi0 {
262 no-busif;
263 };
264
265=============================================
266* SSI (Serial Sound Interface)
267=============================================
268
269** PIO mode
270
271You can use PIO mode which is for connection check by using.
272Note: The system will drop non-SSI modules in PIO mode
273even though if DT is selecting other modules.
274
275 &ssi0 {
276 pio-transfer
277 };
278
279** DMA mode without SSIU
280
281You can use DMA without SSIU.
282Note: under/over run, or noise are likely to occur
283
284 &ssi0 {
285 no-busif;
286 };
287
288** PIN sharing
289
290Each SSI can share WS pin. It is based on platform.
291This is example if SSI1 want to share WS pin with SSI0
292
293 &ssi1 {
294 shared-pin;
295 };
296
297** Multi-SSI
298
299You can use Multi-SSI.
300This is example of SSI0/SSI1/SSI2 (= for 6ch)
301
302 &rcar_sound {
303 ...
304 rcar_sound,dai {
305 dai0 {
306 playback = <&ssi0 &ssi1 &ssi2 &src0 &dvc0>;
307 };
308 };
309 };
310
311** TDM-SSI
312
313You can use TDM with SSI.
314This is example of TDM 6ch.
315Driver can automatically switches TDM <-> stereo mode in this case.
316
317 rsnd_tdm: sound {
318 compatible = "simple-audio-card";
319 ...
320 simple-audio-card,cpu {
321 /* system can use TDM 6ch */
322 dai-tdm-slot-num = <6>;
323 sound-dai = <&rcar_sound>;
324 };
325 simple-audio-card,codec {
326 ...
327 };
328 };
329
330
331=============================================
3Required properties:332Required properties:
333=============================================
334
4- compatible : "renesas,rcar_sound-<soctype>", fallbacks335- compatible : "renesas,rcar_sound-<soctype>", fallbacks
5 "renesas,rcar_sound-gen1" if generation1, and336 "renesas,rcar_sound-gen1" if generation1, and
6 "renesas,rcar_sound-gen2" if generation2337 "renesas,rcar_sound-gen2" if generation2
@@ -64,7 +395,10 @@ DAI subnode properties: · 57 unmodified lines
64- playback : list of playback modules395- playback : list of playback modules
65- capture : list of capture modules396- capture : list of capture modules
66 397
398
399=============================================
67Example:400Example:
401=============================================
68 402
69rcar_sound: sound@ec500000 {403rcar_sound: sound@ec500000 {
70 #sound-dai-cells = <1>;404 #sound-dai-cells = <1>;
@@ -250,7 +584,9 @@ rcar_sound: sound@ec500000 { · 179 unmodified lines
250 };584 };
251};585};
252 586
587=============================================
253Example: simple sound card588Example: simple sound card
589=============================================
254 590
255 rsnd_ak4643: sound {591 rsnd_ak4643: sound {
256 compatible = "simple-audio-card";592 compatible = "simple-audio-card";
@@ -290,7 +626,9 @@ Example: simple sound card · 33 unmodified lines
290 shared-pin;626 shared-pin;
291};627};
292 628
629=============================================
293Example: simple sound card for TDM630Example: simple sound card for TDM
631=============================================
294 632
295 rsnd_tdm: sound {633 rsnd_tdm: sound {
296 compatible = "simple-audio-card";634 compatible = "simple-audio-card";
@@ -309,7 +647,9 @@ Example: simple sound card for TDM · 12 unmodified lines
309 };647 };
310 };648 };
311 649
650=============================================
312Example: simple sound card for Multi channel651Example: simple sound card for Multi channel
652=============================================
313 653
314&rcar_sound {654&rcar_sound {
315 pinctrl-0 = <&sound_pins &sound_clk_pins>;655 pinctrl-0 = <&sound_pins &sound_clk_pins>;
Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt+1−0
@@ -30,6 +30,7 @@ Optional subnode properties: · 29 unmodified lines
30- frame-inversion : bool property. Add this if the30- frame-inversion : bool property. Add this if the
31 dai-link uses frame clock inversion.31 dai-link uses frame clock inversion.
32- convert-rate : platform specified sampling rate convert32- convert-rate : platform specified sampling rate convert
33- convert-channels : platform specified converted channel size (2 - 8 ch)
33- audio-prefix : see audio-routing34- audio-prefix : see audio-routing
34- audio-routing : A list of the connections between audio components.35- audio-routing : A list of the connections between audio components.
35 Each entry is a pair of strings, the first being the connection's sink,36 Each entry is a pair of strings, the first being the connection's sink,
Documentation/devicetree/bindings/sound/rockchip-i2s.txt+1−0
@@ -9,6 +9,7 @@ Required properties: · 8 unmodified lines
9 - "rockchip,rk3066-i2s": for rk30669 - "rockchip,rk3066-i2s": for rk3066
10 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk318810 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
11 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk328811 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288
12 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399
12- reg: physical base address of the controller and length of memory mapped13- reg: physical base address of the controller and length of memory mapped
13 region.14 region.
14- interrupts: should contain the I2S interrupt.15- interrupts: should contain the I2S interrupt.
Documentation/devicetree/bindings/sound/rockchip-spdif.txt+6−2
@@ -7,8 +7,12 @@ a fibre cable. · 6 unmodified lines
7Required properties:7Required properties:
8 8
9- compatible: should be one of the following:9- compatible: should be one of the following:
10 - "rockchip,rk3288-spdif", "rockchip,rk3188-spdif" or10 - "rockchip,rk3066-spdif"
11 "rockchip,rk3066-spdif"11 - "rockchip,rk3188-spdif"
12 - "rockchip,rk3288-spdif"
13 - "rockchip,rk3366-spdif"
14 - "rockchip,rk3368-spdif"
15 - "rockchip,rk3399-spdif"
12- reg: physical base address of the controller and length of memory mapped16- reg: physical base address of the controller and length of memory mapped
13 region.17 region.
14- interrupts: should contain the SPDIF interrupt.18- interrupts: should contain the SPDIF interrupt.
Documentation/devicetree/bindings/sound/rt5514.txt+25−0
@@ -0,0 +1,25 @@
1RT5514 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7- compatible : "realtek,rt5514".
8
9- reg : The I2C address of the device.
10
11Pins on the device (for linking into audio routes) for RT5514:
12
13 * DMIC1L
14 * DMIC1R
15 * DMIC2L
16 * DMIC2R
17 * AMICL
18 * AMICR
19
20Example:
21
22codec: rt5514@57 {
23 compatible = "realtek,rt5514";
24 reg = <0x57>;
25};
Documentation/devicetree/bindings/sound/rt5616.txt+6−0
@@ -8,6 +8,12 @@ Required properties: · 7 unmodified lines
8 8
9- reg : The I2C address of the device.9- reg : The I2C address of the device.
10 10
11Optional properties:
12
13- clocks: The phandle of the master clock to the CODEC.
14
15- clock-names: Should be "mclk".
16
11Pins on the device (for linking into audio routes) for RT5616:17Pins on the device (for linking into audio routes) for RT5616:
12 18
13 * IN1P19 * IN1P
Documentation/devicetree/bindings/sound/rt5640.txt+3−0
@@ -12,6 +12,9 @@ Required properties: · 11 unmodified lines
12 12
13Optional properties:13Optional properties:
14 14
15- clocks: The phandle of the master clock to the CODEC
16- clock-names: Should be "mclk"
17
15- realtek,in1-differential18- realtek,in1-differential
16- realtek,in2-differential19- realtek,in2-differential
17- realtek,in3-differential20- realtek,in3-differential
Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt+39−0
@@ -0,0 +1,39 @@
1Allwinner Sony/Philips Digital Interface Format (S/PDIF) Controller
2
3The Allwinner S/PDIF audio block is a transceiver that allows the
4processor to receive and transmit digital audio via an coaxial cable or
5a fibre cable.
6For now only playback is supported.
7
8Required properties:
9
10 - compatible : should be one of the following:
11 - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
12
13 - reg : Offset and length of the register set for the device.
14
15 - interrupts : Contains the spdif interrupt.
16
17 - dmas : Generic dma devicetree binding as described in
18 Documentation/devicetree/bindings/dma/dma.txt.
19
20 - dma-names : Two dmas have to be defined, "tx" and "rx".
21
22 - clocks : Contains an entry for each entry in clock-names.
23
24 - clock-names : Includes the following entries:
25 "apb" clock for the spdif bus.
26 "spdif" clock for spdif controller.
27
28Example:
29
30spdif: spdif@01c21000 {
31 compatible = "allwinner,sun4i-a10-spdif";
32 reg = <0x01c21000 0x40>;
33 interrupts = <13>;
34 clocks = <&apb0_gates 1>, <&spdif_clk>;
35 clock-names = "apb", "spdif";
36 dmas = <&dma 0 2>, <&dma 0 2>;
37 dma-names = "rx", "tx";
38 status = "okay";
39};
Documentation/devicetree/bindings/sound/ti,ads117x.txt+11−0
@@ -0,0 +1,11 @@
1Texas Intstruments ADS117x ADC
2
3Required properties:
4
5 - compatible : "ti,ads1174" or "ti,ads1178"
6
7Example:
8
9ads1178 {
10 compatible = "ti,ads1178";
11};
Documentation/sound/alsa/ALSA-Configuration.txt+9−0
@@ -1910,6 +1910,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 1909 unmodified lines
1910 - Default: 0x0000 1910 - Default: 0x0000
1911 ignore_ctl_error - Ignore any USB-controller regarding mixer1911 ignore_ctl_error - Ignore any USB-controller regarding mixer
1912 interface (default: no)1912 interface (default: no)
1913 autoclock - Enable auto-clock selection for UAC2 devices
1914 (default: yes)
1915 quirk_alias - Quirk alias list, pass strings like
1916 "0123abcd:5678beef", which applies the existing
1917 quirk for the device 5678:beef to a new device
1918 0123:abcd.
1913 1919
1914 This module supports multiple devices, autoprobe and hotplugging.1920 This module supports multiple devices, autoprobe and hotplugging.
1915 1921
@@ -1919,6 +1925,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. · 3 unmodified lines
1919 NB: ignore_ctl_error=1 may help when you get an error at accessing1925 NB: ignore_ctl_error=1 may help when you get an error at accessing
1920 the mixer element such as URB error -22. This happens on some1926 the mixer element such as URB error -22. This happens on some
1921 buggy USB device or the controller.1927 buggy USB device or the controller.
1928 NB: quirk_alias option is provided only for testing / development.
1929 If you want to have a proper support, contact to upstream for
1930 adding the matching quirk in the driver code statically.
1922 1931
1923 Module snd-usb-caiaq1932 Module snd-usb-caiaq
1924 --------------------1933 --------------------
Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt+74−0
@@ -0,0 +1,74 @@
1To support DP MST audio, HD Audio hdmi codec driver introduces virtual pin
2and dynamic pcm assignment.
3
4Virtual pin is an extension of per_pin. The most difference of DP MST
5from legacy is that DP MST introduces device entry. Each pin can contain
6several device entries. Each device entry behaves as a pin.
7
8As each pin may contain several device entries and each codec may contain
9several pins, if we use one pcm per per_pin, there will be many PCMs.
10The new solution is to create a few PCMs and to dynamically bind pcm to
11per_pin. Driver uses spec->dyn_pcm_assign flag to indicate whether to use
12the new solution.
13
14PCM
15===
16To be added
17
18
19Jack
20====
21
22Presume:
23 - MST must be dyn_pcm_assign, and it is acomp (for Intel scenario);
24 - NON-MST may or may not be dyn_pcm_assign, it can be acomp or !acomp;
25
26So there are the following scenarios:
27 a. MST (&& dyn_pcm_assign && acomp)
28 b. NON-MST && dyn_pcm_assign && acomp
29 c. NON-MST && !dyn_pcm_assign && !acomp
30
31Below discussion will ignore MST and NON-MST difference as it doesn't
32impact on jack handling too much.
33
34Driver uses struct hdmi_pcm pcm[] array in hdmi_spec and snd_jack is
35a member of hdmi_pcm. Each pin has one struct hdmi_pcm * pcm pointer.
36
37For !dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] statically.
38
39For dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n]
40when monitor is hotplugged.
41
42
43Build Jack
44----------
45
46- dyn_pcm_assign
47Will not use hda_jack but use snd_jack in spec->pcm_rec[pcm_idx].jack directly.
48
49- !dyn_pcm_assign
50Use hda_jack and assign spec->pcm_rec[pcm_idx].jack = jack->jack statically.
51
52
53Unsolicited Event Enabling
54--------------------------
55Enable unsolicited event if !acomp.
56
57
58Monitor Hotplug Event Handling
59------------------------------
60- acomp
61pin_eld_notify() -> check_presence_and_report() -> hdmi_present_sense() ->
62sync_eld_via_acomp().
63Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for
64both dyn_pcm_assign and !dyn_pcm_assign
65
66- !acomp
67Hdmi_unsol_event() -> hdmi_intrinsic_event() -> check_presence_and_report() ->
68hdmi_present_sense() -> hdmi_prepsent_sense_via_verbs()
69Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for dyn_pcm_assign.
70Use hda_jack mechanism to handle jack events.
71
72
73Others to be added later
74========================
drivers/misc/atmel-ssc.c+1−0
@@ -34,6 +34,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num) · 33 unmodified lines
34 if (ssc->pdev->dev.of_node) {34 if (ssc->pdev->dev.of_node) {
35 if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc")35 if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc")
36 == ssc_num) {36 == ssc_num) {
37 ssc->pdev->id = ssc_num;
37 ssc_valid = 1;38 ssc_valid = 1;
38 break;39 break;
39 }40 }
include/drm/drm_edid.h+12−0
@@ -403,6 +403,18 @@ static inline int drm_eld_size(const uint8_t *eld) · 402 unmodified lines
403 return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;403 return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
404}404}
405 405
406/**
407 * drm_eld_get_conn_type - Get device type hdmi/dp connected
408 * @eld: pointer to an ELD memory structure
409 *
410 * The caller need to use %DRM_ELD_CONN_TYPE_HDMI or %DRM_ELD_CONN_TYPE_DP to
411 * identify the display type connected.
412 */
413static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
414{
415 return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
416}
417
406struct edid *drm_do_get_edid(struct drm_connector *connector,418struct edid *drm_do_get_edid(struct drm_connector *connector,
407 int (*get_edid_block)(void *data, u8 *buf, unsigned int block,419 int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
408 size_t len),420 size_t len),
include/linux/platform_data/adau17x1.h+1−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961/ADAU1781/ADAU1781 codecs2 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781 codecs
3 *3 *
4 * Copyright 2011-2014 Analog Devices Inc.4 * Copyright 2011-2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>5 * Author: Lars-Peter Clausen <lars@metafoo.de>
include/sound/hda_chmap.h+76−0
@@ -0,0 +1,76 @@
1/*
2 * For multichannel support
3 */
4
5#ifndef __SOUND_HDA_CHMAP_H
6#define __SOUND_HDA_CHMAP_H
7
8#include <sound/pcm.h>
9#include <sound/hdaudio.h>
10
11
12#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
13
14struct hdac_cea_channel_speaker_allocation {
15 int ca_index;
16 int speakers[8];
17
18 /* derived values, just for convenience */
19 int channels;
20 int spk_mask;
21};
22struct hdac_chmap;
23
24struct hdac_chmap_ops {
25 /*
26 * Helpers for producing the channel map TLVs. These can be overridden
27 * for devices that have non-standard mapping requirements.
28 */
29 int (*chmap_cea_alloc_validate_get_type)(struct hdac_chmap *chmap,
30 struct hdac_cea_channel_speaker_allocation *cap, int channels);
31 void (*cea_alloc_to_tlv_chmap)(struct hdac_chmap *hchmap,
32 struct hdac_cea_channel_speaker_allocation *cap,
33 unsigned int *chmap, int channels);
34
35 /* check that the user-given chmap is supported */
36 int (*chmap_validate)(struct hdac_chmap *hchmap, int ca,
37 int channels, unsigned char *chmap);
38
39 void (*get_chmap)(struct hdac_device *hdac, int pcm_idx,
40 unsigned char *chmap);
41 void (*set_chmap)(struct hdac_device *hdac, int pcm_idx,
42 unsigned char *chmap, int prepared);
43 bool (*is_pcm_attached)(struct hdac_device *hdac, int pcm_idx);
44
45 /* get and set channel assigned to each HDMI ASP (audio sample packet) slot */
46 int (*pin_get_slot_channel)(struct hdac_device *codec,
47 hda_nid_t pin_nid, int asp_slot);
48 int (*pin_set_slot_channel)(struct hdac_device *codec,
49 hda_nid_t pin_nid, int asp_slot, int channel);
50 void (*set_channel_count)(struct hdac_device *codec,
51 hda_nid_t cvt_nid, int chs);
52};
53
54struct hdac_chmap {
55 unsigned int channels_max; /* max over all cvts */
56 struct hdac_chmap_ops ops;
57 struct hdac_device *hdac;
58};
59
60void snd_hdac_register_chmap_ops(struct hdac_device *hdac,
61 struct hdac_chmap *chmap);
62int snd_hdac_channel_allocation(struct hdac_device *hdac, int spk_alloc,
63 int channels, bool chmap_set,
64 bool non_pcm, unsigned char *map);
65int snd_hdac_get_active_channels(int ca);
66void snd_hdac_setup_channel_mapping(struct hdac_chmap *chmap,
67 hda_nid_t pin_nid, bool non_pcm, int ca,
68 int channels, unsigned char *map,
69 bool chmap_set);
70void snd_hdac_print_channel_allocation(int spk_alloc, char *buf, int buflen);
71struct hdac_cea_channel_speaker_allocation *snd_hdac_get_ch_alloc_from_ca(int ca);
72int snd_hdac_chmap_to_spk_mask(unsigned char c);
73int snd_hdac_spk_to_chmap(int spk);
74int snd_hdac_add_chmap_ctls(struct snd_pcm *pcm, int pcm_idx,
75 struct hdac_chmap *chmap);
76#endif /* __SOUND_HDA_CHMAP_H */
include/sound/hdaudio.h+2−0
@@ -168,11 +168,13 @@ int snd_hdac_power_up(struct hdac_device *codec); · 167 unmodified lines
168int snd_hdac_power_down(struct hdac_device *codec);168int snd_hdac_power_down(struct hdac_device *codec);
169int snd_hdac_power_up_pm(struct hdac_device *codec);169int snd_hdac_power_up_pm(struct hdac_device *codec);
170int snd_hdac_power_down_pm(struct hdac_device *codec);170int snd_hdac_power_down_pm(struct hdac_device *codec);
171int snd_hdac_keep_power_up(struct hdac_device *codec);
171#else172#else
172static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }173static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
173static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }174static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
174static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }175static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
175static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }176static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
177static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
176#endif178#endif
177 179
178/*180/*
include/sound/jack.h+14−9
@@ -72,14 +72,16 @@ enum snd_jack_types { · 71 unmodified lines
72#define SND_JACK_SWITCH_TYPES 672#define SND_JACK_SWITCH_TYPES 6
73 73
74struct snd_jack {74struct snd_jack {
75 struct input_dev *input_dev;
76 struct list_head kctl_list;75 struct list_head kctl_list;
77 struct snd_card *card;76 struct snd_card *card;
77 const char *id;
78#ifdef CONFIG_SND_JACK_INPUT_DEV
79 struct input_dev *input_dev;
78 int registered;80 int registered;
79 int type;81 int type;
80 const char *id;
81 char name[100];82 char name[100];
82 unsigned int key[6]; /* Keep in sync with definitions above */83 unsigned int key[6]; /* Keep in sync with definitions above */
84#endif /* CONFIG_SND_JACK_INPUT_DEV */
83 void *private_data;85 void *private_data;
84 void (*private_free)(struct snd_jack *);86 void (*private_free)(struct snd_jack *);
85};87};
@@ -89,10 +91,11 @@ struct snd_jack { · 3 unmodified lines
89int snd_jack_new(struct snd_card *card, const char *id, int type,91int snd_jack_new(struct snd_card *card, const char *id, int type,
90 struct snd_jack **jack, bool initial_kctl, bool phantom_jack);92 struct snd_jack **jack, bool initial_kctl, bool phantom_jack);
91int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);93int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name, int mask);
94#ifdef CONFIG_SND_JACK_INPUT_DEV
92void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);95void snd_jack_set_parent(struct snd_jack *jack, struct device *parent);
93int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,96int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
94 int keytype);97 int keytype);
95 98#endif
96void snd_jack_report(struct snd_jack *jack, int status);99void snd_jack_report(struct snd_jack *jack, int status);
97 100
98#else101#else
@@ -107,6 +110,13 @@ static inline int snd_jack_add_new_kctl(struct snd_jack *jack, const char * name · 8 unmodified lines
107 return 0;110 return 0;
108}111}
109 112
113static inline void snd_jack_report(struct snd_jack *jack, int status)
114{
115}
116
117#endif
118
119#if !defined(CONFIG_SND_JACK) || !defined(CONFIG_SND_JACK_INPUT_DEV)
110static inline void snd_jack_set_parent(struct snd_jack *jack,120static inline void snd_jack_set_parent(struct snd_jack *jack,
111 struct device *parent)121 struct device *parent)
112{122{
@@ -118,11 +128,6 @@ static inline int snd_jack_set_key(struct snd_jack *jack, · 5 unmodified lines
118{128{
119 return 0;129 return 0;
120}130}
121 131#endif /* !CONFIG_SND_JACK || !CONFIG_SND_JACK_INPUT_DEV */
122static inline void snd_jack_report(struct snd_jack *jack, int status)
123{
124}
125
126#endif
127 132
128#endif133#endif
include/sound/pcm.h+2−0
@@ -1093,6 +1093,8 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate); · 1092 unmodified lines
1093unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);1093unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
1094unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,1094unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
1095 unsigned int rates_b);1095 unsigned int rates_b);
1096unsigned int snd_pcm_rate_range_to_bits(unsigned int rate_min,
1097 unsigned int rate_max);
1096 1098
1097/**1099/**
1098 * snd_pcm_set_runtime_buffer - Set the PCM runtime buffer1100 * snd_pcm_set_runtime_buffer - Set the PCM runtime buffer
include/sound/soc-topology.h+10−11
@@ -56,12 +56,6 @@ struct snd_soc_dobj_widget { · 55 unmodified lines
56 unsigned int kcontrol_enum:1; /* this widget is an enum kcontrol */56 unsigned int kcontrol_enum:1; /* this widget is an enum kcontrol */
57};57};
58 58
59/* dynamic PCM DAI object */
60struct snd_soc_dobj_pcm_dai {
61 struct snd_soc_tplg_pcm_dai *pd;
62 unsigned int count;
63};
64
65/* generic dynamic object - all dynamic objects belong to this struct */59/* generic dynamic object - all dynamic objects belong to this struct */
66struct snd_soc_dobj {60struct snd_soc_dobj {
67 enum snd_soc_dobj_type type;61 enum snd_soc_dobj_type type;
@@ -71,7 +65,6 @@ struct snd_soc_dobj { · 3 unmodified lines
71 union {65 union {
72 struct snd_soc_dobj_control control;66 struct snd_soc_dobj_control control;
73 struct snd_soc_dobj_widget widget;67 struct snd_soc_dobj_widget widget;
74 struct snd_soc_dobj_pcm_dai pcm_dai;
75 };68 };
76 void *private; /* core does not touch this */69 void *private; /* core does not touch this */
77};70};
@@ -126,10 +119,16 @@ struct snd_soc_tplg_ops { · 48 unmodified lines
126 int (*widget_unload)(struct snd_soc_component *,119 int (*widget_unload)(struct snd_soc_component *,
127 struct snd_soc_dobj *);120 struct snd_soc_dobj *);
128 121
129 /* FE - used for any driver specific init */122 /* FE DAI - used for any driver specific init */
130 int (*pcm_dai_load)(struct snd_soc_component *,123 int (*dai_load)(struct snd_soc_component *,
131 struct snd_soc_tplg_pcm_dai *pcm_dai, int num_fe);124 struct snd_soc_dai_driver *dai_drv);
132 int (*pcm_dai_unload)(struct snd_soc_component *,125 int (*dai_unload)(struct snd_soc_component *,
126 struct snd_soc_dobj *);
127
128 /* DAI link - used for any driver specific init */
129 int (*link_load)(struct snd_soc_component *,
130 struct snd_soc_dai_link *link);
131 int (*link_unload)(struct snd_soc_component *,
133 struct snd_soc_dobj *);132 struct snd_soc_dobj *);
134 133
135 /* callback to handle vendor bespoke data */134 /* callback to handle vendor bespoke data */
include/sound/soc.h+1−1
@@ -27,7 +27,6 @@ · 26 unmodified lines
27#include <sound/compress_driver.h>27#include <sound/compress_driver.h>
28#include <sound/control.h>28#include <sound/control.h>
29#include <sound/ac97_codec.h>29#include <sound/ac97_codec.h>
30#include <sound/soc-topology.h>
31 30
32/*31/*
33 * Convenience kcontrol builders32 * Convenience kcontrol builders
@@ -404,6 +403,7 @@ struct snd_soc_jack_zone; · 370 unmodified lines
404struct snd_soc_jack_pin;403struct snd_soc_jack_pin;
405#include <sound/soc-dapm.h>404#include <sound/soc-dapm.h>
406#include <sound/soc-dpcm.h>405#include <sound/soc-dpcm.h>
406#include <sound/soc-topology.h>
407 407
408struct snd_soc_jack_gpio;408struct snd_soc_jack_gpio;
409 409
include/uapi/sound/asequencer.h+4−8
@@ -25,7 +25,7 @@ · 24 unmodified lines
25#include <sound/asound.h>25#include <sound/asound.h>
26 26
27/** version of the sequencer */27/** version of the sequencer */
28#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION (1, 0, 1)28#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 2)
29 29
30/**30/**
31 * definition of sequencer event types31 * definition of sequencer event types
@@ -357,7 +357,9 @@ struct snd_seq_client_info { · 325 unmodified lines
357 unsigned char event_filter[32]; /* event filter bitmap */357 unsigned char event_filter[32]; /* event filter bitmap */
358 int num_ports; /* RO: number of ports */358 int num_ports; /* RO: number of ports */
359 int event_lost; /* number of lost events */359 int event_lost; /* number of lost events */
360 char reserved[64]; /* for future use */360 int card; /* RO: card number[kernel] */
361 int pid; /* RO: pid[user] */
362 char reserved[56]; /* for future use */
361};363};
362 364
363 365
@@ -594,14 +596,8 @@ struct snd_seq_query_subs { · 230 unmodified lines
594#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)596#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)
595#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct snd_seq_queue_tempo)597#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct snd_seq_queue_tempo)
596#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct snd_seq_queue_tempo)598#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct snd_seq_queue_tempo)
597#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct snd_seq_queue_owner)
598#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct snd_seq_queue_owner)
599#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct snd_seq_queue_timer)599#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct snd_seq_queue_timer)
600#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct snd_seq_queue_timer)600#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct snd_seq_queue_timer)
601/* XXX
602#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct snd_seq_queue_sync)
603#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct snd_seq_queue_sync)
604*/
605#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct snd_seq_queue_client)601#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct snd_seq_queue_client)
606#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct snd_seq_queue_client)602#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct snd_seq_queue_client)
607#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct snd_seq_client_pool)603#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct snd_seq_client_pool)
include/uapi/sound/asound.h+4−0
@@ -23,7 +23,11 @@ · 22 unmodified lines
23#ifndef _UAPI__SOUND_ASOUND_H23#ifndef _UAPI__SOUND_ASOUND_H
24#define _UAPI__SOUND_ASOUND_H24#define _UAPI__SOUND_ASOUND_H
25 25
26#if defined(__KERNEL__) || defined(__linux__)
26#include <linux/types.h>27#include <linux/types.h>
28#else
29#include <sys/ioctl.h>
30#endif
27 31
28#ifndef __KERNEL__32#ifndef __KERNEL__
29#include <stdlib.h>33#include <stdlib.h>
sound/core/Kconfig+6−3
@@ -24,12 +24,15 @@ config SND_RAWMIDI · 23 unmodified lines
24config SND_COMPRESS_OFFLOAD24config SND_COMPRESS_OFFLOAD
25 tristate25 tristate
26 26
27# To be effective this also requires INPUT - users should say:
28# select SND_JACK if INPUT=y || INPUT=SND
29# to avoid having to force INPUT on.
30config SND_JACK27config SND_JACK
31 bool28 bool
32 29
30# enable input device support in jack layer
31config SND_JACK_INPUT_DEV
32 bool
33 depends on SND_JACK
34 default y if INPUT=y || INPUT=SND
35
33config SND_SEQUENCER36config SND_SEQUENCER
34 tristate "Sequencer support"37 tristate "Sequencer support"
35 select SND_TIMER38 select SND_TIMER
sound/core/compress_offload.c+8−4
@@ -69,11 +69,14 @@ struct snd_compr_file { · 68 unmodified lines
69 69
70/*70/*
71 * a note on stream states used:71 * a note on stream states used:
72 * we use follwing states in the compressed core72 * we use following states in the compressed core
73 * SNDRV_PCM_STATE_OPEN: When stream has been opened.73 * SNDRV_PCM_STATE_OPEN: When stream has been opened.
74 * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by74 * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by
75 * calling SNDRV_COMPRESS_SET_PARAMS. running streams will come to this75 * calling SNDRV_COMPRESS_SET_PARAMS. Running streams will come to this
76 * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain.76 * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain.
77 * SNDRV_PCM_STATE_PREPARED: When a stream has been written to (for
78 * playback only). User after setting up stream writes the data buffer
79 * before starting the stream.
77 * SNDRV_PCM_STATE_RUNNING: When stream has been started and is80 * SNDRV_PCM_STATE_RUNNING: When stream has been started and is
78 * decoding/encoding and rendering/capturing data.81 * decoding/encoding and rendering/capturing data.
79 * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done82 * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done
@@ -286,6 +289,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, · 206 unmodified lines
286 mutex_lock(&stream->device->lock);289 mutex_lock(&stream->device->lock);
287 /* write is allowed when stream is running or has been steup */290 /* write is allowed when stream is running or has been steup */
288 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&291 if (stream->runtime->state != SNDRV_PCM_STATE_SETUP &&
292 stream->runtime->state != SNDRV_PCM_STATE_PREPARED &&
289 stream->runtime->state != SNDRV_PCM_STATE_RUNNING) {293 stream->runtime->state != SNDRV_PCM_STATE_RUNNING) {
290 mutex_unlock(&stream->device->lock);294 mutex_unlock(&stream->device->lock);
291 return -EBADFD;295 return -EBADFD;
@@ -700,7 +704,7 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) · 408 unmodified lines
700 704
701 /*705 /*
702 * We are called with lock held. So drop the lock while we wait for706 * We are called with lock held. So drop the lock while we wait for
703 * drain complete notfication from the driver707 * drain complete notification from the driver
704 *708 *
705 * It is expected that driver will notify the drain completion and then709 * It is expected that driver will notify the drain completion and then
706 * stream will be moved to SETUP state, even if draining resulted in an710 * stream will be moved to SETUP state, even if draining resulted in an
@@ -755,7 +759,7 @@ static int snd_compr_next_track(struct snd_compr_stream *stream) · 48 unmodified lines
755 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)759 if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
756 return -EPERM;760 return -EPERM;
757 761
758 /* you can signal next track isf this is intended to be a gapless stream762 /* you can signal next track if this is intended to be a gapless stream
759 * and current track metadata is set763 * and current track metadata is set
760 */764 */
761 if (stream->metadata_set == false)765 if (stream->metadata_set == false)
sound/core/control_compat.c+1−1
@@ -196,7 +196,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, · 195 unmodified lines
196 kctl = snd_ctl_find_id(card, id);196 kctl = snd_ctl_find_id(card, id);
197 if (! kctl) {197 if (! kctl) {
198 up_read(&card->controls_rwsem);198 up_read(&card->controls_rwsem);
199 return -ENXIO;199 return -ENOENT;
200 }200 }
201 info = kzalloc(sizeof(*info), GFP_KERNEL);201 info = kzalloc(sizeof(*info), GFP_KERNEL);
202 if (info == NULL) {202 if (info == NULL) {
sound/core/jack.c+20−3
@@ -32,6 +32,7 @@ struct snd_jack_kctl { · 31 unmodified lines
32 unsigned int mask_bits; /* only masked status bits are reported via kctl */32 unsigned int mask_bits; /* only masked status bits are reported via kctl */
33};33};
34 34
35#ifdef CONFIG_SND_JACK_INPUT_DEV
35static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {36static int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
36 SW_HEADPHONE_INSERT,37 SW_HEADPHONE_INSERT,
37 SW_MICROPHONE_INSERT,38 SW_MICROPHONE_INSERT,
@@ -40,9 +41,11 @@ static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { · 2 unmodified lines
40 SW_VIDEOOUT_INSERT,41 SW_VIDEOOUT_INSERT,
41 SW_LINEIN_INSERT,42 SW_LINEIN_INSERT,
42};43};
44#endif /* CONFIG_SND_JACK_INPUT_DEV */
43 45
44static int snd_jack_dev_disconnect(struct snd_device *device)46static int snd_jack_dev_disconnect(struct snd_device *device)
45{47{
48#ifdef CONFIG_SND_JACK_INPUT_DEV
46 struct snd_jack *jack = device->device_data;49 struct snd_jack *jack = device->device_data;
47 50
48 if (!jack->input_dev)51 if (!jack->input_dev)
@@ -55,6 +58,7 @@ static int snd_jack_dev_disconnect(struct snd_device *device) · 6 unmodified lines
55 else58 else
56 input_free_device(jack->input_dev);59 input_free_device(jack->input_dev);
57 jack->input_dev = NULL;60 jack->input_dev = NULL;
61#endif /* CONFIG_SND_JACK_INPUT_DEV */
58 return 0;62 return 0;
59}63}
60 64
@@ -79,6 +83,7 @@ static int snd_jack_dev_free(struct snd_device *device) · 18 unmodified lines
79 return 0;83 return 0;
80}84}
81 85
86#ifdef CONFIG_SND_JACK_INPUT_DEV
82static int snd_jack_dev_register(struct snd_device *device)87static int snd_jack_dev_register(struct snd_device *device)
83{88{
84 struct snd_jack *jack = device->device_data;89 struct snd_jack *jack = device->device_data;
@@ -116,6 +121,7 @@ static int snd_jack_dev_register(struct snd_device *device) · 31 unmodified lines
116 121
117 return err;122 return err;
118}123}
124#endif /* CONFIG_SND_JACK_INPUT_DEV */
119 125
120static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)126static void snd_jack_kctl_private_free(struct snd_kcontrol *kctl)
121{127{
@@ -209,11 +215,12 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, · 87 unmodified lines
209 struct snd_jack *jack;215 struct snd_jack *jack;
210 struct snd_jack_kctl *jack_kctl = NULL;216 struct snd_jack_kctl *jack_kctl = NULL;
211 int err;217 int err;
212 int i;
213 static struct snd_device_ops ops = {218 static struct snd_device_ops ops = {
214 .dev_free = snd_jack_dev_free,219 .dev_free = snd_jack_dev_free,
220#ifdef CONFIG_SND_JACK_INPUT_DEV
215 .dev_register = snd_jack_dev_register,221 .dev_register = snd_jack_dev_register,
216 .dev_disconnect = snd_jack_dev_disconnect,222 .dev_disconnect = snd_jack_dev_disconnect,
223#endif /* CONFIG_SND_JACK_INPUT_DEV */
217 };224 };
218 225
219 if (initial_kctl) {226 if (initial_kctl) {
@@ -230,6 +237,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, · 10 unmodified lines
230 237
231 /* don't creat input device for phantom jack */238 /* don't creat input device for phantom jack */
232 if (!phantom_jack) {239 if (!phantom_jack) {
240#ifdef CONFIG_SND_JACK_INPUT_DEV
241 int i;
242
233 jack->input_dev = input_allocate_device();243 jack->input_dev = input_allocate_device();
234 if (jack->input_dev == NULL) {244 if (jack->input_dev == NULL) {
235 err = -ENOMEM;245 err = -ENOMEM;
@@ -245,6 +255,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, · 9 unmodified lines
245 input_set_capability(jack->input_dev, EV_SW,255 input_set_capability(jack->input_dev, EV_SW,
246 jack_switch_types[i]);256 jack_switch_types[i]);
247 257
258#endif /* CONFIG_SND_JACK_INPUT_DEV */
248 }259 }
249 260
250 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);261 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
@@ -262,13 +273,16 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, · 11 unmodified lines
262 return 0;273 return 0;
263 274
264fail_input:275fail_input:
276#ifdef CONFIG_SND_JACK_INPUT_DEV
265 input_free_device(jack->input_dev);277 input_free_device(jack->input_dev);
278#endif
266 kfree(jack->id);279 kfree(jack->id);
267 kfree(jack);280 kfree(jack);
268 return err;281 return err;
269}282}
270EXPORT_SYMBOL(snd_jack_new);283EXPORT_SYMBOL(snd_jack_new);
271 284
285#ifdef CONFIG_SND_JACK_INPUT_DEV
272/**286/**
273 * snd_jack_set_parent - Set the parent device for a jack287 * snd_jack_set_parent - Set the parent device for a jack
274 *288 *
@@ -326,10 +340,10 @@ int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, · 51 unmodified lines
326 340
327 jack->type |= type;341 jack->type |= type;
328 jack->key[key] = keytype;342 jack->key[key] = keytype;
329
330 return 0;343 return 0;
331}344}
332EXPORT_SYMBOL(snd_jack_set_key);345EXPORT_SYMBOL(snd_jack_set_key);
346#endif /* CONFIG_SND_JACK_INPUT_DEV */
333 347
334/**348/**
335 * snd_jack_report - Report the current status of a jack349 * snd_jack_report - Report the current status of a jack
@@ -340,7 +354,9 @@ EXPORT_SYMBOL(snd_jack_set_key); · 4 unmodified lines
340void snd_jack_report(struct snd_jack *jack, int status)354void snd_jack_report(struct snd_jack *jack, int status)
341{355{
342 struct snd_jack_kctl *jack_kctl;356 struct snd_jack_kctl *jack_kctl;
357#ifdef CONFIG_SND_JACK_INPUT_DEV
343 int i;358 int i;
359#endif
344 360
345 if (!jack)361 if (!jack)
346 return;362 return;
@@ -349,6 +365,7 @@ void snd_jack_report(struct snd_jack *jack, int status) · 2 unmodified lines
349 snd_kctl_jack_report(jack->card, jack_kctl->kctl,365 snd_kctl_jack_report(jack->card, jack_kctl->kctl,
350 status & jack_kctl->mask_bits);366 status & jack_kctl->mask_bits);
351 367
368#ifdef CONFIG_SND_JACK_INPUT_DEV
352 if (!jack->input_dev)369 if (!jack->input_dev)
353 return;370 return;
354 371
@@ -369,6 +386,6 @@ void snd_jack_report(struct snd_jack *jack, int status) · 14 unmodified lines
369 }386 }
370 387
371 input_sync(jack->input_dev);388 input_sync(jack->input_dev);
372 389#endif /* CONFIG_SND_JACK_INPUT_DEV */
373}390}
374EXPORT_SYMBOL(snd_jack_report);391EXPORT_SYMBOL(snd_jack_report);
sound/core/pcm_lib.c+1−1
@@ -322,7 +322,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 321 unmodified lines
322 char name[16];322 char name[16];
323 snd_pcm_debug_name(substream, name, sizeof(name));323 snd_pcm_debug_name(substream, name, sizeof(name));
324 pcm_err(substream->pcm,324 pcm_err(substream->pcm,
325 "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n",325 "invalid position: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
326 name, pos, runtime->buffer_size,326 name, pos, runtime->buffer_size,
327 runtime->period_size);327 runtime->period_size);
328 }328 }
sound/core/pcm_misc.c+30−0
@@ -565,3 +565,33 @@ unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, · 564 unmodified lines
565 return rates_a & rates_b;565 return rates_a & rates_b;
566}566}
567EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);567EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);
568
569/**
570 * snd_pcm_rate_range_to_bits - converts rate range to SNDRV_PCM_RATE_xxx bit
571 * @rate_min: the minimum sample rate
572 * @rate_max: the maximum sample rate
573 *
574 * This function has an implicit assumption: the rates in the given range have
575 * only the pre-defined rates like 44100 or 16000.
576 *
577 * Return: The SNDRV_PCM_RATE_xxx flag that corresponds to the given rate range,
578 * or SNDRV_PCM_RATE_KNOT for an unknown range.
579 */
580unsigned int snd_pcm_rate_range_to_bits(unsigned int rate_min,
581 unsigned int rate_max)
582{
583 unsigned int rates = 0;
584 int i;
585
586 for (i = 0; i < snd_pcm_known_rates.count; i++) {
587 if (snd_pcm_known_rates.list[i] >= rate_min
588 && snd_pcm_known_rates.list[i] <= rate_max)
589 rates |= 1 << i;
590 }
591
592 if (!rates)
593 rates = SNDRV_PCM_RATE_KNOT;
594
595 return rates;
596}
597EXPORT_SYMBOL_GPL(snd_pcm_rate_range_to_bits);
sound/core/seq/seq_clientmgr.c+14−0
@@ -364,6 +364,7 @@ static int snd_seq_open(struct inode *inode, struct file *file) · 363 unmodified lines
364 /* fill client data */364 /* fill client data */
365 user->file = file;365 user->file = file;
366 sprintf(client->name, "Client-%d", c);366 sprintf(client->name, "Client-%d", c);
367 client->data.user.owner = get_pid(task_pid(current));
367 368
368 /* make others aware this new client */369 /* make others aware this new client */
369 snd_seq_system_client_ev_client_start(c);370 snd_seq_system_client_ev_client_start(c);
@@ -380,6 +381,7 @@ static int snd_seq_release(struct inode *inode, struct file *file) · 10 unmodified lines
380 seq_free_client(client);381 seq_free_client(client);
381 if (client->data.user.fifo)382 if (client->data.user.fifo)
382 snd_seq_fifo_delete(&client->data.user.fifo);383 snd_seq_fifo_delete(&client->data.user.fifo);
384 put_pid(client->data.user.owner);
383 kfree(client);385 kfree(client);
384 }386 }
385 387
@@ -1197,6 +1199,17 @@ static void get_client_info(struct snd_seq_client *cptr, · 811 unmodified lines
1197 info->event_lost = cptr->event_lost;1199 info->event_lost = cptr->event_lost;
1198 memcpy(info->event_filter, cptr->event_filter, 32);1200 memcpy(info->event_filter, cptr->event_filter, 32);
1199 info->num_ports = cptr->num_ports;1201 info->num_ports = cptr->num_ports;
1202
1203 if (cptr->type == USER_CLIENT)
1204 info->pid = pid_vnr(cptr->data.user.owner);
1205 else
1206 info->pid = -1;
1207
1208 if (cptr->type == KERNEL_CLIENT)
1209 info->card = cptr->data.kernel.card ? cptr->data.kernel.card->number : -1;
1210 else
1211 info->card = -1;
1212
1200 memset(info->reserved, 0, sizeof(info->reserved));1213 memset(info->reserved, 0, sizeof(info->reserved));
1201}1214}
1202 1215
@@ -2271,6 +2284,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, · 1068 unmodified lines
2271 2284
2272 client->accept_input = 1;2285 client->accept_input = 1;
2273 client->accept_output = 1;2286 client->accept_output = 1;
2287 client->data.kernel.card = card;
2274 2288
2275 va_start(args, name_fmt);2289 va_start(args, name_fmt);
2276 vsnprintf(client->name, sizeof(client->name), name_fmt, args);2290 vsnprintf(client->name, sizeof(client->name), name_fmt, args);
sound/core/seq/seq_clientmgr.h+2−0
@@ -33,6 +33,7 @@ · 32 unmodified lines
33struct snd_seq_user_client {33struct snd_seq_user_client {
34 struct file *file; /* file struct of client */34 struct file *file; /* file struct of client */
35 /* ... */35 /* ... */
36 struct pid *owner;
36 37
37 /* fifo */38 /* fifo */
38 struct snd_seq_fifo *fifo; /* queue for incoming events */39 struct snd_seq_fifo *fifo; /* queue for incoming events */
@@ -41,6 +42,7 @@ struct snd_seq_user_client { · 2 unmodified lines
41 42
42struct snd_seq_kernel_client {43struct snd_seq_kernel_client {
43 /* ... */44 /* ... */
45 struct snd_card *card;
44};46};
45 47
46 48
sound/core/timer.c+123−145
@@ -305,8 +305,6 @@ int snd_timer_open(struct snd_timer_instance **ti, · 304 unmodified lines
305 return 0;305 return 0;
306}306}
307 307
308static int _snd_timer_stop(struct snd_timer_instance *timeri, int event);
309
310/*308/*
311 * close a timer instance309 * close a timer instance
312 */310 */
@@ -318,25 +316,14 @@ int snd_timer_close(struct snd_timer_instance *timeri) · 5 unmodified lines
318 if (snd_BUG_ON(!timeri))316 if (snd_BUG_ON(!timeri))
319 return -ENXIO;317 return -ENXIO;
320 318
319 mutex_lock(&register_mutex);
320 list_del(&timeri->open_list);
321
321 /* force to stop the timer */322 /* force to stop the timer */
322 snd_timer_stop(timeri);323 snd_timer_stop(timeri);
323 324
324 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {325 timer = timeri->timer;
325 /* wait, until the active callback is finished */326 if (timer) {
326 spin_lock_irq(&slave_active_lock);
327 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
328 spin_unlock_irq(&slave_active_lock);
329 udelay(10);
330 spin_lock_irq(&slave_active_lock);
331 }
332 spin_unlock_irq(&slave_active_lock);
333 mutex_lock(&register_mutex);
334 list_del(&timeri->open_list);
335 mutex_unlock(&register_mutex);
336 } else {
337 timer = timeri->timer;
338 if (snd_BUG_ON(!timer))
339 goto out;
340 /* wait, until the active callback is finished */327 /* wait, until the active callback is finished */
341 spin_lock_irq(&timer->lock);328 spin_lock_irq(&timer->lock);
342 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {329 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@@ -345,11 +332,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) · 2 unmodified lines
345 spin_lock_irq(&timer->lock);332 spin_lock_irq(&timer->lock);
346 }333 }
347 spin_unlock_irq(&timer->lock);334 spin_unlock_irq(&timer->lock);
348 mutex_lock(&register_mutex);335
349 list_del(&timeri->open_list);
350 if (list_empty(&timer->open_list_head) &&
351 timer->hw.close)
352 timer->hw.close(timer);
353 /* remove slave links */336 /* remove slave links */
354 spin_lock_irq(&slave_active_lock);337 spin_lock_irq(&slave_active_lock);
355 spin_lock(&timer->lock);338 spin_lock(&timer->lock);
@@ -363,18 +346,27 @@ int snd_timer_close(struct snd_timer_instance *timeri) · 7 unmodified lines
363 }346 }
364 spin_unlock(&timer->lock);347 spin_unlock(&timer->lock);
365 spin_unlock_irq(&slave_active_lock);348 spin_unlock_irq(&slave_active_lock);
366 /* release a card refcount for safe disconnection */349
367 if (timer->card)350 /* slave doesn't need to release timer resources below */
368 put_device(&timer->card->card_dev);351 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
369 mutex_unlock(&register_mutex);352 timer = NULL;
370 }353 }
371 out:354
372 if (timeri->private_free)355 if (timeri->private_free)
373 timeri->private_free(timeri);356 timeri->private_free(timeri);
374 kfree(timeri->owner);357 kfree(timeri->owner);
375 kfree(timeri);358 kfree(timeri);
376 if (timer)359
360 if (timer) {
361 if (list_empty(&timer->open_list_head) && timer->hw.close)
362 timer->hw.close(timer);
363 /* release a card refcount for safe disconnection */
364 if (timer->card)
365 put_device(&timer->card->card_dev);
377 module_put(timer->module);366 module_put(timer->module);
367 }
368
369 mutex_unlock(&register_mutex);
378 return 0;370 return 0;
379}371}
380 372
@@ -395,7 +387,6 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) · 14 unmodified lines
395static void snd_timer_notify1(struct snd_timer_instance *ti, int event)387static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
396{388{
397 struct snd_timer *timer;389 struct snd_timer *timer;
398 unsigned long flags;
399 unsigned long resolution = 0;390 unsigned long resolution = 0;
400 struct snd_timer_instance *ts;391 struct snd_timer_instance *ts;
401 struct timespec tstamp;392 struct timespec tstamp;
@@ -419,34 +410,66 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) · 17 unmodified lines
419 return;410 return;
420 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)411 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
421 return;412 return;
422 spin_lock_irqsave(&timer->lock, flags);
423 list_for_each_entry(ts, &ti->slave_active_head, active_list)413 list_for_each_entry(ts, &ti->slave_active_head, active_list)
424 if (ts->ccallback)414 if (ts->ccallback)
425 ts->ccallback(ts, event + 100, &tstamp, resolution);415 ts->ccallback(ts, event + 100, &tstamp, resolution);
426 spin_unlock_irqrestore(&timer->lock, flags);
427}416}
428 417
429static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,418/* start/continue a master timer */
430 unsigned long sticks)419static int snd_timer_start1(struct snd_timer_instance *timeri,
420 bool start, unsigned long ticks)
431{421{
422 struct snd_timer *timer;
423 int result;
424 unsigned long flags;
425
426 timer = timeri->timer;
427 if (!timer)
428 return -EINVAL;
429
430 spin_lock_irqsave(&timer->lock, flags);
431 if (timer->card && timer->card->shutdown) {
432 result = -ENODEV;
433 goto unlock;
434 }
435 if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
436 SNDRV_TIMER_IFLG_START)) {
437 result = -EBUSY;
438 goto unlock;
439 }
440
441 if (start)
442 timeri->ticks = timeri->cticks = ticks;
443 else if (!timeri->cticks)
444 timeri->cticks = 1;
445 timeri->pticks = 0;
446
432 list_move_tail(&timeri->active_list, &timer->active_list_head);447 list_move_tail(&timeri->active_list, &timer->active_list_head);
433 if (timer->running) {448 if (timer->running) {
434 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)449 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
435 goto __start_now;450 goto __start_now;
436 timer->flags |= SNDRV_TIMER_FLG_RESCHED;451 timer->flags |= SNDRV_TIMER_FLG_RESCHED;
437 timeri->flags |= SNDRV_TIMER_IFLG_START;452 timeri->flags |= SNDRV_TIMER_IFLG_START;
438 return 1; /* delayed start */453 result = 1; /* delayed start */
439 } else {454 } else {
440 timer->sticks = sticks;455 if (start)
456 timer->sticks = ticks;
441 timer->hw.start(timer);457 timer->hw.start(timer);
442 __start_now:458 __start_now:
443 timer->running++;459 timer->running++;
444 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;460 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
445 return 0;461 result = 0;
446 }462 }
463 snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
464 SNDRV_TIMER_EVENT_CONTINUE);
465 unlock:
466 spin_unlock_irqrestore(&timer->lock, flags);
467 return result;
447}468}
448 469
449static int snd_timer_start_slave(struct snd_timer_instance *timeri)470/* start/continue a slave timer */
471static int snd_timer_start_slave(struct snd_timer_instance *timeri,
472 bool start)
450{473{
451 unsigned long flags;474 unsigned long flags;
452 475
@@ -460,88 +483,37 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) · 7 unmodified lines
460 spin_lock(&timeri->timer->lock);483 spin_lock(&timeri->timer->lock);
461 list_add_tail(&timeri->active_list,484 list_add_tail(&timeri->active_list,
462 &timeri->master->slave_active_head);485 &timeri->master->slave_active_head);
486 snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
487 SNDRV_TIMER_EVENT_CONTINUE);
463 spin_unlock(&timeri->timer->lock);488 spin_unlock(&timeri->timer->lock);
464 }489 }
465 spin_unlock_irqrestore(&slave_active_lock, flags);490 spin_unlock_irqrestore(&slave_active_lock, flags);
466 return 1; /* delayed start */491 return 1; /* delayed start */
467}492}
468 493
469/*494/* stop/pause a master timer */
470 * start the timer instance495static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
471 */
472int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
473{496{
474 struct snd_timer *timer;497 struct snd_timer *timer;
475 int result = -EINVAL;498 int result = 0;
476 unsigned long flags;499 unsigned long flags;
477 500
478 if (timeri == NULL || ticks < 1)
479 return -EINVAL;
480 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
481 result = snd_timer_start_slave(timeri);
482 if (result >= 0)
483 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
484 return result;
485 }
486 timer = timeri->timer;
487 if (timer == NULL)
488 return -EINVAL;
489 if (timer->card && timer->card->shutdown)
490 return -ENODEV;
491 spin_lock_irqsave(&timer->lock, flags);
492 if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
493 SNDRV_TIMER_IFLG_START)) {
494 result = -EBUSY;
495 goto unlock;
496 }
497 timeri->ticks = timeri->cticks = ticks;
498 timeri->pticks = 0;
499 result = snd_timer_start1(timer, timeri, ticks);
500 unlock:
501 spin_unlock_irqrestore(&timer->lock, flags);
502 if (result >= 0)
503 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
504 return result;
505}
506
507static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
508{
509 struct snd_timer *timer;
510 unsigned long flags;
511
512 if (snd_BUG_ON(!timeri))
513 return -ENXIO;
514
515 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
516 spin_lock_irqsave(&slave_active_lock, flags);
517 if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
518 spin_unlock_irqrestore(&slave_active_lock, flags);
519 return -EBUSY;
520 }
521 if (timeri->timer)
522 spin_lock(&timeri->timer->lock);
523 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
524 list_del_init(&timeri->ack_list);
525 list_del_init(&timeri->active_list);
526 if (timeri->timer)
527 spin_unlock(&timeri->timer->lock);
528 spin_unlock_irqrestore(&slave_active_lock, flags);
529 goto __end;
530 }
531 timer = timeri->timer;501 timer = timeri->timer;
532 if (!timer)502 if (!timer)
533 return -EINVAL;503 return -EINVAL;
534 spin_lock_irqsave(&timer->lock, flags);504 spin_lock_irqsave(&timer->lock, flags);
535 if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |505 if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
536 SNDRV_TIMER_IFLG_START))) {506 SNDRV_TIMER_IFLG_START))) {
537 spin_unlock_irqrestore(&timer->lock, flags);507 result = -EBUSY;
538 return -EBUSY;508 goto unlock;
539 }509 }
540 list_del_init(&timeri->ack_list);510 list_del_init(&timeri->ack_list);
541 list_del_init(&timeri->active_list);511 list_del_init(&timeri->active_list);
542 if (timer->card && timer->card->shutdown) {512 if (timer->card && timer->card->shutdown)
543 spin_unlock_irqrestore(&timer->lock, flags);513 goto unlock;
544 return 0;514 if (stop) {
515 timeri->cticks = timeri->ticks;
516 timeri->pticks = 0;
545 }517 }
546 if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&518 if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
547 !(--timer->running)) {519 !(--timer->running)) {
@@ -556,13 +528,49 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) · 8 unmodified lines
556 }528 }
557 }529 }
558 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);530 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
531 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
532 SNDRV_TIMER_EVENT_CONTINUE);
533 unlock:
559 spin_unlock_irqrestore(&timer->lock, flags);534 spin_unlock_irqrestore(&timer->lock, flags);
560 __end:535 return result;
561 if (event != SNDRV_TIMER_EVENT_RESOLUTION)536}
562 snd_timer_notify1(timeri, event);537
538/* stop/pause a slave timer */
539static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop)
540{
541 unsigned long flags;
542
543 spin_lock_irqsave(&slave_active_lock, flags);
544 if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
545 spin_unlock_irqrestore(&slave_active_lock, flags);
546 return -EBUSY;
547 }
548 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
549 if (timeri->timer) {
550 spin_lock(&timeri->timer->lock);
551 list_del_init(&timeri->ack_list);
552 list_del_init(&timeri->active_list);
553 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
554 SNDRV_TIMER_EVENT_CONTINUE);
555 spin_unlock(&timeri->timer->lock);
556 }
557 spin_unlock_irqrestore(&slave_active_lock, flags);
563 return 0;558 return 0;
564}559}
565 560
561/*
562 * start the timer instance
563 */
564int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
565{
566 if (timeri == NULL || ticks < 1)
567 return -EINVAL;
568 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
569 return snd_timer_start_slave(timeri, true);
570 else
571 return snd_timer_start1(timeri, true, ticks);
572}
573
566/*574/*
567 * stop the timer instance.575 * stop the timer instance.
568 *576 *
@@ -570,21 +578,10 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) · 1 unmodified line
570 */578 */
571int snd_timer_stop(struct snd_timer_instance *timeri)579int snd_timer_stop(struct snd_timer_instance *timeri)
572{580{
573 struct snd_timer *timer;581 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
574 unsigned long flags;582 return snd_timer_stop_slave(timeri, true);
575 int err;583 else
576 584 return snd_timer_stop1(timeri, true);
577 err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP);
578 if (err < 0)
579 return err;
580 timer = timeri->timer;
581 if (!timer)
582 return -EINVAL;
583 spin_lock_irqsave(&timer->lock, flags);
584 timeri->cticks = timeri->ticks;
585 timeri->pticks = 0;
586 spin_unlock_irqrestore(&timer->lock, flags);
587 return 0;
588}585}
589 586
590/*587/*
@@ -592,32 +589,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri) · 1 unmodified line
592 */589 */
593int snd_timer_continue(struct snd_timer_instance *timeri)590int snd_timer_continue(struct snd_timer_instance *timeri)
594{591{
595 struct snd_timer *timer;
596 int result = -EINVAL;
597 unsigned long flags;
598
599 if (timeri == NULL)
600 return result;
601 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)592 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
602 return snd_timer_start_slave(timeri);593 return snd_timer_start_slave(timeri, false);
603 timer = timeri->timer;594 else
604 if (! timer)595 return snd_timer_start1(timeri, false, 0);
605 return -EINVAL;
606 if (timer->card && timer->card->shutdown)
607 return -ENODEV;
608 spin_lock_irqsave(&timer->lock, flags);
609 if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
610 result = -EBUSY;
611 goto unlock;
612 }
613 if (!timeri->cticks)
614 timeri->cticks = 1;
615 timeri->pticks = 0;
616 result = snd_timer_start1(timer, timeri, timer->sticks);
617 unlock:
618 spin_unlock_irqrestore(&timer->lock, flags);
619 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
620 return result;
621}596}
622 597
623/*598/*
@@ -625,7 +600,10 @@ int snd_timer_continue(struct snd_timer_instance *timeri) · 1 unmodified line
625 */600 */
626int snd_timer_pause(struct snd_timer_instance * timeri)601int snd_timer_pause(struct snd_timer_instance * timeri)
627{602{
628 return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE);603 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
604 return snd_timer_stop_slave(timeri, false);
605 else
606 return snd_timer_stop1(timeri, false);
629}607}
630 608
631/*609/*
sound/drivers/mts64.c+44−52
@@ -65,8 +65,6 @@ struct mts64 { · 64 unmodified lines
65 struct snd_card *card;65 struct snd_card *card;
66 struct snd_rawmidi *rmidi;66 struct snd_rawmidi *rmidi;
67 struct pardevice *pardev;67 struct pardevice *pardev;
68 int pardev_claimed;
69
70 int open_count;68 int open_count;
71 int current_midi_output_port;69 int current_midi_output_port;
72 int current_midi_input_port;70 int current_midi_input_port;
@@ -850,30 +848,6 @@ __out: · 777 unmodified lines
850 spin_unlock(&mts->lock);848 spin_unlock(&mts->lock);
851}849}
852 850
853static int snd_mts64_probe_port(struct parport *p)
854{
855 struct pardevice *pardev;
856 int res;
857
858 pardev = parport_register_device(p, DRIVER_NAME,
859 NULL, NULL, NULL,
860 0, NULL);
861 if (!pardev)
862 return -EIO;
863
864 if (parport_claim(pardev)) {
865 parport_unregister_device(pardev);
866 return -EIO;
867 }
868
869 res = mts64_probe(p);
870
871 parport_release(pardev);
872 parport_unregister_device(pardev);
873
874 return res;
875}
876
877static void snd_mts64_attach(struct parport *p)851static void snd_mts64_attach(struct parport *p)
878{852{
879 struct platform_device *device;853 struct platform_device *device;
@@ -907,10 +881,20 @@ static void snd_mts64_detach(struct parport *p) · 27 unmodified lines
907 /* nothing to do here */881 /* nothing to do here */
908}882}
909 883
884static int snd_mts64_dev_probe(struct pardevice *pardev)
885{
886 if (strcmp(pardev->name, DRIVER_NAME))
887 return -ENODEV;
888
889 return 0;
890}
891
910static struct parport_driver mts64_parport_driver = {892static struct parport_driver mts64_parport_driver = {
911 .name = "mts64",893 .name = "mts64",
912 .attach = snd_mts64_attach,894 .probe = snd_mts64_dev_probe,
913 .detach = snd_mts64_detach895 .match_port = snd_mts64_attach,
896 .detach = snd_mts64_detach,
897 .devmodel = true,
914};898};
915 899
916/*********************************************************************900/*********************************************************************
@@ -922,8 +906,7 @@ static void snd_mts64_card_private_free(struct snd_card *card) · 5 unmodified lines
922 struct pardevice *pardev = mts->pardev;906 struct pardevice *pardev = mts->pardev;
923 907
924 if (pardev) {908 if (pardev) {
925 if (mts->pardev_claimed)909 parport_release(pardev);
926 parport_release(pardev);
927 parport_unregister_device(pardev);910 parport_unregister_device(pardev);
928 }911 }
929 912
@@ -938,6 +921,12 @@ static int snd_mts64_probe(struct platform_device *pdev) · 8 unmodified lines
938 struct snd_card *card = NULL;921 struct snd_card *card = NULL;
939 struct mts64 *mts = NULL;922 struct mts64 *mts = NULL;
940 int err;923 int err;
924 struct pardev_cb mts64_cb = {
925 .preempt = NULL,
926 .wakeup = NULL,
927 .irq_func = snd_mts64_interrupt, /* ISR */
928 .flags = PARPORT_DEV_EXCL, /* flags */
929 };
941 930
942 p = platform_get_drvdata(pdev);931 p = platform_get_drvdata(pdev);
943 platform_set_drvdata(pdev, NULL);932 platform_set_drvdata(pdev, NULL);
@@ -946,8 +935,6 @@ static int snd_mts64_probe(struct platform_device *pdev) · 2 unmodified lines
946 return -ENODEV;935 return -ENODEV;
947 if (!enable[dev]) 936 if (!enable[dev])
948 return -ENOENT;937 return -ENOENT;
949 if ((err = snd_mts64_probe_port(p)) < 0)
950 return err;
951 938
952 err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,939 err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
953 0, &card);940 0, &card);
@@ -960,40 +947,42 @@ static int snd_mts64_probe(struct platform_device *pdev) · 6 unmodified lines
960 sprintf(card->longname, "%s at 0x%lx, irq %i", 947 sprintf(card->longname, "%s at 0x%lx, irq %i",
961 card->shortname, p->base, p->irq);948 card->shortname, p->base, p->irq);
962 949
963 pardev = parport_register_device(p, /* port */950 mts64_cb.private = card; /* private */
964 DRIVER_NAME, /* name */951 pardev = parport_register_dev_model(p, /* port */
965 NULL, /* preempt */952 DRIVER_NAME, /* name */
966 NULL, /* wakeup */953 &mts64_cb, /* callbacks */
967 snd_mts64_interrupt, /* ISR */954 pdev->id); /* device number */
968 PARPORT_DEV_EXCL, /* flags */955 if (!pardev) {
969 (void *)card); /* private */
970 if (pardev == NULL) {
971 snd_printd("Cannot register pardevice\n");956 snd_printd("Cannot register pardevice\n");
972 err = -EIO;957 err = -EIO;
973 goto __err;958 goto __err;
974 }959 }
975 960
961 /* claim parport */
962 if (parport_claim(pardev)) {
963 snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
964 err = -EIO;
965 goto free_pardev;
966 }
967
976 if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {968 if ((err = snd_mts64_create(card, pardev, &mts)) < 0) {
977 snd_printd("Cannot create main component\n");969 snd_printd("Cannot create main component\n");
978 parport_unregister_device(pardev);970 goto release_pardev;
979 goto __err;
980 }971 }
981 card->private_data = mts;972 card->private_data = mts;
982 card->private_free = snd_mts64_card_private_free;973 card->private_free = snd_mts64_card_private_free;
974
975 err = mts64_probe(p);
976 if (err) {
977 err = -EIO;
978 goto __err;
979 }
983 980
984 if ((err = snd_mts64_rawmidi_create(card)) < 0) {981 if ((err = snd_mts64_rawmidi_create(card)) < 0) {
985 snd_printd("Creating Rawmidi component failed\n");982 snd_printd("Creating Rawmidi component failed\n");
986 goto __err;983 goto __err;
987 }984 }
988 985
989 /* claim parport */
990 if (parport_claim(pardev)) {
991 snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
992 err = -EIO;
993 goto __err;
994 }
995 mts->pardev_claimed = 1;
996
997 /* init device */986 /* init device */
998 if ((err = mts64_device_init(p)) < 0)987 if ((err = mts64_device_init(p)) < 0)
999 goto __err;988 goto __err;
@@ -1009,6 +998,10 @@ static int snd_mts64_probe(struct platform_device *pdev) · 9 unmodified lines
1009 snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);998 snd_printk(KERN_INFO "ESI Miditerminal 4140 on 0x%lx\n", p->base);
1010 return 0;999 return 0;
1011 1000
1001release_pardev:
1002 parport_release(pardev);
1003free_pardev:
1004 parport_unregister_device(pardev);
1012__err:1005__err:
1013 snd_card_free(card);1006 snd_card_free(card);
1014 return err;1007 return err;
@@ -1024,7 +1017,6 @@ static int snd_mts64_remove(struct platform_device *pdev) · 9 unmodified lines
1024 return 0;1017 return 0;
1025}1018}
1026 1019
1027
1028static struct platform_driver snd_mts64_driver = {1020static struct platform_driver snd_mts64_driver = {
1029 .probe = snd_mts64_probe,1021 .probe = snd_mts64_probe,
1030 .remove = snd_mts64_remove,1022 .remove = snd_mts64_remove,
sound/drivers/portman2x4.c+43−51
@@ -83,8 +83,6 @@ struct portman { · 82 unmodified lines
83 struct snd_card *card;83 struct snd_card *card;
84 struct snd_rawmidi *rmidi;84 struct snd_rawmidi *rmidi;
85 struct pardevice *pardev;85 struct pardevice *pardev;
86 int pardev_claimed;
87
88 int open_count;86 int open_count;
89 int mode[PORTMAN_NUM_INPUT_PORTS];87 int mode[PORTMAN_NUM_INPUT_PORTS];
90 struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];88 struct snd_rawmidi_substream *midi_input[PORTMAN_NUM_INPUT_PORTS];
@@ -648,30 +646,6 @@ static void snd_portman_interrupt(void *userdata) · 557 unmodified lines
648 spin_unlock(&pm->reg_lock);646 spin_unlock(&pm->reg_lock);
649}647}
650 648
651static int snd_portman_probe_port(struct parport *p)
652{
653 struct pardevice *pardev;
654 int res;
655
656 pardev = parport_register_device(p, DRIVER_NAME,
657 NULL, NULL, NULL,
658 0, NULL);
659 if (!pardev)
660 return -EIO;
661
662 if (parport_claim(pardev)) {
663 parport_unregister_device(pardev);
664 return -EIO;
665 }
666
667 res = portman_probe(p);
668
669 parport_release(pardev);
670 parport_unregister_device(pardev);
671
672 return res ? -EIO : 0;
673}
674
675static void snd_portman_attach(struct parport *p)649static void snd_portman_attach(struct parport *p)
676{650{
677 struct platform_device *device;651 struct platform_device *device;
@@ -705,10 +679,20 @@ static void snd_portman_detach(struct parport *p) · 27 unmodified lines
705 /* nothing to do here */679 /* nothing to do here */
706}680}
707 681
682static int snd_portman_dev_probe(struct pardevice *pardev)
683{
684 if (strcmp(pardev->name, DRIVER_NAME))
685 return -ENODEV;
686
687 return 0;
688}
689
708static struct parport_driver portman_parport_driver = {690static struct parport_driver portman_parport_driver = {
709 .name = "portman2x4",691 .name = "portman2x4",
710 .attach = snd_portman_attach,692 .probe = snd_portman_dev_probe,
711 .detach = snd_portman_detach693 .match_port = snd_portman_attach,
694 .detach = snd_portman_detach,
695 .devmodel = true,
712};696};
713 697
714/*********************************************************************698/*********************************************************************
@@ -720,8 +704,7 @@ static void snd_portman_card_private_free(struct snd_card *card) · 5 unmodified lines
720 struct pardevice *pardev = pm->pardev;704 struct pardevice *pardev = pm->pardev;
721 705
722 if (pardev) {706 if (pardev) {
723 if (pm->pardev_claimed)707 parport_release(pardev);
724 parport_release(pardev);
725 parport_unregister_device(pardev);708 parport_unregister_device(pardev);
726 }709 }
727 710
@@ -736,6 +719,12 @@ static int snd_portman_probe(struct platform_device *pdev) · 8 unmodified lines
736 struct snd_card *card = NULL;719 struct snd_card *card = NULL;
737 struct portman *pm = NULL;720 struct portman *pm = NULL;
738 int err;721 int err;
722 struct pardev_cb portman_cb = {
723 .preempt = NULL,
724 .wakeup = NULL,
725 .irq_func = snd_portman_interrupt, /* ISR */
726 .flags = PARPORT_DEV_EXCL, /* flags */
727 };
739 728
740 p = platform_get_drvdata(pdev);729 p = platform_get_drvdata(pdev);
741 platform_set_drvdata(pdev, NULL);730 platform_set_drvdata(pdev, NULL);
@@ -745,9 +734,6 @@ static int snd_portman_probe(struct platform_device *pdev) · 3 unmodified lines
745 if (!enable[dev]) 734 if (!enable[dev])
746 return -ENOENT;735 return -ENOENT;
747 736
748 if ((err = snd_portman_probe_port(p)) < 0)
749 return err;
750
751 err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,737 err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
752 0, &card);738 0, &card);
753 if (err < 0) {739 if (err < 0) {
@@ -759,40 +745,42 @@ static int snd_portman_probe(struct platform_device *pdev) · 5 unmodified lines
759 sprintf(card->longname, "%s at 0x%lx, irq %i", 745 sprintf(card->longname, "%s at 0x%lx, irq %i",
760 card->shortname, p->base, p->irq);746 card->shortname, p->base, p->irq);
761 747
762 pardev = parport_register_device(p, /* port */748 portman_cb.private = card; /* private */
763 DRIVER_NAME, /* name */749 pardev = parport_register_dev_model(p, /* port */
764 NULL, /* preempt */750 DRIVER_NAME, /* name */
765 NULL, /* wakeup */751 &portman_cb, /* callbacks */
766 snd_portman_interrupt, /* ISR */752 pdev->id); /* device number */
767 PARPORT_DEV_EXCL, /* flags */
768 (void *)card); /* private */
769 if (pardev == NULL) {753 if (pardev == NULL) {
770 snd_printd("Cannot register pardevice\n");754 snd_printd("Cannot register pardevice\n");
771 err = -EIO;755 err = -EIO;
772 goto __err;756 goto __err;
773 }757 }
774 758
759 /* claim parport */
760 if (parport_claim(pardev)) {
761 snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
762 err = -EIO;
763 goto free_pardev;
764 }
765
775 if ((err = portman_create(card, pardev, &pm)) < 0) {766 if ((err = portman_create(card, pardev, &pm)) < 0) {
776 snd_printd("Cannot create main component\n");767 snd_printd("Cannot create main component\n");
777 parport_unregister_device(pardev);768 goto release_pardev;
778 goto __err;
779 }769 }
780 card->private_data = pm;770 card->private_data = pm;
781 card->private_free = snd_portman_card_private_free;771 card->private_free = snd_portman_card_private_free;
772
773 err = portman_probe(p);
774 if (err) {
775 err = -EIO;
776 goto __err;
777 }
782 778
783 if ((err = snd_portman_rawmidi_create(card)) < 0) {779 if ((err = snd_portman_rawmidi_create(card)) < 0) {
784 snd_printd("Creating Rawmidi component failed\n");780 snd_printd("Creating Rawmidi component failed\n");
785 goto __err;781 goto __err;
786 }782 }
787 783
788 /* claim parport */
789 if (parport_claim(pardev)) {
790 snd_printd("Cannot claim parport 0x%lx\n", pardev->port->base);
791 err = -EIO;
792 goto __err;
793 }
794 pm->pardev_claimed = 1;
795
796 /* init device */784 /* init device */
797 if ((err = portman_device_init(pm)) < 0)785 if ((err = portman_device_init(pm)) < 0)
798 goto __err;786 goto __err;
@@ -808,6 +796,10 @@ static int snd_portman_probe(struct platform_device *pdev) · 9 unmodified lines
808 snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base);796 snd_printk(KERN_INFO "Portman 2x4 on 0x%lx\n", p->base);
809 return 0;797 return 0;
810 798
799release_pardev:
800 parport_release(pardev);
801free_pardev:
802 parport_unregister_device(pardev);
811__err:803__err:
812 snd_card_free(card);804 snd_card_free(card);
813 return err;805 return err;
sound/firewire/bebob/bebob.c+16−5
@@ -300,6 +300,22 @@ error: · 299 unmodified lines
300 return err;300 return err;
301}301}
302 302
303/*
304 * This driver doesn't update streams in bus reset handler.
305 *
306 * DM1000/ DM1100/DM1500 chipsets with BeBoB firmware transfer packets with
307 * discontinued counter at bus reset. This discontinuity is immediately
308 * detected in packet streaming layer, then it sets XRUN to PCM substream.
309 *
310 * ALSA PCM applications can know the XRUN by getting -EPIPE from PCM operation.
311 * Then, they can recover the PCM substream by executing ioctl(2) with
312 * SNDRV_PCM_IOCTL_PREPARE. 'struct snd_pcm_ops.prepare' is called and drivers
313 * restart packet streaming.
314 *
315 * The above processing may be executed before this bus-reset handler is
316 * executed. When this handler updates streams with current isochronous
317 * channels, the streams already have the current ones.
318 */
303static void319static void
304bebob_update(struct fw_unit *unit)320bebob_update(struct fw_unit *unit)
305{321{
@@ -309,7 +325,6 @@ bebob_update(struct fw_unit *unit) · 3 unmodified lines
309 return;325 return;
310 326
311 fcp_bus_reset(bebob->unit);327 fcp_bus_reset(bebob->unit);
312 snd_bebob_stream_update_duplex(bebob);
313 328
314 if (bebob->deferred_registration) {329 if (bebob->deferred_registration) {
315 if (snd_card_register(bebob->card) < 0) {330 if (snd_card_register(bebob->card) < 0) {
@@ -327,10 +342,6 @@ static void bebob_remove(struct fw_unit *unit) · 11 unmodified lines
327 if (bebob == NULL)342 if (bebob == NULL)
328 return;343 return;
329 344
330 /* Awake bus-reset waiters. */
331 if (!completion_done(&bebob->bus_reset))
332 complete_all(&bebob->bus_reset);
333
334 /* No need to wait for releasing card object in this context. */345 /* No need to wait for releasing card object in this context. */
335 snd_card_free_when_closed(bebob->card);346 snd_card_free_when_closed(bebob->card);
336}347}
sound/firewire/bebob/bebob.h+1−4
@@ -88,8 +88,6 @@ struct snd_bebob { · 87 unmodified lines
88 unsigned int midi_input_ports;88 unsigned int midi_input_ports;
89 unsigned int midi_output_ports;89 unsigned int midi_output_ports;
90 90
91 /* for bus reset quirk */
92 struct completion bus_reset;
93 bool connected;91 bool connected;
94 92
95 struct amdtp_stream *master;93 struct amdtp_stream *master;
@@ -97,7 +95,7 @@ struct snd_bebob { · 1 unmodified line
97 struct amdtp_stream rx_stream;95 struct amdtp_stream rx_stream;
98 struct cmp_connection out_conn;96 struct cmp_connection out_conn;
99 struct cmp_connection in_conn;97 struct cmp_connection in_conn;
100 atomic_t substreams_counter;98 unsigned int substreams_counter;
101 99
102 struct snd_bebob_stream_formation100 struct snd_bebob_stream_formation
103 tx_stream_formations[SND_BEBOB_STRM_FMT_ENTRIES];101 tx_stream_formations[SND_BEBOB_STRM_FMT_ENTRIES];
@@ -219,7 +217,6 @@ int snd_bebob_stream_discover(struct snd_bebob *bebob); · 115 unmodified lines
219int snd_bebob_stream_init_duplex(struct snd_bebob *bebob);217int snd_bebob_stream_init_duplex(struct snd_bebob *bebob);
220int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate);218int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate);
221void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob);219void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob);
222void snd_bebob_stream_update_duplex(struct snd_bebob *bebob);
223void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob);220void snd_bebob_stream_destroy_duplex(struct snd_bebob *bebob);
224 221
225void snd_bebob_stream_lock_changed(struct snd_bebob *bebob);222void snd_bebob_stream_lock_changed(struct snd_bebob *bebob);
sound/firewire/bebob/bebob_midi.c+12−4
@@ -17,8 +17,10 @@ static int midi_capture_open(struct snd_rawmidi_substream *substream) · 16 unmodified lines
17 if (err < 0)17 if (err < 0)
18 goto end;18 goto end;
19 19
20 atomic_inc(&bebob->substreams_counter);20 mutex_lock(&bebob->mutex);
21 bebob->substreams_counter++;
21 err = snd_bebob_stream_start_duplex(bebob, 0);22 err = snd_bebob_stream_start_duplex(bebob, 0);
23 mutex_unlock(&bebob->mutex);
22 if (err < 0)24 if (err < 0)
23 snd_bebob_stream_lock_release(bebob);25 snd_bebob_stream_lock_release(bebob);
24end:26end:
@@ -34,8 +36,10 @@ static int midi_playback_open(struct snd_rawmidi_substream *substream) · 9 unmodified lines
34 if (err < 0)36 if (err < 0)
35 goto end;37 goto end;
36 38
37 atomic_inc(&bebob->substreams_counter);39 mutex_lock(&bebob->mutex);
40 bebob->substreams_counter++;
38 err = snd_bebob_stream_start_duplex(bebob, 0);41 err = snd_bebob_stream_start_duplex(bebob, 0);
42 mutex_unlock(&bebob->mutex);
39 if (err < 0)43 if (err < 0)
40 snd_bebob_stream_lock_release(bebob);44 snd_bebob_stream_lock_release(bebob);
41end:45end:
@@ -46,8 +50,10 @@ static int midi_capture_close(struct snd_rawmidi_substream *substream) · 4 unmodified lines
46{50{
47 struct snd_bebob *bebob = substream->rmidi->private_data;51 struct snd_bebob *bebob = substream->rmidi->private_data;
48 52
49 atomic_dec(&bebob->substreams_counter);53 mutex_lock(&bebob->mutex);
54 bebob->substreams_counter--;
50 snd_bebob_stream_stop_duplex(bebob);55 snd_bebob_stream_stop_duplex(bebob);
56 mutex_unlock(&bebob->mutex);
51 57
52 snd_bebob_stream_lock_release(bebob);58 snd_bebob_stream_lock_release(bebob);
53 return 0;59 return 0;
@@ -57,8 +63,10 @@ static int midi_playback_close(struct snd_rawmidi_substream *substream) · 3 unmodified lines
57{63{
58 struct snd_bebob *bebob = substream->rmidi->private_data;64 struct snd_bebob *bebob = substream->rmidi->private_data;
59 65
60 atomic_dec(&bebob->substreams_counter);66 mutex_lock(&bebob->mutex);
67 bebob->substreams_counter--;
61 snd_bebob_stream_stop_duplex(bebob);68 snd_bebob_stream_stop_duplex(bebob);
69 mutex_unlock(&bebob->mutex);
62 70
63 snd_bebob_stream_lock_release(bebob);71 snd_bebob_stream_lock_release(bebob);
64 return 0;72 return 0;
sound/firewire/bebob/bebob_pcm.c+20−8
@@ -218,8 +218,11 @@ pcm_capture_hw_params(struct snd_pcm_substream *substream, · 217 unmodified lines
218 if (err < 0)218 if (err < 0)
219 return err;219 return err;
220 220
221 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)221 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
222 atomic_inc(&bebob->substreams_counter);222 mutex_lock(&bebob->mutex);
223 bebob->substreams_counter++;
224 mutex_unlock(&bebob->mutex);
225 }
223 226
224 amdtp_am824_set_pcm_format(&bebob->tx_stream, params_format(hw_params));227 amdtp_am824_set_pcm_format(&bebob->tx_stream, params_format(hw_params));
225 228
@@ -237,8 +240,11 @@ pcm_playback_hw_params(struct snd_pcm_substream *substream, · 11 unmodified lines
237 if (err < 0)240 if (err < 0)
238 return err;241 return err;
239 242
240 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)243 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {
241 atomic_inc(&bebob->substreams_counter);244 mutex_lock(&bebob->mutex);
245 bebob->substreams_counter++;
246 mutex_unlock(&bebob->mutex);
247 }
242 248
243 amdtp_am824_set_pcm_format(&bebob->rx_stream, params_format(hw_params));249 amdtp_am824_set_pcm_format(&bebob->rx_stream, params_format(hw_params));
244 250
@@ -250,8 +256,11 @@ pcm_capture_hw_free(struct snd_pcm_substream *substream) · 5 unmodified lines
250{256{
251 struct snd_bebob *bebob = substream->private_data;257 struct snd_bebob *bebob = substream->private_data;
252 258
253 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)259 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
254 atomic_dec(&bebob->substreams_counter);260 mutex_lock(&bebob->mutex);
261 bebob->substreams_counter--;
262 mutex_unlock(&bebob->mutex);
263 }
255 264
256 snd_bebob_stream_stop_duplex(bebob);265 snd_bebob_stream_stop_duplex(bebob);
257 266
@@ -262,8 +271,11 @@ pcm_playback_hw_free(struct snd_pcm_substream *substream) · 4 unmodified lines
262{271{
263 struct snd_bebob *bebob = substream->private_data;272 struct snd_bebob *bebob = substream->private_data;
264 273
265 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)274 if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) {
266 atomic_dec(&bebob->substreams_counter);275 mutex_lock(&bebob->mutex);
276 bebob->substreams_counter--;
277 mutex_unlock(&bebob->mutex);
278 }
267 279
268 snd_bebob_stream_stop_duplex(bebob);280 snd_bebob_stream_stop_duplex(bebob);
269 281
sound/firewire/bebob/bebob_stream.c+4−54
@@ -549,8 +549,7 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob) · 548 unmodified lines
549 destroy_both_connections(bebob);549 destroy_both_connections(bebob);
550 goto end;550 goto end;
551 }551 }
552 /* See comments in next function */552
553 init_completion(&bebob->bus_reset);
554 bebob->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK;553 bebob->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK;
555 554
556 /*555 /*
@@ -588,29 +587,10 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate) · 31 unmodified lines
588 struct amdtp_stream *master, *slave;587 struct amdtp_stream *master, *slave;
589 enum cip_flags sync_mode;588 enum cip_flags sync_mode;
590 unsigned int curr_rate;589 unsigned int curr_rate;
591 bool updated = false;
592 int err = 0;590 int err = 0;
593 591
594 /*
595 * Normal BeBoB firmware has a quirk at bus reset to transmits packets
596 * with discontinuous value in dbc field.
597 *
598 * This 'struct completion' is used to call .update() at first to update
599 * connections/streams. Next following codes handle streaming error.
600 */
601 if (amdtp_streaming_error(&bebob->tx_stream)) {
602 if (completion_done(&bebob->bus_reset))
603 reinit_completion(&bebob->bus_reset);
604
605 updated = (wait_for_completion_interruptible_timeout(
606 &bebob->bus_reset,
607 msecs_to_jiffies(FW_ISO_RESOURCE_DELAY)) > 0);
608 }
609
610 mutex_lock(&bebob->mutex);
611
612 /* Need no substreams */592 /* Need no substreams */
613 if (atomic_read(&bebob->substreams_counter) == 0)593 if (bebob->substreams_counter == 0)
614 goto end;594 goto end;
615 595
616 err = get_sync_mode(bebob, &sync_mode);596 err = get_sync_mode(bebob, &sync_mode);
@@ -642,8 +622,7 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate) · 25 unmodified lines
642 amdtp_stream_stop(master);622 amdtp_stream_stop(master);
643 if (amdtp_streaming_error(slave))623 if (amdtp_streaming_error(slave))
644 amdtp_stream_stop(slave);624 amdtp_stream_stop(slave);
645 if (!updated &&625 if (!amdtp_stream_running(master) && !amdtp_stream_running(slave))
646 !amdtp_stream_running(master) && !amdtp_stream_running(slave))
647 break_both_connections(bebob);626 break_both_connections(bebob);
648 627
649 /* stop streams if rate is different */628 /* stop streams if rate is different */
@@ -741,7 +720,6 @@ int snd_bebob_stream_start_duplex(struct snd_bebob *bebob, unsigned int rate) · 91 unmodified lines
741 }720 }
742 }721 }
743end:722end:
744 mutex_unlock(&bebob->mutex);
745 return err;723 return err;
746}724}
747 725
@@ -757,9 +735,7 @@ void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob) · 9 unmodified lines
757 master = &bebob->tx_stream;735 master = &bebob->tx_stream;
758 }736 }
759 737
760 mutex_lock(&bebob->mutex);738 if (bebob->substreams_counter == 0) {
761
762 if (atomic_read(&bebob->substreams_counter) == 0) {
763 amdtp_stream_pcm_abort(master);739 amdtp_stream_pcm_abort(master);
764 amdtp_stream_stop(master);740 amdtp_stream_stop(master);
765 741
@@ -768,32 +744,6 @@ void snd_bebob_stream_stop_duplex(struct snd_bebob *bebob) · 2 unmodified lines
768 744
769 break_both_connections(bebob);745 break_both_connections(bebob);
770 }746 }
771
772 mutex_unlock(&bebob->mutex);
773}
774
775void snd_bebob_stream_update_duplex(struct snd_bebob *bebob)
776{
777 /* vs. XRUN recovery due to discontinuity at bus reset */
778 mutex_lock(&bebob->mutex);
779
780 if ((cmp_connection_update(&bebob->in_conn) < 0) ||
781 (cmp_connection_update(&bebob->out_conn) < 0)) {
782 amdtp_stream_pcm_abort(&bebob->rx_stream);
783 amdtp_stream_pcm_abort(&bebob->tx_stream);
784 amdtp_stream_stop(&bebob->rx_stream);
785 amdtp_stream_stop(&bebob->tx_stream);
786 break_both_connections(bebob);
787 } else {
788 amdtp_stream_update(&bebob->rx_stream);
789 amdtp_stream_update(&bebob->tx_stream);
790 }
791
792 /* wake up stream_start_duplex() */
793 if (!completion_done(&bebob->bus_reset))
794 complete_all(&bebob->bus_reset);
795
796 mutex_unlock(&bebob->mutex);
797}747}
798 748
799/*749/*
sound/firewire/dice/dice-midi.c+21−10
@@ -52,10 +52,10 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) · 51 unmodified lines
52 spin_lock_irqsave(&dice->lock, flags);52 spin_lock_irqsave(&dice->lock, flags);
53 53
54 if (up)54 if (up)
55 amdtp_am824_midi_trigger(&dice->tx_stream,55 amdtp_am824_midi_trigger(&dice->tx_stream[0],
56 substrm->number, substrm);56 substrm->number, substrm);
57 else57 else
58 amdtp_am824_midi_trigger(&dice->tx_stream,58 amdtp_am824_midi_trigger(&dice->tx_stream[0],
59 substrm->number, NULL);59 substrm->number, NULL);
60 60
61 spin_unlock_irqrestore(&dice->lock, flags);61 spin_unlock_irqrestore(&dice->lock, flags);
@@ -69,10 +69,10 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up) · 7 unmodified lines
69 spin_lock_irqsave(&dice->lock, flags);69 spin_lock_irqsave(&dice->lock, flags);
70 70
71 if (up)71 if (up)
72 amdtp_am824_midi_trigger(&dice->rx_stream,72 amdtp_am824_midi_trigger(&dice->rx_stream[0],
73 substrm->number, substrm);73 substrm->number, substrm);
74 else74 else
75 amdtp_am824_midi_trigger(&dice->rx_stream,75 amdtp_am824_midi_trigger(&dice->rx_stream[0],
76 substrm->number, NULL);76 substrm->number, NULL);
77 77
78 spin_unlock_irqrestore(&dice->lock, flags);78 spin_unlock_irqrestore(&dice->lock, flags);
@@ -103,16 +103,27 @@ static void set_midi_substream_names(struct snd_dice *dice, · 24 unmodified lines
103 103
104int snd_dice_create_midi(struct snd_dice *dice)104int snd_dice_create_midi(struct snd_dice *dice)
105{105{
106 __be32 reg;
106 struct snd_rawmidi *rmidi;107 struct snd_rawmidi *rmidi;
107 struct snd_rawmidi_str *str;108 struct snd_rawmidi_str *str;
108 unsigned int i, midi_in_ports, midi_out_ports;109 unsigned int midi_in_ports, midi_out_ports;
109 int err;110 int err;
110 111
111 midi_in_ports = midi_out_ports = 0;112 /*
112 for (i = 0; i < 3; i++) {113 * Use the number of MIDI conformant data channel at current sampling
113 midi_in_ports = max(dice->tx_midi_ports[i], midi_in_ports);114 * transfer frequency.
114 midi_out_ports = max(dice->rx_midi_ports[i], midi_out_ports);115 */
115 }116 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_MIDI,
117 &reg, sizeof(reg));
118 if (err < 0)
119 return err;
120 midi_in_ports = be32_to_cpu(reg);
121
122 err = snd_dice_transaction_read_rx(dice, RX_NUMBER_MIDI,
123 &reg, sizeof(reg));
124 if (err < 0)
125 return err;
126 midi_out_ports = be32_to_cpu(reg);
116 127
117 if (midi_in_ports + midi_out_ports == 0)128 if (midi_in_ports + midi_out_ports == 0)
118 return 0;129 return 0;
sound/firewire/dice/dice-pcm.c+113−165
@@ -9,99 +9,46 @@ · 8 unmodified lines
9 9
10#include "dice.h"10#include "dice.h"
11 11
12static int dice_rate_constraint(struct snd_pcm_hw_params *params,12static int limit_channels_and_rates(struct snd_dice *dice,
13 struct snd_pcm_hw_rule *rule)13 struct snd_pcm_runtime *runtime,
14{14 enum amdtp_stream_direction dir,
15 struct snd_pcm_substream *substream = rule->private;15 unsigned int index, unsigned int size)
16 struct snd_dice *dice = substream->private_data;
17
18 const struct snd_interval *c =
19 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
20 struct snd_interval *r =
21 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
22 struct snd_interval rates = {
23 .min = UINT_MAX, .max = 0, .integer = 1
24 };
25 unsigned int i, rate, mode, *pcm_channels;
26
27 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
28 pcm_channels = dice->tx_channels;
29 else
30 pcm_channels = dice->rx_channels;
31
32 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
33 rate = snd_dice_rates[i];
34 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
35 continue;
36
37 if (!snd_interval_test(c, pcm_channels[mode]))
38 continue;
39
40 rates.min = min(rates.min, rate);
41 rates.max = max(rates.max, rate);
42 }
43
44 return snd_interval_refine(r, &rates);
45}
46
47static int dice_channels_constraint(struct snd_pcm_hw_params *params,
48 struct snd_pcm_hw_rule *rule)
49{
50 struct snd_pcm_substream *substream = rule->private;
51 struct snd_dice *dice = substream->private_data;
52
53 const struct snd_interval *r =
54 hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
55 struct snd_interval *c =
56 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
57 struct snd_interval channels = {
58 .min = UINT_MAX, .max = 0, .integer = 1
59 };
60 unsigned int i, rate, mode, *pcm_channels;
61
62 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
63 pcm_channels = dice->tx_channels;
64 else
65 pcm_channels = dice->rx_channels;
66
67 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
68 rate = snd_dice_rates[i];
69 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
70 continue;
71
72 if (!snd_interval_test(r, rate))
73 continue;
74
75 channels.min = min(channels.min, pcm_channels[mode]);
76 channels.max = max(channels.max, pcm_channels[mode]);
77 }
78
79 return snd_interval_refine(c, &channels);
80}
81
82static void limit_channels_and_rates(struct snd_dice *dice,
83 struct snd_pcm_runtime *runtime,
84 unsigned int *pcm_channels)
85{16{
86 struct snd_pcm_hardware *hw = &runtime->hw;17 struct snd_pcm_hardware *hw = &runtime->hw;
87 unsigned int i, rate, mode;18 struct amdtp_stream *stream;
19 unsigned int rate;
20 __be32 reg;
21 int err;
88 22
89 hw->channels_min = UINT_MAX;23 /*
90 hw->channels_max = 0;24 * Retrieve current Multi Bit Linear Audio data channel and limit to
25 * it.
26 */
27 if (dir == AMDTP_IN_STREAM) {
28 stream = &dice->tx_stream[index];
29 err = snd_dice_transaction_read_tx(dice,
30 size * index + TX_NUMBER_AUDIO,
31 &reg, sizeof(reg));
32 } else {
33 stream = &dice->rx_stream[index];
34 err = snd_dice_transaction_read_rx(dice,
35 size * index + RX_NUMBER_AUDIO,
36 &reg, sizeof(reg));
37 }
38 if (err < 0)
39 return err;
91 40
92 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {41 hw->channels_min = hw->channels_max = be32_to_cpu(reg);
93 rate = snd_dice_rates[i];
94 if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
95 continue;
96 hw->rates |= snd_pcm_rate_to_rate_bit(rate);
97 42
98 if (pcm_channels[mode] == 0)43 /* Retrieve current sampling transfer frequency and limit to it. */
99 continue;44 err = snd_dice_transaction_get_rate(dice, &rate);
100 hw->channels_min = min(hw->channels_min, pcm_channels[mode]);45 if (err < 0)
101 hw->channels_max = max(hw->channels_max, pcm_channels[mode]);46 return err;
102 }
103 47
48 hw->rates = snd_pcm_rate_to_rate_bit(rate);
104 snd_pcm_limit_hw_rates(runtime);49 snd_pcm_limit_hw_rates(runtime);
50
51 return 0;
105}52}
106 53
107static void limit_period_and_buffer(struct snd_pcm_hardware *hw)54static void limit_period_and_buffer(struct snd_pcm_hardware *hw)
@@ -121,8 +68,10 @@ static int init_hw_info(struct snd_dice *dice, · 13 unmodified lines
121{68{
122 struct snd_pcm_runtime *runtime = substream->runtime;69 struct snd_pcm_runtime *runtime = substream->runtime;
123 struct snd_pcm_hardware *hw = &runtime->hw;70 struct snd_pcm_hardware *hw = &runtime->hw;
71 enum amdtp_stream_direction dir;
124 struct amdtp_stream *stream;72 struct amdtp_stream *stream;
125 unsigned int *pcm_channels;73 __be32 reg[2];
74 unsigned int count, size;
126 int err;75 int err;
127 76
128 hw->info = SNDRV_PCM_INFO_MMAP |77 hw->info = SNDRV_PCM_INFO_MMAP |
@@ -134,38 +83,38 @@ static int init_hw_info(struct snd_dice *dice, · 5 unmodified lines
134 83
135 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {84 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
136 hw->formats = AM824_IN_PCM_FORMAT_BITS;85 hw->formats = AM824_IN_PCM_FORMAT_BITS;
137 stream = &dice->tx_stream;86 dir = AMDTP_IN_STREAM;
138 pcm_channels = dice->tx_channels;87 stream = &dice->tx_stream[substream->pcm->device];
88 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg,
89 sizeof(reg));
139 } else {90 } else {
140 hw->formats = AM824_OUT_PCM_FORMAT_BITS;91 hw->formats = AM824_OUT_PCM_FORMAT_BITS;
141 stream = &dice->rx_stream;92 dir = AMDTP_OUT_STREAM;
142 pcm_channels = dice->rx_channels;93 stream = &dice->rx_stream[substream->pcm->device];
94 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg,
95 sizeof(reg));
143 }96 }
144 97
145 limit_channels_and_rates(dice, runtime, pcm_channels);
146 limit_period_and_buffer(hw);
147
148 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
149 dice_rate_constraint, substream,
150 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
151 if (err < 0)98 if (err < 0)
152 goto end;99 return err;
153 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,100
154 dice_channels_constraint, substream,101 count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
155 SNDRV_PCM_HW_PARAM_RATE, -1);102 if (substream->pcm->device >= count)
103 return -ENXIO;
104
105 size = be32_to_cpu(reg[1]) * 4;
106 err = limit_channels_and_rates(dice, substream->runtime, dir,
107 substream->pcm->device, size);
156 if (err < 0)108 if (err < 0)
157 goto end;109 return err;
110 limit_period_and_buffer(hw);
158 111
159 err = amdtp_am824_add_pcm_hw_constraints(stream, runtime);112 return amdtp_am824_add_pcm_hw_constraints(stream, runtime);
160end:
161 return err;
162}113}
163 114
164static int pcm_open(struct snd_pcm_substream *substream)115static int pcm_open(struct snd_pcm_substream *substream)
165{116{
166 struct snd_dice *dice = substream->private_data;117 struct snd_dice *dice = substream->private_data;
167 unsigned int source, rate;
168 bool internal;
169 int err;118 int err;
170 119
171 err = snd_dice_stream_lock_try(dice);120 err = snd_dice_stream_lock_try(dice);
@@ -176,39 +125,6 @@ static int pcm_open(struct snd_pcm_substream *substream) · 4 unmodified lines
176 if (err < 0)125 if (err < 0)
177 goto err_locked;126 goto err_locked;
178 127
179 err = snd_dice_transaction_get_clock_source(dice, &source);
180 if (err < 0)
181 goto err_locked;
182 switch (source) {
183 case CLOCK_SOURCE_AES1:
184 case CLOCK_SOURCE_AES2:
185 case CLOCK_SOURCE_AES3:
186 case CLOCK_SOURCE_AES4:
187 case CLOCK_SOURCE_AES_ANY:
188 case CLOCK_SOURCE_ADAT:
189 case CLOCK_SOURCE_TDIF:
190 case CLOCK_SOURCE_WC:
191 internal = false;
192 break;
193 default:
194 internal = true;
195 break;
196 }
197
198 /*
199 * When source of clock is not internal or any PCM streams are running,
200 * available sampling rate is limited at current sampling rate.
201 */
202 if (!internal ||
203 amdtp_stream_pcm_running(&dice->tx_stream) ||
204 amdtp_stream_pcm_running(&dice->rx_stream)) {
205 err = snd_dice_transaction_get_rate(dice, &rate);
206 if (err < 0)
207 goto err_locked;
208 substream->runtime->hw.rate_min = rate;
209 substream->runtime->hw.rate_max = rate;
210 }
211
212 snd_pcm_set_sync(substream);128 snd_pcm_set_sync(substream);
213end:129end:
214 return err;130 return err;
@@ -230,6 +146,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream, · 15 unmodified lines
230 struct snd_pcm_hw_params *hw_params)146 struct snd_pcm_hw_params *hw_params)
231{147{
232 struct snd_dice *dice = substream->private_data;148 struct snd_dice *dice = substream->private_data;
149 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
233 int err;150 int err;
234 151
235 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,152 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -243,7 +160,7 @@ static int capture_hw_params(struct snd_pcm_substream *substream, · 7 unmodified lines
243 mutex_unlock(&dice->mutex);160 mutex_unlock(&dice->mutex);
244 }161 }
245 162
246 amdtp_am824_set_pcm_format(&dice->tx_stream, params_format(hw_params));163 amdtp_am824_set_pcm_format(stream, params_format(hw_params));
247 164
248 return 0;165 return 0;
249}166}
@@ -251,6 +168,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line
251 struct snd_pcm_hw_params *hw_params)168 struct snd_pcm_hw_params *hw_params)
252{169{
253 struct snd_dice *dice = substream->private_data;170 struct snd_dice *dice = substream->private_data;
171 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
254 int err;172 int err;
255 173
256 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,174 err = snd_pcm_lib_alloc_vmalloc_buffer(substream,
@@ -264,7 +182,7 @@ static int playback_hw_params(struct snd_pcm_substream *substream, · 7 unmodified lines
264 mutex_unlock(&dice->mutex);182 mutex_unlock(&dice->mutex);
265 }183 }
266 184
267 amdtp_am824_set_pcm_format(&dice->rx_stream, params_format(hw_params));185 amdtp_am824_set_pcm_format(stream, params_format(hw_params));
268 186
269 return 0;187 return 0;
270}188}
@@ -304,26 +222,28 @@ static int playback_hw_free(struct snd_pcm_substream *substream) · 33 unmodified lines
304static int capture_prepare(struct snd_pcm_substream *substream)222static int capture_prepare(struct snd_pcm_substream *substream)
305{223{
306 struct snd_dice *dice = substream->private_data;224 struct snd_dice *dice = substream->private_data;
225 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
307 int err;226 int err;
308 227
309 mutex_lock(&dice->mutex);228 mutex_lock(&dice->mutex);
310 err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);229 err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
311 mutex_unlock(&dice->mutex);230 mutex_unlock(&dice->mutex);
312 if (err >= 0)231 if (err >= 0)
313 amdtp_stream_pcm_prepare(&dice->tx_stream);232 amdtp_stream_pcm_prepare(stream);
314 233
315 return 0;234 return 0;
316}235}
317static int playback_prepare(struct snd_pcm_substream *substream)236static int playback_prepare(struct snd_pcm_substream *substream)
318{237{
319 struct snd_dice *dice = substream->private_data;238 struct snd_dice *dice = substream->private_data;
239 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
320 int err;240 int err;
321 241
322 mutex_lock(&dice->mutex);242 mutex_lock(&dice->mutex);
323 err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);243 err = snd_dice_stream_start_duplex(dice, substream->runtime->rate);
324 mutex_unlock(&dice->mutex);244 mutex_unlock(&dice->mutex);
325 if (err >= 0)245 if (err >= 0)
326 amdtp_stream_pcm_prepare(&dice->rx_stream);246 amdtp_stream_pcm_prepare(stream);
327 247
328 return err;248 return err;
329}249}
@@ -331,13 +251,14 @@ static int playback_prepare(struct snd_pcm_substream *substream) · 1 unmodified line
331static int capture_trigger(struct snd_pcm_substream *substream, int cmd)251static int capture_trigger(struct snd_pcm_substream *substream, int cmd)
332{252{
333 struct snd_dice *dice = substream->private_data;253 struct snd_dice *dice = substream->private_data;
254 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
334 255
335 switch (cmd) {256 switch (cmd) {
336 case SNDRV_PCM_TRIGGER_START:257 case SNDRV_PCM_TRIGGER_START:
337 amdtp_stream_pcm_trigger(&dice->tx_stream, substream);258 amdtp_stream_pcm_trigger(stream, substream);
338 break;259 break;
339 case SNDRV_PCM_TRIGGER_STOP:260 case SNDRV_PCM_TRIGGER_STOP:
340 amdtp_stream_pcm_trigger(&dice->tx_stream, NULL);261 amdtp_stream_pcm_trigger(stream, NULL);
341 break;262 break;
342 default:263 default:
343 return -EINVAL;264 return -EINVAL;
@@ -348,13 +269,14 @@ static int capture_trigger(struct snd_pcm_substream *substream, int cmd) · 4 unmodified lines
348static int playback_trigger(struct snd_pcm_substream *substream, int cmd)269static int playback_trigger(struct snd_pcm_substream *substream, int cmd)
349{270{
350 struct snd_dice *dice = substream->private_data;271 struct snd_dice *dice = substream->private_data;
272 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
351 273
352 switch (cmd) {274 switch (cmd) {
353 case SNDRV_PCM_TRIGGER_START:275 case SNDRV_PCM_TRIGGER_START:
354 amdtp_stream_pcm_trigger(&dice->rx_stream, substream);276 amdtp_stream_pcm_trigger(stream, substream);
355 break;277 break;
356 case SNDRV_PCM_TRIGGER_STOP:278 case SNDRV_PCM_TRIGGER_STOP:
357 amdtp_stream_pcm_trigger(&dice->rx_stream, NULL);279 amdtp_stream_pcm_trigger(stream, NULL);
358 break;280 break;
359 default:281 default:
360 return -EINVAL;282 return -EINVAL;
@@ -366,14 +288,16 @@ static int playback_trigger(struct snd_pcm_substream *substream, int cmd) · 5 unmodified lines
366static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)288static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream)
367{289{
368 struct snd_dice *dice = substream->private_data;290 struct snd_dice *dice = substream->private_data;
291 struct amdtp_stream *stream = &dice->tx_stream[substream->pcm->device];
369 292
370 return amdtp_stream_pcm_pointer(&dice->tx_stream);293 return amdtp_stream_pcm_pointer(stream);
371}294}
372static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)295static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream)
373{296{
374 struct snd_dice *dice = substream->private_data;297 struct snd_dice *dice = substream->private_data;
298 struct amdtp_stream *stream = &dice->rx_stream[substream->pcm->device];
375 299
376 return amdtp_stream_pcm_pointer(&dice->rx_stream);300 return amdtp_stream_pcm_pointer(stream);
377}301}
378 302
379int snd_dice_create_pcm(struct snd_dice *dice)303int snd_dice_create_pcm(struct snd_dice *dice)
@@ -402,29 +326,53 @@ int snd_dice_create_pcm(struct snd_dice *dice) · 22 unmodified lines
402 .page = snd_pcm_lib_get_vmalloc_page,326 .page = snd_pcm_lib_get_vmalloc_page,
403 .mmap = snd_pcm_lib_mmap_vmalloc,327 .mmap = snd_pcm_lib_mmap_vmalloc,
404 };328 };
329 __be32 reg;
405 struct snd_pcm *pcm;330 struct snd_pcm *pcm;
406 unsigned int i, capture, playback;331 unsigned int i, max_capture, max_playback, capture, playback;
407 int err;332 int err;
408 333
409 capture = playback = 0;334 /* Check whether PCM substreams are required. */
410 for (i = 0; i < 3; i++) {335 if (dice->force_two_pcms) {
411 if (dice->tx_channels[i] > 0)336 max_capture = max_playback = 2;
337 } else {
338 max_capture = max_playback = 0;
339 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg,
340 sizeof(reg));
341 if (err < 0)
342 return err;
343 max_capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
344
345 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg,
346 sizeof(reg));
347 if (err < 0)
348 return err;
349 max_playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
350 }
351
352 for (i = 0; i < MAX_STREAMS; i++) {
353 capture = playback = 0;
354 if (i < max_capture)
412 capture = 1;355 capture = 1;
413 if (dice->rx_channels[i] > 0)356 if (i < max_playback)
414 playback = 1;357 playback = 1;
415 }358 if (capture == 0 && playback == 0)
359 break;
416 360
417 err = snd_pcm_new(dice->card, "DICE", 0, playback, capture, &pcm);361 err = snd_pcm_new(dice->card, "DICE", i, playback, capture,
418 if (err < 0)362 &pcm);
419 return err;363 if (err < 0)
420 pcm->private_data = dice;364 return err;
421 strcpy(pcm->name, dice->card->shortname);365 pcm->private_data = dice;
366 strcpy(pcm->name, dice->card->shortname);
422 367
423 if (capture > 0)368 if (capture > 0)
424 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);369 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
370 &capture_ops);
425 371
426 if (playback > 0)372 if (playback > 0)
427 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);373 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
374 &playback_ops);
375 }
428 376
429 return 0;377 return 0;
430}378}
sound/firewire/dice/dice-stream.c+285−183
@@ -10,6 +10,12 @@ · 9 unmodified lines
10#include "dice.h"10#include "dice.h"
11 11
12#define CALLBACK_TIMEOUT 20012#define CALLBACK_TIMEOUT 200
13#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
14
15struct reg_params {
16 unsigned int count;
17 unsigned int size;
18};
13 19
14const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {20const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
15 /* mode 0 */21 /* mode 0 */
@@ -24,96 +30,126 @@ const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = { · 8 unmodified lines
24 [6] = 192000,30 [6] = 192000,
25};31};
26 32
27int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,33/*
28 unsigned int *mode)34 * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE
35 * to GLOBAL_STATUS. Especially, just after powering on, these are different.
36 */
37static int ensure_phase_lock(struct snd_dice *dice)
29{38{
30 int i;39 __be32 reg, nominal;
40 int err;
41
42 err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT,
43 &reg, sizeof(reg));
44 if (err < 0)
45 return err;
31 46
32 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {47 if (completion_done(&dice->clock_accepted))
33 if (!(dice->clock_caps & BIT(i)))48 reinit_completion(&dice->clock_accepted);
34 continue;
35 if (snd_dice_rates[i] != rate)
36 continue;
37 49
38 *mode = (i - 1) / 2;50 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
39 return 0;51 &reg, sizeof(reg));
52 if (err < 0)
53 return err;
54
55 if (wait_for_completion_timeout(&dice->clock_accepted,
56 msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0) {
57 /*
58 * Old versions of Dice firmware transfer no notification when
59 * the same clock status as current one is set. In this case,
60 * just check current clock status.
61 */
62 err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS,
63 &nominal, sizeof(nominal));
64 if (err < 0)
65 return err;
66 if (!(be32_to_cpu(nominal) & STATUS_SOURCE_LOCKED))
67 return -ETIMEDOUT;
40 }68 }
41 return -EINVAL;
42}
43 69
44static void release_resources(struct snd_dice *dice,70 return 0;
45 struct fw_iso_resources *resources)
46{
47 __be32 channel;
48
49 /* Reset channel number */
50 channel = cpu_to_be32((u32)-1);
51 if (resources == &dice->tx_resources)
52 snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
53 &channel, sizeof(channel));
54 else
55 snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
56 &channel, sizeof(channel));
57
58 fw_iso_resources_free(resources);
59}71}
60 72
61static int keep_resources(struct snd_dice *dice,73static int get_register_params(struct snd_dice *dice,
62 struct fw_iso_resources *resources,74 struct reg_params *tx_params,
63 unsigned int max_payload_bytes)75 struct reg_params *rx_params)
64{76{
65 __be32 channel;77 __be32 reg[2];
66 int err;78 int err;
67 79
68 err = fw_iso_resources_allocate(resources, max_payload_bytes,80 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg));
69 fw_parent_device(dice->unit)->max_speed);
70 if (err < 0)81 if (err < 0)
71 goto end;82 return err;
83 tx_params->count =
84 min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
85 tx_params->size = be32_to_cpu(reg[1]) * 4;
72 86
73 /* Set channel number */87 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg));
74 channel = cpu_to_be32(resources->channel);
75 if (resources == &dice->tx_resources)
76 err = snd_dice_transaction_write_tx(dice, TX_ISOCHRONOUS,
77 &channel, sizeof(channel));
78 else
79 err = snd_dice_transaction_write_rx(dice, RX_ISOCHRONOUS,
80 &channel, sizeof(channel));
81 if (err < 0)88 if (err < 0)
82 release_resources(dice, resources);89 return err;
83end:90 rx_params->count =
84 return err;91 min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
92 rx_params->size = be32_to_cpu(reg[1]) * 4;
93
94 return 0;
85}95}
86 96
87static void stop_stream(struct snd_dice *dice, struct amdtp_stream *stream)97static void release_resources(struct snd_dice *dice)
88{98{
89 amdtp_stream_pcm_abort(stream);99 unsigned int i;
90 amdtp_stream_stop(stream);
91 100
92 if (stream == &dice->tx_stream)101 for (i = 0; i < MAX_STREAMS; i++) {
93 release_resources(dice, &dice->tx_resources);102 if (amdtp_stream_running(&dice->tx_stream[i])) {
94 else103 amdtp_stream_pcm_abort(&dice->tx_stream[i]);
95 release_resources(dice, &dice->rx_resources);104 amdtp_stream_stop(&dice->tx_stream[i]);
105 }
106 if (amdtp_stream_running(&dice->rx_stream[i])) {
107 amdtp_stream_pcm_abort(&dice->rx_stream[i]);
108 amdtp_stream_stop(&dice->rx_stream[i]);
109 }
110
111 fw_iso_resources_free(&dice->tx_resources[i]);
112 fw_iso_resources_free(&dice->rx_resources[i]);
113 }
96}114}
97 115
98static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream,116static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
99 unsigned int rate)117 struct reg_params *params)
100{118{
119 __be32 reg;
120 unsigned int i;
121
122 for (i = 0; i < params->count; i++) {
123 reg = cpu_to_be32((u32)-1);
124 if (dir == AMDTP_IN_STREAM) {
125 snd_dice_transaction_write_tx(dice,
126 params->size * i + TX_ISOCHRONOUS,
127 &reg, sizeof(reg));
128 } else {
129 snd_dice_transaction_write_rx(dice,
130 params->size * i + RX_ISOCHRONOUS,
131 &reg, sizeof(reg));
132 }
133 }
134}
135
136static int keep_resources(struct snd_dice *dice,
137 enum amdtp_stream_direction dir, unsigned int index,
138 unsigned int rate, unsigned int pcm_chs,
139 unsigned int midi_ports)
140{
141 struct amdtp_stream *stream;
101 struct fw_iso_resources *resources;142 struct fw_iso_resources *resources;
102 unsigned int i, mode, pcm_chs, midi_ports;
103 bool double_pcm_frames;143 bool double_pcm_frames;
144 unsigned int i;
104 int err;145 int err;
105 146
106 err = snd_dice_stream_get_rate_mode(dice, rate, &mode);147 if (dir == AMDTP_IN_STREAM) {
107 if (err < 0)148 stream = &dice->tx_stream[index];
108 goto end;149 resources = &dice->tx_resources[index];
109 if (stream == &dice->tx_stream) {
110 resources = &dice->tx_resources;
111 pcm_chs = dice->tx_channels[mode];
112 midi_ports = dice->tx_midi_ports[mode];
113 } else {150 } else {
114 resources = &dice->rx_resources;151 stream = &dice->rx_stream[index];
115 pcm_chs = dice->rx_channels[mode];152 resources = &dice->rx_resources[index];
116 midi_ports = dice->rx_midi_ports[mode];
117 }153 }
118 154
119 /*155 /*
@@ -126,7 +162,7 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream, · 6 unmodified lines
126 * For this quirk, blocking mode is required and PCM buffer size should162 * For this quirk, blocking mode is required and PCM buffer size should
127 * be aligned to SYT_INTERVAL.163 * be aligned to SYT_INTERVAL.
128 */164 */
129 double_pcm_frames = mode > 1;165 double_pcm_frames = rate > 96000;
130 if (double_pcm_frames) {166 if (double_pcm_frames) {
131 rate /= 2;167 rate /= 2;
132 pcm_chs *= 2;168 pcm_chs *= 2;
@@ -135,7 +171,7 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream, · 2 unmodified lines
135 err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,171 err = amdtp_am824_set_parameters(stream, rate, pcm_chs, midi_ports,
136 double_pcm_frames);172 double_pcm_frames);
137 if (err < 0)173 if (err < 0)
138 goto end;174 return err;
139 175
140 if (double_pcm_frames) {176 if (double_pcm_frames) {
141 pcm_chs /= 2;177 pcm_chs /= 2;
@@ -147,158 +183,201 @@ static int start_stream(struct snd_dice *dice, struct amdtp_stream *stream, · 5 unmodified lines
147 }183 }
148 }184 }
149 185
150 err = keep_resources(dice, resources,186 return fw_iso_resources_allocate(resources,
151 amdtp_stream_get_max_payload(stream));187 amdtp_stream_get_max_payload(stream),
152 if (err < 0) {188 fw_parent_device(dice->unit)->max_speed);
153 dev_err(&dice->unit->device,
154 "fail to keep isochronous resources\n");
155 goto end;
156 }
157
158 err = amdtp_stream_start(stream, resources->channel,
159 fw_parent_device(dice->unit)->max_speed);
160 if (err < 0)
161 release_resources(dice, resources);
162end:
163 return err;
164}189}
165 190
166static int get_sync_mode(struct snd_dice *dice, enum cip_flags *sync_mode)191static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir,
192 unsigned int rate, struct reg_params *params)
167{193{
168 u32 source;194 __be32 reg[2];
169 int err;195 unsigned int i, pcm_chs, midi_ports;
196 struct amdtp_stream *streams;
197 struct fw_iso_resources *resources;
198 int err = 0;
170 199
171 err = snd_dice_transaction_get_clock_source(dice, &source);200 if (dir == AMDTP_IN_STREAM) {
172 if (err < 0)201 streams = dice->tx_stream;
173 goto end;202 resources = dice->tx_resources;
203 } else {
204 streams = dice->rx_stream;
205 resources = dice->rx_resources;
206 }
207
208 for (i = 0; i < params->count; i++) {
209 if (dir == AMDTP_IN_STREAM) {
210 err = snd_dice_transaction_read_tx(dice,
211 params->size * i + TX_NUMBER_AUDIO,
212 reg, sizeof(reg));
213 } else {
214 err = snd_dice_transaction_read_rx(dice,
215 params->size * i + RX_NUMBER_AUDIO,
216 reg, sizeof(reg));
217 }
218 if (err < 0)
219 return err;
220 pcm_chs = be32_to_cpu(reg[0]);
221 midi_ports = be32_to_cpu(reg[1]);
222
223 err = keep_resources(dice, dir, i, rate, pcm_chs, midi_ports);
224 if (err < 0)
225 return err;
226
227 reg[0] = cpu_to_be32(resources[i].channel);
228 if (dir == AMDTP_IN_STREAM) {
229 err = snd_dice_transaction_write_tx(dice,
230 params->size * i + TX_ISOCHRONOUS,
231 reg, sizeof(reg[0]));
232 } else {
233 err = snd_dice_transaction_write_rx(dice,
234 params->size * i + RX_ISOCHRONOUS,
235 reg, sizeof(reg[0]));
236 }
237 if (err < 0)
238 return err;
174 239
175 switch (source) {240 err = amdtp_stream_start(&streams[i], resources[i].channel,
176 /* So-called 'SYT Match' modes, sync_to_syt value of packets received */241 fw_parent_device(dice->unit)->max_speed);
177 case CLOCK_SOURCE_ARX4: /* in 4th stream */242 if (err < 0)
178 case CLOCK_SOURCE_ARX3: /* in 3rd stream */243 return err;
179 case CLOCK_SOURCE_ARX2: /* in 2nd stream */
180 err = -ENOSYS;
181 break;
182 case CLOCK_SOURCE_ARX1: /* in 1st stream, which this driver uses */
183 *sync_mode = 0;
184 break;
185 default:
186 *sync_mode = CIP_SYNC_TO_DEVICE;
187 break;
188 }244 }
189end:245
190 return err;246 return err;
191}247}
192 248
249/*
250 * MEMO: After this function, there're two states of streams:
251 * - None streams are running.
252 * - All streams are running.
253 */
193int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)254int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate)
194{255{
195 struct amdtp_stream *master, *slave;
196 unsigned int curr_rate;256 unsigned int curr_rate;
197 enum cip_flags sync_mode;257 unsigned int i;
198 int err = 0;258 struct reg_params tx_params, rx_params;
259 bool need_to_start;
260 int err;
199 261
200 if (dice->substreams_counter == 0)262 if (dice->substreams_counter == 0)
201 goto end;263 return -EIO;
202 264
203 err = get_sync_mode(dice, &sync_mode);265 err = get_register_params(dice, &tx_params, &rx_params);
204 if (err < 0)266 if (err < 0)
205 goto end;267 return err;
206 if (sync_mode == CIP_SYNC_TO_DEVICE) {
207 master = &dice->tx_stream;
208 slave = &dice->rx_stream;
209 } else {
210 master = &dice->rx_stream;
211 slave = &dice->tx_stream;
212 }
213
214 /* Some packet queueing errors. */
215 if (amdtp_streaming_error(master) || amdtp_streaming_error(slave))
216 stop_stream(dice, master);
217 268
218 /* Stop stream if rate is different. */
219 err = snd_dice_transaction_get_rate(dice, &curr_rate);269 err = snd_dice_transaction_get_rate(dice, &curr_rate);
220 if (err < 0) {270 if (err < 0) {
221 dev_err(&dice->unit->device,271 dev_err(&dice->unit->device,
222 "fail to get sampling rate\n");272 "fail to get sampling rate\n");
223 goto end;273 return err;
224 }274 }
225 if (rate == 0)275 if (rate == 0)
226 rate = curr_rate;276 rate = curr_rate;
227 if (rate != curr_rate)277 if (rate != curr_rate)
228 stop_stream(dice, master);278 return -EINVAL;
279
280 /* Judge to need to restart streams. */
281 for (i = 0; i < MAX_STREAMS; i++) {
282 if (i < tx_params.count) {
283 if (amdtp_streaming_error(&dice->tx_stream[i]) ||
284 !amdtp_stream_running(&dice->tx_stream[i]))
285 break;
286 }
287 if (i < rx_params.count) {
288 if (amdtp_streaming_error(&dice->rx_stream[i]) ||
289 !amdtp_stream_running(&dice->rx_stream[i]))
290 break;
291 }
292 }
293 need_to_start = (i < MAX_STREAMS);
229 294
230 if (!amdtp_stream_running(master)) {295 if (need_to_start) {
231 stop_stream(dice, slave);296 /* Stop transmission. */
232 snd_dice_transaction_clear_enable(dice);297 snd_dice_transaction_clear_enable(dice);
298 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
299 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
300 release_resources(dice);
233 301
234 amdtp_stream_set_sync(sync_mode, master, slave);302 err = ensure_phase_lock(dice);
235
236 err = snd_dice_transaction_set_rate(dice, rate);
237 if (err < 0) {303 if (err < 0) {
238 dev_err(&dice->unit->device,304 dev_err(&dice->unit->device,
239 "fail to set sampling rate\n");305 "fail to ensure phase lock\n");
240 goto end;306 return err;
241 }307 }
242 308
243 /* Start both streams. */309 /* Start both streams. */
244 err = start_stream(dice, master, rate);310 err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params);
245 if (err < 0) {311 if (err < 0)
246 dev_err(&dice->unit->device,312 goto error;
247 "fail to start AMDTP master stream\n");313 err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params);
248 goto end;314 if (err < 0)
249 }315 goto error;
250 err = start_stream(dice, slave, rate);316
251 if (err < 0) {
252 dev_err(&dice->unit->device,
253 "fail to start AMDTP slave stream\n");
254 stop_stream(dice, master);
255 goto end;
256 }
257 err = snd_dice_transaction_set_enable(dice);317 err = snd_dice_transaction_set_enable(dice);
258 if (err < 0) {318 if (err < 0) {
259 dev_err(&dice->unit->device,319 dev_err(&dice->unit->device,
260 "fail to enable interface\n");320 "fail to enable interface\n");
261 stop_stream(dice, master);321 goto error;
262 stop_stream(dice, slave);
263 goto end;
264 }322 }
265 323
266 /* Wait first callbacks */324 for (i = 0; i < MAX_STREAMS; i++) {
267 if (!amdtp_stream_wait_callback(master, CALLBACK_TIMEOUT) ||325 if ((i < tx_params.count &&
268 !amdtp_stream_wait_callback(slave, CALLBACK_TIMEOUT)) {326 !amdtp_stream_wait_callback(&dice->tx_stream[i],
269 snd_dice_transaction_clear_enable(dice);327 CALLBACK_TIMEOUT)) ||
270 stop_stream(dice, master);328 (i < rx_params.count &&
271 stop_stream(dice, slave);329 !amdtp_stream_wait_callback(&dice->rx_stream[i],
272 err = -ETIMEDOUT;330 CALLBACK_TIMEOUT))) {
331 err = -ETIMEDOUT;
332 goto error;
333 }
273 }334 }
274 }335 }
275end:336
337 return err;
338error:
339 snd_dice_transaction_clear_enable(dice);
340 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
341 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
342 release_resources(dice);
276 return err;343 return err;
277}344}
278 345
346/*
347 * MEMO: After this function, there're two states of streams:
348 * - None streams are running.
349 * - All streams are running.
350 */
279void snd_dice_stream_stop_duplex(struct snd_dice *dice)351void snd_dice_stream_stop_duplex(struct snd_dice *dice)
280{352{
353 struct reg_params tx_params, rx_params;
354
281 if (dice->substreams_counter > 0)355 if (dice->substreams_counter > 0)
282 return;356 return;
283 357
284 snd_dice_transaction_clear_enable(dice);358 snd_dice_transaction_clear_enable(dice);
285 359
286 stop_stream(dice, &dice->tx_stream);360 if (get_register_params(dice, &tx_params, &rx_params) == 0) {
287 stop_stream(dice, &dice->rx_stream);361 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
362 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
363 }
364
365 release_resources(dice);
288}366}
289 367
290static int init_stream(struct snd_dice *dice, struct amdtp_stream *stream)368static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir,
369 unsigned int index)
291{370{
292 int err;371 struct amdtp_stream *stream;
293 struct fw_iso_resources *resources;372 struct fw_iso_resources *resources;
294 enum amdtp_stream_direction dir;373 int err;
295 374
296 if (stream == &dice->tx_stream) {375 if (dir == AMDTP_IN_STREAM) {
297 resources = &dice->tx_resources;376 stream = &dice->tx_stream[index];
298 dir = AMDTP_IN_STREAM;377 resources = &dice->tx_resources[index];
299 } else {378 } else {
300 resources = &dice->rx_resources;379 stream = &dice->rx_stream[index];
301 dir = AMDTP_OUT_STREAM;380 resources = &dice->rx_resources[index];
302 }381 }
303 382
304 err = fw_iso_resources_init(resources, dice->unit);383 err = fw_iso_resources_init(resources, dice->unit);
@@ -319,14 +398,20 @@ end: · 14 unmodified lines
319 * This function should be called before starting streams or after stopping398 * This function should be called before starting streams or after stopping
320 * streams.399 * streams.
321 */400 */
322static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream)401static void destroy_stream(struct snd_dice *dice,
402 enum amdtp_stream_direction dir,
403 unsigned int index)
323{404{
405 struct amdtp_stream *stream;
324 struct fw_iso_resources *resources;406 struct fw_iso_resources *resources;
325 407
326 if (stream == &dice->tx_stream)408 if (dir == AMDTP_IN_STREAM) {
327 resources = &dice->tx_resources;409 stream = &dice->tx_stream[index];
328 else410 resources = &dice->tx_resources[index];
329 resources = &dice->rx_resources;411 } else {
412 stream = &dice->rx_stream[index];
413 resources = &dice->rx_resources[index];
414 }
330 415
331 amdtp_stream_destroy(stream);416 amdtp_stream_destroy(stream);
332 fw_iso_resources_destroy(resources);417 fw_iso_resources_destroy(resources);
@@ -334,33 +419,51 @@ static void destroy_stream(struct snd_dice *dice, struct amdtp_stream *stream) · 1 unmodified line
334 419
335int snd_dice_stream_init_duplex(struct snd_dice *dice)420int snd_dice_stream_init_duplex(struct snd_dice *dice)
336{421{
337 int err;422 int i, err;
338
339 dice->substreams_counter = 0;
340 423
341 err = init_stream(dice, &dice->tx_stream);424 for (i = 0; i < MAX_STREAMS; i++) {
342 if (err < 0)425 err = init_stream(dice, AMDTP_IN_STREAM, i);
343 goto end;426 if (err < 0) {
427 for (; i >= 0; i--)
428 destroy_stream(dice, AMDTP_OUT_STREAM, i);
429 goto end;
430 }
431 }
344 432
345 err = init_stream(dice, &dice->rx_stream);433 for (i = 0; i < MAX_STREAMS; i++) {
346 if (err < 0)434 err = init_stream(dice, AMDTP_OUT_STREAM, i);
347 destroy_stream(dice, &dice->tx_stream);435 if (err < 0) {
436 for (; i >= 0; i--)
437 destroy_stream(dice, AMDTP_OUT_STREAM, i);
438 for (i = 0; i < MAX_STREAMS; i++)
439 destroy_stream(dice, AMDTP_IN_STREAM, i);
440 break;
441 }
442 }
348end:443end:
349 return err;444 return err;
350}445}
351 446
352void snd_dice_stream_destroy_duplex(struct snd_dice *dice)447void snd_dice_stream_destroy_duplex(struct snd_dice *dice)
353{448{
449 struct reg_params tx_params, rx_params;
450
354 snd_dice_transaction_clear_enable(dice);451 snd_dice_transaction_clear_enable(dice);
355 452
356 destroy_stream(dice, &dice->tx_stream);453 if (get_register_params(dice, &tx_params, &rx_params) == 0) {
357 destroy_stream(dice, &dice->rx_stream);454 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
455 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
456 }
457
458 release_resources(dice);
358 459
359 dice->substreams_counter = 0;460 dice->substreams_counter = 0;
360}461}
361 462
362void snd_dice_stream_update_duplex(struct snd_dice *dice)463void snd_dice_stream_update_duplex(struct snd_dice *dice)
363{464{
465 struct reg_params tx_params, rx_params;
466
364 /*467 /*
365 * On a bus reset, the DICE firmware disables streaming and then goes468 * On a bus reset, the DICE firmware disables streaming and then goes
366 * off contemplating its own navel for hundreds of milliseconds before469 * off contemplating its own navel for hundreds of milliseconds before
@@ -371,11 +474,10 @@ void snd_dice_stream_update_duplex(struct snd_dice *dice) · 4 unmodified lines
371 */474 */
372 dice->global_enabled = false;475 dice->global_enabled = false;
373 476
374 stop_stream(dice, &dice->rx_stream);477 if (get_register_params(dice, &tx_params, &rx_params) == 0) {
375 stop_stream(dice, &dice->tx_stream);478 stop_streams(dice, AMDTP_IN_STREAM, &tx_params);
376 479 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params);
377 fw_iso_resources_update(&dice->rx_resources);480 }
378 fw_iso_resources_update(&dice->tx_resources);
379}481}
380 482
381static void dice_lock_changed(struct snd_dice *dice)483static void dice_lock_changed(struct snd_dice *dice)
sound/firewire/dice/dice-transaction.c+1−55
@@ -9,8 +9,6 @@ · 8 unmodified lines
9 9
10#include "dice.h"10#include "dice.h"
11 11
12#define NOTIFICATION_TIMEOUT_MS (2 * MSEC_PER_SEC)
13
14static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type,12static u64 get_subaddr(struct snd_dice *dice, enum snd_dice_addr_type type,
15 u64 offset)13 u64 offset)
16{14{
@@ -62,54 +60,6 @@ static unsigned int get_clock_info(struct snd_dice *dice, __be32 *info) · 45 unmodified lines
62 info, 4);60 info, 4);
63}61}
64 62
65static int set_clock_info(struct snd_dice *dice,
66 unsigned int rate, unsigned int source)
67{
68 unsigned int i;
69 __be32 info;
70 u32 mask;
71 u32 clock;
72 int err;
73
74 err = get_clock_info(dice, &info);
75 if (err < 0)
76 return err;
77
78 clock = be32_to_cpu(info);
79 if (source != UINT_MAX) {
80 mask = CLOCK_SOURCE_MASK;
81 clock &= ~mask;
82 clock |= source;
83 }
84 if (rate != UINT_MAX) {
85 for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
86 if (snd_dice_rates[i] == rate)
87 break;
88 }
89 if (i == ARRAY_SIZE(snd_dice_rates))
90 return -EINVAL;
91
92 mask = CLOCK_RATE_MASK;
93 clock &= ~mask;
94 clock |= i << CLOCK_RATE_SHIFT;
95 }
96 info = cpu_to_be32(clock);
97
98 if (completion_done(&dice->clock_accepted))
99 reinit_completion(&dice->clock_accepted);
100
101 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
102 &info, 4);
103 if (err < 0)
104 return err;
105
106 if (wait_for_completion_timeout(&dice->clock_accepted,
107 msecs_to_jiffies(NOTIFICATION_TIMEOUT_MS)) == 0)
108 return -ETIMEDOUT;
109
110 return 0;
111}
112
113int snd_dice_transaction_get_clock_source(struct snd_dice *dice,63int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
114 unsigned int *source)64 unsigned int *source)
115{65{
@@ -143,10 +93,6 @@ int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate) · 27 unmodified lines
143end:93end:
144 return err;94 return err;
145}95}
146int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate)
147{
148 return set_clock_info(dice, rate, UINT_MAX);
149}
150 96
151int snd_dice_transaction_set_enable(struct snd_dice *dice)97int snd_dice_transaction_set_enable(struct snd_dice *dice)
152{98{
@@ -210,7 +156,7 @@ static void dice_notification(struct fw_card *card, struct fw_request *request, · 57 unmodified lines
210 156
211 fw_send_response(card, request, RCODE_COMPLETE);157 fw_send_response(card, request, RCODE_COMPLETE);
212 158
213 if (bits & NOTIFY_CLOCK_ACCEPTED)159 if (bits & NOTIFY_LOCK_CHG)
214 complete(&dice->clock_accepted);160 complete(&dice->clock_accepted);
215 wake_up(&dice->hwdep_wait);161 wake_up(&dice->hwdep_wait);
216}162}
sound/firewire/dice/dice.c+44−64
@@ -13,6 +13,8 @@ MODULE_LICENSE("GPL v2"); · 12 unmodified lines
13 13
14#define OUI_WEISS 0x001c6a14#define OUI_WEISS 0x001c6a
15#define OUI_LOUD 0x000ff215#define OUI_LOUD 0x000ff2
16#define OUI_FOCUSRITE 0x00130e
17#define OUI_TCELECTRONIC 0x001486
16 18
17#define DICE_CATEGORY_ID 0x0419#define DICE_CATEGORY_ID 0x04
18#define WEISS_CATEGORY_ID 0x0020#define WEISS_CATEGORY_ID 0x00
@@ -20,6 +22,36 @@ MODULE_LICENSE("GPL v2"); · 1 unmodified line
20 22
21#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)23#define PROBE_DELAY_MS (2 * MSEC_PER_SEC)
22 24
25/*
26 * Some models support several isochronous channels, while these streams are not
27 * always available. In this case, add the model name to this list.
28 */
29static bool force_two_pcm_support(struct fw_unit *unit)
30{
31 const char *const models[] = {
32 /* TC Electronic models. */
33 "StudioKonnekt48",
34 /* Focusrite models. */
35 "SAFFIRE_PRO_40",
36 "LIQUID_SAFFIRE_56",
37 "SAFFIRE_PRO_40_1",
38 };
39 char model[32];
40 unsigned int i;
41 int err;
42
43 err = fw_csr_string(unit->directory, CSR_MODEL, model, sizeof(model));
44 if (err < 0)
45 return false;
46
47 for (i = 0; i < ARRAY_SIZE(models); i++) {
48 if (strcmp(models[i], model) == 0)
49 break;
50 }
51
52 return i < ARRAY_SIZE(models);
53}
54
23static int check_dice_category(struct fw_unit *unit)55static int check_dice_category(struct fw_unit *unit)
24{56{
25 struct fw_device *device = fw_parent_device(unit);57 struct fw_device *device = fw_parent_device(unit);
@@ -44,6 +76,12 @@ static int check_dice_category(struct fw_unit *unit) · 18 unmodified lines
44 break;76 break;
45 }77 }
46 }78 }
79
80 if (vendor == OUI_FOCUSRITE || vendor == OUI_TCELECTRONIC) {
81 if (force_two_pcm_support(unit))
82 return 0;
83 }
84
47 if (vendor == OUI_WEISS)85 if (vendor == OUI_WEISS)
48 category = WEISS_CATEGORY_ID;86 category = WEISS_CATEGORY_ID;
49 else if (vendor == OUI_LOUD)87 else if (vendor == OUI_LOUD)
@@ -57,65 +95,10 @@ static int check_dice_category(struct fw_unit *unit) · 7 unmodified lines
57 return 0;95 return 0;
58}96}
59 97
60static int highest_supported_mode_rate(struct snd_dice *dice,98static int check_clock_caps(struct snd_dice *dice)
61 unsigned int mode, unsigned int *rate)
62{
63 unsigned int i, m;
64
65 for (i = ARRAY_SIZE(snd_dice_rates); i > 0; i--) {
66 *rate = snd_dice_rates[i - 1];
67 if (snd_dice_stream_get_rate_mode(dice, *rate, &m) < 0)
68 continue;
69 if (mode == m)
70 break;
71 }
72 if (i == 0)
73 return -EINVAL;
74
75 return 0;
76}
77
78static int dice_read_mode_params(struct snd_dice *dice, unsigned int mode)
79{
80 __be32 values[2];
81 unsigned int rate;
82 int err;
83
84 if (highest_supported_mode_rate(dice, mode, &rate) < 0) {
85 dice->tx_channels[mode] = 0;
86 dice->tx_midi_ports[mode] = 0;
87 dice->rx_channels[mode] = 0;
88 dice->rx_midi_ports[mode] = 0;
89 return 0;
90 }
91
92 err = snd_dice_transaction_set_rate(dice, rate);
93 if (err < 0)
94 return err;
95
96 err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO,
97 values, sizeof(values));
98 if (err < 0)
99 return err;
100
101 dice->tx_channels[mode] = be32_to_cpu(values[0]);
102 dice->tx_midi_ports[mode] = be32_to_cpu(values[1]);
103
104 err = snd_dice_transaction_read_rx(dice, RX_NUMBER_AUDIO,
105 values, sizeof(values));
106 if (err < 0)
107 return err;
108
109 dice->rx_channels[mode] = be32_to_cpu(values[0]);
110 dice->rx_midi_ports[mode] = be32_to_cpu(values[1]);
111
112 return 0;
113}
114
115static int dice_read_params(struct snd_dice *dice)
116{99{
117 __be32 value;100 __be32 value;
118 int mode, err;101 int err;
119 102
120 /* some very old firmwares don't tell about their clock support */103 /* some very old firmwares don't tell about their clock support */
121 if (dice->clock_caps > 0) {104 if (dice->clock_caps > 0) {
@@ -133,12 +116,6 @@ static int dice_read_params(struct snd_dice *dice) · 11 unmodified lines
133 CLOCK_CAP_SOURCE_INTERNAL;116 CLOCK_CAP_SOURCE_INTERNAL;
134 }117 }
135 118
136 for (mode = 2; mode >= 0; --mode) {
137 err = dice_read_mode_params(dice, mode);
138 if (err < 0)
139 return err;
140 }
141
142 return 0;119 return 0;
143}120}
144 121
@@ -211,11 +188,14 @@ static void do_registration(struct work_struct *work) · 66 unmodified lines
211 if (err < 0)188 if (err < 0)
212 return;189 return;
213 190
191 if (force_two_pcm_support(dice->unit))
192 dice->force_two_pcms = true;
193
214 err = snd_dice_transaction_init(dice);194 err = snd_dice_transaction_init(dice);
215 if (err < 0)195 if (err < 0)
216 goto error;196 goto error;
217 197
218 err = dice_read_params(dice);198 err = check_clock_caps(dice);
219 if (err < 0)199 if (err < 0)
220 goto error;200 goto error;
221 201
sound/firewire/dice/dice.h+29−12
@@ -39,6 +39,29 @@ · 38 unmodified lines
39#include "../lib.h"39#include "../lib.h"
40#include "dice-interface.h"40#include "dice-interface.h"
41 41
42/*
43 * This module support maximum 2 pairs of tx/rx isochronous streams for
44 * our convinience.
45 *
46 * In documents for ASICs called with a name of 'DICE':
47 * - ASIC for DICE II:
48 * - Maximum 2 tx and 4 rx are supported.
49 * - A packet supports maximum 16 data channels.
50 * - TCD2210/2210-E (so-called 'Dice Mini'):
51 * - Maximum 2 tx and 2 rx are supported.
52 * - A packet supports maximum 16 data channels.
53 * - TCD2220/2220-E (so-called 'Dice Jr.')
54 * - 2 tx and 2 rx are supported.
55 * - A packet supports maximum 16 data channels.
56 * - TCD3070-CH (so-called 'Dice III')
57 * - Maximum 2 tx and 2 rx are supported.
58 * - A packet supports maximum 32 data channels.
59 *
60 * For the above, MIDI conformant data channel is just on the first isochronous
61 * stream.
62 */
63#define MAX_STREAMS 2
64
42struct snd_dice {65struct snd_dice {
43 struct snd_card *card;66 struct snd_card *card;
44 struct fw_unit *unit;67 struct fw_unit *unit;
@@ -56,10 +79,6 @@ struct snd_dice { · 11 unmodified lines
56 unsigned int rsrv_offset;79 unsigned int rsrv_offset;
57 80
58 unsigned int clock_caps;81 unsigned int clock_caps;
59 unsigned int tx_channels[3];
60 unsigned int rx_channels[3];
61 unsigned int tx_midi_ports[3];
62 unsigned int rx_midi_ports[3];
63 82
64 struct fw_address_handler notification_handler;83 struct fw_address_handler notification_handler;
65 int owner_generation;84 int owner_generation;
@@ -71,13 +90,15 @@ struct snd_dice { · 5 unmodified lines
71 wait_queue_head_t hwdep_wait;90 wait_queue_head_t hwdep_wait;
72 91
73 /* For streaming */92 /* For streaming */
74 struct fw_iso_resources tx_resources;93 struct fw_iso_resources tx_resources[MAX_STREAMS];
75 struct fw_iso_resources rx_resources;94 struct fw_iso_resources rx_resources[MAX_STREAMS];
76 struct amdtp_stream tx_stream;95 struct amdtp_stream tx_stream[MAX_STREAMS];
77 struct amdtp_stream rx_stream;96 struct amdtp_stream rx_stream[MAX_STREAMS];
78 bool global_enabled;97 bool global_enabled;
79 struct completion clock_accepted;98 struct completion clock_accepted;
80 unsigned int substreams_counter;99 unsigned int substreams_counter;
100
101 bool force_two_pcms;
81};102};
82 103
83enum snd_dice_addr_type {104enum snd_dice_addr_type {
@@ -158,7 +179,6 @@ static inline int snd_dice_transaction_read_sync(struct snd_dice *dice, · 74 unmodified lines
158 179
159int snd_dice_transaction_get_clock_source(struct snd_dice *dice,180int snd_dice_transaction_get_clock_source(struct snd_dice *dice,
160 unsigned int *source);181 unsigned int *source);
161int snd_dice_transaction_set_rate(struct snd_dice *dice, unsigned int rate);
162int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate);182int snd_dice_transaction_get_rate(struct snd_dice *dice, unsigned int *rate);
163int snd_dice_transaction_set_enable(struct snd_dice *dice);183int snd_dice_transaction_set_enable(struct snd_dice *dice);
164void snd_dice_transaction_clear_enable(struct snd_dice *dice);184void snd_dice_transaction_clear_enable(struct snd_dice *dice);
@@ -169,9 +189,6 @@ void snd_dice_transaction_destroy(struct snd_dice *dice); · 4 unmodified lines
169#define SND_DICE_RATES_COUNT 7189#define SND_DICE_RATES_COUNT 7
170extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];190extern const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT];
171 191
172int snd_dice_stream_get_rate_mode(struct snd_dice *dice,
173 unsigned int rate, unsigned int *mode);
174
175int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate);192int snd_dice_stream_start_duplex(struct snd_dice *dice, unsigned int rate);
176void snd_dice_stream_stop_duplex(struct snd_dice *dice);193void snd_dice_stream_stop_duplex(struct snd_dice *dice);
177int snd_dice_stream_init_duplex(struct snd_dice *dice);194int snd_dice_stream_init_duplex(struct snd_dice *dice);
sound/firewire/fireworks/fireworks.c+3−0
@@ -301,7 +301,10 @@ static void efw_update(struct fw_unit *unit) · 300 unmodified lines
301 struct snd_efw *efw = dev_get_drvdata(&unit->device);301 struct snd_efw *efw = dev_get_drvdata(&unit->device);
302 302
303 snd_efw_transaction_bus_reset(efw->unit);303 snd_efw_transaction_bus_reset(efw->unit);
304
305 mutex_lock(&efw->mutex);
304 snd_efw_stream_update_duplex(efw);306 snd_efw_stream_update_duplex(efw);
307 mutex_unlock(&efw->mutex);
305}308}
306 309
307static void efw_remove(struct fw_unit *unit)310static void efw_remove(struct fw_unit *unit)
sound/firewire/fireworks/fireworks_stream.c+2−4
@@ -313,12 +313,10 @@ void snd_efw_stream_stop_duplex(struct snd_efw *efw) · 312 unmodified lines
313 313
314void snd_efw_stream_update_duplex(struct snd_efw *efw)314void snd_efw_stream_update_duplex(struct snd_efw *efw)
315{315{
316 if ((cmp_connection_update(&efw->out_conn) < 0) ||316 if (cmp_connection_update(&efw->out_conn) < 0 ||
317 (cmp_connection_update(&efw->in_conn) < 0)) {317 cmp_connection_update(&efw->in_conn) < 0) {
318 mutex_lock(&efw->mutex);
319 stop_stream(efw, &efw->rx_stream);318 stop_stream(efw, &efw->rx_stream);
320 stop_stream(efw, &efw->tx_stream);319 stop_stream(efw, &efw->tx_stream);
321 mutex_unlock(&efw->mutex);
322 } else {320 } else {
323 amdtp_stream_update(&efw->rx_stream);321 amdtp_stream_update(&efw->rx_stream);
324 amdtp_stream_update(&efw->tx_stream);322 amdtp_stream_update(&efw->tx_stream);
sound/firewire/oxfw/oxfw-scs1x.c+25−10
@@ -26,11 +26,13 @@ struct fw_scs1x { · 25 unmodified lines
26 u8 output_bytes;26 u8 output_bytes;
27 bool output_escaped;27 bool output_escaped;
28 bool output_escape_high_nibble;28 bool output_escape_high_nibble;
29 struct tasklet_struct tasklet;29 struct work_struct work;
30 wait_queue_head_t idle_wait;30 wait_queue_head_t idle_wait;
31 u8 buffer[HSS1394_MAX_PACKET_SIZE];31 u8 buffer[HSS1394_MAX_PACKET_SIZE];
32 bool transaction_running;32 bool transaction_running;
33 struct fw_transaction transaction;33 struct fw_transaction transaction;
34 unsigned int transaction_bytes;
35 bool error;
34 struct fw_device *fw_dev;36 struct fw_device *fw_dev;
35};37};
36 38
@@ -125,11 +127,16 @@ static void scs_write_callback(struct fw_card *card, int rcode, · 88 unmodified lines
125{127{
126 struct fw_scs1x *scs = callback_data;128 struct fw_scs1x *scs = callback_data;
127 129
128 if (rcode == RCODE_GENERATION)130 if (!rcode_is_permanent_error(rcode)) {
129 ; /* TODO: retry this packet */131 /* Don't retry for this data. */
132 if (rcode == RCODE_COMPLETE)
133 scs->transaction_bytes = 0;
134 } else {
135 scs->error = true;
136 }
130 137
131 scs->transaction_running = false;138 scs->transaction_running = false;
132 tasklet_schedule(&scs->tasklet);139 schedule_work(&scs->work);
133}140}
134 141
135static bool is_valid_running_status(u8 status)142static bool is_valid_running_status(u8 status)
@@ -165,9 +172,9 @@ static bool is_invalid_cmd(u8 status) · 29 unmodified lines
165 status == 0xfd;172 status == 0xfd;
166}173}
167 174
168static void scs_output_tasklet(unsigned long data)175static void scs_output_work(struct work_struct *work)
169{176{
170 struct fw_scs1x *scs = (struct fw_scs1x *)data;177 struct fw_scs1x *scs = container_of(work, struct fw_scs1x, work);
171 struct snd_rawmidi_substream *stream;178 struct snd_rawmidi_substream *stream;
172 unsigned int i;179 unsigned int i;
173 u8 byte;180 u8 byte;
@@ -177,12 +184,15 @@ static void scs_output_tasklet(unsigned long data) · 3 unmodified lines
177 return;184 return;
178 185
179 stream = ACCESS_ONCE(scs->output);186 stream = ACCESS_ONCE(scs->output);
180 if (!stream) {187 if (!stream || scs->error) {
181 scs->output_idle = true;188 scs->output_idle = true;
182 wake_up(&scs->idle_wait);189 wake_up(&scs->idle_wait);
183 return;190 return;
184 }191 }
185 192
193 if (scs->transaction_bytes > 0)
194 goto retry;
195
186 i = scs->output_bytes;196 i = scs->output_bytes;
187 for (;;) {197 for (;;) {
188 if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {198 if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {
@@ -253,13 +263,16 @@ static void scs_output_tasklet(unsigned long data) · 64 unmodified lines
253 scs->output_bytes = 1;263 scs->output_bytes = 1;
254 scs->output_escaped = false;264 scs->output_escaped = false;
255 265
266 scs->transaction_bytes = i;
267retry:
256 scs->transaction_running = true;268 scs->transaction_running = true;
257 generation = scs->fw_dev->generation;269 generation = scs->fw_dev->generation;
258 smp_rmb(); /* node_id vs. generation */270 smp_rmb(); /* node_id vs. generation */
259 fw_send_request(scs->fw_dev->card, &scs->transaction,271 fw_send_request(scs->fw_dev->card, &scs->transaction,
260 TCODE_WRITE_BLOCK_REQUEST, scs->fw_dev->node_id,272 TCODE_WRITE_BLOCK_REQUEST, scs->fw_dev->node_id,
261 generation, scs->fw_dev->max_speed, HSS1394_ADDRESS,273 generation, scs->fw_dev->max_speed, HSS1394_ADDRESS,
262 scs->buffer, i, scs_write_callback, scs);274 scs->buffer, scs->transaction_bytes,
275 scs_write_callback, scs);
263}276}
264 277
265static int midi_capture_open(struct snd_rawmidi_substream *stream)278static int midi_capture_open(struct snd_rawmidi_substream *stream)
@@ -309,9 +322,11 @@ static void midi_playback_trigger(struct snd_rawmidi_substream *stream, int up) · 43 unmodified lines
309 scs->output_bytes = 1;322 scs->output_bytes = 1;
310 scs->output_escaped = false;323 scs->output_escaped = false;
311 scs->output_idle = false;324 scs->output_idle = false;
325 scs->transaction_bytes = 0;
326 scs->error = false;
312 327
313 ACCESS_ONCE(scs->output) = stream;328 ACCESS_ONCE(scs->output) = stream;
314 tasklet_schedule(&scs->tasklet);329 schedule_work(&scs->work);
315 } else {330 } else {
316 ACCESS_ONCE(scs->output) = NULL;331 ACCESS_ONCE(scs->output) = NULL;
317 }332 }
@@ -395,7 +410,7 @@ int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw) · 77 unmodified lines
395 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,410 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
396 &midi_playback_ops);411 &midi_playback_ops);
397 412
398 tasklet_init(&scs->tasklet, scs_output_tasklet, (unsigned long)scs);413 INIT_WORK(&scs->work, scs_output_work);
399 init_waitqueue_head(&scs->idle_wait);414 init_waitqueue_head(&scs->idle_wait);
400 scs->output_idle = true;415 scs->output_idle = true;
401 416
sound/hda/Makefile+1−1
@@ -1,5 +1,5 @@
1snd-hda-core-objs := hda_bus_type.o hdac_bus.o hdac_device.o hdac_sysfs.o \1snd-hda-core-objs := hda_bus_type.o hdac_bus.o hdac_device.o hdac_sysfs.o \
2 hdac_regmap.o hdac_controller.o hdac_stream.o array.o2 hdac_regmap.o hdac_controller.o hdac_stream.o array.o hdmi_chmap.o
3 3
4snd-hda-core-objs += trace.o4snd-hda-core-objs += trace.o
5CFLAGS_trace.o := -I$(src)5CFLAGS_trace.o := -I$(src)
sound/hda/hdac_device.c+16−0
@@ -611,6 +611,22 @@ int snd_hdac_power_up_pm(struct hdac_device *codec) · 610 unmodified lines
611}611}
612EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);612EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
613 613
614/* like snd_hdac_power_up_pm(), but only increment the pm count when
615 * already powered up. Returns -1 if not powered up, 1 if incremented
616 * or 0 if unchanged. Only used in hdac_regmap.c
617 */
618int snd_hdac_keep_power_up(struct hdac_device *codec)
619{
620 if (!atomic_inc_not_zero(&codec->in_pm)) {
621 int ret = pm_runtime_get_if_in_use(&codec->dev);
622 if (!ret)
623 return -1;
624 if (ret < 0)
625 return 0;
626 }
627 return 1;
628}
629
614/**630/**
615 * snd_hdac_power_down_pm - power down the codec631 * snd_hdac_power_down_pm - power down the codec
616 * @codec: the codec object632 * @codec: the codec object
sound/hda/hdac_i915.c+12−2
@@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_get_display_clk); · 125 unmodified lines
126 */126 */
127static int pin2port(hda_nid_t pin_nid)127static int pin2port(hda_nid_t pin_nid)
128{128{
129 if (WARN_ON(pin_nid < 5 || pin_nid > 7))
130 return -1;
129 return pin_nid - 4;131 return pin_nid - 4;
130}132}
131 133
@@ -144,10 +146,14 @@ static int pin2port(hda_nid_t pin_nid) · 12 unmodified lines
144int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate)146int snd_hdac_sync_audio_rate(struct hdac_bus *bus, hda_nid_t nid, int rate)
145{147{
146 struct i915_audio_component *acomp = bus->audio_component;148 struct i915_audio_component *acomp = bus->audio_component;
149 int port;
147 150
148 if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)151 if (!acomp || !acomp->ops || !acomp->ops->sync_audio_rate)
149 return -ENODEV;152 return -ENODEV;
150 return acomp->ops->sync_audio_rate(acomp->dev, pin2port(nid), rate);153 port = pin2port(nid);
154 if (port < 0)
155 return -EINVAL;
156 return acomp->ops->sync_audio_rate(acomp->dev, port, rate);
151}157}
152EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);158EXPORT_SYMBOL_GPL(snd_hdac_sync_audio_rate);
153 159
@@ -175,11 +181,15 @@ int snd_hdac_acomp_get_eld(struct hdac_bus *bus, hda_nid_t nid, · 21 unmodified lines
175 bool *audio_enabled, char *buffer, int max_bytes)181 bool *audio_enabled, char *buffer, int max_bytes)
176{182{
177 struct i915_audio_component *acomp = bus->audio_component;183 struct i915_audio_component *acomp = bus->audio_component;
184 int port;
178 185
179 if (!acomp || !acomp->ops || !acomp->ops->get_eld)186 if (!acomp || !acomp->ops || !acomp->ops->get_eld)
180 return -ENODEV;187 return -ENODEV;
181 188
182 return acomp->ops->get_eld(acomp->dev, pin2port(nid), audio_enabled,189 port = pin2port(nid);
190 if (port < 0)
191 return -EINVAL;
192 return acomp->ops->get_eld(acomp->dev, port, audio_enabled,
183 buffer, max_bytes);193 buffer, max_bytes);
184}194}
185EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);195EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
sound/hda/hdac_regmap.c+46−23
@@ -21,13 +21,16 @@ · 20 unmodified lines
21#include <sound/hdaudio.h>21#include <sound/hdaudio.h>
22#include <sound/hda_regmap.h>22#include <sound/hda_regmap.h>
23 23
24#ifdef CONFIG_PM24static int codec_pm_lock(struct hdac_device *codec)
25#define codec_is_running(codec) \25{
26 (atomic_read(&(codec)->in_pm) || \26 return snd_hdac_keep_power_up(codec);
27 !pm_runtime_suspended(&(codec)->dev))27}
28#else28
29#define codec_is_running(codec) true29static void codec_pm_unlock(struct hdac_device *codec, int lock)
30#endif30{
31 if (lock == 1)
32 snd_hdac_power_down_pm(codec);
33}
31 34
32#define get_verb(reg) (((reg) >> 8) & 0xfff)35#define get_verb(reg) (((reg) >> 8) & 0xfff)
33 36
@@ -238,20 +241,28 @@ static int hda_reg_read(void *context, unsigned int reg, unsigned int *val) · 204 unmodified lines
238 struct hdac_device *codec = context;241 struct hdac_device *codec = context;
239 int verb = get_verb(reg);242 int verb = get_verb(reg);
240 int err;243 int err;
244 int pm_lock = 0;
241 245
242 if (!codec_is_running(codec) && verb != AC_VERB_GET_POWER_STATE)246 if (verb != AC_VERB_GET_POWER_STATE) {
243 return -EAGAIN;247 pm_lock = codec_pm_lock(codec);
248 if (pm_lock < 0)
249 return -EAGAIN;
250 }
244 reg |= (codec->addr << 28);251 reg |= (codec->addr << 28);
245 if (is_stereo_amp_verb(reg))252 if (is_stereo_amp_verb(reg)) {
246 return hda_reg_read_stereo_amp(codec, reg, val);253 err = hda_reg_read_stereo_amp(codec, reg, val);
247 if (verb == AC_VERB_GET_PROC_COEF)254 goto out;
248 return hda_reg_read_coef(codec, reg, val);255 }
256 if (verb == AC_VERB_GET_PROC_COEF) {
257 err = hda_reg_read_coef(codec, reg, val);
258 goto out;
259 }
249 if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)260 if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)
250 reg &= ~AC_AMP_FAKE_MUTE;261 reg &= ~AC_AMP_FAKE_MUTE;
251 262
252 err = snd_hdac_exec_verb(codec, reg, 0, val);263 err = snd_hdac_exec_verb(codec, reg, 0, val);
253 if (err < 0)264 if (err < 0)
254 return err;265 goto out;
255 /* special handling for asymmetric reads */266 /* special handling for asymmetric reads */
256 if (verb == AC_VERB_GET_POWER_STATE) {267 if (verb == AC_VERB_GET_POWER_STATE) {
257 if (*val & AC_PWRST_ERROR)268 if (*val & AC_PWRST_ERROR)
@@ -259,7 +270,9 @@ static int hda_reg_read(void *context, unsigned int reg, unsigned int *val) · 1 unmodified line
259 else /* take only the actual state */270 else /* take only the actual state */
260 *val = (*val >> 4) & 0x0f;271 *val = (*val >> 4) & 0x0f;
261 }272 }
262 return 0;273 out:
274 codec_pm_unlock(codec, pm_lock);
275 return err;
263}276}
264 277
265static int hda_reg_write(void *context, unsigned int reg, unsigned int val)278static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
@@ -267,6 +280,7 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val) · 1 unmodified line
267 struct hdac_device *codec = context;280 struct hdac_device *codec = context;
268 unsigned int verb;281 unsigned int verb;
269 int i, bytes, err;282 int i, bytes, err;
283 int pm_lock = 0;
270 284
271 if (codec->caps_overwriting)285 if (codec->caps_overwriting)
272 return 0;286 return 0;
@@ -275,14 +289,21 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val) · 2 unmodified lines
275 reg |= (codec->addr << 28);289 reg |= (codec->addr << 28);
276 verb = get_verb(reg);290 verb = get_verb(reg);
277 291
278 if (!codec_is_running(codec) && verb != AC_VERB_SET_POWER_STATE)292 if (verb != AC_VERB_SET_POWER_STATE) {
279 return codec->lazy_cache ? 0 : -EAGAIN;293 pm_lock = codec_pm_lock(codec);
294 if (pm_lock < 0)
295 return codec->lazy_cache ? 0 : -EAGAIN;
296 }
280 297
281 if (is_stereo_amp_verb(reg))298 if (is_stereo_amp_verb(reg)) {
282 return hda_reg_write_stereo_amp(codec, reg, val);299 err = hda_reg_write_stereo_amp(codec, reg, val);
300 goto out;
301 }
283 302
284 if (verb == AC_VERB_SET_PROC_COEF)303 if (verb == AC_VERB_SET_PROC_COEF) {
285 return hda_reg_write_coef(codec, reg, val);304 err = hda_reg_write_coef(codec, reg, val);
305 goto out;
306 }
286 307
287 switch (verb & 0xf00) {308 switch (verb & 0xf00) {
288 case AC_VERB_SET_AMP_GAIN_MUTE:309 case AC_VERB_SET_AMP_GAIN_MUTE:
@@ -319,10 +340,12 @@ static int hda_reg_write(void *context, unsigned int reg, unsigned int val) · 30 unmodified lines
319 reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff);340 reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff);
320 err = snd_hdac_exec_verb(codec, reg, 0, NULL);341 err = snd_hdac_exec_verb(codec, reg, 0, NULL);
321 if (err < 0)342 if (err < 0)
322 return err;343 goto out;
323 }344 }
324 345
325 return 0;346 out:
347 codec_pm_unlock(codec, pm_lock);
348 return err;
326}349}
327 350
328static const struct regmap_config hda_regmap_cfg = {351static const struct regmap_config hda_regmap_cfg = {
sound/hda/hdmi_chmap.c+791−0
@@ -0,0 +1,791 @@
1/*
2 * HDMI Channel map support helpers
3 */
4
5#include <linux/module.h>
6#include <sound/control.h>
7#include <sound/tlv.h>
8#include <sound/hda_chmap.h>
9
10/*
11 * CEA speaker placement:
12 *
13 * FLH FCH FRH
14 * FLW FL FLC FC FRC FR FRW
15 *
16 * LFE
17 * TC
18 *
19 * RL RLC RC RRC RR
20 *
21 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
22 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
23 */
24enum cea_speaker_placement {
25 FL = (1 << 0), /* Front Left */
26 FC = (1 << 1), /* Front Center */
27 FR = (1 << 2), /* Front Right */
28 FLC = (1 << 3), /* Front Left Center */
29 FRC = (1 << 4), /* Front Right Center */
30 RL = (1 << 5), /* Rear Left */
31 RC = (1 << 6), /* Rear Center */
32 RR = (1 << 7), /* Rear Right */
33 RLC = (1 << 8), /* Rear Left Center */
34 RRC = (1 << 9), /* Rear Right Center */
35 LFE = (1 << 10), /* Low Frequency Effect */
36 FLW = (1 << 11), /* Front Left Wide */
37 FRW = (1 << 12), /* Front Right Wide */
38 FLH = (1 << 13), /* Front Left High */
39 FCH = (1 << 14), /* Front Center High */
40 FRH = (1 << 15), /* Front Right High */
41 TC = (1 << 16), /* Top Center */
42};
43
44static const char * const cea_speaker_allocation_names[] = {
45 /* 0 */ "FL/FR",
46 /* 1 */ "LFE",
47 /* 2 */ "FC",
48 /* 3 */ "RL/RR",
49 /* 4 */ "RC",
50 /* 5 */ "FLC/FRC",
51 /* 6 */ "RLC/RRC",
52 /* 7 */ "FLW/FRW",
53 /* 8 */ "FLH/FRH",
54 /* 9 */ "TC",
55 /* 10 */ "FCH",
56};
57
58/*
59 * ELD SA bits in the CEA Speaker Allocation data block
60 */
61static int eld_speaker_allocation_bits[] = {
62 [0] = FL | FR,
63 [1] = LFE,
64 [2] = FC,
65 [3] = RL | RR,
66 [4] = RC,
67 [5] = FLC | FRC,
68 [6] = RLC | RRC,
69 /* the following are not defined in ELD yet */
70 [7] = FLW | FRW,
71 [8] = FLH | FRH,
72 [9] = TC,
73 [10] = FCH,
74};
75
76/*
77 * ALSA sequence is:
78 *
79 * surround40 surround41 surround50 surround51 surround71
80 * ch0 front left = = = =
81 * ch1 front right = = = =
82 * ch2 rear left = = = =
83 * ch3 rear right = = = =
84 * ch4 LFE center center center
85 * ch5 LFE LFE
86 * ch6 side left
87 * ch7 side right
88 *
89 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
90 */
91static int hdmi_channel_mapping[0x32][8] = {
92 /* stereo */
93 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
94 /* 2.1 */
95 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
96 /* Dolby Surround */
97 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
98 /* surround40 */
99 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
100 /* 4ch */
101 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
102 /* surround41 */
103 [0x09] = { 0x00, 0x11, 0x24, 0x35, 0x42, 0xf3, 0xf6, 0xf7 },
104 /* surround50 */
105 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
106 /* surround51 */
107 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
108 /* 7.1 */
109 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
110};
111
112/*
113 * This is an ordered list!
114 *
115 * The preceding ones have better chances to be selected by
116 * hdmi_channel_allocation().
117 */
118static struct hdac_cea_channel_speaker_allocation channel_allocations[] = {
119/* channel: 7 6 5 4 3 2 1 0 */
120{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
121 /* 2.1 */
122{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
123 /* Dolby Surround */
124{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
125 /* surround40 */
126{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
127 /* surround41 */
128{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
129 /* surround50 */
130{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
131 /* surround51 */
132{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
133 /* 6.1 */
134{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
135 /* surround71 */
136{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
137
138{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
139{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
140{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
141{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
142{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
143{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
144{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
145{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
146{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
147{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
148{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
149{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
150{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
151{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
152{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
153{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
154{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
155{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
156{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
157{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
158{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
159{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
160{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
161{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
162{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
163{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
164{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
165{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
166{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
167{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
168{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
169{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
170{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
171{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
172{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
173{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
174{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
175{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
176{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
177{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
178{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
179};
180
181static int hdmi_pin_set_slot_channel(struct hdac_device *codec,
182 hda_nid_t pin_nid, int asp_slot, int channel)
183{
184 return snd_hdac_codec_write(codec, pin_nid, 0,
185 AC_VERB_SET_HDMI_CHAN_SLOT,
186 (channel << 4) | asp_slot);
187}
188
189static int hdmi_pin_get_slot_channel(struct hdac_device *codec,
190 hda_nid_t pin_nid, int asp_slot)
191{
192 return (snd_hdac_codec_read(codec, pin_nid, 0,
193 AC_VERB_GET_HDMI_CHAN_SLOT,
194 asp_slot) & 0xf0) >> 4;
195}
196
197static int hdmi_get_channel_count(struct hdac_device *codec, hda_nid_t cvt_nid)
198{
199 return 1 + snd_hdac_codec_read(codec, cvt_nid, 0,
200 AC_VERB_GET_CVT_CHAN_COUNT, 0);
201}
202
203static void hdmi_set_channel_count(struct hdac_device *codec,
204 hda_nid_t cvt_nid, int chs)
205{
206 if (chs != hdmi_get_channel_count(codec, cvt_nid))
207 snd_hdac_codec_write(codec, cvt_nid, 0,
208 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
209}
210
211/*
212 * Channel mapping routines
213 */
214
215/*
216 * Compute derived values in channel_allocations[].
217 */
218static void init_channel_allocations(void)
219{
220 int i, j;
221 struct hdac_cea_channel_speaker_allocation *p;
222
223 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
224 p = channel_allocations + i;
225 p->channels = 0;
226 p->spk_mask = 0;
227 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
228 if (p->speakers[j]) {
229 p->channels++;
230 p->spk_mask |= p->speakers[j];
231 }
232 }
233}
234
235static int get_channel_allocation_order(int ca)
236{
237 int i;
238
239 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
240 if (channel_allocations[i].ca_index == ca)
241 break;
242 }
243 return i;
244}
245
246void snd_hdac_print_channel_allocation(int spk_alloc, char *buf, int buflen)
247{
248 int i, j;
249
250 for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
251 if (spk_alloc & (1 << i))
252 j += snprintf(buf + j, buflen - j, " %s",
253 cea_speaker_allocation_names[i]);
254 }
255 buf[j] = '\0'; /* necessary when j == 0 */
256}
257EXPORT_SYMBOL_GPL(snd_hdac_print_channel_allocation);
258
259/*
260 * The transformation takes two steps:
261 *
262 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
263 * spk_mask => (channel_allocations[]) => ai->CA
264 *
265 * TODO: it could select the wrong CA from multiple candidates.
266*/
267static int hdmi_channel_allocation_spk_alloc_blk(struct hdac_device *codec,
268 int spk_alloc, int channels)
269{
270 int i;
271 int ca = 0;
272 int spk_mask = 0;
273 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
274
275 /*
276 * CA defaults to 0 for basic stereo audio
277 */
278 if (channels <= 2)
279 return 0;
280
281 /*
282 * expand ELD's speaker allocation mask
283 *
284 * ELD tells the speaker mask in a compact(paired) form,
285 * expand ELD's notions to match the ones used by Audio InfoFrame.
286 */
287 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
288 if (spk_alloc & (1 << i))
289 spk_mask |= eld_speaker_allocation_bits[i];
290 }
291
292 /* search for the first working match in the CA table */
293 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
294 if (channels == channel_allocations[i].channels &&
295 (spk_mask & channel_allocations[i].spk_mask) ==
296 channel_allocations[i].spk_mask) {
297 ca = channel_allocations[i].ca_index;
298 break;
299 }
300 }
301
302 if (!ca) {
303 /*
304 * if there was no match, select the regular ALSA channel
305 * allocation with the matching number of channels
306 */
307 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
308 if (channels == channel_allocations[i].channels) {
309 ca = channel_allocations[i].ca_index;
310 break;
311 }
312 }
313 }
314
315 snd_hdac_print_channel_allocation(spk_alloc, buf, sizeof(buf));
316 dev_dbg(&codec->dev, "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
317 ca, channels, buf);
318
319 return ca;
320}
321
322static void hdmi_debug_channel_mapping(struct hdac_chmap *chmap,
323 hda_nid_t pin_nid)
324{
325#ifdef CONFIG_SND_DEBUG_VERBOSE
326 int i;
327 int channel;
328
329 for (i = 0; i < 8; i++) {
330 channel = chmap->ops.pin_get_slot_channel(
331 chmap->hdac, pin_nid, i);
332 dev_dbg(&chmap->hdac->dev, "HDMI: ASP channel %d => slot %d\n",
333 channel, i);
334 }
335#endif
336}
337
338static void hdmi_std_setup_channel_mapping(struct hdac_chmap *chmap,
339 hda_nid_t pin_nid,
340 bool non_pcm,
341 int ca)
342{
343 struct hdac_cea_channel_speaker_allocation *ch_alloc;
344 int i;
345 int err;
346 int order;
347 int non_pcm_mapping[8];
348
349 order = get_channel_allocation_order(ca);
350 ch_alloc = &channel_allocations[order];
351
352 if (hdmi_channel_mapping[ca][1] == 0) {
353 int hdmi_slot = 0;
354 /* fill actual channel mappings in ALSA channel (i) order */
355 for (i = 0; i < ch_alloc->channels; i++) {
356 while (!ch_alloc->speakers[7 - hdmi_slot] && !WARN_ON(hdmi_slot >= 8))
357 hdmi_slot++; /* skip zero slots */
358
359 hdmi_channel_mapping[ca][i] = (i << 4) | hdmi_slot++;
360 }
361 /* fill the rest of the slots with ALSA channel 0xf */
362 for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++)
363 if (!ch_alloc->speakers[7 - hdmi_slot])
364 hdmi_channel_mapping[ca][i++] = (0xf << 4) | hdmi_slot;
365 }
366
367 if (non_pcm) {
368 for (i = 0; i < ch_alloc->channels; i++)
369 non_pcm_mapping[i] = (i << 4) | i;
370 for (; i < 8; i++)
371 non_pcm_mapping[i] = (0xf << 4) | i;
372 }
373
374 for (i = 0; i < 8; i++) {
375 int slotsetup = non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i];
376 int hdmi_slot = slotsetup & 0x0f;
377 int channel = (slotsetup & 0xf0) >> 4;
378
379 err = chmap->ops.pin_set_slot_channel(chmap->hdac,
380 pin_nid, hdmi_slot, channel);
381 if (err) {
382 dev_dbg(&chmap->hdac->dev, "HDMI: channel mapping failed\n");
383 break;
384 }
385 }
386}
387
388struct channel_map_table {
389 unsigned char map; /* ALSA API channel map position */
390 int spk_mask; /* speaker position bit mask */
391};
392
393static struct channel_map_table map_tables[] = {
394 { SNDRV_CHMAP_FL, FL },
395 { SNDRV_CHMAP_FR, FR },
396 { SNDRV_CHMAP_RL, RL },
397 { SNDRV_CHMAP_RR, RR },
398 { SNDRV_CHMAP_LFE, LFE },
399 { SNDRV_CHMAP_FC, FC },
400 { SNDRV_CHMAP_RLC, RLC },
401 { SNDRV_CHMAP_RRC, RRC },
402 { SNDRV_CHMAP_RC, RC },
403 { SNDRV_CHMAP_FLC, FLC },
404 { SNDRV_CHMAP_FRC, FRC },
405 { SNDRV_CHMAP_TFL, FLH },
406 { SNDRV_CHMAP_TFR, FRH },
407 { SNDRV_CHMAP_FLW, FLW },
408 { SNDRV_CHMAP_FRW, FRW },
409 { SNDRV_CHMAP_TC, TC },
410 { SNDRV_CHMAP_TFC, FCH },
411 {} /* terminator */
412};
413
414/* from ALSA API channel position to speaker bit mask */
415int snd_hdac_chmap_to_spk_mask(unsigned char c)
416{
417 struct channel_map_table *t = map_tables;
418
419 for (; t->map; t++) {
420 if (t->map == c)
421 return t->spk_mask;
422 }
423 return 0;
424}
425EXPORT_SYMBOL_GPL(snd_hdac_chmap_to_spk_mask);
426
427/* from ALSA API channel position to CEA slot */
428static int to_cea_slot(int ordered_ca, unsigned char pos)
429{
430 int mask = snd_hdac_chmap_to_spk_mask(pos);
431 int i;
432
433 if (mask) {
434 for (i = 0; i < 8; i++) {
435 if (channel_allocations[ordered_ca].speakers[7 - i] == mask)
436 return i;
437 }
438 }
439
440 return -1;
441}
442
443/* from speaker bit mask to ALSA API channel position */
444int snd_hdac_spk_to_chmap(int spk)
445{
446 struct channel_map_table *t = map_tables;
447
448 for (; t->map; t++) {
449 if (t->spk_mask == spk)
450 return t->map;
451 }
452 return 0;
453}
454EXPORT_SYMBOL_GPL(snd_hdac_spk_to_chmap);
455
456/* from CEA slot to ALSA API channel position */
457static int from_cea_slot(int ordered_ca, unsigned char slot)
458{
459 int mask = channel_allocations[ordered_ca].speakers[7 - slot];
460
461 return snd_hdac_spk_to_chmap(mask);
462}
463
464/* get the CA index corresponding to the given ALSA API channel map */
465static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
466{
467 int i, spks = 0, spk_mask = 0;
468
469 for (i = 0; i < chs; i++) {
470 int mask = snd_hdac_chmap_to_spk_mask(map[i]);
471
472 if (mask) {
473 spk_mask |= mask;
474 spks++;
475 }
476 }
477
478 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
479 if ((chs == channel_allocations[i].channels ||
480 spks == channel_allocations[i].channels) &&
481 (spk_mask & channel_allocations[i].spk_mask) ==
482 channel_allocations[i].spk_mask)
483 return channel_allocations[i].ca_index;
484 }
485 return -1;
486}
487
488/* set up the channel slots for the given ALSA API channel map */
489static int hdmi_manual_setup_channel_mapping(struct hdac_chmap *chmap,
490 hda_nid_t pin_nid,
491 int chs, unsigned char *map,
492 int ca)
493{
494 int ordered_ca = get_channel_allocation_order(ca);
495 int alsa_pos, hdmi_slot;
496 int assignments[8] = {[0 ... 7] = 0xf};
497
498 for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) {
499
500 hdmi_slot = to_cea_slot(ordered_ca, map[alsa_pos]);
501
502 if (hdmi_slot < 0)
503 continue; /* unassigned channel */
504
505 assignments[hdmi_slot] = alsa_pos;
506 }
507
508 for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) {
509 int err;
510
511 err = chmap->ops.pin_set_slot_channel(chmap->hdac,
512 pin_nid, hdmi_slot, assignments[hdmi_slot]);
513 if (err)
514 return -EINVAL;
515 }
516 return 0;
517}
518
519/* store ALSA API channel map from the current default map */
520static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
521{
522 int i;
523 int ordered_ca = get_channel_allocation_order(ca);
524
525 for (i = 0; i < 8; i++) {
526 if (i < channel_allocations[ordered_ca].channels)
527 map[i] = from_cea_slot(ordered_ca, hdmi_channel_mapping[ca][i] & 0x0f);
528 else
529 map[i] = 0;
530 }
531}
532
533void snd_hdac_setup_channel_mapping(struct hdac_chmap *chmap,
534 hda_nid_t pin_nid, bool non_pcm, int ca,
535 int channels, unsigned char *map,
536 bool chmap_set)
537{
538 if (!non_pcm && chmap_set) {
539 hdmi_manual_setup_channel_mapping(chmap, pin_nid,
540 channels, map, ca);
541 } else {
542 hdmi_std_setup_channel_mapping(chmap, pin_nid, non_pcm, ca);
543 hdmi_setup_fake_chmap(map, ca);
544 }
545
546 hdmi_debug_channel_mapping(chmap, pin_nid);
547}
548EXPORT_SYMBOL_GPL(snd_hdac_setup_channel_mapping);
549
550int snd_hdac_get_active_channels(int ca)
551{
552 int ordered_ca = get_channel_allocation_order(ca);
553
554 return channel_allocations[ordered_ca].channels;
555}
556EXPORT_SYMBOL_GPL(snd_hdac_get_active_channels);
557
558struct hdac_cea_channel_speaker_allocation *snd_hdac_get_ch_alloc_from_ca(int ca)
559{
560 return &channel_allocations[get_channel_allocation_order(ca)];
561}
562EXPORT_SYMBOL_GPL(snd_hdac_get_ch_alloc_from_ca);
563
564int snd_hdac_channel_allocation(struct hdac_device *hdac, int spk_alloc,
565 int channels, bool chmap_set, bool non_pcm, unsigned char *map)
566{
567 int ca;
568
569 if (!non_pcm && chmap_set)
570 ca = hdmi_manual_channel_allocation(channels, map);
571 else
572 ca = hdmi_channel_allocation_spk_alloc_blk(hdac,
573 spk_alloc, channels);
574
575 if (ca < 0)
576 ca = 0;
577
578 return ca;
579}
580EXPORT_SYMBOL_GPL(snd_hdac_channel_allocation);
581
582/*
583 * ALSA API channel-map control callbacks
584 */
585static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_info *uinfo)
587{
588 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
589 struct hdac_chmap *chmap = info->private_data;
590
591 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
592 uinfo->count = chmap->channels_max;
593 uinfo->value.integer.min = 0;
594 uinfo->value.integer.max = SNDRV_CHMAP_LAST;
595 return 0;
596}
597
598static int hdmi_chmap_cea_alloc_validate_get_type(struct hdac_chmap *chmap,
599 struct hdac_cea_channel_speaker_allocation *cap, int channels)
600{
601 /* If the speaker allocation matches the channel count, it is OK.*/
602 if (cap->channels != channels)
603 return -1;
604
605 /* all channels are remappable freely */
606 return SNDRV_CTL_TLVT_CHMAP_VAR;
607}
608
609static void hdmi_cea_alloc_to_tlv_chmap(struct hdac_chmap *hchmap,
610 struct hdac_cea_channel_speaker_allocation *cap,
611 unsigned int *chmap, int channels)
612{
613 int count = 0;
614 int c;
615
616 for (c = 7; c >= 0; c--) {
617 int spk = cap->speakers[c];
618
619 if (!spk)
620 continue;
621
622 chmap[count++] = snd_hdac_spk_to_chmap(spk);
623 }
624
625 WARN_ON(count != channels);
626}
627
628static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
629 unsigned int size, unsigned int __user *tlv)
630{
631 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
632 struct hdac_chmap *chmap = info->private_data;
633 unsigned int __user *dst;
634 int chs, count = 0;
635
636 if (size < 8)
637 return -ENOMEM;
638 if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
639 return -EFAULT;
640 size -= 8;
641 dst = tlv + 2;
642 for (chs = 2; chs <= chmap->channels_max; chs++) {
643 int i;
644 struct hdac_cea_channel_speaker_allocation *cap;
645
646 cap = channel_allocations;
647 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
648 int chs_bytes = chs * 4;
649 int type = chmap->ops.chmap_cea_alloc_validate_get_type(
650 chmap, cap, chs);
651 unsigned int tlv_chmap[8];
652
653 if (type < 0)
654 continue;
655 if (size < 8)
656 return -ENOMEM;
657 if (put_user(type, dst) ||
658 put_user(chs_bytes, dst + 1))
659 return -EFAULT;
660 dst += 2;
661 size -= 8;
662 count += 8;
663 if (size < chs_bytes)
664 return -ENOMEM;
665 size -= chs_bytes;
666 count += chs_bytes;
667 chmap->ops.cea_alloc_to_tlv_chmap(chmap, cap,
668 tlv_chmap, chs);
669 if (copy_to_user(dst, tlv_chmap, chs_bytes))
670 return -EFAULT;
671 dst += chs;
672 }
673 }
674 if (put_user(count, tlv + 1))
675 return -EFAULT;
676 return 0;
677}
678
679static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
681{
682 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
683 struct hdac_chmap *chmap = info->private_data;
684 int pcm_idx = kcontrol->private_value;
685 unsigned char pcm_chmap[8];
686 int i;
687
688 memset(pcm_chmap, 0, sizeof(pcm_chmap));
689 chmap->ops.get_chmap(chmap->hdac, pcm_idx, pcm_chmap);
690
691 for (i = 0; i < sizeof(chmap); i++)
692 ucontrol->value.integer.value[i] = pcm_chmap[i];
693
694 return 0;
695}
696
697static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
698 struct snd_ctl_elem_value *ucontrol)
699{
700 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
701 struct hdac_chmap *hchmap = info->private_data;
702 int pcm_idx = kcontrol->private_value;
703 unsigned int ctl_idx;
704 struct snd_pcm_substream *substream;
705 unsigned char chmap[8], per_pin_chmap[8];
706 int i, err, ca, prepared = 0;
707
708 /* No monitor is connected in dyn_pcm_assign.
709 * It's invalid to setup the chmap
710 */
711 if (!hchmap->ops.is_pcm_attached(hchmap->hdac, pcm_idx))
712 return 0;
713
714 ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
715 substream = snd_pcm_chmap_substream(info, ctl_idx);
716 if (!substream || !substream->runtime)
717 return 0; /* just for avoiding error from alsactl restore */
718 switch (substream->runtime->status->state) {
719 case SNDRV_PCM_STATE_OPEN:
720 case SNDRV_PCM_STATE_SETUP:
721 break;
722 case SNDRV_PCM_STATE_PREPARED:
723 prepared = 1;
724 break;
725 default:
726 return -EBUSY;
727 }
728 memset(chmap, 0, sizeof(chmap));
729 for (i = 0; i < ARRAY_SIZE(chmap); i++)
730 chmap[i] = ucontrol->value.integer.value[i];
731
732 hchmap->ops.get_chmap(hchmap->hdac, pcm_idx, per_pin_chmap);
733 if (!memcmp(chmap, per_pin_chmap, sizeof(chmap)))
734 return 0;
735 ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
736 if (ca < 0)
737 return -EINVAL;
738 if (hchmap->ops.chmap_validate) {
739 err = hchmap->ops.chmap_validate(hchmap, ca,
740 ARRAY_SIZE(chmap), chmap);
741 if (err)
742 return err;
743 }
744
745 hchmap->ops.set_chmap(hchmap->hdac, pcm_idx, chmap, prepared);
746
747 return 0;
748}
749
750static const struct hdac_chmap_ops chmap_ops = {
751 .chmap_cea_alloc_validate_get_type = hdmi_chmap_cea_alloc_validate_get_type,
752 .cea_alloc_to_tlv_chmap = hdmi_cea_alloc_to_tlv_chmap,
753 .pin_get_slot_channel = hdmi_pin_get_slot_channel,
754 .pin_set_slot_channel = hdmi_pin_set_slot_channel,
755 .set_channel_count = hdmi_set_channel_count,
756};
757
758void snd_hdac_register_chmap_ops(struct hdac_device *hdac,
759 struct hdac_chmap *chmap)
760{
761 chmap->ops = chmap_ops;
762 chmap->hdac = hdac;
763 init_channel_allocations();
764}
765EXPORT_SYMBOL_GPL(snd_hdac_register_chmap_ops);
766
767int snd_hdac_add_chmap_ctls(struct snd_pcm *pcm, int pcm_idx,
768 struct hdac_chmap *hchmap)
769{
770 struct snd_pcm_chmap *chmap;
771 struct snd_kcontrol *kctl;
772 int err, i;
773
774 err = snd_pcm_add_chmap_ctls(pcm,
775 SNDRV_PCM_STREAM_PLAYBACK,
776 NULL, 0, pcm_idx, &chmap);
777 if (err < 0)
778 return err;
779 /* override handlers */
780 chmap->private_data = hchmap;
781 kctl = chmap->kctl;
782 for (i = 0; i < kctl->count; i++)
783 kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
784 kctl->info = hdmi_chmap_ctl_info;
785 kctl->get = hdmi_chmap_ctl_get;
786 kctl->put = hdmi_chmap_ctl_put;
787 kctl->tlv.c = hdmi_chmap_ctl_tlv;
788
789 return 0;
790}
791EXPORT_SYMBOL_GPL(snd_hdac_add_chmap_ctls);
sound/mips/Kconfig+0−12
@@ -23,17 +23,5 @@ config SND_SGI_HAL2 · 22 unmodified lines
23 help23 help
24 Sound support for the SGI Indy and Indigo2 Workstation.24 Sound support for the SGI Indy and Indigo2 Workstation.
25 25
26
27config SND_AU1X00
28 tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
29 depends on MIPS_ALCHEMY
30 select SND_PCM
31 select SND_AC97_CODEC
32 help
33 ALSA Sound driver for the Au1x00's AC97 port.
34
35 Newer drivers for ASoC are available, please do not use
36 this driver as it will be removed in the future.
37
38endif # SND_MIPS26endif # SND_MIPS
39 27
sound/mips/Makefile+0−2
@@ -2,11 +2,9 @@ · 1 unmodified line
2# Makefile for ALSA2# Makefile for ALSA
3#3#
4 4
5snd-au1x00-objs := au1x00.o
6snd-sgi-o2-objs := sgio2audio.o ad1843.o5snd-sgi-o2-objs := sgio2audio.o ad1843.o
7snd-sgi-hal2-objs := hal2.o6snd-sgi-hal2-objs := hal2.o
8 7
9# Toplevel Module Dependency8# Toplevel Module Dependency
10obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o
11obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o9obj-$(CONFIG_SND_SGI_O2) += snd-sgi-o2.o
12obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o10obj-$(CONFIG_SND_SGI_HAL2) += snd-sgi-hal2.o
sound/mips/au1x00.c+0−734
@@ -1,734 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Driver for AMD Au1000 MIPS Processor, AC'97 Sound Port
4 *
5 * Copyright 2004 Cooper Street Innovations Inc.
6 * Author: Charles Eidsness <charles@cooper-street.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 * History:
29 *
30 * 2004-09-09 Charles Eidsness -- Original verion -- based on
31 * sa11xx-uda1341.c ALSA driver and the
32 * au1000.c OSS driver.
33 * 2004-09-09 Matt Porter -- Added support for ALSA 1.0.6
34 *
35 */
36
37#include <linux/ioport.h>
38#include <linux/interrupt.h>
39#include <linux/init.h>
40#include <linux/platform_device.h>
41#include <linux/slab.h>
42#include <linux/module.h>
43#include <sound/core.h>
44#include <sound/initval.h>
45#include <sound/pcm.h>
46#include <sound/pcm_params.h>
47#include <sound/ac97_codec.h>
48#include <asm/mach-au1x00/au1000.h>
49#include <asm/mach-au1x00/au1000_dma.h>
50
51MODULE_AUTHOR("Charles Eidsness <charles@cooper-street.com>");
52MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
53MODULE_LICENSE("GPL");
54MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
55
56#define PLAYBACK 0
57#define CAPTURE 1
58#define AC97_SLOT_3 0x01
59#define AC97_SLOT_4 0x02
60#define AC97_SLOT_6 0x08
61#define AC97_CMD_IRQ 31
62#define READ 0
63#define WRITE 1
64#define READ_WAIT 2
65#define RW_DONE 3
66
67struct au1000_period
68{
69 u32 start;
70 u32 relative_end; /*realtive to start of buffer*/
71 struct au1000_period * next;
72};
73
74/*Au1000 AC97 Port Control Reisters*/
75struct au1000_ac97_reg {
76 u32 volatile config;
77 u32 volatile status;
78 u32 volatile data;
79 u32 volatile cmd;
80 u32 volatile cntrl;
81};
82
83struct audio_stream {
84 struct snd_pcm_substream *substream;
85 int dma;
86 spinlock_t dma_lock;
87 struct au1000_period * buffer;
88 unsigned int period_size;
89 unsigned int periods;
90};
91
92struct snd_au1000 {
93 struct snd_card *card;
94 struct au1000_ac97_reg volatile *ac97_ioport;
95
96 struct resource *ac97_res_port;
97 spinlock_t ac97_lock;
98 struct snd_ac97 *ac97;
99
100 struct snd_pcm *pcm;
101 struct audio_stream *stream[2]; /* playback & capture */
102 int dmaid[2]; /* tx(0)/rx(1) DMA ids */
103};
104
105/*--------------------------- Local Functions --------------------------------*/
106static void
107au1000_set_ac97_xmit_slots(struct snd_au1000 *au1000, long xmit_slots)
108{
109 u32 volatile ac97_config;
110
111 spin_lock(&au1000->ac97_lock);
112 ac97_config = au1000->ac97_ioport->config;
113 ac97_config = ac97_config & ~AC97C_XMIT_SLOTS_MASK;
114 ac97_config |= (xmit_slots << AC97C_XMIT_SLOTS_BIT);
115 au1000->ac97_ioport->config = ac97_config;
116 spin_unlock(&au1000->ac97_lock);
117}
118
119static void
120au1000_set_ac97_recv_slots(struct snd_au1000 *au1000, long recv_slots)
121{
122 u32 volatile ac97_config;
123
124 spin_lock(&au1000->ac97_lock);
125 ac97_config = au1000->ac97_ioport->config;
126 ac97_config = ac97_config & ~AC97C_RECV_SLOTS_MASK;
127 ac97_config |= (recv_slots << AC97C_RECV_SLOTS_BIT);
128 au1000->ac97_ioport->config = ac97_config;
129 spin_unlock(&au1000->ac97_lock);
130}
131
132
133static void
134au1000_release_dma_link(struct audio_stream *stream)
135{
136 struct au1000_period * pointer;
137 struct au1000_period * pointer_next;
138
139 stream->period_size = 0;
140 stream->periods = 0;
141 pointer = stream->buffer;
142 if (! pointer)
143 return;
144 do {
145 pointer_next = pointer->next;
146 kfree(pointer);
147 pointer = pointer_next;
148 } while (pointer != stream->buffer);
149 stream->buffer = NULL;
150}
151
152static int
153au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes,
154 unsigned int periods)
155{
156 struct snd_pcm_substream *substream = stream->substream;
157 struct snd_pcm_runtime *runtime = substream->runtime;
158 struct au1000_period *pointer;
159 unsigned long dma_start;
160 int i;
161
162 dma_start = virt_to_phys(runtime->dma_area);
163
164 if (stream->period_size == period_bytes &&
165 stream->periods == periods)
166 return 0; /* not changed */
167
168 au1000_release_dma_link(stream);
169
170 stream->period_size = period_bytes;
171 stream->periods = periods;
172
173 stream->buffer = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
174 if (! stream->buffer)
175 return -ENOMEM;
176 pointer = stream->buffer;
177 for (i = 0; i < periods; i++) {
178 pointer->start = (u32)(dma_start + (i * period_bytes));
179 pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
180 if (i < periods - 1) {
181 pointer->next = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
182 if (! pointer->next) {
183 au1000_release_dma_link(stream);
184 return -ENOMEM;
185 }
186 pointer = pointer->next;
187 }
188 }
189 pointer->next = stream->buffer;
190 return 0;
191}
192
193static void
194au1000_dma_stop(struct audio_stream *stream)
195{
196 if (snd_BUG_ON(!stream->buffer))
197 return;
198 disable_dma(stream->dma);
199}
200
201static void
202au1000_dma_start(struct audio_stream *stream)
203{
204 if (snd_BUG_ON(!stream->buffer))
205 return;
206
207 init_dma(stream->dma);
208 if (get_dma_active_buffer(stream->dma) == 0) {
209 clear_dma_done0(stream->dma);
210 set_dma_addr0(stream->dma, stream->buffer->start);
211 set_dma_count0(stream->dma, stream->period_size >> 1);
212 set_dma_addr1(stream->dma, stream->buffer->next->start);
213 set_dma_count1(stream->dma, stream->period_size >> 1);
214 } else {
215 clear_dma_done1(stream->dma);
216 set_dma_addr1(stream->dma, stream->buffer->start);
217 set_dma_count1(stream->dma, stream->period_size >> 1);
218 set_dma_addr0(stream->dma, stream->buffer->next->start);
219 set_dma_count0(stream->dma, stream->period_size >> 1);
220 }
221 enable_dma_buffers(stream->dma);
222 start_dma(stream->dma);
223}
224
225static irqreturn_t
226au1000_dma_interrupt(int irq, void *dev_id)
227{
228 struct audio_stream *stream = (struct audio_stream *) dev_id;
229 struct snd_pcm_substream *substream = stream->substream;
230
231 spin_lock(&stream->dma_lock);
232 switch (get_dma_buffer_done(stream->dma)) {
233 case DMA_D0:
234 stream->buffer = stream->buffer->next;
235 clear_dma_done0(stream->dma);
236 set_dma_addr0(stream->dma, stream->buffer->next->start);
237 set_dma_count0(stream->dma, stream->period_size >> 1);
238 enable_dma_buffer0(stream->dma);
239 break;
240 case DMA_D1:
241 stream->buffer = stream->buffer->next;
242 clear_dma_done1(stream->dma);
243 set_dma_addr1(stream->dma, stream->buffer->next->start);
244 set_dma_count1(stream->dma, stream->period_size >> 1);
245 enable_dma_buffer1(stream->dma);
246 break;
247 case (DMA_D0 | DMA_D1):
248 printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
249 au1000_dma_stop(stream);
250 au1000_dma_start(stream);
251 break;
252 case (~DMA_D0 & ~DMA_D1):
253 printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);
254 }
255 spin_unlock(&stream->dma_lock);
256 snd_pcm_period_elapsed(substream);
257 return IRQ_HANDLED;
258}
259
260/*-------------------------- PCM Audio Streams -------------------------------*/
261
262static unsigned int rates[] = {8000, 11025, 16000, 22050};
263static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
264 .count = ARRAY_SIZE(rates),
265 .list = rates,
266 .mask = 0,
267};
268
269static struct snd_pcm_hardware snd_au1000_hw =
270{
271 .info = (SNDRV_PCM_INFO_INTERLEAVED | \
272 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
273 .formats = SNDRV_PCM_FMTBIT_S16_LE,
274 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
275 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050),
276 .rate_min = 8000,
277 .rate_max = 22050,
278 .channels_min = 1,
279 .channels_max = 2,
280 .buffer_bytes_max = 128*1024,
281 .period_bytes_min = 32,
282 .period_bytes_max = 16*1024,
283 .periods_min = 8,
284 .periods_max = 255,
285 .fifo_size = 16,
286};
287
288static int
289snd_au1000_playback_open(struct snd_pcm_substream *substream)
290{
291 struct snd_au1000 *au1000 = substream->pcm->private_data;
292
293 au1000->stream[PLAYBACK]->substream = substream;
294 au1000->stream[PLAYBACK]->buffer = NULL;
295 substream->private_data = au1000->stream[PLAYBACK];
296 substream->runtime->hw = snd_au1000_hw;
297 return (snd_pcm_hw_constraint_list(substream->runtime, 0,
298 SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
299}
300
301static int
302snd_au1000_capture_open(struct snd_pcm_substream *substream)
303{
304 struct snd_au1000 *au1000 = substream->pcm->private_data;
305
306 au1000->stream[CAPTURE]->substream = substream;
307 au1000->stream[CAPTURE]->buffer = NULL;
308 substream->private_data = au1000->stream[CAPTURE];
309 substream->runtime->hw = snd_au1000_hw;
310 return (snd_pcm_hw_constraint_list(substream->runtime, 0,
311 SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
312}
313
314static int
315snd_au1000_playback_close(struct snd_pcm_substream *substream)
316{
317 struct snd_au1000 *au1000 = substream->pcm->private_data;
318
319 au1000->stream[PLAYBACK]->substream = NULL;
320 return 0;
321}
322
323static int
324snd_au1000_capture_close(struct snd_pcm_substream *substream)
325{
326 struct snd_au1000 *au1000 = substream->pcm->private_data;
327
328 au1000->stream[CAPTURE]->substream = NULL;
329 return 0;
330}
331
332static int
333snd_au1000_hw_params(struct snd_pcm_substream *substream,
334 struct snd_pcm_hw_params *hw_params)
335{
336 struct audio_stream *stream = substream->private_data;
337 int err;
338
339 err = snd_pcm_lib_malloc_pages(substream,
340 params_buffer_bytes(hw_params));
341 if (err < 0)
342 return err;
343 return au1000_setup_dma_link(stream,
344 params_period_bytes(hw_params),
345 params_periods(hw_params));
346}
347
348static int
349snd_au1000_hw_free(struct snd_pcm_substream *substream)
350{
351 struct audio_stream *stream = substream->private_data;
352 au1000_release_dma_link(stream);
353 return snd_pcm_lib_free_pages(substream);
354}
355
356static int
357snd_au1000_playback_prepare(struct snd_pcm_substream *substream)
358{
359 struct snd_au1000 *au1000 = substream->pcm->private_data;
360 struct snd_pcm_runtime *runtime = substream->runtime;
361
362 if (runtime->channels == 1)
363 au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_4);
364 else
365 au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
366 snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
367 return 0;
368}
369
370static int
371snd_au1000_capture_prepare(struct snd_pcm_substream *substream)
372{
373 struct snd_au1000 *au1000 = substream->pcm->private_data;
374 struct snd_pcm_runtime *runtime = substream->runtime;
375
376 if (runtime->channels == 1)
377 au1000_set_ac97_recv_slots(au1000, AC97_SLOT_4);
378 else
379 au1000_set_ac97_recv_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
380 snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
381 return 0;
382}
383
384static int
385snd_au1000_trigger(struct snd_pcm_substream *substream, int cmd)
386{
387 struct audio_stream *stream = substream->private_data;
388 int err = 0;
389
390 spin_lock(&stream->dma_lock);
391 switch (cmd) {
392 case SNDRV_PCM_TRIGGER_START:
393 au1000_dma_start(stream);
394 break;
395 case SNDRV_PCM_TRIGGER_STOP:
396 au1000_dma_stop(stream);
397 break;
398 default:
399 err = -EINVAL;
400 break;
401 }
402 spin_unlock(&stream->dma_lock);
403 return err;
404}
405
406static snd_pcm_uframes_t
407snd_au1000_pointer(struct snd_pcm_substream *substream)
408{
409 struct audio_stream *stream = substream->private_data;
410 struct snd_pcm_runtime *runtime = substream->runtime;
411 long location;
412
413 spin_lock(&stream->dma_lock);
414 location = get_dma_residue(stream->dma);
415 spin_unlock(&stream->dma_lock);
416 location = stream->buffer->relative_end - location;
417 if (location == -1)
418 location = 0;
419 return bytes_to_frames(runtime,location);
420}
421
422static struct snd_pcm_ops snd_card_au1000_playback_ops = {
423 .open = snd_au1000_playback_open,
424 .close = snd_au1000_playback_close,
425 .ioctl = snd_pcm_lib_ioctl,
426 .hw_params = snd_au1000_hw_params,
427 .hw_free = snd_au1000_hw_free,
428 .prepare = snd_au1000_playback_prepare,
429 .trigger = snd_au1000_trigger,
430 .pointer = snd_au1000_pointer,
431};
432
433static struct snd_pcm_ops snd_card_au1000_capture_ops = {
434 .open = snd_au1000_capture_open,
435 .close = snd_au1000_capture_close,
436 .ioctl = snd_pcm_lib_ioctl,
437 .hw_params = snd_au1000_hw_params,
438 .hw_free = snd_au1000_hw_free,
439 .prepare = snd_au1000_capture_prepare,
440 .trigger = snd_au1000_trigger,
441 .pointer = snd_au1000_pointer,
442};
443
444static int
445snd_au1000_pcm_new(struct snd_au1000 *au1000)
446{
447 struct snd_pcm *pcm;
448 int err;
449 unsigned long flags;
450
451 if ((err = snd_pcm_new(au1000->card, "AU1000 AC97 PCM", 0, 1, 1, &pcm)) < 0)
452 return err;
453
454 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
455 snd_dma_continuous_data(GFP_KERNEL), 128*1024, 128*1024);
456
457 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
458 &snd_card_au1000_playback_ops);
459 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
460 &snd_card_au1000_capture_ops);
461
462 pcm->private_data = au1000;
463 pcm->info_flags = 0;
464 strcpy(pcm->name, "Au1000 AC97 PCM");
465
466 spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
467 spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
468
469 flags = claim_dma_lock();
470 au1000->stream[PLAYBACK]->dma = request_au1000_dma(au1000->dmaid[0],
471 "AC97 TX", au1000_dma_interrupt, 0,
472 au1000->stream[PLAYBACK]);
473 if (au1000->stream[PLAYBACK]->dma < 0) {
474 release_dma_lock(flags);
475 return -EBUSY;
476 }
477 au1000->stream[CAPTURE]->dma = request_au1000_dma(au1000->dmaid[1],
478 "AC97 RX", au1000_dma_interrupt, 0,
479 au1000->stream[CAPTURE]);
480 if (au1000->stream[CAPTURE]->dma < 0){
481 release_dma_lock(flags);
482 return -EBUSY;
483 }
484 /* enable DMA coherency in read/write DMA channels */
485 set_dma_mode(au1000->stream[PLAYBACK]->dma,
486 get_dma_mode(au1000->stream[PLAYBACK]->dma) & ~DMA_NC);
487 set_dma_mode(au1000->stream[CAPTURE]->dma,
488 get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
489 release_dma_lock(flags);
490 au1000->pcm = pcm;
491 return 0;
492}
493
494
495/*-------------------------- AC97 CODEC Control ------------------------------*/
496
497static unsigned short
498snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
499{
500 struct snd_au1000 *au1000 = ac97->private_data;
501 u32 volatile cmd;
502 u16 volatile data;
503 int i;
504
505 spin_lock(&au1000->ac97_lock);
506/* would rather use the interrupt than this polling but it works and I can't
507get the interrupt driven case to work efficiently */
508 for (i = 0; i < 0x5000; i++)
509 if (!(au1000->ac97_ioport->status & AC97C_CP))
510 break;
511 if (i == 0x5000)
512 printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
513
514 cmd = (u32) reg & AC97C_INDEX_MASK;
515 cmd |= AC97C_READ;
516 au1000->ac97_ioport->cmd = cmd;
517
518 /* now wait for the data */
519 for (i = 0; i < 0x5000; i++)
520 if (!(au1000->ac97_ioport->status & AC97C_CP))
521 break;
522 if (i == 0x5000) {
523 printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
524 spin_unlock(&au1000->ac97_lock);
525 return 0;
526 }
527
528 data = au1000->ac97_ioport->cmd & 0xffff;
529 spin_unlock(&au1000->ac97_lock);
530
531 return data;
532
533}
534
535
536static void
537snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
538{
539 struct snd_au1000 *au1000 = ac97->private_data;
540 u32 cmd;
541 int i;
542
543 spin_lock(&au1000->ac97_lock);
544/* would rather use the interrupt than this polling but it works and I can't
545get the interrupt driven case to work efficiently */
546 for (i = 0; i < 0x5000; i++)
547 if (!(au1000->ac97_ioport->status & AC97C_CP))
548 break;
549 if (i == 0x5000)
550 printk(KERN_ERR "au1000 AC97: AC97 command write timeout\n");
551
552 cmd = (u32) reg & AC97C_INDEX_MASK;
553 cmd &= ~AC97C_READ;
554 cmd |= ((u32) val << AC97C_WD_BIT);
555 au1000->ac97_ioport->cmd = cmd;
556 spin_unlock(&au1000->ac97_lock);
557}
558
559/*------------------------------ Setup / Destroy ----------------------------*/
560
561static void snd_au1000_free(struct snd_card *card)
562{
563 struct snd_au1000 *au1000 = card->private_data;
564
565 if (au1000->stream[PLAYBACK]) {
566 if (au1000->stream[PLAYBACK]->dma >= 0)
567 free_au1000_dma(au1000->stream[PLAYBACK]->dma);
568 kfree(au1000->stream[PLAYBACK]);
569 }
570
571 if (au1000->stream[CAPTURE]) {
572 if (au1000->stream[CAPTURE]->dma >= 0)
573 free_au1000_dma(au1000->stream[CAPTURE]->dma);
574 kfree(au1000->stream[CAPTURE]);
575 }
576
577 if (au1000->ac97_res_port) {
578 /* put internal AC97 block into reset */
579 if (au1000->ac97_ioport) {
580 au1000->ac97_ioport->cntrl = AC97C_RS;
581 iounmap(au1000->ac97_ioport);
582 au1000->ac97_ioport = NULL;
583 }
584 release_and_free_resource(au1000->ac97_res_port);
585 au1000->ac97_res_port = NULL;
586 }
587}
588
589static struct snd_ac97_bus_ops ops = {
590 .write = snd_au1000_ac97_write,
591 .read = snd_au1000_ac97_read,
592};
593
594static int au1000_ac97_probe(struct platform_device *pdev)
595{
596 int err;
597 void __iomem *io;
598 struct resource *r;
599 struct snd_card *card;
600 struct snd_au1000 *au1000;
601 struct snd_ac97_bus *pbus;
602 struct snd_ac97_template ac97;
603
604 err = snd_card_new(&pdev->dev, -1, "AC97", THIS_MODULE,
605 sizeof(struct snd_au1000), &card);
606 if (err < 0)
607 return err;
608
609 au1000 = card->private_data;
610 au1000->card = card;
611 spin_lock_init(&au1000->ac97_lock);
612
613 /* from here on let ALSA call the special freeing function */
614 card->private_free = snd_au1000_free;
615
616 /* TX DMA ID */
617 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
618 if (!r) {
619 err = -ENODEV;
620 snd_printk(KERN_INFO "no TX DMA platform resource!\n");
621 goto out;
622 }
623 au1000->dmaid[0] = r->start;
624
625 /* RX DMA ID */
626 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
627 if (!r) {
628 err = -ENODEV;
629 snd_printk(KERN_INFO "no RX DMA platform resource!\n");
630 goto out;
631 }
632 au1000->dmaid[1] = r->start;
633
634 au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream),
635 GFP_KERNEL);
636 if (!au1000->stream[PLAYBACK]) {
637 err = -ENOMEM;
638 goto out;
639 }
640 au1000->stream[PLAYBACK]->dma = -1;
641
642 au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream),
643 GFP_KERNEL);
644 if (!au1000->stream[CAPTURE]) {
645 err = -ENOMEM;
646 goto out;
647 }
648 au1000->stream[CAPTURE]->dma = -1;
649
650 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
651 if (!r) {
652 err = -ENODEV;
653 goto out;
654 }
655
656 err = -EBUSY;
657 au1000->ac97_res_port = request_mem_region(r->start, resource_size(r),
658 pdev->name);
659 if (!au1000->ac97_res_port) {
660 snd_printk(KERN_ERR "ALSA AC97: can't grab AC97 port\n");
661 goto out;
662 }
663
664 io = ioremap(r->start, resource_size(r));
665 if (!io)
666 goto out;
667
668 au1000->ac97_ioport = (struct au1000_ac97_reg *)io;
669
670 /* configure pins for AC'97
671 TODO: move to board_setup.c */
672 au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
673
674 /* Initialise Au1000's AC'97 Control Block */
675 au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
676 udelay(10);
677 au1000->ac97_ioport->cntrl = AC97C_CE;
678 udelay(10);
679
680 /* Initialise External CODEC -- cold reset */
681 au1000->ac97_ioport->config = AC97C_RESET;
682 udelay(10);
683 au1000->ac97_ioport->config = 0x0;
684 mdelay(5);
685
686 /* Initialise AC97 middle-layer */
687 err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus);
688 if (err < 0)
689 goto out;
690
691 memset(&ac97, 0, sizeof(ac97));
692 ac97.private_data = au1000;
693 err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97);
694 if (err < 0)
695 goto out;
696
697 err = snd_au1000_pcm_new(au1000);
698 if (err < 0)
699 goto out;
700
701 strcpy(card->driver, "Au1000-AC97");
702 strcpy(card->shortname, "AMD Au1000-AC97");
703 sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
704
705 err = snd_card_register(card);
706 if (err < 0)
707 goto out;
708
709 printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
710
711 platform_set_drvdata(pdev, card);
712
713 return 0;
714
715 out:
716 snd_card_free(card);
717 return err;
718}
719
720static int au1000_ac97_remove(struct platform_device *pdev)
721{
722 return snd_card_free(platform_get_drvdata(pdev));
723}
724
725struct platform_driver au1000_ac97c_driver = {
726 .driver = {
727 .name = "au1000-ac97c",
728 .owner = THIS_MODULE,
729 },
730 .probe = au1000_ac97_probe,
731 .remove = au1000_ac97_remove,
732};
733
734module_platform_driver(au1000_ac97c_driver);
sound/pci/Kconfig+1−1
@@ -866,7 +866,7 @@ config SND_VIRTUOSO · 865 unmodified lines
866 select SND_OXYGEN_LIB866 select SND_OXYGEN_LIB
867 select SND_PCM867 select SND_PCM
868 select SND_MPU401_UART868 select SND_MPU401_UART
869 select SND_JACK if INPUT=y || INPUT=SND869 select SND_JACK
870 help870 help
871 Say Y here to include support for sound cards based on the871 Say Y here to include support for sound cards based on the
872 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, DSX,872 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, DSX,
sound/pci/hda/Kconfig+1−1
@@ -4,7 +4,7 @@ config SND_HDA · 3 unmodified lines
4 tristate4 tristate
5 select SND_PCM5 select SND_PCM
6 select SND_VMASTER6 select SND_VMASTER
7 select SND_JACK if INPUT=y || INPUT=SND7 select SND_JACK
8 select SND_HDA_CORE8 select SND_HDA_CORE
9 9
10config SND_HDA_INTEL10config SND_HDA_INTEL
sound/pci/hda/hda_eld.c+3−28
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include <linux/slab.h>26#include <linux/slab.h>
27#include <sound/core.h>27#include <sound/core.h>
28#include <asm/unaligned.h>28#include <asm/unaligned.h>
29#include <sound/hda_chmap.h>
29#include "hda_codec.h"30#include "hda_codec.h"
30#include "hda_local.h"31#include "hda_local.h"
31 32
@@ -42,20 +43,6 @@ enum cea_edid_versions { · 10 unmodified lines
42 CEA_EDID_VER_RESERVED = 4,43 CEA_EDID_VER_RESERVED = 4,
43};44};
44 45
45static const char * const cea_speaker_allocation_names[] = {
46 /* 0 */ "FL/FR",
47 /* 1 */ "LFE",
48 /* 2 */ "FC",
49 /* 3 */ "RL/RR",
50 /* 4 */ "RC",
51 /* 5 */ "FLC/FRC",
52 /* 6 */ "RLC/RRC",
53 /* 7 */ "FLW/FRW",
54 /* 8 */ "FLH/FRH",
55 /* 9 */ "TC",
56 /* 10 */ "FCH",
57};
58
59static const char * const eld_connection_type_names[4] = {46static const char * const eld_connection_type_names[4] = {
60 "HDMI",47 "HDMI",
61 "DisplayPort",48 "DisplayPort",
@@ -419,18 +406,6 @@ static void hdmi_show_short_audio_desc(struct hda_codec *codec, · 357 unmodified lines
419 a->channels, buf, buf2);406 a->channels, buf, buf2);
420}407}
421 408
422void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
423{
424 int i, j;
425
426 for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
427 if (spk_alloc & (1 << i))
428 j += snprintf(buf + j, buflen - j, " %s",
429 cea_speaker_allocation_names[i]);
430 }
431 buf[j] = '\0'; /* necessary when j == 0 */
432}
433
434void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e)409void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e)
435{410{
436 int i;411 int i;
@@ -441,7 +416,7 @@ void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e) · 4 unmodified lines
441 416
442 if (e->spk_alloc) {417 if (e->spk_alloc) {
443 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];418 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
444 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));419 snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
445 codec_dbg(codec, "HDMI: available speakers:%s\n", buf);420 codec_dbg(codec, "HDMI: available speakers:%s\n", buf);
446 }421 }
447 422
@@ -516,7 +491,7 @@ void snd_hdmi_print_eld_info(struct hdmi_eld *eld, · 68 unmodified lines
516 snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);491 snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
517 snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);492 snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
518 493
519 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));494 snd_hdac_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
520 snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);495 snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
521 496
522 snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);497 snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
sound/pci/hda/hda_intel.c+1−1
@@ -2145,7 +2145,7 @@ static int azx_probe_continue(struct azx *chip) · 2144 unmodified lines
2145 azx_add_card_list(chip);2145 azx_add_card_list(chip);
2146 snd_hda_set_power_save(&chip->bus, power_save * 1000);2146 snd_hda_set_power_save(&chip->bus, power_save * 1000);
2147 if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)2147 if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
2148 pm_runtime_put_noidle(&pci->dev);2148 pm_runtime_put_autosuspend(&pci->dev);
2149 2149
2150out_free:2150out_free:
2151 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL2151 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
sound/pci/hda/patch_cirrus.c+6−2
@@ -174,8 +174,12 @@ static void cs_automute(struct hda_codec *codec) · 173 unmodified lines
174 snd_hda_gen_update_outputs(codec);174 snd_hda_gen_update_outputs(codec);
175 175
176 if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {176 if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
177 spec->gpio_data = spec->gen.hp_jack_present ?177 if (spec->gen.automute_speaker)
178 spec->gpio_eapd_hp : spec->gpio_eapd_speaker;178 spec->gpio_data = spec->gen.hp_jack_present ?
179 spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
180 else
181 spec->gpio_data =
182 spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
179 snd_hda_codec_write(codec, 0x01, 0,183 snd_hda_codec_write(codec, 0x01, 0,
180 AC_VERB_SET_GPIO_DATA, spec->gpio_data);184 AC_VERB_SET_GPIO_DATA, spec->gpio_data);
181 }185 }
sound/pci/hda/patch_conexant.c+6−1
@@ -204,8 +204,13 @@ static void cx_auto_reboot_notify(struct hda_codec *codec) · 203 unmodified lines
204{204{
205 struct conexant_spec *spec = codec->spec;205 struct conexant_spec *spec = codec->spec;
206 206
207 if (codec->core.vendor_id != 0x14f150f2)207 switch (codec->core.vendor_id) {
208 case 0x14f150f2: /* CX20722 */
209 case 0x14f150f4: /* CX20724 */
210 break;
211 default:
208 return;212 return;
213 }
209 214
210 /* Turn the CX20722 codec into D3 to avoid spurious noises215 /* Turn the CX20722 codec into D3 to avoid spurious noises
211 from the internal speaker during (and after) reboot */216 from the internal speaker during (and after) reboot */
sound/pci/hda/patch_hdmi.c+630−821
@@ -39,6 +39,7 @@ · 38 unmodified lines
39#include <sound/tlv.h>39#include <sound/tlv.h>
40#include <sound/hdaudio.h>40#include <sound/hdaudio.h>
41#include <sound/hda_i915.h>41#include <sound/hda_i915.h>
42#include <sound/hda_chmap.h>
42#include "hda_codec.h"43#include "hda_codec.h"
43#include "hda_local.h"44#include "hda_local.h"
44#include "hda_jack.h"45#include "hda_jack.h"
@@ -75,6 +76,8 @@ struct hdmi_spec_per_cvt { · 30 unmodified lines
75 76
76struct hdmi_spec_per_pin {77struct hdmi_spec_per_pin {
77 hda_nid_t pin_nid;78 hda_nid_t pin_nid;
79 /* pin idx, different device entries on the same pin use the same idx */
80 int pin_nid_idx;
78 int num_mux_nids;81 int num_mux_nids;
79 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];82 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
80 int mux_idx;83 int mux_idx;
@@ -84,8 +87,8 @@ struct hdmi_spec_per_pin { · 3 unmodified lines
84 struct hdmi_eld sink_eld;87 struct hdmi_eld sink_eld;
85 struct mutex lock;88 struct mutex lock;
86 struct delayed_work work;89 struct delayed_work work;
87 struct snd_kcontrol *eld_ctl;90 struct hdmi_pcm *pcm; /* pointer to spec->pcm_rec[n] dynamically*/
88 struct snd_jack *acomp_jack; /* jack via audio component */91 int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
89 int repoll_count;92 int repoll_count;
90 bool setup; /* the stream has been set up by prepare callback */93 bool setup; /* the stream has been set up by prepare callback */
91 int channels; /* current number of channels */94 int channels; /* current number of channels */
@@ -97,19 +100,11 @@ struct hdmi_spec_per_pin { · 5 unmodified lines
97#endif100#endif
98};101};
99 102
100struct cea_channel_speaker_allocation;
101
102/* operations used by generic code that can be overridden by patches */103/* operations used by generic code that can be overridden by patches */
103struct hdmi_ops {104struct hdmi_ops {
104 int (*pin_get_eld)(struct hda_codec *codec, hda_nid_t pin_nid,105 int (*pin_get_eld)(struct hda_codec *codec, hda_nid_t pin_nid,
105 unsigned char *buf, int *eld_size);106 unsigned char *buf, int *eld_size);
106 107
107 /* get and set channel assigned to each HDMI ASP (audio sample packet) slot */
108 int (*pin_get_slot_channel)(struct hda_codec *codec, hda_nid_t pin_nid,
109 int asp_slot);
110 int (*pin_set_slot_channel)(struct hda_codec *codec, hda_nid_t pin_nid,
111 int asp_slot, int channel);
112
113 void (*pin_setup_infoframe)(struct hda_codec *codec, hda_nid_t pin_nid,108 void (*pin_setup_infoframe)(struct hda_codec *codec, hda_nid_t pin_nid,
114 int ca, int active_channels, int conn_type);109 int ca, int active_channels, int conn_type);
115 110
@@ -119,15 +114,12 @@ struct hdmi_ops { · 3 unmodified lines
119 int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid,114 int (*setup_stream)(struct hda_codec *codec, hda_nid_t cvt_nid,
120 hda_nid_t pin_nid, u32 stream_tag, int format);115 hda_nid_t pin_nid, u32 stream_tag, int format);
121 116
122 /* Helpers for producing the channel map TLVs. These can be overridden117};
123 * for devices that have non-standard mapping requirements. */
124 int (*chmap_cea_alloc_validate_get_type)(struct cea_channel_speaker_allocation *cap,
125 int channels);
126 void (*cea_alloc_to_tlv_chmap)(struct cea_channel_speaker_allocation *cap,
127 unsigned int *chmap, int channels);
128 118
129 /* check that the user-given chmap is supported */119struct hdmi_pcm {
130 int (*chmap_validate)(int ca, int channels, unsigned char *chmap);120 struct hda_pcm *pcm;
121 struct snd_jack *jack;
122 struct snd_kcontrol *eld_ctl;
131};123};
132 124
133struct hdmi_spec {125struct hdmi_spec {
@@ -137,14 +129,22 @@ struct hdmi_spec { · 3 unmodified lines
137 129
138 int num_pins;130 int num_pins;
139 struct snd_array pins; /* struct hdmi_spec_per_pin */131 struct snd_array pins; /* struct hdmi_spec_per_pin */
140 struct hda_pcm *pcm_rec[16];132 struct hdmi_pcm pcm_rec[16];
141 unsigned int channels_max; /* max over all cvts */133 struct mutex pcm_lock;
134 /* pcm_bitmap means which pcms have been assigned to pins*/
135 unsigned long pcm_bitmap;
136 int pcm_used; /* counter of pcm_rec[] */
137 /* bitmap shows whether the pcm is opened in user space
138 * bit 0 means the first playback PCM (PCM3);
139 * bit 1 means the second playback PCM, and so on.
140 */
141 unsigned long pcm_in_use;
142 142
143 struct hdmi_eld temp_eld;143 struct hdmi_eld temp_eld;
144 struct hdmi_ops ops;144 struct hdmi_ops ops;
145 145
146 bool dyn_pin_out;146 bool dyn_pin_out;
147 147 bool dyn_pcm_assign;
148 /*148 /*
149 * Non-generic VIA/NVIDIA specific149 * Non-generic VIA/NVIDIA specific
150 */150 */
@@ -154,6 +154,8 @@ struct hdmi_spec { · 3 unmodified lines
154 /* i915/powerwell (Haswell+/Valleyview+) specific */154 /* i915/powerwell (Haswell+/Valleyview+) specific */
155 struct i915_audio_component_audio_ops i915_audio_ops;155 struct i915_audio_component_audio_ops i915_audio_ops;
156 bool i915_bound; /* was i915 bound in this driver? */156 bool i915_bound; /* was i915 bound in this driver? */
157
158 struct hdac_chmap chmap;
157};159};
158 160
159#ifdef CONFIG_SND_HDA_I915161#ifdef CONFIG_SND_HDA_I915
@@ -195,173 +197,6 @@ union audio_infoframe { · 35 unmodified lines
195 u8 bytes[0];197 u8 bytes[0];
196};198};
197 199
198/*
199 * CEA speaker placement:
200 *
201 * FLH FCH FRH
202 * FLW FL FLC FC FRC FR FRW
203 *
204 * LFE
205 * TC
206 *
207 * RL RLC RC RRC RR
208 *
209 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
210 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
211 */
212enum cea_speaker_placement {
213 FL = (1 << 0), /* Front Left */
214 FC = (1 << 1), /* Front Center */
215 FR = (1 << 2), /* Front Right */
216 FLC = (1 << 3), /* Front Left Center */
217 FRC = (1 << 4), /* Front Right Center */
218 RL = (1 << 5), /* Rear Left */
219 RC = (1 << 6), /* Rear Center */
220 RR = (1 << 7), /* Rear Right */
221 RLC = (1 << 8), /* Rear Left Center */
222 RRC = (1 << 9), /* Rear Right Center */
223 LFE = (1 << 10), /* Low Frequency Effect */
224 FLW = (1 << 11), /* Front Left Wide */
225 FRW = (1 << 12), /* Front Right Wide */
226 FLH = (1 << 13), /* Front Left High */
227 FCH = (1 << 14), /* Front Center High */
228 FRH = (1 << 15), /* Front Right High */
229 TC = (1 << 16), /* Top Center */
230};
231
232/*
233 * ELD SA bits in the CEA Speaker Allocation data block
234 */
235static int eld_speaker_allocation_bits[] = {
236 [0] = FL | FR,
237 [1] = LFE,
238 [2] = FC,
239 [3] = RL | RR,
240 [4] = RC,
241 [5] = FLC | FRC,
242 [6] = RLC | RRC,
243 /* the following are not defined in ELD yet */
244 [7] = FLW | FRW,
245 [8] = FLH | FRH,
246 [9] = TC,
247 [10] = FCH,
248};
249
250struct cea_channel_speaker_allocation {
251 int ca_index;
252 int speakers[8];
253
254 /* derived values, just for convenience */
255 int channels;
256 int spk_mask;
257};
258
259/*
260 * ALSA sequence is:
261 *
262 * surround40 surround41 surround50 surround51 surround71
263 * ch0 front left = = = =
264 * ch1 front right = = = =
265 * ch2 rear left = = = =
266 * ch3 rear right = = = =
267 * ch4 LFE center center center
268 * ch5 LFE LFE
269 * ch6 side left
270 * ch7 side right
271 *
272 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
273 */
274static int hdmi_channel_mapping[0x32][8] = {
275 /* stereo */
276 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
277 /* 2.1 */
278 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
279 /* Dolby Surround */
280 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
281 /* surround40 */
282 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
283 /* 4ch */
284 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
285 /* surround41 */
286 [0x09] = { 0x00, 0x11, 0x24, 0x35, 0x42, 0xf3, 0xf6, 0xf7 },
287 /* surround50 */
288 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
289 /* surround51 */
290 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
291 /* 7.1 */
292 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
293};
294
295/*
296 * This is an ordered list!
297 *
298 * The preceding ones have better chances to be selected by
299 * hdmi_channel_allocation().
300 */
301static struct cea_channel_speaker_allocation channel_allocations[] = {
302/* channel: 7 6 5 4 3 2 1 0 */
303{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
304 /* 2.1 */
305{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
306 /* Dolby Surround */
307{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
308 /* surround40 */
309{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
310 /* surround41 */
311{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
312 /* surround50 */
313{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
314 /* surround51 */
315{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
316 /* 6.1 */
317{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
318 /* surround71 */
319{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
320
321{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
322{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
323{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
324{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
325{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
326{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
327{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
328{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
329{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
330{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
331{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
332{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
333{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
334{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
335{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
336{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
337{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
338{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
339{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
340{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
341{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
342{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
343{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
344{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
345{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
346{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
347{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
348{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
349{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
350{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
351{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
352{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
353{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
354{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
355{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
356{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
357{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
358{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
359{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
360{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
361{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
362};
363
364
365/*200/*
366 * HDMI routines201 * HDMI routines
367 */202 */
@@ -370,7 +205,10 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { · 2 unmodified lines
370 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))205 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
371#define get_cvt(spec, idx) \206#define get_cvt(spec, idx) \
372 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))207 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
373#define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx])208/* obtain hdmi_pcm object assigned to idx */
209#define get_hdmi_pcm(spec, idx) (&(spec)->pcm_rec[idx])
210/* obtain hda_pcm object assigned to idx */
211#define get_pcm_rec(spec, idx) (get_hdmi_pcm(spec, idx)->pcm)
374 212
375static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)213static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid)
376{214{
@@ -385,20 +223,52 @@ static int pin_nid_to_pin_index(struct hda_codec *codec, hda_nid_t pin_nid) · 8 unmodified lines
385 return -EINVAL;223 return -EINVAL;
386}224}
387 225
226static int hinfo_to_pcm_index(struct hda_codec *codec,
227 struct hda_pcm_stream *hinfo)
228{
229 struct hdmi_spec *spec = codec->spec;
230 int pcm_idx;
231
232 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++)
233 if (get_pcm_rec(spec, pcm_idx)->stream == hinfo)
234 return pcm_idx;
235
236 codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo);
237 return -EINVAL;
238}
239
388static int hinfo_to_pin_index(struct hda_codec *codec,240static int hinfo_to_pin_index(struct hda_codec *codec,
389 struct hda_pcm_stream *hinfo)241 struct hda_pcm_stream *hinfo)
390{242{
391 struct hdmi_spec *spec = codec->spec;243 struct hdmi_spec *spec = codec->spec;
244 struct hdmi_spec_per_pin *per_pin;
392 int pin_idx;245 int pin_idx;
393 246
394 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)247 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
395 if (get_pcm_rec(spec, pin_idx)->stream == hinfo)248 per_pin = get_pin(spec, pin_idx);
249 if (per_pin->pcm &&
250 per_pin->pcm->pcm->stream == hinfo)
396 return pin_idx;251 return pin_idx;
252 }
397 253
398 codec_warn(codec, "HDMI: hinfo %p not registered\n", hinfo);254 codec_dbg(codec, "HDMI: hinfo %p not registered\n", hinfo);
399 return -EINVAL;255 return -EINVAL;
400}256}
401 257
258static struct hdmi_spec_per_pin *pcm_idx_to_pin(struct hdmi_spec *spec,
259 int pcm_idx)
260{
261 int i;
262 struct hdmi_spec_per_pin *per_pin;
263
264 for (i = 0; i < spec->num_pins; i++) {
265 per_pin = get_pin(spec, i);
266 if (per_pin->pcm_idx == pcm_idx)
267 return per_pin;
268 }
269 return NULL;
270}
271
402static int cvt_nid_to_cvt_index(struct hda_codec *codec, hda_nid_t cvt_nid)272static int cvt_nid_to_cvt_index(struct hda_codec *codec, hda_nid_t cvt_nid)
403{273{
404 struct hdmi_spec *spec = codec->spec;274 struct hdmi_spec *spec = codec->spec;
@@ -419,17 +289,22 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, · 14 unmodified lines
419 struct hdmi_spec *spec = codec->spec;289 struct hdmi_spec *spec = codec->spec;
420 struct hdmi_spec_per_pin *per_pin;290 struct hdmi_spec_per_pin *per_pin;
421 struct hdmi_eld *eld;291 struct hdmi_eld *eld;
422 int pin_idx;292 int pcm_idx;
423 293
424 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;294 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
425 295
426 pin_idx = kcontrol->private_value;296 pcm_idx = kcontrol->private_value;
427 per_pin = get_pin(spec, pin_idx);297 mutex_lock(&spec->pcm_lock);
298 per_pin = pcm_idx_to_pin(spec, pcm_idx);
299 if (!per_pin) {
300 /* no pin is bound to the pcm */
301 uinfo->count = 0;
302 mutex_unlock(&spec->pcm_lock);
303 return 0;
304 }
428 eld = &per_pin->sink_eld;305 eld = &per_pin->sink_eld;
429
430 mutex_lock(&per_pin->lock);
431 uinfo->count = eld->eld_valid ? eld->eld_size : 0;306 uinfo->count = eld->eld_valid ? eld->eld_size : 0;
432 mutex_unlock(&per_pin->lock);307 mutex_unlock(&spec->pcm_lock);
433 308
434 return 0;309 return 0;
435}310}
@@ -441,16 +316,23 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, · 5 unmodified lines
441 struct hdmi_spec *spec = codec->spec;316 struct hdmi_spec *spec = codec->spec;
442 struct hdmi_spec_per_pin *per_pin;317 struct hdmi_spec_per_pin *per_pin;
443 struct hdmi_eld *eld;318 struct hdmi_eld *eld;
444 int pin_idx;319 int pcm_idx;
445 320
446 pin_idx = kcontrol->private_value;321 pcm_idx = kcontrol->private_value;
447 per_pin = get_pin(spec, pin_idx);322 mutex_lock(&spec->pcm_lock);
323 per_pin = pcm_idx_to_pin(spec, pcm_idx);
324 if (!per_pin) {
325 /* no pin is bound to the pcm */
326 memset(ucontrol->value.bytes.data, 0,
327 ARRAY_SIZE(ucontrol->value.bytes.data));
328 mutex_unlock(&spec->pcm_lock);
329 return 0;
330 }
448 eld = &per_pin->sink_eld;331 eld = &per_pin->sink_eld;
449 332
450 mutex_lock(&per_pin->lock);
451 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||333 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
452 eld->eld_size > ELD_MAX_SIZE) {334 eld->eld_size > ELD_MAX_SIZE) {
453 mutex_unlock(&per_pin->lock);335 mutex_unlock(&spec->pcm_lock);
454 snd_BUG();336 snd_BUG();
455 return -EINVAL;337 return -EINVAL;
456 }338 }
@@ -460,7 +342,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, · 3 unmodified lines
460 if (eld->eld_valid)342 if (eld->eld_valid)
461 memcpy(ucontrol->value.bytes.data, eld->eld_buffer,343 memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
462 eld->eld_size);344 eld->eld_size);
463 mutex_unlock(&per_pin->lock);345 mutex_unlock(&spec->pcm_lock);
464 346
465 return 0;347 return 0;
466}348}
@@ -473,7 +355,7 @@ static struct snd_kcontrol_new eld_bytes_ctl = { · 6 unmodified lines
473 .get = hdmi_eld_ctl_get,355 .get = hdmi_eld_ctl_get,
474};356};
475 357
476static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,358static int hdmi_create_eld_ctl(struct hda_codec *codec, int pcm_idx,
477 int device)359 int device)
478{360{
479 struct snd_kcontrol *kctl;361 struct snd_kcontrol *kctl;
@@ -483,14 +365,17 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx, · 3 unmodified lines
483 kctl = snd_ctl_new1(&eld_bytes_ctl, codec);365 kctl = snd_ctl_new1(&eld_bytes_ctl, codec);
484 if (!kctl)366 if (!kctl)
485 return -ENOMEM;367 return -ENOMEM;
486 kctl->private_value = pin_idx;368 kctl->private_value = pcm_idx;
487 kctl->id.device = device;369 kctl->id.device = device;
488 370
489 err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid, kctl);371 /* no pin nid is associated with the kctl now
372 * tbd: associate pin nid to eld ctl later
373 */
374 err = snd_hda_ctl_add(codec, 0, kctl);
490 if (err < 0)375 if (err < 0)
491 return err;376 return err;
492 377
493 get_pin(spec, pin_idx)->eld_ctl = kctl;378 get_hdmi_pcm(spec, pcm_idx)->eld_ctl = kctl;
494 return 0;379 return 0;
495}380}
496 381
@@ -547,20 +432,6 @@ static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid) · 50 unmodified lines
547 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out);432 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_out);
548}433}
549 434
550static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
551{
552 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
553 AC_VERB_GET_CVT_CHAN_COUNT, 0);
554}
555
556static void hdmi_set_channel_count(struct hda_codec *codec,
557 hda_nid_t cvt_nid, int chs)
558{
559 if (chs != hdmi_get_channel_count(codec, cvt_nid))
560 snd_hda_codec_write(codec, cvt_nid, 0,
561 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
562}
563
564/*435/*
565 * ELD proc files436 * ELD proc files
566 */437 */
@@ -624,339 +495,6 @@ static inline void eld_proc_free(struct hdmi_spec_per_pin *per_pin) · 57 unmodified lines
624}495}
625#endif496#endif
626 497
627/*
628 * Channel mapping routines
629 */
630
631/*
632 * Compute derived values in channel_allocations[].
633 */
634static void init_channel_allocations(void)
635{
636 int i, j;
637 struct cea_channel_speaker_allocation *p;
638
639 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
640 p = channel_allocations + i;
641 p->channels = 0;
642 p->spk_mask = 0;
643 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
644 if (p->speakers[j]) {
645 p->channels++;
646 p->spk_mask |= p->speakers[j];
647 }
648 }
649}
650
651static int get_channel_allocation_order(int ca)
652{
653 int i;
654
655 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
656 if (channel_allocations[i].ca_index == ca)
657 break;
658 }
659 return i;
660}
661
662/*
663 * The transformation takes two steps:
664 *
665 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
666 * spk_mask => (channel_allocations[]) => ai->CA
667 *
668 * TODO: it could select the wrong CA from multiple candidates.
669*/
670static int hdmi_channel_allocation(struct hda_codec *codec,
671 struct hdmi_eld *eld, int channels)
672{
673 int i;
674 int ca = 0;
675 int spk_mask = 0;
676 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
677
678 /*
679 * CA defaults to 0 for basic stereo audio
680 */
681 if (channels <= 2)
682 return 0;
683
684 /*
685 * expand ELD's speaker allocation mask
686 *
687 * ELD tells the speaker mask in a compact(paired) form,
688 * expand ELD's notions to match the ones used by Audio InfoFrame.
689 */
690 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
691 if (eld->info.spk_alloc & (1 << i))
692 spk_mask |= eld_speaker_allocation_bits[i];
693 }
694
695 /* search for the first working match in the CA table */
696 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
697 if (channels == channel_allocations[i].channels &&
698 (spk_mask & channel_allocations[i].spk_mask) ==
699 channel_allocations[i].spk_mask) {
700 ca = channel_allocations[i].ca_index;
701 break;
702 }
703 }
704
705 if (!ca) {
706 /* if there was no match, select the regular ALSA channel
707 * allocation with the matching number of channels */
708 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
709 if (channels == channel_allocations[i].channels) {
710 ca = channel_allocations[i].ca_index;
711 break;
712 }
713 }
714 }
715
716 snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
717 codec_dbg(codec, "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
718 ca, channels, buf);
719
720 return ca;
721}
722
723static void hdmi_debug_channel_mapping(struct hda_codec *codec,
724 hda_nid_t pin_nid)
725{
726#ifdef CONFIG_SND_DEBUG_VERBOSE
727 struct hdmi_spec *spec = codec->spec;
728 int i;
729 int channel;
730
731 for (i = 0; i < 8; i++) {
732 channel = spec->ops.pin_get_slot_channel(codec, pin_nid, i);
733 codec_dbg(codec, "HDMI: ASP channel %d => slot %d\n",
734 channel, i);
735 }
736#endif
737}
738
739static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
740 hda_nid_t pin_nid,
741 bool non_pcm,
742 int ca)
743{
744 struct hdmi_spec *spec = codec->spec;
745 struct cea_channel_speaker_allocation *ch_alloc;
746 int i;
747 int err;
748 int order;
749 int non_pcm_mapping[8];
750
751 order = get_channel_allocation_order(ca);
752 ch_alloc = &channel_allocations[order];
753
754 if (hdmi_channel_mapping[ca][1] == 0) {
755 int hdmi_slot = 0;
756 /* fill actual channel mappings in ALSA channel (i) order */
757 for (i = 0; i < ch_alloc->channels; i++) {
758 while (!ch_alloc->speakers[7 - hdmi_slot] && !WARN_ON(hdmi_slot >= 8))
759 hdmi_slot++; /* skip zero slots */
760
761 hdmi_channel_mapping[ca][i] = (i << 4) | hdmi_slot++;
762 }
763 /* fill the rest of the slots with ALSA channel 0xf */
764 for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++)
765 if (!ch_alloc->speakers[7 - hdmi_slot])
766 hdmi_channel_mapping[ca][i++] = (0xf << 4) | hdmi_slot;
767 }
768
769 if (non_pcm) {
770 for (i = 0; i < ch_alloc->channels; i++)
771 non_pcm_mapping[i] = (i << 4) | i;
772 for (; i < 8; i++)
773 non_pcm_mapping[i] = (0xf << 4) | i;
774 }
775
776 for (i = 0; i < 8; i++) {
777 int slotsetup = non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i];
778 int hdmi_slot = slotsetup & 0x0f;
779 int channel = (slotsetup & 0xf0) >> 4;
780 err = spec->ops.pin_set_slot_channel(codec, pin_nid, hdmi_slot, channel);
781 if (err) {
782 codec_dbg(codec, "HDMI: channel mapping failed\n");
783 break;
784 }
785 }
786}
787
788struct channel_map_table {
789 unsigned char map; /* ALSA API channel map position */
790 int spk_mask; /* speaker position bit mask */
791};
792
793static struct channel_map_table map_tables[] = {
794 { SNDRV_CHMAP_FL, FL },
795 { SNDRV_CHMAP_FR, FR },
796 { SNDRV_CHMAP_RL, RL },
797 { SNDRV_CHMAP_RR, RR },
798 { SNDRV_CHMAP_LFE, LFE },
799 { SNDRV_CHMAP_FC, FC },
800 { SNDRV_CHMAP_RLC, RLC },
801 { SNDRV_CHMAP_RRC, RRC },
802 { SNDRV_CHMAP_RC, RC },
803 { SNDRV_CHMAP_FLC, FLC },
804 { SNDRV_CHMAP_FRC, FRC },
805 { SNDRV_CHMAP_TFL, FLH },
806 { SNDRV_CHMAP_TFR, FRH },
807 { SNDRV_CHMAP_FLW, FLW },
808 { SNDRV_CHMAP_FRW, FRW },
809 { SNDRV_CHMAP_TC, TC },
810 { SNDRV_CHMAP_TFC, FCH },
811 {} /* terminator */
812};
813
814/* from ALSA API channel position to speaker bit mask */
815static int to_spk_mask(unsigned char c)
816{
817 struct channel_map_table *t = map_tables;
818 for (; t->map; t++) {
819 if (t->map == c)
820 return t->spk_mask;
821 }
822 return 0;
823}
824
825/* from ALSA API channel position to CEA slot */
826static int to_cea_slot(int ordered_ca, unsigned char pos)
827{
828 int mask = to_spk_mask(pos);
829 int i;
830
831 if (mask) {
832 for (i = 0; i < 8; i++) {
833 if (channel_allocations[ordered_ca].speakers[7 - i] == mask)
834 return i;
835 }
836 }
837
838 return -1;
839}
840
841/* from speaker bit mask to ALSA API channel position */
842static int spk_to_chmap(int spk)
843{
844 struct channel_map_table *t = map_tables;
845 for (; t->map; t++) {
846 if (t->spk_mask == spk)
847 return t->map;
848 }
849 return 0;
850}
851
852/* from CEA slot to ALSA API channel position */
853static int from_cea_slot(int ordered_ca, unsigned char slot)
854{
855 int mask = channel_allocations[ordered_ca].speakers[7 - slot];
856
857 return spk_to_chmap(mask);
858}
859
860/* get the CA index corresponding to the given ALSA API channel map */
861static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
862{
863 int i, spks = 0, spk_mask = 0;
864
865 for (i = 0; i < chs; i++) {
866 int mask = to_spk_mask(map[i]);
867 if (mask) {
868 spk_mask |= mask;
869 spks++;
870 }
871 }
872
873 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
874 if ((chs == channel_allocations[i].channels ||
875 spks == channel_allocations[i].channels) &&
876 (spk_mask & channel_allocations[i].spk_mask) ==
877 channel_allocations[i].spk_mask)
878 return channel_allocations[i].ca_index;
879 }
880 return -1;
881}
882
883/* set up the channel slots for the given ALSA API channel map */
884static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
885 hda_nid_t pin_nid,
886 int chs, unsigned char *map,
887 int ca)
888{
889 struct hdmi_spec *spec = codec->spec;
890 int ordered_ca = get_channel_allocation_order(ca);
891 int alsa_pos, hdmi_slot;
892 int assignments[8] = {[0 ... 7] = 0xf};
893
894 for (alsa_pos = 0; alsa_pos < chs; alsa_pos++) {
895
896 hdmi_slot = to_cea_slot(ordered_ca, map[alsa_pos]);
897
898 if (hdmi_slot < 0)
899 continue; /* unassigned channel */
900
901 assignments[hdmi_slot] = alsa_pos;
902 }
903
904 for (hdmi_slot = 0; hdmi_slot < 8; hdmi_slot++) {
905 int err;
906
907 err = spec->ops.pin_set_slot_channel(codec, pin_nid, hdmi_slot,
908 assignments[hdmi_slot]);
909 if (err)
910 return -EINVAL;
911 }
912 return 0;
913}
914
915/* store ALSA API channel map from the current default map */
916static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
917{
918 int i;
919 int ordered_ca = get_channel_allocation_order(ca);
920 for (i = 0; i < 8; i++) {
921 if (i < channel_allocations[ordered_ca].channels)
922 map[i] = from_cea_slot(ordered_ca, hdmi_channel_mapping[ca][i] & 0x0f);
923 else
924 map[i] = 0;
925 }
926}
927
928static void hdmi_setup_channel_mapping(struct hda_codec *codec,
929 hda_nid_t pin_nid, bool non_pcm, int ca,
930 int channels, unsigned char *map,
931 bool chmap_set)
932{
933 if (!non_pcm && chmap_set) {
934 hdmi_manual_setup_channel_mapping(codec, pin_nid,
935 channels, map, ca);
936 } else {
937 hdmi_std_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
938 hdmi_setup_fake_chmap(map, ca);
939 }
940
941 hdmi_debug_channel_mapping(codec, pin_nid);
942}
943
944static int hdmi_pin_set_slot_channel(struct hda_codec *codec, hda_nid_t pin_nid,
945 int asp_slot, int channel)
946{
947 return snd_hda_codec_write(codec, pin_nid, 0,
948 AC_VERB_SET_HDMI_CHAN_SLOT,
949 (channel << 4) | asp_slot);
950}
951
952static int hdmi_pin_get_slot_channel(struct hda_codec *codec, hda_nid_t pin_nid,
953 int asp_slot)
954{
955 return (snd_hda_codec_read(codec, pin_nid, 0,
956 AC_VERB_GET_HDMI_CHAN_SLOT,
957 asp_slot) & 0xf0) >> 4;
958}
959
960/*498/*
961 * Audio InfoFrame routines499 * Audio InfoFrame routines
962 */500 */
@@ -1132,11 +670,12 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, · 169 unmodified lines
1132 bool non_pcm)670 bool non_pcm)
1133{671{
1134 struct hdmi_spec *spec = codec->spec;672 struct hdmi_spec *spec = codec->spec;
673 struct hdac_chmap *chmap = &spec->chmap;
1135 hda_nid_t pin_nid = per_pin->pin_nid;674 hda_nid_t pin_nid = per_pin->pin_nid;
1136 int channels = per_pin->channels;675 int channels = per_pin->channels;
1137 int active_channels;676 int active_channels;
1138 struct hdmi_eld *eld;677 struct hdmi_eld *eld;
1139 int ca, ordered_ca;678 int ca;
1140 679
1141 if (!channels)680 if (!channels)
1142 return;681 return;
@@ -1148,25 +687,22 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, · 5 unmodified lines
1148 687
1149 eld = &per_pin->sink_eld;688 eld = &per_pin->sink_eld;
1150 689
1151 if (!non_pcm && per_pin->chmap_set)690 ca = snd_hdac_channel_allocation(&codec->core,
1152 ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);691 eld->info.spk_alloc, channels,
1153 else692 per_pin->chmap_set, non_pcm, per_pin->chmap);
1154 ca = hdmi_channel_allocation(codec, eld, channels);
1155 if (ca < 0)
1156 ca = 0;
1157 693
1158 ordered_ca = get_channel_allocation_order(ca);694 active_channels = snd_hdac_get_active_channels(ca);
1159 active_channels = channel_allocations[ordered_ca].channels;
1160 695
1161 hdmi_set_channel_count(codec, per_pin->cvt_nid, active_channels);696 chmap->ops.set_channel_count(&codec->core, per_pin->cvt_nid,
697 active_channels);
1162 698
1163 /*699 /*
1164 * always configure channel mapping, it may have been changed by the700 * always configure channel mapping, it may have been changed by the
1165 * user in the meantime701 * user in the meantime
1166 */702 */
1167 hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,703 snd_hdac_setup_channel_mapping(&spec->chmap,
1168 channels, per_pin->chmap,704 pin_nid, non_pcm, ca, channels,
1169 per_pin->chmap_set);705 per_pin->chmap, per_pin->chmap_set);
1170 706
1171 spec->ops.pin_setup_infoframe(codec, pin_nid, ca, active_channels,707 spec->ops.pin_setup_infoframe(codec, pin_nid, ca, active_channels,
1172 eld->info.conn_type);708 eld->info.conn_type);
@@ -1338,6 +874,11 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, · 165 unmodified lines
1338 return 0;874 return 0;
1339}875}
1340 876
877/* Try to find an available converter
878 * If pin_idx is less then zero, just try to find an available converter.
879 * Otherwise, try to find an available converter and get the cvt mux index
880 * of the pin.
881 */
1341static int hdmi_choose_cvt(struct hda_codec *codec,882static int hdmi_choose_cvt(struct hda_codec *codec,
1342 int pin_idx, int *cvt_id, int *mux_id)883 int pin_idx, int *cvt_id, int *mux_id)
1343{884{
@@ -1346,7 +887,11 @@ static int hdmi_choose_cvt(struct hda_codec *codec, · 2 unmodified lines
1346 struct hdmi_spec_per_cvt *per_cvt = NULL;887 struct hdmi_spec_per_cvt *per_cvt = NULL;
1347 int cvt_idx, mux_idx = 0;888 int cvt_idx, mux_idx = 0;
1348 889
1349 per_pin = get_pin(spec, pin_idx);890 /* pin_idx < 0 means no pin will be bound to the converter */
891 if (pin_idx < 0)
892 per_pin = NULL;
893 else
894 per_pin = get_pin(spec, pin_idx);
1350 895
1351 /* Dynamically assign converter to stream */896 /* Dynamically assign converter to stream */
1352 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {897 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
@@ -1355,6 +900,8 @@ static int hdmi_choose_cvt(struct hda_codec *codec, · 2 unmodified lines
1355 /* Must not already be assigned */900 /* Must not already be assigned */
1356 if (per_cvt->assigned)901 if (per_cvt->assigned)
1357 continue;902 continue;
903 if (per_pin == NULL)
904 break;
1358 /* Must be in pin's mux's list of converters */905 /* Must be in pin's mux's list of converters */
1359 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)906 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
1360 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)907 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
@@ -1367,9 +914,10 @@ static int hdmi_choose_cvt(struct hda_codec *codec, · 6 unmodified lines
1367 914
1368 /* No free converters */915 /* No free converters */
1369 if (cvt_idx == spec->num_cvts)916 if (cvt_idx == spec->num_cvts)
1370 return -ENODEV;917 return -EBUSY;
1371 918
1372 per_pin->mux_idx = mux_idx;919 if (per_pin != NULL)
920 per_pin->mux_idx = mux_idx;
1373 921
1374 if (cvt_id)922 if (cvt_id)
1375 *cvt_id = cvt_idx;923 *cvt_id = cvt_idx;
@@ -1395,6 +943,20 @@ static void intel_verify_pin_cvt_connect(struct hda_codec *codec, · 19 unmodified lines
1395 mux_idx);943 mux_idx);
1396}944}
1397 945
946/* get the mux index for the converter of the pins
947 * converter's mux index is the same for all pins on Intel platform
948 */
949static int intel_cvt_id_to_mux_idx(struct hdmi_spec *spec,
950 hda_nid_t cvt_nid)
951{
952 int i;
953
954 for (i = 0; i < spec->num_cvts; i++)
955 if (spec->cvt_nids[i] == cvt_nid)
956 return i;
957 return -EINVAL;
958}
959
1398/* Intel HDMI workaround to fix audio routing issue:960/* Intel HDMI workaround to fix audio routing issue:
1399 * For some Intel display codecs, pins share the same connection list.961 * For some Intel display codecs, pins share the same connection list.
1400 * So a conveter can be selected by multiple pins and playback on any of these962 * So a conveter can be selected by multiple pins and playback on any of these
@@ -1446,6 +1008,74 @@ static void intel_not_share_assigned_cvt(struct hda_codec *codec, · 45 unmodified lines
1446 }1008 }
1447}1009}
1448 1010
1011/* A wrapper of intel_not_share_asigned_cvt() */
1012static void intel_not_share_assigned_cvt_nid(struct hda_codec *codec,
1013 hda_nid_t pin_nid, hda_nid_t cvt_nid)
1014{
1015 int mux_idx;
1016 struct hdmi_spec *spec = codec->spec;
1017
1018 if (!is_haswell_plus(codec) && !is_valleyview_plus(codec))
1019 return;
1020
1021 /* On Intel platform, the mapping of converter nid to
1022 * mux index of the pins are always the same.
1023 * The pin nid may be 0, this means all pins will not
1024 * share the converter.
1025 */
1026 mux_idx = intel_cvt_id_to_mux_idx(spec, cvt_nid);
1027 if (mux_idx >= 0)
1028 intel_not_share_assigned_cvt(codec, pin_nid, mux_idx);
1029}
1030
1031/* called in hdmi_pcm_open when no pin is assigned to the PCM
1032 * in dyn_pcm_assign mode.
1033 */
1034static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
1035 struct hda_codec *codec,
1036 struct snd_pcm_substream *substream)
1037{
1038 struct hdmi_spec *spec = codec->spec;
1039 struct snd_pcm_runtime *runtime = substream->runtime;
1040 int cvt_idx, pcm_idx;
1041 struct hdmi_spec_per_cvt *per_cvt = NULL;
1042 int err;
1043
1044 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1045 if (pcm_idx < 0)
1046 return -EINVAL;
1047
1048 err = hdmi_choose_cvt(codec, -1, &cvt_idx, NULL);
1049 if (err)
1050 return err;
1051
1052 per_cvt = get_cvt(spec, cvt_idx);
1053 per_cvt->assigned = 1;
1054 hinfo->nid = per_cvt->cvt_nid;
1055
1056 intel_not_share_assigned_cvt_nid(codec, 0, per_cvt->cvt_nid);
1057
1058 set_bit(pcm_idx, &spec->pcm_in_use);
1059 /* todo: setup spdif ctls assign */
1060
1061 /* Initially set the converter's capabilities */
1062 hinfo->channels_min = per_cvt->channels_min;
1063 hinfo->channels_max = per_cvt->channels_max;
1064 hinfo->rates = per_cvt->rates;
1065 hinfo->formats = per_cvt->formats;
1066 hinfo->maxbps = per_cvt->maxbps;
1067
1068 /* Store the updated parameters */
1069 runtime->hw.channels_min = hinfo->channels_min;
1070 runtime->hw.channels_max = hinfo->channels_max;
1071 runtime->hw.formats = hinfo->formats;
1072 runtime->hw.rates = hinfo->rates;
1073
1074 snd_pcm_hw_constraint_step(substream->runtime, 0,
1075 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1076 return 0;
1077}
1078
1449/*1079/*
1450 * HDA PCM callbacks1080 * HDA PCM callbacks
1451 */1081 */
@@ -1455,26 +1085,47 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, · 3 unmodified lines
1455{1085{
1456 struct hdmi_spec *spec = codec->spec;1086 struct hdmi_spec *spec = codec->spec;
1457 struct snd_pcm_runtime *runtime = substream->runtime;1087 struct snd_pcm_runtime *runtime = substream->runtime;
1458 int pin_idx, cvt_idx, mux_idx = 0;1088 int pin_idx, cvt_idx, pcm_idx, mux_idx = 0;
1459 struct hdmi_spec_per_pin *per_pin;1089 struct hdmi_spec_per_pin *per_pin;
1460 struct hdmi_eld *eld;1090 struct hdmi_eld *eld;
1461 struct hdmi_spec_per_cvt *per_cvt = NULL;1091 struct hdmi_spec_per_cvt *per_cvt = NULL;
1462 int err;1092 int err;
1463 1093
1464 /* Validate hinfo */1094 /* Validate hinfo */
1465 pin_idx = hinfo_to_pin_index(codec, hinfo);1095 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1466 if (snd_BUG_ON(pin_idx < 0))1096 if (pcm_idx < 0)
1467 return -EINVAL;1097 return -EINVAL;
1468 per_pin = get_pin(spec, pin_idx);1098
1469 eld = &per_pin->sink_eld;1099 mutex_lock(&spec->pcm_lock);
1100 pin_idx = hinfo_to_pin_index(codec, hinfo);
1101 if (!spec->dyn_pcm_assign) {
1102 if (snd_BUG_ON(pin_idx < 0)) {
1103 mutex_unlock(&spec->pcm_lock);
1104 return -EINVAL;
1105 }
1106 } else {
1107 /* no pin is assigned to the PCM
1108 * PA need pcm open successfully when probe
1109 */
1110 if (pin_idx < 0) {
1111 err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
1112 mutex_unlock(&spec->pcm_lock);
1113 return err;
1114 }
1115 }
1470 1116
1471 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);1117 err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
1472 if (err < 0)1118 if (err < 0) {
1119 mutex_unlock(&spec->pcm_lock);
1473 return err;1120 return err;
1121 }
1474 1122
1475 per_cvt = get_cvt(spec, cvt_idx);1123 per_cvt = get_cvt(spec, cvt_idx);
1476 /* Claim converter */1124 /* Claim converter */
1477 per_cvt->assigned = 1;1125 per_cvt->assigned = 1;
1126
1127 set_bit(pcm_idx, &spec->pcm_in_use);
1128 per_pin = get_pin(spec, pin_idx);
1478 per_pin->cvt_nid = per_cvt->cvt_nid;1129 per_pin->cvt_nid = per_cvt->cvt_nid;
1479 hinfo->nid = per_cvt->cvt_nid;1130 hinfo->nid = per_cvt->cvt_nid;
1480 1131
@@ -1486,7 +1137,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, · 5 unmodified lines
1486 if (is_haswell_plus(codec) || is_valleyview_plus(codec))1137 if (is_haswell_plus(codec) || is_valleyview_plus(codec))
1487 intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);1138 intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
1488 1139
1489 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);1140 snd_hda_spdif_ctls_assign(codec, pcm_idx, per_cvt->cvt_nid);
1490 1141
1491 /* Initially set the converter's capabilities */1142 /* Initially set the converter's capabilities */
1492 hinfo->channels_min = per_cvt->channels_min;1143 hinfo->channels_min = per_cvt->channels_min;
@@ -1495,6 +1146,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, · 2 unmodified lines
1495 hinfo->formats = per_cvt->formats;1146 hinfo->formats = per_cvt->formats;
1496 hinfo->maxbps = per_cvt->maxbps;1147 hinfo->maxbps = per_cvt->maxbps;
1497 1148
1149 eld = &per_pin->sink_eld;
1498 /* Restrict capabilities by ELD if this isn't disabled */1150 /* Restrict capabilities by ELD if this isn't disabled */
1499 if (!static_hdmi_pcm && eld->eld_valid) {1151 if (!static_hdmi_pcm && eld->eld_valid) {
1500 snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);1152 snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);
@@ -1502,11 +1154,13 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, · 1 unmodified line
1502 !hinfo->rates || !hinfo->formats) {1154 !hinfo->rates || !hinfo->formats) {
1503 per_cvt->assigned = 0;1155 per_cvt->assigned = 0;
1504 hinfo->nid = 0;1156 hinfo->nid = 0;
1505 snd_hda_spdif_ctls_unassign(codec, pin_idx);1157 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
1158 mutex_unlock(&spec->pcm_lock);
1506 return -ENODEV;1159 return -ENODEV;
1507 }1160 }
1508 }1161 }
1509 1162
1163 mutex_unlock(&spec->pcm_lock);
1510 /* Store the updated parameters */1164 /* Store the updated parameters */
1511 runtime->hw.channels_min = hinfo->channels_min;1165 runtime->hw.channels_min = hinfo->channels_min;
1512 runtime->hw.channels_max = hinfo->channels_max;1166 runtime->hw.channels_max = hinfo->channels_max;
@@ -1541,6 +1195,125 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) · 28 unmodified lines
1541 return 0;1195 return 0;
1542}1196}
1543 1197
1198static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
1199 struct hdmi_spec_per_pin *per_pin)
1200{
1201 int i;
1202
1203 /* try the prefer PCM */
1204 if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
1205 return per_pin->pin_nid_idx;
1206
1207 /* have a second try; check the "reserved area" over num_pins */
1208 for (i = spec->num_pins; i < spec->pcm_used; i++) {
1209 if (!test_bit(i, &spec->pcm_bitmap))
1210 return i;
1211 }
1212
1213 /* the last try; check the empty slots in pins */
1214 for (i = 0; i < spec->num_pins; i++) {
1215 if (!test_bit(i, &spec->pcm_bitmap))
1216 return i;
1217 }
1218 return -EBUSY;
1219}
1220
1221static void hdmi_attach_hda_pcm(struct hdmi_spec *spec,
1222 struct hdmi_spec_per_pin *per_pin)
1223{
1224 int idx;
1225
1226 /* pcm already be attached to the pin */
1227 if (per_pin->pcm)
1228 return;
1229 idx = hdmi_find_pcm_slot(spec, per_pin);
1230 if (idx == -EBUSY)
1231 return;
1232 per_pin->pcm_idx = idx;
1233 per_pin->pcm = get_hdmi_pcm(spec, idx);
1234 set_bit(idx, &spec->pcm_bitmap);
1235}
1236
1237static void hdmi_detach_hda_pcm(struct hdmi_spec *spec,
1238 struct hdmi_spec_per_pin *per_pin)
1239{
1240 int idx;
1241
1242 /* pcm already be detached from the pin */
1243 if (!per_pin->pcm)
1244 return;
1245 idx = per_pin->pcm_idx;
1246 per_pin->pcm_idx = -1;
1247 per_pin->pcm = NULL;
1248 if (idx >= 0 && idx < spec->pcm_used)
1249 clear_bit(idx, &spec->pcm_bitmap);
1250}
1251
1252static int hdmi_get_pin_cvt_mux(struct hdmi_spec *spec,
1253 struct hdmi_spec_per_pin *per_pin, hda_nid_t cvt_nid)
1254{
1255 int mux_idx;
1256
1257 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
1258 if (per_pin->mux_nids[mux_idx] == cvt_nid)
1259 break;
1260 return mux_idx;
1261}
1262
1263static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid);
1264
1265static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,
1266 struct hdmi_spec_per_pin *per_pin)
1267{
1268 struct hda_codec *codec = per_pin->codec;
1269 struct hda_pcm *pcm;
1270 struct hda_pcm_stream *hinfo;
1271 struct snd_pcm_substream *substream;
1272 int mux_idx;
1273 bool non_pcm;
1274
1275 if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)
1276 pcm = get_pcm_rec(spec, per_pin->pcm_idx);
1277 else
1278 return;
1279 if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
1280 return;
1281
1282 /* hdmi audio only uses playback and one substream */
1283 hinfo = pcm->stream;
1284 substream = pcm->pcm->streams[0].substream;
1285
1286 per_pin->cvt_nid = hinfo->nid;
1287
1288 mux_idx = hdmi_get_pin_cvt_mux(spec, per_pin, hinfo->nid);
1289 if (mux_idx < per_pin->num_mux_nids)
1290 snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
1291 AC_VERB_SET_CONNECT_SEL,
1292 mux_idx);
1293 snd_hda_spdif_ctls_assign(codec, per_pin->pcm_idx, hinfo->nid);
1294
1295 non_pcm = check_non_pcm_per_cvt(codec, hinfo->nid);
1296 if (substream->runtime)
1297 per_pin->channels = substream->runtime->channels;
1298 per_pin->setup = true;
1299 per_pin->mux_idx = mux_idx;
1300
1301 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1302}
1303
1304static void hdmi_pcm_reset_pin(struct hdmi_spec *spec,
1305 struct hdmi_spec_per_pin *per_pin)
1306{
1307 if (per_pin->pcm_idx >= 0 && per_pin->pcm_idx < spec->pcm_used)
1308 snd_hda_spdif_ctls_unassign(per_pin->codec, per_pin->pcm_idx);
1309
1310 per_pin->chmap_set = false;
1311 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1312
1313 per_pin->setup = false;
1314 per_pin->channels = 0;
1315}
1316
1544/* update per_pin ELD from the given new ELD;1317/* update per_pin ELD from the given new ELD;
1545 * setup info frame and notification accordingly1318 * setup info frame and notification accordingly
1546 */1319 */
@@ -1549,8 +1322,27 @@ static void update_eld(struct hda_codec *codec, · 2 unmodified lines
1549 struct hdmi_eld *eld)1322 struct hdmi_eld *eld)
1550{1323{
1551 struct hdmi_eld *pin_eld = &per_pin->sink_eld;1324 struct hdmi_eld *pin_eld = &per_pin->sink_eld;
1325 struct hdmi_spec *spec = codec->spec;
1552 bool old_eld_valid = pin_eld->eld_valid;1326 bool old_eld_valid = pin_eld->eld_valid;
1553 bool eld_changed;1327 bool eld_changed;
1328 int pcm_idx = -1;
1329
1330 /* for monitor disconnection, save pcm_idx firstly */
1331 pcm_idx = per_pin->pcm_idx;
1332 if (spec->dyn_pcm_assign) {
1333 if (eld->eld_valid) {
1334 hdmi_attach_hda_pcm(spec, per_pin);
1335 hdmi_pcm_setup_pin(spec, per_pin);
1336 } else {
1337 hdmi_pcm_reset_pin(spec, per_pin);
1338 hdmi_detach_hda_pcm(spec, per_pin);
1339 }
1340 }
1341 /* if pcm_idx == -1, it means this is in monitor connection event
1342 * we can get the correct pcm_idx now.
1343 */
1344 if (pcm_idx == -1)
1345 pcm_idx = per_pin->pcm_idx;
1554 1346
1555 if (eld->eld_valid)1347 if (eld->eld_valid)
1556 snd_hdmi_show_eld(codec, &eld->info);1348 snd_hdmi_show_eld(codec, &eld->info);
@@ -1584,11 +1376,11 @@ static void update_eld(struct hda_codec *codec, · 27 unmodified lines
1584 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);1376 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1585 }1377 }
1586 1378
1587 if (eld_changed)1379 if (eld_changed && pcm_idx >= 0)
1588 snd_ctl_notify(codec->card,1380 snd_ctl_notify(codec->card,
1589 SNDRV_CTL_EVENT_MASK_VALUE |1381 SNDRV_CTL_EVENT_MASK_VALUE |
1590 SNDRV_CTL_EVENT_MASK_INFO,1382 SNDRV_CTL_EVENT_MASK_INFO,
1591 &per_pin->eld_ctl->id);1383 &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id);
1592}1384}
1593 1385
1594/* update ELD and jack state via HD-audio verbs */1386/* update ELD and jack state via HD-audio verbs */
@@ -1613,7 +1405,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, · 18 unmodified lines
1613 bool ret;1405 bool ret;
1614 bool do_repoll = false;1406 bool do_repoll = false;
1615 1407
1616 snd_hda_power_up_pm(codec);
1617 present = snd_hda_pin_sense(codec, pin_nid);1408 present = snd_hda_pin_sense(codec, pin_nid);
1618 1409
1619 mutex_lock(&per_pin->lock);1410 mutex_lock(&per_pin->lock);
@@ -1652,16 +1443,39 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, · 32 unmodified lines
1652 jack->block_report = !ret;1443 jack->block_report = !ret;
1653 1444
1654 mutex_unlock(&per_pin->lock);1445 mutex_unlock(&per_pin->lock);
1655 snd_hda_power_down_pm(codec);
1656 return ret;1446 return ret;
1657}1447}
1658 1448
1449static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec,
1450 struct hdmi_spec_per_pin *per_pin)
1451{
1452 struct hdmi_spec *spec = codec->spec;
1453 struct snd_jack *jack = NULL;
1454 struct hda_jack_tbl *jack_tbl;
1455
1456 /* if !dyn_pcm_assign, get jack from hda_jack_tbl
1457 * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
1458 * NULL even after snd_hda_jack_tbl_clear() is called to
1459 * free snd_jack. This may cause access invalid memory
1460 * when calling snd_jack_report
1461 */
1462 if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign)
1463 jack = spec->pcm_rec[per_pin->pcm_idx].jack;
1464 else if (!spec->dyn_pcm_assign) {
1465 jack_tbl = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);
1466 if (jack_tbl)
1467 jack = jack_tbl->jack;
1468 }
1469 return jack;
1470}
1471
1659/* update ELD and jack state via audio component */1472/* update ELD and jack state via audio component */
1660static void sync_eld_via_acomp(struct hda_codec *codec,1473static void sync_eld_via_acomp(struct hda_codec *codec,
1661 struct hdmi_spec_per_pin *per_pin)1474 struct hdmi_spec_per_pin *per_pin)
1662{1475{
1663 struct hdmi_spec *spec = codec->spec;1476 struct hdmi_spec *spec = codec->spec;
1664 struct hdmi_eld *eld = &spec->temp_eld;1477 struct hdmi_eld *eld = &spec->temp_eld;
1478 struct snd_jack *jack = NULL;
1665 int size;1479 int size;
1666 1480
1667 mutex_lock(&per_pin->lock);1481 mutex_lock(&per_pin->lock);
@@ -1685,8 +1499,16 @@ static void sync_eld_via_acomp(struct hda_codec *codec, · 17 unmodified lines
1685 eld->eld_size = 0;1499 eld->eld_size = 0;
1686 }1500 }
1687 1501
1502 /* pcm_idx >=0 before update_eld() means it is in monitor
1503 * disconnected event. Jack must be fetched before update_eld()
1504 */
1505 jack = pin_idx_to_jack(codec, per_pin);
1688 update_eld(codec, per_pin, eld);1506 update_eld(codec, per_pin, eld);
1689 snd_jack_report(per_pin->acomp_jack,1507 if (jack == NULL)
1508 jack = pin_idx_to_jack(codec, per_pin);
1509 if (jack == NULL)
1510 goto unlock;
1511 snd_jack_report(jack,
1690 eld->monitor_present ? SND_JACK_AVOUT : 0);1512 eld->monitor_present ? SND_JACK_AVOUT : 0);
1691 unlock:1513 unlock:
1692 mutex_unlock(&per_pin->lock);1514 mutex_unlock(&per_pin->lock);
@@ -1695,13 +1517,26 @@ static void sync_eld_via_acomp(struct hda_codec *codec, · 2 unmodified lines
1695static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)1517static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1696{1518{
1697 struct hda_codec *codec = per_pin->codec;1519 struct hda_codec *codec = per_pin->codec;
1520 struct hdmi_spec *spec = codec->spec;
1521 int ret;
1522
1523 /* no temporary power up/down needed for component notifier */
1524 if (!codec_has_acomp(codec))
1525 snd_hda_power_up_pm(codec);
1698 1526
1527 mutex_lock(&spec->pcm_lock);
1699 if (codec_has_acomp(codec)) {1528 if (codec_has_acomp(codec)) {
1700 sync_eld_via_acomp(codec, per_pin);1529 sync_eld_via_acomp(codec, per_pin);
1701 return false; /* don't call snd_hda_jack_report_sync() */1530 ret = false; /* don't call snd_hda_jack_report_sync() */
1702 } else {1531 } else {
1703 return hdmi_present_sense_via_verbs(per_pin, repoll);1532 ret = hdmi_present_sense_via_verbs(per_pin, repoll);
1704 }1533 }
1534 mutex_unlock(&spec->pcm_lock);
1535
1536 if (!codec_has_acomp(codec))
1537 snd_hda_power_down_pm(codec);
1538
1539 return ret;
1705}1540}
1706 1541
1707static void hdmi_repoll_eld(struct work_struct *work)1542static void hdmi_repoll_eld(struct work_struct *work)
@@ -1745,6 +1580,13 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) · 37 unmodified lines
1745 1580
1746 per_pin->pin_nid = pin_nid;1581 per_pin->pin_nid = pin_nid;
1747 per_pin->non_pcm = false;1582 per_pin->non_pcm = false;
1583 if (spec->dyn_pcm_assign)
1584 per_pin->pcm_idx = -1;
1585 else {
1586 per_pin->pcm = get_hdmi_pcm(spec, pin_idx);
1587 per_pin->pcm_idx = pin_idx;
1588 }
1589 per_pin->pin_nid_idx = pin_idx;
1748 1590
1749 err = hdmi_read_pin_conn(codec, pin_idx);1591 err = hdmi_read_pin_conn(codec, pin_idx);
1750 if (err < 0)1592 if (err < 0)
@@ -1773,8 +1615,8 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) · 22 unmodified lines
1773 per_cvt->channels_min = 2;1615 per_cvt->channels_min = 2;
1774 if (chans <= 16) {1616 if (chans <= 16) {
1775 per_cvt->channels_max = chans;1617 per_cvt->channels_max = chans;
1776 if (chans > spec->channels_max)1618 if (chans > spec->chmap.channels_max)
1777 spec->channels_max = chans;1619 spec->chmap.channels_max = chans;
1778 }1620 }
1779 1621
1780 err = snd_hda_query_supported_pcm(codec, cvt_nid,1622 err = snd_hda_query_supported_pcm(codec, cvt_nid,
@@ -1851,13 +1693,34 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, · 70 unmodified lines
1851{1693{
1852 hda_nid_t cvt_nid = hinfo->nid;1694 hda_nid_t cvt_nid = hinfo->nid;
1853 struct hdmi_spec *spec = codec->spec;1695 struct hdmi_spec *spec = codec->spec;
1854 int pin_idx = hinfo_to_pin_index(codec, hinfo);1696 int pin_idx;
1855 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);1697 struct hdmi_spec_per_pin *per_pin;
1856 hda_nid_t pin_nid = per_pin->pin_nid;1698 hda_nid_t pin_nid;
1857 struct snd_pcm_runtime *runtime = substream->runtime;1699 struct snd_pcm_runtime *runtime = substream->runtime;
1858 bool non_pcm;1700 bool non_pcm;
1859 int pinctl;1701 int pinctl;
1702 int err;
1703
1704 mutex_lock(&spec->pcm_lock);
1705 pin_idx = hinfo_to_pin_index(codec, hinfo);
1706 if (spec->dyn_pcm_assign && pin_idx < 0) {
1707 /* when dyn_pcm_assign and pcm is not bound to a pin
1708 * skip pin setup and return 0 to make audio playback
1709 * be ongoing
1710 */
1711 intel_not_share_assigned_cvt_nid(codec, 0, cvt_nid);
1712 snd_hda_codec_setup_stream(codec, cvt_nid,
1713 stream_tag, 0, format);
1714 mutex_unlock(&spec->pcm_lock);
1715 return 0;
1716 }
1860 1717
1718 if (snd_BUG_ON(pin_idx < 0)) {
1719 mutex_unlock(&spec->pcm_lock);
1720 return -EINVAL;
1721 }
1722 per_pin = get_pin(spec, pin_idx);
1723 pin_nid = per_pin->pin_nid;
1861 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {1724 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) {
1862 /* Verify pin:cvt selections to avoid silent audio after S3.1725 /* Verify pin:cvt selections to avoid silent audio after S3.
1863 * After S3, the audio driver restores pin:cvt selections1726 * After S3, the audio driver restores pin:cvt selections
@@ -1882,7 +1745,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, · 18 unmodified lines
1882 1745
1883 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);1746 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1884 mutex_unlock(&per_pin->lock);1747 mutex_unlock(&per_pin->lock);
1885
1886 if (spec->dyn_pin_out) {1748 if (spec->dyn_pin_out) {
1887 pinctl = snd_hda_codec_read(codec, pin_nid, 0,1749 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
1888 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);1750 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
@@ -1891,7 +1753,10 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, · 2 unmodified lines
1891 pinctl | PIN_OUT);1753 pinctl | PIN_OUT);
1892 }1754 }
1893 1755
1894 return spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);1756 err = spec->ops.setup_stream(codec, cvt_nid, pin_nid,
1757 stream_tag, format);
1758 mutex_unlock(&spec->pcm_lock);
1759 return err;
1895}1760}
1896 1761
1897static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,1762static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
@@ -1907,12 +1772,15 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 9 unmodified lines
1907 struct snd_pcm_substream *substream)1772 struct snd_pcm_substream *substream)
1908{1773{
1909 struct hdmi_spec *spec = codec->spec;1774 struct hdmi_spec *spec = codec->spec;
1910 int cvt_idx, pin_idx;1775 int cvt_idx, pin_idx, pcm_idx;
1911 struct hdmi_spec_per_cvt *per_cvt;1776 struct hdmi_spec_per_cvt *per_cvt;
1912 struct hdmi_spec_per_pin *per_pin;1777 struct hdmi_spec_per_pin *per_pin;
1913 int pinctl;1778 int pinctl;
1914 1779
1915 if (hinfo->nid) {1780 if (hinfo->nid) {
1781 pcm_idx = hinfo_to_pcm_index(codec, hinfo);
1782 if (snd_BUG_ON(pcm_idx < 0))
1783 return -EINVAL;
1916 cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);1784 cvt_idx = cvt_nid_to_cvt_index(codec, hinfo->nid);
1917 if (snd_BUG_ON(cvt_idx < 0))1785 if (snd_BUG_ON(cvt_idx < 0))
1918 return -EINVAL;1786 return -EINVAL;
@@ -1922,9 +1790,19 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 3 unmodified lines
1922 per_cvt->assigned = 0;1790 per_cvt->assigned = 0;
1923 hinfo->nid = 0;1791 hinfo->nid = 0;
1924 1792
1793 mutex_lock(&spec->pcm_lock);
1794 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
1795 clear_bit(pcm_idx, &spec->pcm_in_use);
1925 pin_idx = hinfo_to_pin_index(codec, hinfo);1796 pin_idx = hinfo_to_pin_index(codec, hinfo);
1926 if (snd_BUG_ON(pin_idx < 0))1797 if (spec->dyn_pcm_assign && pin_idx < 0) {
1798 mutex_unlock(&spec->pcm_lock);
1799 return 0;
1800 }
1801
1802 if (snd_BUG_ON(pin_idx < 0)) {
1803 mutex_unlock(&spec->pcm_lock);
1927 return -EINVAL;1804 return -EINVAL;
1805 }
1928 per_pin = get_pin(spec, pin_idx);1806 per_pin = get_pin(spec, pin_idx);
1929 1807
1930 if (spec->dyn_pin_out) {1808 if (spec->dyn_pin_out) {
@@ -1935,8 +1813,6 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 4 unmodified lines
1935 pinctl & ~PIN_OUT);1813 pinctl & ~PIN_OUT);
1936 }1814 }
1937 1815
1938 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1939
1940 mutex_lock(&per_pin->lock);1816 mutex_lock(&per_pin->lock);
1941 per_pin->chmap_set = false;1817 per_pin->chmap_set = false;
1942 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));1818 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
@@ -1944,6 +1820,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 1 unmodified line
1944 per_pin->setup = false;1820 per_pin->setup = false;
1945 per_pin->channels = 0;1821 per_pin->channels = 0;
1946 mutex_unlock(&per_pin->lock);1822 mutex_unlock(&per_pin->lock);
1823 mutex_unlock(&spec->pcm_lock);
1947 }1824 }
1948 1825
1949 return 0;1826 return 0;
@@ -1956,162 +1833,42 @@ static const struct hda_pcm_ops generic_ops = { · 6 unmodified lines
1956 .cleanup = generic_hdmi_playback_pcm_cleanup,1833 .cleanup = generic_hdmi_playback_pcm_cleanup,
1957};1834};
1958 1835
1959/*1836static void hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx,
1960 * ALSA API channel-map control callbacks1837 unsigned char *chmap)
1961 */
1962static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
1963 struct snd_ctl_elem_info *uinfo)
1964{1838{
1965 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);1839 struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
1966 struct hda_codec *codec = info->private_data;
1967 struct hdmi_spec *spec = codec->spec;1840 struct hdmi_spec *spec = codec->spec;
1968 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;1841 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
1969 uinfo->count = spec->channels_max;
1970 uinfo->value.integer.min = 0;
1971 uinfo->value.integer.max = SNDRV_CHMAP_LAST;
1972 return 0;
1973}
1974
1975static int hdmi_chmap_cea_alloc_validate_get_type(struct cea_channel_speaker_allocation *cap,
1976 int channels)
1977{
1978 /* If the speaker allocation matches the channel count, it is OK.*/
1979 if (cap->channels != channels)
1980 return -1;
1981
1982 /* all channels are remappable freely */
1983 return SNDRV_CTL_TLVT_CHMAP_VAR;
1984}
1985
1986static void hdmi_cea_alloc_to_tlv_chmap(struct cea_channel_speaker_allocation *cap,
1987 unsigned int *chmap, int channels)
1988{
1989 int count = 0;
1990 int c;
1991
1992 for (c = 7; c >= 0; c--) {
1993 int spk = cap->speakers[c];
1994 if (!spk)
1995 continue;
1996
1997 chmap[count++] = spk_to_chmap(spk);
1998 }
1999 1842
2000 WARN_ON(count != channels);1843 /* chmap is already set to 0 in caller */
2001}1844 if (!per_pin)
2002 1845 return;
2003static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2004 unsigned int size, unsigned int __user *tlv)
2005{
2006 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
2007 struct hda_codec *codec = info->private_data;
2008 struct hdmi_spec *spec = codec->spec;
2009 unsigned int __user *dst;
2010 int chs, count = 0;
2011 1846
2012 if (size < 8)1847 memcpy(chmap, per_pin->chmap, ARRAY_SIZE(per_pin->chmap));
2013 return -ENOMEM;
2014 if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
2015 return -EFAULT;
2016 size -= 8;
2017 dst = tlv + 2;
2018 for (chs = 2; chs <= spec->channels_max; chs++) {
2019 int i;
2020 struct cea_channel_speaker_allocation *cap;
2021 cap = channel_allocations;
2022 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
2023 int chs_bytes = chs * 4;
2024 int type = spec->ops.chmap_cea_alloc_validate_get_type(cap, chs);
2025 unsigned int tlv_chmap[8];
2026
2027 if (type < 0)
2028 continue;
2029 if (size < 8)
2030 return -ENOMEM;
2031 if (put_user(type, dst) ||
2032 put_user(chs_bytes, dst + 1))
2033 return -EFAULT;
2034 dst += 2;
2035 size -= 8;
2036 count += 8;
2037 if (size < chs_bytes)
2038 return -ENOMEM;
2039 size -= chs_bytes;
2040 count += chs_bytes;
2041 spec->ops.cea_alloc_to_tlv_chmap(cap, tlv_chmap, chs);
2042 if (copy_to_user(dst, tlv_chmap, chs_bytes))
2043 return -EFAULT;
2044 dst += chs;
2045 }
2046 }
2047 if (put_user(count, tlv + 1))
2048 return -EFAULT;
2049 return 0;
2050}1848}
2051 1849
2052static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,1850static void hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
2053 struct snd_ctl_elem_value *ucontrol)1851 unsigned char *chmap, int prepared)
2054{1852{
2055 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);1853 struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
2056 struct hda_codec *codec = info->private_data;
2057 struct hdmi_spec *spec = codec->spec;1854 struct hdmi_spec *spec = codec->spec;
2058 int pin_idx = kcontrol->private_value;1855 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
2059 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2060 int i;
2061
2062 for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)
2063 ucontrol->value.integer.value[i] = per_pin->chmap[i];
2064 return 0;
2065}
2066 1856
2067static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
2068 struct snd_ctl_elem_value *ucontrol)
2069{
2070 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
2071 struct hda_codec *codec = info->private_data;
2072 struct hdmi_spec *spec = codec->spec;
2073 int pin_idx = kcontrol->private_value;
2074 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2075 unsigned int ctl_idx;
2076 struct snd_pcm_substream *substream;
2077 unsigned char chmap[8];
2078 int i, err, ca, prepared = 0;
2079
2080 ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2081 substream = snd_pcm_chmap_substream(info, ctl_idx);
2082 if (!substream || !substream->runtime)
2083 return 0; /* just for avoiding error from alsactl restore */
2084 switch (substream->runtime->status->state) {
2085 case SNDRV_PCM_STATE_OPEN:
2086 case SNDRV_PCM_STATE_SETUP:
2087 break;
2088 case SNDRV_PCM_STATE_PREPARED:
2089 prepared = 1;
2090 break;
2091 default:
2092 return -EBUSY;
2093 }
2094 memset(chmap, 0, sizeof(chmap));
2095 for (i = 0; i < ARRAY_SIZE(chmap); i++)
2096 chmap[i] = ucontrol->value.integer.value[i];
2097 if (!memcmp(chmap, per_pin->chmap, sizeof(chmap)))
2098 return 0;
2099 ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
2100 if (ca < 0)
2101 return -EINVAL;
2102 if (spec->ops.chmap_validate) {
2103 err = spec->ops.chmap_validate(ca, ARRAY_SIZE(chmap), chmap);
2104 if (err)
2105 return err;
2106 }
2107 mutex_lock(&per_pin->lock);1857 mutex_lock(&per_pin->lock);
2108 per_pin->chmap_set = true;1858 per_pin->chmap_set = true;
2109 memcpy(per_pin->chmap, chmap, sizeof(chmap));1859 memcpy(per_pin->chmap, chmap, ARRAY_SIZE(per_pin->chmap));
2110 if (prepared)1860 if (prepared)
2111 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);1861 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
2112 mutex_unlock(&per_pin->lock);1862 mutex_unlock(&per_pin->lock);
1863}
2113 1864
2114 return 0;1865static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
1866{
1867 struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
1868 struct hdmi_spec *spec = codec->spec;
1869 struct hdmi_spec_per_pin *per_pin = pcm_idx_to_pin(spec, pcm_idx);
1870
1871 return per_pin ? true:false;
2115}1872}
2116 1873
2117static int generic_hdmi_build_pcms(struct hda_codec *codec)1874static int generic_hdmi_build_pcms(struct hda_codec *codec)
@@ -2126,7 +1883,9 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) · 8 unmodified lines
2126 info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx);1883 info = snd_hda_codec_pcm_new(codec, "HDMI %d", pin_idx);
2127 if (!info)1884 if (!info)
2128 return -ENOMEM;1885 return -ENOMEM;
2129 spec->pcm_rec[pin_idx] = info;1886
1887 spec->pcm_rec[pin_idx].pcm = info;
1888 spec->pcm_used++;
2130 info->pcm_type = HDA_PCM_TYPE_HDMI;1889 info->pcm_type = HDA_PCM_TYPE_HDMI;
2131 info->own_chmap = true;1890 info->own_chmap = true;
2132 1891
@@ -2139,15 +1898,16 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) · 6 unmodified lines
2139 return 0;1898 return 0;
2140}1899}
2141 1900
2142static void free_acomp_jack_priv(struct snd_jack *jack)1901static void free_hdmi_jack_priv(struct snd_jack *jack)
2143{1902{
2144 struct hdmi_spec_per_pin *per_pin = jack->private_data;1903 struct hdmi_pcm *pcm = jack->private_data;
2145 1904
2146 per_pin->acomp_jack = NULL;1905 pcm->jack = NULL;
2147}1906}
2148 1907
2149static int add_acomp_jack_kctl(struct hda_codec *codec,1908static int add_hdmi_jack_kctl(struct hda_codec *codec,
2150 struct hdmi_spec_per_pin *per_pin,1909 struct hdmi_spec *spec,
1910 int pcm_idx,
2151 const char *name)1911 const char *name)
2152{1912{
2153 struct snd_jack *jack;1913 struct snd_jack *jack;
@@ -2157,88 +1917,107 @@ static int add_acomp_jack_kctl(struct hda_codec *codec, · 3 unmodified lines
2157 true, false);1917 true, false);
2158 if (err < 0)1918 if (err < 0)
2159 return err;1919 return err;
2160 per_pin->acomp_jack = jack;1920
2161 jack->private_data = per_pin;1921 spec->pcm_rec[pcm_idx].jack = jack;
2162 jack->private_free = free_acomp_jack_priv;1922 jack->private_data = &spec->pcm_rec[pcm_idx];
1923 jack->private_free = free_hdmi_jack_priv;
2163 return 0;1924 return 0;
2164}1925}
2165 1926
2166static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)1927static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
2167{1928{
2168 char hdmi_str[32] = "HDMI/DP";1929 char hdmi_str[32] = "HDMI/DP";
2169 struct hdmi_spec *spec = codec->spec;1930 struct hdmi_spec *spec = codec->spec;
2170 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);1931 struct hdmi_spec_per_pin *per_pin;
2171 int pcmdev = get_pcm_rec(spec, pin_idx)->device;1932 struct hda_jack_tbl *jack;
1933 int pcmdev = get_pcm_rec(spec, pcm_idx)->device;
2172 bool phantom_jack;1934 bool phantom_jack;
1935 int ret;
2173 1936
2174 if (pcmdev > 0)1937 if (pcmdev > 0)
2175 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);1938 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
2176 if (codec_has_acomp(codec))1939
2177 return add_acomp_jack_kctl(codec, per_pin, hdmi_str);1940 if (spec->dyn_pcm_assign)
1941 return add_hdmi_jack_kctl(codec, spec, pcm_idx, hdmi_str);
1942
1943 /* for !dyn_pcm_assign, we still use hda_jack for compatibility */
1944 /* if !dyn_pcm_assign, it must be non-MST mode.
1945 * This means pcms and pins are statically mapped.
1946 * And pcm_idx is pin_idx.
1947 */
1948 per_pin = get_pin(spec, pcm_idx);
2178 phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid);1949 phantom_jack = !is_jack_detectable(codec, per_pin->pin_nid);
2179 if (phantom_jack)1950 if (phantom_jack)
2180 strncat(hdmi_str, " Phantom",1951 strncat(hdmi_str, " Phantom",
2181 sizeof(hdmi_str) - strlen(hdmi_str) - 1);1952 sizeof(hdmi_str) - strlen(hdmi_str) - 1);
2182 1953 ret = snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,
2183 return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str,1954 phantom_jack);
2184 phantom_jack);1955 if (ret < 0)
1956 return ret;
1957 jack = snd_hda_jack_tbl_get(codec, per_pin->pin_nid);
1958 if (jack == NULL)
1959 return 0;
1960 /* assign jack->jack to pcm_rec[].jack to
1961 * align with dyn_pcm_assign mode
1962 */
1963 spec->pcm_rec[pcm_idx].jack = jack->jack;
1964 return 0;
2185}1965}
2186 1966
2187static int generic_hdmi_build_controls(struct hda_codec *codec)1967static int generic_hdmi_build_controls(struct hda_codec *codec)
2188{1968{
2189 struct hdmi_spec *spec = codec->spec;1969 struct hdmi_spec *spec = codec->spec;
2190 int err;1970 int err;
2191 int pin_idx;1971 int pin_idx, pcm_idx;
2192 1972
2193 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2194 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2195 1973
2196 err = generic_hdmi_build_jack(codec, pin_idx);1974 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
1975 err = generic_hdmi_build_jack(codec, pcm_idx);
2197 if (err < 0)1976 if (err < 0)
2198 return err;1977 return err;
2199 1978
2200 err = snd_hda_create_dig_out_ctls(codec,1979 /* create the spdif for each pcm
1980 * pin will be bound when monitor is connected
1981 */
1982 if (spec->dyn_pcm_assign)
1983 err = snd_hda_create_dig_out_ctls(codec,
1984 0, spec->cvt_nids[0],
1985 HDA_PCM_TYPE_HDMI);
1986 else {
1987 struct hdmi_spec_per_pin *per_pin =
1988 get_pin(spec, pcm_idx);
1989 err = snd_hda_create_dig_out_ctls(codec,
2201 per_pin->pin_nid,1990 per_pin->pin_nid,
2202 per_pin->mux_nids[0],1991 per_pin->mux_nids[0],
2203 HDA_PCM_TYPE_HDMI);1992 HDA_PCM_TYPE_HDMI);
1993 }
2204 if (err < 0)1994 if (err < 0)
2205 return err;1995 return err;
2206 snd_hda_spdif_ctls_unassign(codec, pin_idx);1996 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
2207 1997
2208 /* add control for ELD Bytes */1998 /* add control for ELD Bytes */
2209 err = hdmi_create_eld_ctl(codec, pin_idx,1999 err = hdmi_create_eld_ctl(codec, pcm_idx,
2210 get_pcm_rec(spec, pin_idx)->device);2000 get_pcm_rec(spec, pcm_idx)->device);
2211
2212 if (err < 0)2001 if (err < 0)
2213 return err;2002 return err;
2003 }
2004
2005 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2006 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2214 2007
2215 hdmi_present_sense(per_pin, 0);2008 hdmi_present_sense(per_pin, 0);
2216 }2009 }
2217 2010
2218 /* add channel maps */2011 /* add channel maps */
2219 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {2012 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
2220 struct hda_pcm *pcm;2013 struct hda_pcm *pcm;
2221 struct snd_pcm_chmap *chmap;
2222 struct snd_kcontrol *kctl;
2223 int i;
2224 2014
2225 pcm = spec->pcm_rec[pin_idx];2015 pcm = get_pcm_rec(spec, pcm_idx);
2226 if (!pcm || !pcm->pcm)2016 if (!pcm || !pcm->pcm)
2227 break;2017 break;
2228 err = snd_pcm_add_chmap_ctls(pcm->pcm,2018 err = snd_hdac_add_chmap_ctls(pcm->pcm, pcm_idx, &spec->chmap);
2229 SNDRV_PCM_STREAM_PLAYBACK,
2230 NULL, 0, pin_idx, &chmap);
2231 if (err < 0)2019 if (err < 0)
2232 return err;2020 return err;
2233 /* override handlers */
2234 chmap->private_data = codec;
2235 kctl = chmap->kctl;
2236 for (i = 0; i < kctl->count; i++)
2237 kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
2238 kctl->info = hdmi_chmap_ctl_info;
2239 kctl->get = hdmi_chmap_ctl_get;
2240 kctl->put = hdmi_chmap_ctl_put;
2241 kctl->tlv.c = hdmi_chmap_ctl_tlv;
2242 }2021 }
2243 2022
2244 return 0;2023 return 0;
@@ -2293,18 +2072,25 @@ static void hdmi_array_free(struct hdmi_spec *spec) · 48 unmodified lines
2293static void generic_hdmi_free(struct hda_codec *codec)2072static void generic_hdmi_free(struct hda_codec *codec)
2294{2073{
2295 struct hdmi_spec *spec = codec->spec;2074 struct hdmi_spec *spec = codec->spec;
2296 int pin_idx;2075 int pin_idx, pcm_idx;
2297 2076
2298 if (codec_has_acomp(codec))2077 if (codec_has_acomp(codec))
2299 snd_hdac_i915_register_notifier(NULL);2078 snd_hdac_i915_register_notifier(NULL);
2300 2079
2301 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {2080 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2302 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);2081 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
2303
2304 cancel_delayed_work_sync(&per_pin->work);2082 cancel_delayed_work_sync(&per_pin->work);
2305 eld_proc_free(per_pin);2083 eld_proc_free(per_pin);
2306 if (per_pin->acomp_jack)2084 }
2307 snd_device_free(codec->card, per_pin->acomp_jack);2085
2086 for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
2087 if (spec->pcm_rec[pcm_idx].jack == NULL)
2088 continue;
2089 if (spec->dyn_pcm_assign)
2090 snd_device_free(codec->card,
2091 spec->pcm_rec[pcm_idx].jack);
2092 else
2093 spec->pcm_rec[pcm_idx].jack = NULL;
2308 }2094 }
2309 2095
2310 if (spec->i915_bound)2096 if (spec->i915_bound)
@@ -2343,16 +2129,11 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = { · 32 unmodified lines
2343 2129
2344static const struct hdmi_ops generic_standard_hdmi_ops = {2130static const struct hdmi_ops generic_standard_hdmi_ops = {
2345 .pin_get_eld = snd_hdmi_get_eld,2131 .pin_get_eld = snd_hdmi_get_eld,
2346 .pin_get_slot_channel = hdmi_pin_get_slot_channel,
2347 .pin_set_slot_channel = hdmi_pin_set_slot_channel,
2348 .pin_setup_infoframe = hdmi_pin_setup_infoframe,2132 .pin_setup_infoframe = hdmi_pin_setup_infoframe,
2349 .pin_hbr_setup = hdmi_pin_hbr_setup,2133 .pin_hbr_setup = hdmi_pin_hbr_setup,
2350 .setup_stream = hdmi_setup_stream,2134 .setup_stream = hdmi_setup_stream,
2351 .chmap_cea_alloc_validate_get_type = hdmi_chmap_cea_alloc_validate_get_type,
2352 .cea_alloc_to_tlv_chmap = hdmi_cea_alloc_to_tlv_chmap,
2353};2135};
2354 2136
2355
2356static void intel_haswell_fixup_connect_list(struct hda_codec *codec,2137static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
2357 hda_nid_t nid)2138 hda_nid_t nid)
2358{2139{
@@ -2432,6 +2213,10 @@ static void intel_pin_eld_notify(void *audio_ptr, int port) · 73 unmodified lines
2432 struct hda_codec *codec = audio_ptr;2213 struct hda_codec *codec = audio_ptr;
2433 int pin_nid = port + 0x04;2214 int pin_nid = port + 0x04;
2434 2215
2216 /* we assume only from port-B to port-D */
2217 if (port < 1 || port > 3)
2218 return;
2219
2435 /* skip notification during system suspend (but not in runtime PM);2220 /* skip notification during system suspend (but not in runtime PM);
2436 * the state will be updated at resume2221 * the state will be updated at resume
2437 */2222 */
@@ -2453,12 +2238,20 @@ static int patch_generic_hdmi(struct hda_codec *codec) · 15 unmodified lines
2453 return -ENOMEM;2238 return -ENOMEM;
2454 2239
2455 spec->ops = generic_standard_hdmi_ops;2240 spec->ops = generic_standard_hdmi_ops;
2241 mutex_init(&spec->pcm_lock);
2242 snd_hdac_register_chmap_ops(&codec->core, &spec->chmap);
2243
2244 spec->chmap.ops.get_chmap = hdmi_get_chmap;
2245 spec->chmap.ops.set_chmap = hdmi_set_chmap;
2246 spec->chmap.ops.is_pcm_attached = is_hdmi_pcm_attached;
2247
2456 codec->spec = spec;2248 codec->spec = spec;
2457 hdmi_array_init(spec, 4);2249 hdmi_array_init(spec, 4);
2458 2250
2459 /* Try to bind with i915 for any Intel codecs (if not done yet) */2251 /* Try to bind with i915 for Intel HSW+ codecs (if not done yet) */
2460 if (!codec_has_acomp(codec) &&2252 if (!codec_has_acomp(codec) &&
2461 (codec->core.vendor_id >> 16) == 0x8086)2253 (codec->core.vendor_id >> 16) == 0x8086 &&
2254 is_haswell_plus(codec))
2462 if (!snd_hdac_i915_init(&codec->bus->core))2255 if (!snd_hdac_i915_init(&codec->bus->core))
2463 spec->i915_bound = true;2256 spec->i915_bound = true;
2464 2257
@@ -2496,7 +2289,6 @@ static int patch_generic_hdmi(struct hda_codec *codec) · 31 unmodified lines
2496 2289
2497 generic_hdmi_init_per_pins(codec);2290 generic_hdmi_init_per_pins(codec);
2498 2291
2499 init_channel_allocations();
2500 2292
2501 if (codec_has_acomp(codec)) {2293 if (codec_has_acomp(codec)) {
2502 codec->depop_delay = 0;2294 codec->depop_delay = 0;
@@ -2510,6 +2302,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) · 7 unmodified lines
2510 snd_hdac_i915_register_notifier(&spec->i915_audio_ops);2302 snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
2511 }2303 }
2512 2304
2305 WARN_ON(spec->dyn_pcm_assign && !codec_has_acomp(codec));
2513 return 0;2306 return 0;
2514}2307}
2515 2308
@@ -2532,7 +2325,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) · 16 unmodified lines
2532 info = snd_hda_codec_pcm_new(codec, "HDMI 0");2325 info = snd_hda_codec_pcm_new(codec, "HDMI 0");
2533 if (!info)2326 if (!info)
2534 return -ENOMEM;2327 return -ENOMEM;
2535 spec->pcm_rec[0] = info;2328 spec->pcm_rec[0].pcm = info;
2536 info->pcm_type = HDA_PCM_TYPE_HDMI;2329 info->pcm_type = HDA_PCM_TYPE_HDMI;
2537 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];2330 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
2538 *pstr = spec->pcm_playback;2331 *pstr = spec->pcm_playback;
@@ -3043,16 +2836,22 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) · 504 unmodified lines
3043 * - 0x10de00152836 * - 0x10de0015
3044 * - 0x10de00402837 * - 0x10de0040
3045 */2838 */
3046static int nvhdmi_chmap_cea_alloc_validate_get_type(struct cea_channel_speaker_allocation *cap,2839static int nvhdmi_chmap_cea_alloc_validate_get_type(struct hdac_chmap *chmap,
3047 int channels)2840 struct hdac_cea_channel_speaker_allocation *cap, int channels)
3048{2841{
3049 if (cap->ca_index == 0x00 && channels == 2)2842 if (cap->ca_index == 0x00 && channels == 2)
3050 return SNDRV_CTL_TLVT_CHMAP_FIXED;2843 return SNDRV_CTL_TLVT_CHMAP_FIXED;
3051 2844
3052 return hdmi_chmap_cea_alloc_validate_get_type(cap, channels);2845 /* If the speaker allocation matches the channel count, it is OK. */
2846 if (cap->channels != channels)
2847 return -1;
2848
2849 /* all channels are remappable freely */
2850 return SNDRV_CTL_TLVT_CHMAP_VAR;
3053}2851}
3054 2852
3055static int nvhdmi_chmap_validate(int ca, int chs, unsigned char *map)2853static int nvhdmi_chmap_validate(struct hdac_chmap *chmap,
2854 int ca, int chs, unsigned char *map)
3056{2855{
3057 if (ca == 0x00 && (map[0] != SNDRV_CHMAP_FL || map[1] != SNDRV_CHMAP_FR))2856 if (ca == 0x00 && (map[0] != SNDRV_CHMAP_FL || map[1] != SNDRV_CHMAP_FR))
3058 return -EINVAL;2857 return -EINVAL;
@@ -3072,9 +2871,9 @@ static int patch_nvhdmi(struct hda_codec *codec) · 13 unmodified lines
3072 spec = codec->spec;2871 spec = codec->spec;
3073 spec->dyn_pin_out = true;2872 spec->dyn_pin_out = true;
3074 2873
3075 spec->ops.chmap_cea_alloc_validate_get_type =2874 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
3076 nvhdmi_chmap_cea_alloc_validate_get_type;2875 nvhdmi_chmap_cea_alloc_validate_get_type;
3077 spec->ops.chmap_validate = nvhdmi_chmap_validate;2876 spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
3078 2877
3079 return 0;2878 return 0;
3080}2879}
@@ -3322,16 +3121,17 @@ static int atihdmi_paired_swap_fc_lfe(int pos) · 241 unmodified lines
3322 return pos;3121 return pos;
3323}3122}
3324 3123
3325static int atihdmi_paired_chmap_validate(int ca, int chs, unsigned char *map)3124static int atihdmi_paired_chmap_validate(struct hdac_chmap *chmap,
3125 int ca, int chs, unsigned char *map)
3326{3126{
3327 struct cea_channel_speaker_allocation *cap;3127 struct hdac_cea_channel_speaker_allocation *cap;
3328 int i, j;3128 int i, j;
3329 3129
3330 /* check that only channel pairs need to be remapped on old pre-rev3 ATI/AMD */3130 /* check that only channel pairs need to be remapped on old pre-rev3 ATI/AMD */
3331 3131
3332 cap = &channel_allocations[get_channel_allocation_order(ca)];3132 cap = snd_hdac_get_ch_alloc_from_ca(ca);
3333 for (i = 0; i < chs; ++i) {3133 for (i = 0; i < chs; ++i) {
3334 int mask = to_spk_mask(map[i]);3134 int mask = snd_hdac_chmap_to_spk_mask(map[i]);
3335 bool ok = false;3135 bool ok = false;
3336 bool companion_ok = false;3136 bool companion_ok = false;
3337 3137
@@ -3347,7 +3147,7 @@ static int atihdmi_paired_chmap_validate(int ca, int chs, unsigned char *map) · 9 unmodified lines
3347 if (i % 2 == 0 && i + 1 < chs) {3147 if (i % 2 == 0 && i + 1 < chs) {
3348 /* even channel, check the odd companion */3148 /* even channel, check the odd companion */
3349 int comp_chan_idx = 7 - atihdmi_paired_swap_fc_lfe(j + 1);3149 int comp_chan_idx = 7 - atihdmi_paired_swap_fc_lfe(j + 1);
3350 int comp_mask_req = to_spk_mask(map[i+1]);3150 int comp_mask_req = snd_hdac_chmap_to_spk_mask(map[i+1]);
3351 int comp_mask_act = cap->speakers[comp_chan_idx];3151 int comp_mask_act = cap->speakers[comp_chan_idx];
3352 3152
3353 if (comp_mask_req == comp_mask_act)3153 if (comp_mask_req == comp_mask_act)
@@ -3369,9 +3169,10 @@ static int atihdmi_paired_chmap_validate(int ca, int chs, unsigned char *map) · 15 unmodified lines
3369 return 0;3169 return 0;
3370}3170}
3371 3171
3372static int atihdmi_pin_set_slot_channel(struct hda_codec *codec, hda_nid_t pin_nid,3172static int atihdmi_pin_set_slot_channel(struct hdac_device *hdac,
3373 int hdmi_slot, int stream_channel)3173 hda_nid_t pin_nid, int hdmi_slot, int stream_channel)
3374{3174{
3175 struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
3375 int verb;3176 int verb;
3376 int ati_channel_setup = 0;3177 int ati_channel_setup = 0;
3377 3178
@@ -3404,9 +3205,10 @@ static int atihdmi_pin_set_slot_channel(struct hda_codec *codec, hda_nid_t pin_n · 26 unmodified lines
3404 return snd_hda_codec_write(codec, pin_nid, 0, verb, ati_channel_setup);3205 return snd_hda_codec_write(codec, pin_nid, 0, verb, ati_channel_setup);
3405}3206}
3406 3207
3407static int atihdmi_pin_get_slot_channel(struct hda_codec *codec, hda_nid_t pin_nid,3208static int atihdmi_pin_get_slot_channel(struct hdac_device *hdac,
3408 int asp_slot)3209 hda_nid_t pin_nid, int asp_slot)
3409{3210{
3211 struct hda_codec *codec = container_of(hdac, struct hda_codec, core);
3410 bool was_odd = false;3212 bool was_odd = false;
3411 int ati_asp_slot = asp_slot;3213 int ati_asp_slot = asp_slot;
3412 int verb;3214 int verb;
@@ -3433,8 +3235,10 @@ static int atihdmi_pin_get_slot_channel(struct hda_codec *codec, hda_nid_t pin_n · 20 unmodified lines
3433 return ((ati_channel_setup & 0xf0) >> 4) + !!was_odd;3235 return ((ati_channel_setup & 0xf0) >> 4) + !!was_odd;
3434}3236}
3435 3237
3436static int atihdmi_paired_chmap_cea_alloc_validate_get_type(struct cea_channel_speaker_allocation *cap,3238static int atihdmi_paired_chmap_cea_alloc_validate_get_type(
3437 int channels)3239 struct hdac_chmap *chmap,
3240 struct hdac_cea_channel_speaker_allocation *cap,
3241 int channels)
3438{3242{
3439 int c;3243 int c;
3440 3244
@@ -3461,8 +3265,9 @@ static int atihdmi_paired_chmap_cea_alloc_validate_get_type(struct cea_channel_s · 20 unmodified lines
3461 return SNDRV_CTL_TLVT_CHMAP_PAIRED;3265 return SNDRV_CTL_TLVT_CHMAP_PAIRED;
3462}3266}
3463 3267
3464static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct cea_channel_speaker_allocation *cap,3268static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct hdac_chmap *hchmap,
3465 unsigned int *chmap, int channels)3269 struct hdac_cea_channel_speaker_allocation *cap,
3270 unsigned int *chmap, int channels)
3466{3271{
3467 /* produce paired maps for pre-rev3 ATI/AMD codecs */3272 /* produce paired maps for pre-rev3 ATI/AMD codecs */
3468 int count = 0;3273 int count = 0;
@@ -3479,7 +3284,7 @@ static void atihdmi_paired_cea_alloc_to_tlv_chmap(struct cea_channel_speaker_all · 10 unmodified lines
3479 continue;3284 continue;
3480 }3285 }
3481 3286
3482 chmap[count++] = spk_to_chmap(spk);3287 chmap[count++] = snd_hdac_spk_to_chmap(spk);
3483 }3288 }
3484 3289
3485 WARN_ON(count != channels);3290 WARN_ON(count != channels);
@@ -3573,18 +3378,21 @@ static int patch_atihdmi(struct hda_codec *codec) · 87 unmodified lines
3573 spec = codec->spec;3378 spec = codec->spec;
3574 3379
3575 spec->ops.pin_get_eld = atihdmi_pin_get_eld;3380 spec->ops.pin_get_eld = atihdmi_pin_get_eld;
3576 spec->ops.pin_get_slot_channel = atihdmi_pin_get_slot_channel;
3577 spec->ops.pin_set_slot_channel = atihdmi_pin_set_slot_channel;
3578 spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;3381 spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;
3579 spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;3382 spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
3580 spec->ops.setup_stream = atihdmi_setup_stream;3383 spec->ops.setup_stream = atihdmi_setup_stream;
3581 3384
3582 if (!has_amd_full_remap_support(codec)) {3385 if (!has_amd_full_remap_support(codec)) {
3583 /* override to ATI/AMD-specific versions with pairwise mapping */3386 /* override to ATI/AMD-specific versions with pairwise mapping */
3584 spec->ops.chmap_cea_alloc_validate_get_type =3387 spec->chmap.ops.chmap_cea_alloc_validate_get_type =
3585 atihdmi_paired_chmap_cea_alloc_validate_get_type;3388 atihdmi_paired_chmap_cea_alloc_validate_get_type;
3586 spec->ops.cea_alloc_to_tlv_chmap = atihdmi_paired_cea_alloc_to_tlv_chmap;3389 spec->chmap.ops.cea_alloc_to_tlv_chmap =
3587 spec->ops.chmap_validate = atihdmi_paired_chmap_validate;3390 atihdmi_paired_cea_alloc_to_tlv_chmap;
3391 spec->chmap.ops.chmap_validate = atihdmi_paired_chmap_validate;
3392 spec->chmap.ops.pin_get_slot_channel =
3393 atihdmi_pin_get_slot_channel;
3394 spec->chmap.ops.pin_set_slot_channel =
3395 atihdmi_pin_set_slot_channel;
3588 }3396 }
3589 3397
3590 /* ATI/AMD converters do not advertise all of their capabilities */3398 /* ATI/AMD converters do not advertise all of their capabilities */
@@ -3596,7 +3404,7 @@ static int patch_atihdmi(struct hda_codec *codec) · 5 unmodified lines
3596 per_cvt->maxbps = max(per_cvt->maxbps, 24u);3404 per_cvt->maxbps = max(per_cvt->maxbps, 24u);
3597 }3405 }
3598 3406
3599 spec->channels_max = max(spec->channels_max, 8u);3407 spec->chmap.channels_max = max(spec->chmap.channels_max, 8u);
3600 3408
3601 return 0;3409 return 0;
3602}3410}
@@ -3659,6 +3467,7 @@ HDA_CODEC_ENTRY(0x10de0070, "GPU 70 HDMI/DP", patch_nvhdmi), · 56 unmodified lines
3659HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),3467HDA_CODEC_ENTRY(0x10de0071, "GPU 71 HDMI/DP", patch_nvhdmi),
3660HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),3468HDA_CODEC_ENTRY(0x10de0072, "GPU 72 HDMI/DP", patch_nvhdmi),
3661HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),3469HDA_CODEC_ENTRY(0x10de007d, "GPU 7d HDMI/DP", patch_nvhdmi),
3470HDA_CODEC_ENTRY(0x10de0082, "GPU 82 HDMI/DP", patch_nvhdmi),
3662HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi),3471HDA_CODEC_ENTRY(0x10de0083, "GPU 83 HDMI/DP", patch_nvhdmi),
3663HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),3472HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch),
3664HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),3473HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
sound/pci/hda/patch_realtek.c+1−0
@@ -5556,6 +5556,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 5555 unmodified lines
5556 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),5556 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5557 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),5557 SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
5558 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),5558 SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5559 SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
5559 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),5560 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
5560 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),5561 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5561 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),5562 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
sound/pci/hda/thinkpad_helper.c+2−15
@@ -10,23 +10,10 @@ · 9 unmodified lines
10static int (*led_set_func)(int, bool);10static int (*led_set_func)(int, bool);
11static void (*old_vmaster_hook)(void *, int);11static void (*old_vmaster_hook)(void *, int);
12 12
13static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
14 void **rv)
15{
16 bool *found = context;
17 *found = true;
18 return AE_OK;
19}
20
21static bool is_thinkpad(struct hda_codec *codec)13static bool is_thinkpad(struct hda_codec *codec)
22{14{
23 bool found = false;15 return (codec->core.subsystem_id >> 16 == 0x17aa) &&
24 if (codec->core.subsystem_id >> 16 != 0x17aa)16 (acpi_dev_present("LEN0068") || acpi_dev_present("IBM0068"));
25 return false;
26 if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
27 return true;
28 found = false;
29 return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
30}17}
31 18
32static void update_tpacpi_mute_led(void *private_data, int enabled)19static void update_tpacpi_mute_led(void *private_data, int enabled)
sound/pci/intel8x0.c+1−0
@@ -2879,6 +2879,7 @@ static void intel8x0_measure_ac97_clock(struct intel8x0 *chip) · 2878 unmodified lines
2879 2879
2880static struct snd_pci_quirk intel8x0_clock_list[] = {2880static struct snd_pci_quirk intel8x0_clock_list[] = {
2881 SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),2881 SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
2882 SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000),
2882 SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),2883 SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
2883 SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),2884 SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
2884 SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),2885 SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
sound/pci/mixart/mixart.c+1−1
@@ -132,7 +132,7 @@ static int mixart_set_pipe_state(struct mixart_mgr *mgr, · 131 unmodified lines
132 }132 }
133 133
134 if(start) {134 if(start) {
135 u32 stat;135 u32 stat = 0;
136 136
137 group_state.pipe_count = 0; /* in case of start same command once again with pipe_count=0 */137 group_state.pipe_count = 0; /* in case of start same command once again with pipe_count=0 */
138 138
sound/pci/mixart/mixart_mixer.c+2−2
@@ -726,7 +726,7 @@ int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int · 725 unmodified lines
726 int volume[2];726 int volume[2];
727 struct mixart_msg request;727 struct mixart_msg request;
728 struct mixart_set_out_stream_level_req set_level;728 struct mixart_set_out_stream_level_req set_level;
729 u32 status;729 u32 status = 0;
730 struct mixart_pipe *pipe;730 struct mixart_pipe *pipe;
731 731
732 memset(&set_level, 0, sizeof(set_level));732 memset(&set_level, 0, sizeof(set_level));
@@ -778,7 +778,7 @@ int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes) · 45 unmodified lines
778 struct mixart_pipe *pipe;778 struct mixart_pipe *pipe;
779 struct mixart_msg request;779 struct mixart_msg request;
780 struct mixart_set_in_audio_level_req set_level;780 struct mixart_set_in_audio_level_req set_level;
781 u32 status;781 u32 status = 0;
782 782
783 if(is_aes) {783 if(is_aes) {
784 idx = 1;784 idx = 1;
sound/soc/Kconfig+1−1
@@ -6,7 +6,7 @@ menuconfig SND_SOC · 5 unmodified lines
6 tristate "ALSA for SoC audio support"6 tristate "ALSA for SoC audio support"
7 select SND_PCM7 select SND_PCM
8 select AC97_BUS if SND_SOC_AC97_BUS8 select AC97_BUS if SND_SOC_AC97_BUS
9 select SND_JACK if INPUT=y || INPUT=SND9 select SND_JACK
10 select REGMAP_I2C if I2C10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER11 select REGMAP_SPI if SPI_MASTER
12 ---help---12 ---help---
sound/soc/atmel/atmel_ssc_dai.c+18−9
@@ -285,7 +285,8 @@ static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params, · 284 unmodified lines
285static int atmel_ssc_startup(struct snd_pcm_substream *substream,285static int atmel_ssc_startup(struct snd_pcm_substream *substream,
286 struct snd_soc_dai *dai)286 struct snd_soc_dai *dai)
287{287{
288 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];288 struct platform_device *pdev = to_platform_device(dai->dev);
289 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
289 struct atmel_pcm_dma_params *dma_params;290 struct atmel_pcm_dma_params *dma_params;
290 int dir, dir_mask;291 int dir, dir_mask;
291 int ret;292 int ret;
@@ -346,7 +347,8 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, · 54 unmodified lines
346static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,347static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
347 struct snd_soc_dai *dai)348 struct snd_soc_dai *dai)
348{349{
349 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];350 struct platform_device *pdev = to_platform_device(dai->dev);
351 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
350 struct atmel_pcm_dma_params *dma_params;352 struct atmel_pcm_dma_params *dma_params;
351 int dir, dir_mask;353 int dir, dir_mask;
352 354
@@ -392,7 +394,8 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream, · 39 unmodified lines
392static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,394static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
393 unsigned int fmt)395 unsigned int fmt)
394{396{
395 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];397 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
398 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
396 399
397 ssc_p->daifmt = fmt;400 ssc_p->daifmt = fmt;
398 return 0;401 return 0;
@@ -404,7 +407,8 @@ static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai, · 5 unmodified lines
404static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,407static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
405 int div_id, int div)408 int div_id, int div)
406{409{
407 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];410 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
411 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
408 412
409 switch (div_id) {413 switch (div_id) {
410 case ATMEL_SSC_CMR_DIV:414 case ATMEL_SSC_CMR_DIV:
@@ -445,7 +449,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 34 unmodified lines
445 struct snd_pcm_hw_params *params,449 struct snd_pcm_hw_params *params,
446 struct snd_soc_dai *dai)450 struct snd_soc_dai *dai)
447{451{
448 int id = dai->id;452 struct platform_device *pdev = to_platform_device(dai->dev);
453 int id = pdev->id;
449 struct atmel_ssc_info *ssc_p = &ssc_info[id];454 struct atmel_ssc_info *ssc_p = &ssc_info[id];
450 struct ssc_device *ssc = ssc_p->ssc;455 struct ssc_device *ssc = ssc_p->ssc;
451 struct atmel_pcm_dma_params *dma_params;456 struct atmel_pcm_dma_params *dma_params;
@@ -772,7 +777,8 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, · 320 unmodified lines
772static int atmel_ssc_prepare(struct snd_pcm_substream *substream,777static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
773 struct snd_soc_dai *dai)778 struct snd_soc_dai *dai)
774{779{
775 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];780 struct platform_device *pdev = to_platform_device(dai->dev);
781 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
776 struct atmel_pcm_dma_params *dma_params;782 struct atmel_pcm_dma_params *dma_params;
777 int dir;783 int dir;
778 784
@@ -795,7 +801,8 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream, · 16 unmodified lines
795static int atmel_ssc_trigger(struct snd_pcm_substream *substream,801static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
796 int cmd, struct snd_soc_dai *dai)802 int cmd, struct snd_soc_dai *dai)
797{803{
798 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];804 struct platform_device *pdev = to_platform_device(dai->dev);
805 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
799 struct atmel_pcm_dma_params *dma_params;806 struct atmel_pcm_dma_params *dma_params;
800 int dir;807 int dir;
801 808
@@ -824,11 +831,12 @@ static int atmel_ssc_trigger(struct snd_pcm_substream *substream, · 22 unmodified lines
824static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)831static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
825{832{
826 struct atmel_ssc_info *ssc_p;833 struct atmel_ssc_info *ssc_p;
834 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
827 835
828 if (!cpu_dai->active)836 if (!cpu_dai->active)
829 return 0;837 return 0;
830 838
831 ssc_p = &ssc_info[cpu_dai->id];839 ssc_p = &ssc_info[pdev->id];
832 840
833 /* Save the status register before disabling transmit and receive */841 /* Save the status register before disabling transmit and receive */
834 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);842 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
@@ -852,12 +860,13 @@ static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai) · 17 unmodified lines
852static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)860static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
853{861{
854 struct atmel_ssc_info *ssc_p;862 struct atmel_ssc_info *ssc_p;
863 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
855 u32 cr;864 u32 cr;
856 865
857 if (!cpu_dai->active)866 if (!cpu_dai->active)
858 return 0;867 return 0;
859 868
860 ssc_p = &ssc_info[cpu_dai->id];869 ssc_p = &ssc_info[pdev->id];
861 870
862 /* restore SSC register settings */871 /* restore SSC register settings */
863 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);872 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
sound/soc/bcm/bcm2835-i2s.c+64−220
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#include <linux/init.h>37#include <linux/init.h>
38#include <linux/io.h>38#include <linux/io.h>
39#include <linux/module.h>39#include <linux/module.h>
40#include <linux/of_address.h>
40#include <linux/slab.h>41#include <linux/slab.h>
41 42
42#include <sound/core.h>43#include <sound/core.h>
@@ -46,55 +47,6 @@ · 3 unmodified lines
46#include <sound/pcm_params.h>47#include <sound/pcm_params.h>
47#include <sound/soc.h>48#include <sound/soc.h>
48 49
49/* Clock registers */
50#define BCM2835_CLK_PCMCTL_REG 0x00
51#define BCM2835_CLK_PCMDIV_REG 0x04
52
53/* Clock register settings */
54#define BCM2835_CLK_PASSWD (0x5a000000)
55#define BCM2835_CLK_PASSWD_MASK (0xff000000)
56#define BCM2835_CLK_MASH(v) ((v) << 9)
57#define BCM2835_CLK_FLIP BIT(8)
58#define BCM2835_CLK_BUSY BIT(7)
59#define BCM2835_CLK_KILL BIT(5)
60#define BCM2835_CLK_ENAB BIT(4)
61#define BCM2835_CLK_SRC(v) (v)
62
63#define BCM2835_CLK_SHIFT (12)
64#define BCM2835_CLK_DIVI(v) ((v) << BCM2835_CLK_SHIFT)
65#define BCM2835_CLK_DIVF(v) (v)
66#define BCM2835_CLK_DIVF_MASK (0xFFF)
67
68enum {
69 BCM2835_CLK_MASH_0 = 0,
70 BCM2835_CLK_MASH_1,
71 BCM2835_CLK_MASH_2,
72 BCM2835_CLK_MASH_3,
73};
74
75enum {
76 BCM2835_CLK_SRC_GND = 0,
77 BCM2835_CLK_SRC_OSC,
78 BCM2835_CLK_SRC_DBG0,
79 BCM2835_CLK_SRC_DBG1,
80 BCM2835_CLK_SRC_PLLA,
81 BCM2835_CLK_SRC_PLLC,
82 BCM2835_CLK_SRC_PLLD,
83 BCM2835_CLK_SRC_HDMI,
84};
85
86/* Most clocks are not useable (freq = 0) */
87static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = {
88 [BCM2835_CLK_SRC_GND] = 0,
89 [BCM2835_CLK_SRC_OSC] = 19200000,
90 [BCM2835_CLK_SRC_DBG0] = 0,
91 [BCM2835_CLK_SRC_DBG1] = 0,
92 [BCM2835_CLK_SRC_PLLA] = 0,
93 [BCM2835_CLK_SRC_PLLC] = 0,
94 [BCM2835_CLK_SRC_PLLD] = 500000000,
95 [BCM2835_CLK_SRC_HDMI] = 0,
96};
97
98/* I2S registers */50/* I2S registers */
99#define BCM2835_I2S_CS_A_REG 0x0051#define BCM2835_I2S_CS_A_REG 0x00
100#define BCM2835_I2S_FIFO_A_REG 0x0452#define BCM2835_I2S_FIFO_A_REG 0x04
@@ -158,10 +110,6 @@ static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { · 57 unmodified lines
158#define BCM2835_I2S_INT_RXR BIT(1)110#define BCM2835_I2S_INT_RXR BIT(1)
159#define BCM2835_I2S_INT_TXW BIT(0)111#define BCM2835_I2S_INT_TXW BIT(0)
160 112
161/* I2S DMA interface */
162/* FIXME: Needs IOMMU support */
163#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000)
164
165/* General device struct */113/* General device struct */
166struct bcm2835_i2s_dev {114struct bcm2835_i2s_dev {
167 struct device *dev;115 struct device *dev;
@@ -169,21 +117,23 @@ struct bcm2835_i2s_dev { · 1 unmodified line
169 unsigned int fmt;117 unsigned int fmt;
170 unsigned int bclk_ratio;118 unsigned int bclk_ratio;
171 119
172 struct regmap *i2s_regmap;120 struct regmap *i2s_regmap;
173 struct regmap *clk_regmap;121 struct clk *clk;
122 bool clk_prepared;
174};123};
175 124
176static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev)125static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev)
177{126{
178 /* Start the clock if in master mode */
179 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;127 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
180 128
129 if (dev->clk_prepared)
130 return;
131
181 switch (master) {132 switch (master) {
182 case SND_SOC_DAIFMT_CBS_CFS:133 case SND_SOC_DAIFMT_CBS_CFS:
183 case SND_SOC_DAIFMT_CBS_CFM:134 case SND_SOC_DAIFMT_CBS_CFM:
184 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,135 clk_prepare_enable(dev->clk);
185 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,136 dev->clk_prepared = true;
186 BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
187 break;137 break;
188 default:138 default:
189 break;139 break;
@@ -192,28 +142,9 @@ static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) · 2 unmodified lines
192 142
193static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev)143static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev)
194{144{
195 uint32_t clkreg;145 if (dev->clk_prepared)
196 int timeout = 1000;146 clk_disable_unprepare(dev->clk);
197 147 dev->clk_prepared = false;
198 /* Stop clock */
199 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
200 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
201 BCM2835_CLK_PASSWD);
202
203 /* Wait for the BUSY flag going down */
204 while (--timeout) {
205 regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
206 if (!(clkreg & BCM2835_CLK_BUSY))
207 break;
208 }
209
210 if (!timeout) {
211 /* KILL the clock */
212 dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n");
213 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
214 BCM2835_CLK_KILL | BCM2835_CLK_PASSWD_MASK,
215 BCM2835_CLK_KILL | BCM2835_CLK_PASSWD);
216 }
217}148}
218 149
219static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev,150static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev,
@@ -223,8 +154,7 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, · 3 unmodified lines
223 uint32_t syncval;154 uint32_t syncval;
224 uint32_t csreg;155 uint32_t csreg;
225 uint32_t i2s_active_state;156 uint32_t i2s_active_state;
226 uint32_t clkreg;157 bool clk_was_prepared;
227 uint32_t clk_active_state;
228 uint32_t off;158 uint32_t off;
229 uint32_t clr;159 uint32_t clr;
230 160
@@ -238,15 +168,10 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, · 7 unmodified lines
238 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);168 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
239 i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON);169 i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON);
240 170
241 regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
242 clk_active_state = clkreg & BCM2835_CLK_ENAB;
243
244 /* Start clock if not running */171 /* Start clock if not running */
245 if (!clk_active_state) {172 clk_was_prepared = dev->clk_prepared;
246 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,173 if (!clk_was_prepared)
247 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,174 bcm2835_i2s_start_clock(dev);
248 BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
249 }
250 175
251 /* Stop I2S module */176 /* Stop I2S module */
252 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0);177 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0);
@@ -280,7 +205,7 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, · 27 unmodified lines
280 dev_err(dev->dev, "I2S SYNC error!\n");205 dev_err(dev->dev, "I2S SYNC error!\n");
281 206
282 /* Stop clock if it was not running before */207 /* Stop clock if it was not running before */
283 if (!clk_active_state)208 if (!clk_was_prepared)
284 bcm2835_i2s_stop_clock(dev);209 bcm2835_i2s_stop_clock(dev);
285 210
286 /* Restore I2S state */211 /* Restore I2S state */
@@ -309,19 +234,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, · 22 unmodified lines
309 struct snd_soc_dai *dai)234 struct snd_soc_dai *dai)
310{235{
311 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);236 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
312
313 unsigned int sampling_rate = params_rate(params);237 unsigned int sampling_rate = params_rate(params);
314 unsigned int data_length, data_delay, bclk_ratio;238 unsigned int data_length, data_delay, bclk_ratio;
315 unsigned int ch1pos, ch2pos, mode, format;239 unsigned int ch1pos, ch2pos, mode, format;
316 unsigned int mash = BCM2835_CLK_MASH_1;
317 unsigned int divi, divf, target_frequency;
318 int clk_src = -1;
319 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
320 bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS
321 || master == SND_SOC_DAIFMT_CBS_CFM);
322
323 bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS
324 || master == SND_SOC_DAIFMT_CBM_CFS);
325 uint32_t csreg;240 uint32_t csreg;
326 241
327 /*242 /*
@@ -343,11 +258,9 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, · 15 unmodified lines
343 switch (params_format(params)) {258 switch (params_format(params)) {
344 case SNDRV_PCM_FORMAT_S16_LE:259 case SNDRV_PCM_FORMAT_S16_LE:
345 data_length = 16;260 data_length = 16;
346 bclk_ratio = 40;
347 break;261 break;
348 case SNDRV_PCM_FORMAT_S32_LE:262 case SNDRV_PCM_FORMAT_S32_LE:
349 data_length = 32;263 data_length = 32;
350 bclk_ratio = 80;
351 break;264 break;
352 default:265 default:
353 return -EINVAL;266 return -EINVAL;
@@ -356,69 +269,12 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines
356 /* If bclk_ratio already set, use that one. */269 /* If bclk_ratio already set, use that one. */
357 if (dev->bclk_ratio)270 if (dev->bclk_ratio)
358 bclk_ratio = dev->bclk_ratio;271 bclk_ratio = dev->bclk_ratio;
272 else
273 /* otherwise calculate a fitting block ratio */
274 bclk_ratio = 2 * data_length;
359 275
360 /*276 /* set target clock rate*/
361 * Clock Settings277 clk_set_rate(dev->clk, sampling_rate * bclk_ratio);
362 *
363 * The target frequency of the bit clock is
364 * sampling rate * frame length
365 *
366 * Integer mode:
367 * Sampling rates that are multiples of 8000 kHz
368 * can be driven by the oscillator of 19.2 MHz
369 * with an integer divider as long as the frame length
370 * is an integer divider of 19200000/8000=2400 as set up above.
371 * This is no longer possible if the sampling rate
372 * is too high (e.g. 192 kHz), because the oscillator is too slow.
373 *
374 * MASH mode:
375 * For all other sampling rates, it is not possible to
376 * have an integer divider. Approximate the clock
377 * with the MASH module that induces a slight frequency
378 * variance. To minimize that it is best to have the fastest
379 * clock here. That is PLLD with 500 MHz.
380 */
381 target_frequency = sampling_rate * bclk_ratio;
382 clk_src = BCM2835_CLK_SRC_OSC;
383 mash = BCM2835_CLK_MASH_0;
384
385 if (bcm2835_clk_freq[clk_src] % target_frequency == 0
386 && bit_master && frame_master) {
387 divi = bcm2835_clk_freq[clk_src] / target_frequency;
388 divf = 0;
389 } else {
390 uint64_t dividend;
391
392 if (!dev->bclk_ratio) {
393 /*
394 * Overwrite bclk_ratio, because the
395 * above trick is not needed or can
396 * not be used.
397 */
398 bclk_ratio = 2 * data_length;
399 }
400
401 target_frequency = sampling_rate * bclk_ratio;
402
403 clk_src = BCM2835_CLK_SRC_PLLD;
404 mash = BCM2835_CLK_MASH_1;
405
406 dividend = bcm2835_clk_freq[clk_src];
407 dividend <<= BCM2835_CLK_SHIFT;
408 do_div(dividend, target_frequency);
409 divi = dividend >> BCM2835_CLK_SHIFT;
410 divf = dividend & BCM2835_CLK_DIVF_MASK;
411 }
412
413 /* Set clock divider */
414 regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD
415 | BCM2835_CLK_DIVI(divi)
416 | BCM2835_CLK_DIVF(divf));
417
418 /* Setup clock, but don't start it yet */
419 regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD
420 | BCM2835_CLK_MASH(mash)
421 | BCM2835_CLK_SRC(clk_src));
422 278
423 /* Setup the frame format */279 /* Setup the frame format */
424 format = BCM2835_I2S_CHEN;280 format = BCM2835_I2S_CHEN;
@@ -692,7 +548,7 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { · 267 unmodified lines
692 .trigger = bcm2835_i2s_trigger,548 .trigger = bcm2835_i2s_trigger,
693 .hw_params = bcm2835_i2s_hw_params,549 .hw_params = bcm2835_i2s_hw_params,
694 .set_fmt = bcm2835_i2s_set_dai_fmt,550 .set_fmt = bcm2835_i2s_set_dai_fmt,
695 .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio551 .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio,
696};552};
697 553
698static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)554static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
@@ -750,34 +606,14 @@ static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg) · 51 unmodified lines
750 };606 };
751}607}
752 608
753static bool bcm2835_clk_volatile_reg(struct device *dev, unsigned int reg)609static const struct regmap_config bcm2835_regmap_config = {
754{610 .reg_bits = 32,
755 switch (reg) {611 .reg_stride = 4,
756 case BCM2835_CLK_PCMCTL_REG:612 .val_bits = 32,
757 return true;613 .max_register = BCM2835_I2S_GRAY_REG,
758 default:614 .precious_reg = bcm2835_i2s_precious_reg,
759 return false;615 .volatile_reg = bcm2835_i2s_volatile_reg,
760 };616 .cache_type = REGCACHE_RBTREE,
761}
762
763static const struct regmap_config bcm2835_regmap_config[] = {
764 {
765 .reg_bits = 32,
766 .reg_stride = 4,
767 .val_bits = 32,
768 .max_register = BCM2835_I2S_GRAY_REG,
769 .precious_reg = bcm2835_i2s_precious_reg,
770 .volatile_reg = bcm2835_i2s_volatile_reg,
771 .cache_type = REGCACHE_RBTREE,
772 },
773 {
774 .reg_bits = 32,
775 .reg_stride = 4,
776 .val_bits = 32,
777 .max_register = BCM2835_CLK_PCMDIV_REG,
778 .volatile_reg = bcm2835_clk_volatile_reg,
779 .cache_type = REGCACHE_RBTREE,
780 },
781};617};
782 618
783static const struct snd_soc_component_driver bcm2835_i2s_component = {619static const struct snd_soc_component_driver bcm2835_i2s_component = {
@@ -787,42 +623,50 @@ static const struct snd_soc_component_driver bcm2835_i2s_component = { · 3 unmodified lines
787static int bcm2835_i2s_probe(struct platform_device *pdev)623static int bcm2835_i2s_probe(struct platform_device *pdev)
788{624{
789 struct bcm2835_i2s_dev *dev;625 struct bcm2835_i2s_dev *dev;
790 int i;
791 int ret;626 int ret;
792 struct regmap *regmap[2];627 struct resource *mem;
793 struct resource *mem[2];628 void __iomem *base;
794 629 const __be32 *addr;
795 /* Request both ioareas */630 dma_addr_t dma_base;
796 for (i = 0; i <= 1; i++) {
797 void __iomem *base;
798
799 mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
800 base = devm_ioremap_resource(&pdev->dev, mem[i]);
801 if (IS_ERR(base))
802 return PTR_ERR(base);
803
804 regmap[i] = devm_regmap_init_mmio(&pdev->dev, base,
805 &bcm2835_regmap_config[i]);
806 if (IS_ERR(regmap[i]))
807 return PTR_ERR(regmap[i]);
808 }
809 631
810 dev = devm_kzalloc(&pdev->dev, sizeof(*dev),632 dev = devm_kzalloc(&pdev->dev, sizeof(*dev),
811 GFP_KERNEL);633 GFP_KERNEL);
812 if (!dev)634 if (!dev)
813 return -ENOMEM;635 return -ENOMEM;
814 636
815 dev->i2s_regmap = regmap[0];637 /* get the clock */
816 dev->clk_regmap = regmap[1];638 dev->clk_prepared = false;
639 dev->clk = devm_clk_get(&pdev->dev, NULL);
640 if (IS_ERR(dev->clk)) {
641 dev_err(&pdev->dev, "could not get clk: %ld\n",
642 PTR_ERR(dev->clk));
643 return PTR_ERR(dev->clk);
644 }
645
646 /* Request ioarea */
647 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
648 base = devm_ioremap_resource(&pdev->dev, mem);
649 if (IS_ERR(base))
650 return PTR_ERR(base);
651
652 dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base,
653 &bcm2835_regmap_config);
654 if (IS_ERR(dev->i2s_regmap))
655 return PTR_ERR(dev->i2s_regmap);
656
657 /* Set the DMA address - we have to parse DT ourselves */
658 addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL);
659 if (!addr) {
660 dev_err(&pdev->dev, "could not get DMA-register address\n");
661 return -EINVAL;
662 }
663 dma_base = be32_to_cpup(addr);
817 664
818 /* Set the DMA address */
819 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =665 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
820 (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG666 dma_base + BCM2835_I2S_FIFO_A_REG;
821 + BCM2835_VCMMU_SHIFT;
822 667
823 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =668 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
824 (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG669 dma_base + BCM2835_I2S_FIFO_A_REG;
825 + BCM2835_VCMMU_SHIFT;
826 670
827 /* Set the bus width */671 /* Set the bus width */
828 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =672 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =
sound/soc/codecs/Kconfig+35−3
@@ -79,7 +79,9 @@ config SND_SOC_ALL_CODECS · 78 unmodified lines
79 select SND_SOC_MAX98090 if I2C79 select SND_SOC_MAX98090 if I2C
80 select SND_SOC_MAX98095 if I2C80 select SND_SOC_MAX98095 if I2C
81 select SND_SOC_MAX98357A if GPIOLIB81 select SND_SOC_MAX98357A if GPIOLIB
82 select SND_SOC_MAX9867 if I2C
82 select SND_SOC_MAX98925 if I2C83 select SND_SOC_MAX98925 if I2C
84 select SND_SOC_MAX98926 if I2C
83 select SND_SOC_MAX9850 if I2C85 select SND_SOC_MAX9850 if I2C
84 select SND_SOC_MAX9768 if I2C86 select SND_SOC_MAX9768 if I2C
85 select SND_SOC_MAX9877 if I2C87 select SND_SOC_MAX9877 if I2C
@@ -87,7 +89,8 @@ config SND_SOC_ALL_CODECS · 1 unmodified line
87 select SND_SOC_ML26124 if I2C89 select SND_SOC_ML26124 if I2C
88 select SND_SOC_NAU8825 if I2C90 select SND_SOC_NAU8825 if I2C
89 select SND_SOC_PCM1681 if I2C91 select SND_SOC_PCM1681 if I2C
90 select SND_SOC_PCM179X if SPI_MASTER92 select SND_SOC_PCM179X_I2C if I2C
93 select SND_SOC_PCM179X_SPI if SPI_MASTER
91 select SND_SOC_PCM300894 select SND_SOC_PCM3008
92 select SND_SOC_PCM3168A_I2C if I2C95 select SND_SOC_PCM3168A_I2C if I2C
93 select SND_SOC_PCM3168A_SPI if SPI_MASTER96 select SND_SOC_PCM3168A_SPI if SPI_MASTER
@@ -95,6 +98,7 @@ config SND_SOC_ALL_CODECS · 1 unmodified line
95 select SND_SOC_PCM512x_SPI if SPI_MASTER98 select SND_SOC_PCM512x_SPI if SPI_MASTER
96 select SND_SOC_RT286 if I2C99 select SND_SOC_RT286 if I2C
97 select SND_SOC_RT298 if I2C100 select SND_SOC_RT298 if I2C
101 select SND_SOC_RT5514 if I2C
98 select SND_SOC_RT5616 if I2C102 select SND_SOC_RT5616 if I2C
99 select SND_SOC_RT5631 if I2C103 select SND_SOC_RT5631 if I2C
100 select SND_SOC_RT5640 if I2C104 select SND_SOC_RT5640 if I2C
@@ -490,6 +494,7 @@ config SND_SOC_GTM601 · 389 unmodified lines
490config SND_SOC_HDAC_HDMI494config SND_SOC_HDAC_HDMI
491 tristate495 tristate
492 select SND_HDA_EXT_CORE496 select SND_HDA_EXT_CORE
497 select SND_PCM_ELD
493 select HDMI498 select HDMI
494 499
495config SND_SOC_ICS43432500config SND_SOC_ICS43432
@@ -497,6 +502,7 @@ config SND_SOC_ICS43432 · 1 unmodified line
497 502
498config SND_SOC_INNO_RK3036503config SND_SOC_INNO_RK3036
499 tristate "Inno codec driver for RK3036 SoC"504 tristate "Inno codec driver for RK3036 SoC"
505 select REGMAP_MMIO
500 506
501config SND_SOC_ISABELLE507config SND_SOC_ISABELLE
502 tristate508 tristate
@@ -516,9 +522,15 @@ config SND_SOC_MAX98095 · 13 unmodified lines
516config SND_SOC_MAX98357A522config SND_SOC_MAX98357A
517 tristate523 tristate
518 524
525config SND_SOC_MAX9867
526 tristate
527
519config SND_SOC_MAX98925528config SND_SOC_MAX98925
520 tristate529 tristate
521 530
531config SND_SOC_MAX98926
532 tristate
533
522config SND_SOC_MAX9850534config SND_SOC_MAX9850
523 tristate535 tristate
524 536
@@ -527,8 +539,23 @@ config SND_SOC_PCM1681 · 2 unmodified lines
527 depends on I2C539 depends on I2C
528 540
529config SND_SOC_PCM179X541config SND_SOC_PCM179X
530 tristate "Texas Instruments PCM179X CODEC"542 tristate
543
544config SND_SOC_PCM179X_I2C
545 tristate "Texas Instruments PCM179X CODEC (I2C)"
546 depends on I2C
547 select SND_SOC_PCM179X
548 help
549 Enable support for Texas Instruments PCM179x CODEC.
550 Select this if your PCM179x is connected via an I2C bus.
551
552config SND_SOC_PCM179X_SPI
553 tristate "Texas Instruments PCM179X CODEC (SPI)"
531 depends on SPI_MASTER554 depends on SPI_MASTER
555 select SND_SOC_PCM179X
556 help
557 Enable support for Texas Instruments PCM179x CODEC.
558 Select this if your PCM179x is connected via an SPI bus.
532 559
533config SND_SOC_PCM3008560config SND_SOC_PCM3008
534 tristate561 tristate
@@ -565,6 +592,7 @@ config SND_SOC_PCM512x_SPI · 30 unmodified lines
565 592
566config SND_SOC_RL6231593config SND_SOC_RL6231
567 tristate594 tristate
595 default y if SND_SOC_RT5514=y
568 default y if SND_SOC_RT5616=y596 default y if SND_SOC_RT5616=y
569 default y if SND_SOC_RT5640=y597 default y if SND_SOC_RT5640=y
570 default y if SND_SOC_RT5645=y598 default y if SND_SOC_RT5645=y
@@ -572,6 +600,7 @@ config SND_SOC_RL6231 · 1 unmodified line
572 default y if SND_SOC_RT5659=y600 default y if SND_SOC_RT5659=y
573 default y if SND_SOC_RT5670=y601 default y if SND_SOC_RT5670=y
574 default y if SND_SOC_RT5677=y602 default y if SND_SOC_RT5677=y
603 default m if SND_SOC_RT5514=m
575 default m if SND_SOC_RT5616=m604 default m if SND_SOC_RT5616=m
576 default m if SND_SOC_RT5640=m605 default m if SND_SOC_RT5640=m
577 default m if SND_SOC_RT5645=m606 default m if SND_SOC_RT5645=m
@@ -595,9 +624,12 @@ config SND_SOC_RT298 · 17 unmodified lines
595 tristate624 tristate
596 depends on I2C625 depends on I2C
597 626
598config SND_SOC_RT5616627config SND_SOC_RT5514
599 tristate628 tristate
600 629
630config SND_SOC_RT5616
631 tristate "Realtek RT5616 CODEC"
632
601config SND_SOC_RT5631633config SND_SOC_RT5631
602 tristate "Realtek ALC5631/RT5631 CODEC"634 tristate "Realtek ALC5631/RT5631 CODEC"
603 depends on I2C635 depends on I2C
sound/soc/codecs/Makefile+10−0
@@ -74,13 +74,17 @@ snd-soc-max98088-objs := max98088.o · 73 unmodified lines
74snd-soc-max98090-objs := max98090.o74snd-soc-max98090-objs := max98090.o
75snd-soc-max98095-objs := max98095.o75snd-soc-max98095-objs := max98095.o
76snd-soc-max98357a-objs := max98357a.o76snd-soc-max98357a-objs := max98357a.o
77snd-soc-max9867-objs := max9867.o
77snd-soc-max98925-objs := max98925.o78snd-soc-max98925-objs := max98925.o
79snd-soc-max98926-objs := max98926.o
78snd-soc-max9850-objs := max9850.o80snd-soc-max9850-objs := max9850.o
79snd-soc-mc13783-objs := mc13783.o81snd-soc-mc13783-objs := mc13783.o
80snd-soc-ml26124-objs := ml26124.o82snd-soc-ml26124-objs := ml26124.o
81snd-soc-nau8825-objs := nau8825.o83snd-soc-nau8825-objs := nau8825.o
82snd-soc-pcm1681-objs := pcm1681.o84snd-soc-pcm1681-objs := pcm1681.o
83snd-soc-pcm179x-codec-objs := pcm179x.o85snd-soc-pcm179x-codec-objs := pcm179x.o
86snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o
87snd-soc-pcm179x-spi-objs := pcm179x-spi.o
84snd-soc-pcm3008-objs := pcm3008.o88snd-soc-pcm3008-objs := pcm3008.o
85snd-soc-pcm3168a-objs := pcm3168a.o89snd-soc-pcm3168a-objs := pcm3168a.o
86snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o90snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o
@@ -92,6 +96,7 @@ snd-soc-rl6231-objs := rl6231.o · 5 unmodified lines
92snd-soc-rl6347a-objs := rl6347a.o96snd-soc-rl6347a-objs := rl6347a.o
93snd-soc-rt286-objs := rt286.o97snd-soc-rt286-objs := rt286.o
94snd-soc-rt298-objs := rt298.o98snd-soc-rt298-objs := rt298.o
99snd-soc-rt5514-objs := rt5514.o
95snd-soc-rt5616-objs := rt5616.o100snd-soc-rt5616-objs := rt5616.o
96snd-soc-rt5631-objs := rt5631.o101snd-soc-rt5631-objs := rt5631.o
97snd-soc-rt5640-objs := rt5640.o102snd-soc-rt5640-objs := rt5640.o
@@ -278,13 +283,17 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o · 180 unmodified lines
278obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o283obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
279obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o284obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
280obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o285obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
286obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
281obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o287obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
288obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
282obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o289obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
283obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o290obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
284obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o291obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
285obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o292obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
286obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o293obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
287obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o294obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o
295obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o
296obj-$(CONFIG_SND_SOC_PCM179X_SPI) += snd-soc-pcm179x-spi.o
288obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o297obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
289obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o298obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o
290obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o299obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o
@@ -296,6 +305,7 @@ obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o · 5 unmodified lines
296obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o305obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
297obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o306obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
298obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o307obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
308obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o
299obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o309obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
300obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o310obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
301obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o311obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
sound/soc/codecs/ab8500-codec.c+0−1
@@ -2134,7 +2134,6 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) · 2133 unmodified lines
2134 "%s: ERROR: Unsupporter master mask 0x%x\n",2134 "%s: ERROR: Unsupporter master mask 0x%x\n",
2135 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);2135 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
2136 return -EINVAL;2136 return -EINVAL;
2137 break;
2138 }2137 }
2139 2138
2140 snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);2139 snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
sound/soc/codecs/adau1761-i2c.c+13−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec2 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
3 *3 *
4 * Copyright 2014 Analog Devices Inc.4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>5 * Author: Lars-Peter Clausen <lars@metafoo.de>
@@ -44,9 +44,21 @@ static const struct i2c_device_id adau1761_i2c_ids[] = { · 38 unmodified lines
44};44};
45MODULE_DEVICE_TABLE(i2c, adau1761_i2c_ids);45MODULE_DEVICE_TABLE(i2c, adau1761_i2c_ids);
46 46
47#if defined(CONFIG_OF)
48static const struct of_device_id adau1761_i2c_dt_ids[] = {
49 { .compatible = "adi,adau1361", },
50 { .compatible = "adi,adau1461", },
51 { .compatible = "adi,adau1761", },
52 { .compatible = "adi,adau1961", },
53 { },
54};
55MODULE_DEVICE_TABLE(of, adau1761_i2c_dt_ids);
56#endif
57
47static struct i2c_driver adau1761_i2c_driver = {58static struct i2c_driver adau1761_i2c_driver = {
48 .driver = {59 .driver = {
49 .name = "adau1761",60 .name = "adau1761",
61 .of_match_table = of_match_ptr(adau1761_i2c_dt_ids),
50 },62 },
51 .probe = adau1761_i2c_probe,63 .probe = adau1761_i2c_probe,
52 .remove = adau1761_i2c_remove,64 .remove = adau1761_i2c_remove,
sound/soc/codecs/adau1761-spi.c+13−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec2 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
3 *3 *
4 * Copyright 2014 Analog Devices Inc.4 * Copyright 2014 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>5 * Author: Lars-Peter Clausen <lars@metafoo.de>
@@ -61,9 +61,21 @@ static const struct spi_device_id adau1761_spi_id[] = { · 55 unmodified lines
61};61};
62MODULE_DEVICE_TABLE(spi, adau1761_spi_id);62MODULE_DEVICE_TABLE(spi, adau1761_spi_id);
63 63
64#if defined(CONFIG_OF)
65static const struct of_device_id adau1761_spi_dt_ids[] = {
66 { .compatible = "adi,adau1361", },
67 { .compatible = "adi,adau1461", },
68 { .compatible = "adi,adau1761", },
69 { .compatible = "adi,adau1961", },
70 { },
71};
72MODULE_DEVICE_TABLE(of, adau1761_spi_dt_ids);
73#endif
74
64static struct spi_driver adau1761_spi_driver = {75static struct spi_driver adau1761_spi_driver = {
65 .driver = {76 .driver = {
66 .name = "adau1761",77 .name = "adau1761",
78 .of_match_table = of_match_ptr(adau1761_spi_dt_ids),
67 },79 },
68 .probe = adau1761_spi_probe,80 .probe = adau1761_spi_probe,
69 .remove = adau1761_spi_remove,81 .remove = adau1761_spi_remove,
sound/soc/codecs/adau1761.c+9−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec2 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
3 *3 *
4 * Copyright 2011-2013 Analog Devices Inc.4 * Copyright 2011-2013 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>5 * Author: Lars-Peter Clausen <lars@metafoo.de>
@@ -456,13 +456,17 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec, · 450 unmodified lines
456 case SND_SOC_BIAS_PREPARE:456 case SND_SOC_BIAS_PREPARE:
457 break;457 break;
458 case SND_SOC_BIAS_STANDBY:458 case SND_SOC_BIAS_STANDBY:
459 regcache_cache_only(adau->regmap, false);
459 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,460 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
460 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,461 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
461 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);462 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
463 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
464 regcache_sync(adau->regmap);
462 break;465 break;
463 case SND_SOC_BIAS_OFF:466 case SND_SOC_BIAS_OFF:
464 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,467 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
465 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);468 ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
469 regcache_cache_only(adau->regmap, true);
466 break;470 break;
467 471
468 }472 }
@@ -783,6 +787,10 @@ int adau1761_probe(struct device *dev, struct regmap *regmap, · 314 unmodified lines
783 if (ret)787 if (ret)
784 return ret;788 return ret;
785 789
790 /* Enable cache only mode as we could miss writes before bias level
791 * reaches standby and the core clock is enabled */
792 regcache_cache_only(regmap, true);
793
786 return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);794 return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
787}795}
788EXPORT_SYMBOL_GPL(adau1761_probe);796EXPORT_SYMBOL_GPL(adau1761_probe);
sound/soc/codecs/adau1781-i2c.c+10−0
@@ -42,9 +42,19 @@ static const struct i2c_device_id adau1781_i2c_ids[] = { · 41 unmodified lines
42};42};
43MODULE_DEVICE_TABLE(i2c, adau1781_i2c_ids);43MODULE_DEVICE_TABLE(i2c, adau1781_i2c_ids);
44 44
45#if defined(CONFIG_OF)
46static const struct of_device_id adau1781_i2c_dt_ids[] = {
47 { .compatible = "adi,adau1381", },
48 { .compatible = "adi,adau1781", },
49 { },
50};
51MODULE_DEVICE_TABLE(of, adau1781_i2c_dt_ids);
52#endif
53
45static struct i2c_driver adau1781_i2c_driver = {54static struct i2c_driver adau1781_i2c_driver = {
46 .driver = {55 .driver = {
47 .name = "adau1781",56 .name = "adau1781",
57 .of_match_table = of_match_ptr(adau1781_i2c_dt_ids),
48 },58 },
49 .probe = adau1781_i2c_probe,59 .probe = adau1781_i2c_probe,
50 .remove = adau1781_i2c_remove,60 .remove = adau1781_i2c_remove,
sound/soc/codecs/adau1781-spi.c+10−0
@@ -59,9 +59,19 @@ static const struct spi_device_id adau1781_spi_id[] = { · 58 unmodified lines
59};59};
60MODULE_DEVICE_TABLE(spi, adau1781_spi_id);60MODULE_DEVICE_TABLE(spi, adau1781_spi_id);
61 61
62#if defined(CONFIG_OF)
63static const struct of_device_id adau1781_spi_dt_ids[] = {
64 { .compatible = "adi,adau1381", },
65 { .compatible = "adi,adau1781", },
66 { },
67};
68MODULE_DEVICE_TABLE(of, adau1781_spi_dt_ids);
69#endif
70
62static struct spi_driver adau1781_spi_driver = {71static struct spi_driver adau1781_spi_driver = {
63 .driver = {72 .driver = {
64 .name = "adau1781",73 .name = "adau1781",
74 .of_match_table = of_match_ptr(adau1781_spi_dt_ids),
65 },75 },
66 .probe = adau1781_spi_probe,76 .probe = adau1781_spi_probe,
67 .remove = adau1781_spi_remove,77 .remove = adau1781_spi_remove,
sound/soc/codecs/adau1781.c+1−1
@@ -1,5 +1,5 @@
1/*1/*
2 * Driver for ADAU1781/ADAU1781 codec2 * Driver for ADAU1381/ADAU1781 codec
3 *3 *
4 * Copyright 2011-2013 Analog Devices Inc.4 * Copyright 2011-2013 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>5 * Author: Lars-Peter Clausen <lars@metafoo.de>
sound/soc/codecs/ads117x.c+12−0
@@ -20,6 +20,8 @@ · 19 unmodified lines
20#include <sound/initval.h>20#include <sound/initval.h>
21#include <sound/soc.h>21#include <sound/soc.h>
22 22
23#include <linux/of.h>
24
23#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)25#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
24#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)26#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
25 27
@@ -75,9 +77,19 @@ static int ads117x_remove(struct platform_device *pdev) · 49 unmodified lines
75 return 0;77 return 0;
76}78}
77 79
80#if defined(CONFIG_OF)
81static const struct of_device_id ads117x_dt_ids[] = {
82 { .compatible = "ti,ads1174" },
83 { .compatible = "ti,ads1178" },
84 { },
85};
86MODULE_DEVICE_TABLE(of, ads117x_dt_ids);
87#endif
88
78static struct platform_driver ads117x_codec_driver = {89static struct platform_driver ads117x_codec_driver = {
79 .driver = {90 .driver = {
80 .name = "ads117x-codec",91 .name = "ads117x-codec",
92 .of_match_table = of_match_ptr(ads117x_dt_ids),
81 },93 },
82 94
83 .probe = ads117x_probe,95 .probe = ads117x_probe,
sound/soc/codecs/arizona.c+21−50
@@ -1398,29 +1398,6 @@ static const int arizona_48k_bclk_rates[] = { · 1397 unmodified lines
1398 24576000,1398 24576000,
1399};1399};
1400 1400
1401static const unsigned int arizona_48k_rates[] = {
1402 12000,
1403 24000,
1404 48000,
1405 96000,
1406 192000,
1407 384000,
1408 768000,
1409 4000,
1410 8000,
1411 16000,
1412 32000,
1413 64000,
1414 128000,
1415 256000,
1416 512000,
1417};
1418
1419static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
1420 .count = ARRAY_SIZE(arizona_48k_rates),
1421 .list = arizona_48k_rates,
1422};
1423
1424static const int arizona_44k1_bclk_rates[] = {1401static const int arizona_44k1_bclk_rates[] = {
1425 -1,1402 -1,
1426 44100,1403 44100,
@@ -1443,22 +1420,7 @@ static const int arizona_44k1_bclk_rates[] = { · 16 unmodified lines
1443 22579200,1420 22579200,
1444};1421};
1445 1422
1446static const unsigned int arizona_44k1_rates[] = {1423static const unsigned int arizona_sr_vals[] = {
1447 11025,
1448 22050,
1449 44100,
1450 88200,
1451 176400,
1452 352800,
1453 705600,
1454};
1455
1456static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
1457 .count = ARRAY_SIZE(arizona_44k1_rates),
1458 .list = arizona_44k1_rates,
1459};
1460
1461static int arizona_sr_vals[] = {
1462 0,1424 0,
1463 12000,1425 12000,
1464 24000,1426 24000,
@@ -1485,13 +1447,21 @@ static int arizona_sr_vals[] = { · 20 unmodified lines
1485 512000,1447 512000,
1486};1448};
1487 1449
1450#define ARIZONA_48K_RATE_MASK 0x0F003E
1451#define ARIZONA_44K1_RATE_MASK 0x003E00
1452#define ARIZONA_RATE_MASK (ARIZONA_48K_RATE_MASK | ARIZONA_44K1_RATE_MASK)
1453
1454static const struct snd_pcm_hw_constraint_list arizona_constraint = {
1455 .count = ARRAY_SIZE(arizona_sr_vals),
1456 .list = arizona_sr_vals,
1457};
1458
1488static int arizona_startup(struct snd_pcm_substream *substream,1459static int arizona_startup(struct snd_pcm_substream *substream,
1489 struct snd_soc_dai *dai)1460 struct snd_soc_dai *dai)
1490{1461{
1491 struct snd_soc_codec *codec = dai->codec;1462 struct snd_soc_codec *codec = dai->codec;
1492 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);1463 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
1493 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];1464 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
1494 const struct snd_pcm_hw_constraint_list *constraint;
1495 unsigned int base_rate;1465 unsigned int base_rate;
1496 1466
1497 if (!substream->runtime)1467 if (!substream->runtime)
@@ -1509,16 +1479,15 @@ static int arizona_startup(struct snd_pcm_substream *substream, · 11 unmodified lines
1509 }1479 }
1510 1480
1511 if (base_rate == 0)1481 if (base_rate == 0)
1512 return 0;1482 dai_priv->constraint.mask = ARIZONA_RATE_MASK;
1513 1483 else if (base_rate % 8000)
1514 if (base_rate % 8000)1484 dai_priv->constraint.mask = ARIZONA_44K1_RATE_MASK;
1515 constraint = &arizona_44k1_constraint;
1516 else1485 else
1517 constraint = &arizona_48k_constraint;1486 dai_priv->constraint.mask = ARIZONA_48K_RATE_MASK;
1518 1487
1519 return snd_pcm_hw_constraint_list(substream->runtime, 0,1488 return snd_pcm_hw_constraint_list(substream->runtime, 0,
1520 SNDRV_PCM_HW_PARAM_RATE,1489 SNDRV_PCM_HW_PARAM_RATE,
1521 constraint);1490 &dai_priv->constraint);
1522}1491}
1523 1492
1524static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,1493static void arizona_wm5102_set_dac_comp(struct snd_soc_codec *codec,
@@ -1911,6 +1880,7 @@ int arizona_init_dai(struct arizona_priv *priv, int id) · 386 unmodified lines
1911 struct arizona_dai_priv *dai_priv = &priv->dai[id];1880 struct arizona_dai_priv *dai_priv = &priv->dai[id];
1912 1881
1913 dai_priv->clk = ARIZONA_CLK_SYSCLK;1882 dai_priv->clk = ARIZONA_CLK_SYSCLK;
1883 dai_priv->constraint = arizona_constraint;
1914 1884
1915 return 0;1885 return 0;
1916}1886}
@@ -2179,11 +2149,12 @@ static int arizona_calc_fll(struct arizona_fll *fll, · 262 unmodified lines
2179 return -EINVAL;2149 return -EINVAL;
2180 }2150 }
2181 2151
2182 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",2152 arizona_fll_dbg(fll, "N=%d THETA=%d LAMBDA=%d\n",
2183 cfg->n, cfg->theta, cfg->lambda);2153 cfg->n, cfg->theta, cfg->lambda);
2184 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",2154 arizona_fll_dbg(fll, "FRATIO=0x%x(%d) OUTDIV=%d REFCLK_DIV=0x%x(%d)\n",
2185 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);2155 cfg->fratio, ratio, cfg->outdiv,
2186 arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain);2156 cfg->refdiv, 1 << cfg->refdiv);
2157 arizona_fll_dbg(fll, "GAIN=0x%x(%d)\n", cfg->gain, 1 << cfg->gain);
2187 2158
2188 return 0;2159 return 0;
2189 2160
sound/soc/codecs/arizona.h+3−1
@@ -57,7 +57,7 @@ · 56 unmodified lines
57#define ARIZONA_CLK_98MHZ 557#define ARIZONA_CLK_98MHZ 5
58#define ARIZONA_CLK_147MHZ 658#define ARIZONA_CLK_147MHZ 6
59 59
60#define ARIZONA_MAX_DAI 860#define ARIZONA_MAX_DAI 10
61#define ARIZONA_MAX_ADSP 461#define ARIZONA_MAX_ADSP 4
62 62
63#define ARIZONA_DVFS_SR1_RQ 0x00163#define ARIZONA_DVFS_SR1_RQ 0x001
@@ -68,6 +68,8 @@ struct wm_adsp; · 4 unmodified lines
68 68
69struct arizona_dai_priv {69struct arizona_dai_priv {
70 int clk;70 int clk;
71
72 struct snd_pcm_hw_constraint_list constraint;
71};73};
72 74
73struct arizona_priv {75struct arizona_priv {
sound/soc/codecs/cs42xx8.c+8−2
@@ -44,6 +44,7 @@ struct cs42xx8_priv { · 43 unmodified lines
44 44
45 bool slave_mode;45 bool slave_mode;
46 unsigned long sysclk;46 unsigned long sysclk;
47 u32 tx_channels;
47};48};
48 49
49/* -127.5dB to 0dB with step of 0.5dB */50/* -127.5dB to 0dB with step of 0.5dB */
@@ -257,6 +258,9 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream, · 207 unmodified lines
257 u32 ratio = cs42xx8->sysclk / params_rate(params);258 u32 ratio = cs42xx8->sysclk / params_rate(params);
258 u32 i, fm, val, mask;259 u32 i, fm, val, mask;
259 260
261 if (tx)
262 cs42xx8->tx_channels = params_channels(params);
263
260 for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {264 for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
261 if (cs42xx8_ratios[i].ratio == ratio)265 if (cs42xx8_ratios[i].ratio == ratio)
262 break;266 break;
@@ -283,9 +287,11 @@ static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute) · 20 unmodified lines
283{287{
284 struct snd_soc_codec *codec = dai->codec;288 struct snd_soc_codec *codec = dai->codec;
285 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);289 struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
290 u8 dac_unmute = cs42xx8->tx_channels ?
291 ~((0x1 << cs42xx8->tx_channels) - 1) : 0;
286 292
287 regmap_update_bits(cs42xx8->regmap, CS42XX8_DACMUTE,293 regmap_write(cs42xx8->regmap, CS42XX8_DACMUTE,
288 CS42XX8_DACMUTE_ALL, mute ? CS42XX8_DACMUTE_ALL : 0);294 mute ? CS42XX8_DACMUTE_ALL : dac_unmute);
289 295
290 return 0;296 return 0;
291}297}
sound/soc/codecs/cs47l24.c+118−5
@@ -57,6 +57,25 @@ static const struct wm_adsp_region *cs47l24_dsp_regions[] = { · 56 unmodified lines
57 cs47l24_dsp3_regions,57 cs47l24_dsp3_regions,
58};58};
59 59
60static int cs47l24_adsp_power_ev(struct snd_soc_dapm_widget *w,
61 struct snd_kcontrol *kcontrol, int event)
62{
63 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
64 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
65 unsigned int v;
66 int ret;
67
68 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
69 if (ret != 0) {
70 dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
71 return ret;
72 }
73
74 v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
75
76 return wm_adsp2_early_event(w, kcontrol, event, v);
77}
78
60static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);79static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
61static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);80static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
62static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);81static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
@@ -405,8 +424,8 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0, · 342 unmodified lines
405SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,424SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
406 NULL, 0),425 NULL, 0),
407 426
408WM_ADSP2("DSP2", 1),427WM_ADSP2("DSP2", 1, cs47l24_adsp_power_ev),
409WM_ADSP2("DSP3", 2),428WM_ADSP2("DSP3", 2, cs47l24_adsp_power_ev),
410 429
411SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,430SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
412 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),431 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
@@ -779,6 +798,9 @@ static const struct snd_soc_dapm_route cs47l24_dapm_routes[] = { · 366 unmodified lines
779 { "AIF2 Capture", NULL, "SYSCLK" },798 { "AIF2 Capture", NULL, "SYSCLK" },
780 { "AIF3 Capture", NULL, "SYSCLK" },799 { "AIF3 Capture", NULL, "SYSCLK" },
781 800
801 { "Voice Control DSP", NULL, "DSP3" },
802 { "Voice Control DSP", NULL, "SYSCLK" },
803
782 { "IN1L PGA", NULL, "IN1L" },804 { "IN1L PGA", NULL, "IN1L" },
783 { "IN1R PGA", NULL, "IN1R" },805 { "IN1R PGA", NULL, "IN1R" },
784 806
@@ -901,7 +923,7 @@ static int cs47l24_set_fll(struct snd_soc_codec *codec, int fll_id, int source, · 116 unmodified lines
901 }923 }
902}924}
903 925
904#define CS47L24_RATES SNDRV_PCM_RATE_8000_192000926#define CS47L24_RATES SNDRV_PCM_RATE_KNOT
905 927
906#define CS47L24_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\928#define CS47L24_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
907 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)929 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -973,12 +995,68 @@ static struct snd_soc_dai_driver cs47l24_dai[] = { · 65 unmodified lines
973 .symmetric_rates = 1,995 .symmetric_rates = 1,
974 .symmetric_samplebits = 1,996 .symmetric_samplebits = 1,
975 },997 },
998 {
999 .name = "cs47l24-cpu-voicectrl",
1000 .capture = {
1001 .stream_name = "Voice Control CPU",
1002 .channels_min = 1,
1003 .channels_max = 1,
1004 .rates = CS47L24_RATES,
1005 .formats = CS47L24_FORMATS,
1006 },
1007 .compress_new = snd_soc_new_compress,
1008 },
1009 {
1010 .name = "cs47l24-dsp-voicectrl",
1011 .capture = {
1012 .stream_name = "Voice Control DSP",
1013 .channels_min = 1,
1014 .channels_max = 1,
1015 .rates = CS47L24_RATES,
1016 .formats = CS47L24_FORMATS,
1017 },
1018 },
976};1019};
977 1020
1021static int cs47l24_open(struct snd_compr_stream *stream)
1022{
1023 struct snd_soc_pcm_runtime *rtd = stream->private_data;
1024 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
1025 struct arizona *arizona = priv->core.arizona;
1026 int n_adsp;
1027
1028 if (strcmp(rtd->codec_dai->name, "cs47l24-dsp-voicectrl") == 0) {
1029 n_adsp = 2;
1030 } else {
1031 dev_err(arizona->dev,
1032 "No suitable compressed stream for DAI '%s'\n",
1033 rtd->codec_dai->name);
1034 return -EINVAL;
1035 }
1036
1037 return wm_adsp_compr_open(&priv->core.adsp[n_adsp], stream);
1038}
1039
1040static irqreturn_t cs47l24_adsp2_irq(int irq, void *data)
1041{
1042 struct cs47l24_priv *priv = data;
1043 struct arizona *arizona = priv->core.arizona;
1044 int ret;
1045
1046 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[2]);
1047 if (ret == -ENODEV) {
1048 dev_err(arizona->dev, "Spurious compressed data IRQ\n");
1049 return IRQ_NONE;
1050 }
1051
1052 return IRQ_HANDLED;
1053}
1054
978static int cs47l24_codec_probe(struct snd_soc_codec *codec)1055static int cs47l24_codec_probe(struct snd_soc_codec *codec)
979{1056{
980 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);1057 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
981 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);1058 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
1059 struct arizona *arizona = priv->core.arizona;
982 int ret;1060 int ret;
983 1061
984 priv->core.arizona->dapm = dapm;1062 priv->core.arizona->dapm = dapm;
@@ -987,6 +1065,14 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec) · 2 unmodified lines
987 arizona_init_gpio(codec);1065 arizona_init_gpio(codec);
988 arizona_init_mono(codec);1066 arizona_init_mono(codec);
989 1067
1068 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
1069 "ADSP2 Compressed IRQ", cs47l24_adsp2_irq,
1070 priv);
1071 if (ret != 0) {
1072 dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
1073 return ret;
1074 }
1075
990 ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);1076 ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
991 if (ret)1077 if (ret)
992 goto err_adsp2_codec_probe;1078 goto err_adsp2_codec_probe;
@@ -1014,13 +1100,14 @@ err_adsp2_codec_probe: · 21 unmodified lines
1014static int cs47l24_codec_remove(struct snd_soc_codec *codec)1100static int cs47l24_codec_remove(struct snd_soc_codec *codec)
1015{1101{
1016 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);1102 struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec);
1017 1103 struct arizona *arizona = priv->core.arizona;
1018 1104
1019 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);1105 wm_adsp2_codec_remove(&priv->core.adsp[1], codec);
1020 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);1106 wm_adsp2_codec_remove(&priv->core.adsp[2], codec);
1021 1107
1022 priv->core.arizona->dapm = NULL;1108 priv->core.arizona->dapm = NULL;
1023 1109
1110 arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv);
1024 return 0;1111 return 0;
1025}1112}
1026 1113
@@ -1057,6 +1144,19 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { · 30 unmodified lines
1057 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),1144 .num_dapm_routes = ARRAY_SIZE(cs47l24_dapm_routes),
1058};1145};
1059 1146
1147static struct snd_compr_ops cs47l24_compr_ops = {
1148 .open = cs47l24_open,
1149 .free = wm_adsp_compr_free,
1150 .set_params = wm_adsp_compr_set_params,
1151 .get_caps = wm_adsp_compr_get_caps,
1152 .trigger = wm_adsp_compr_trigger,
1153 .pointer = wm_adsp_compr_pointer,
1154 .copy = wm_adsp_compr_copy,
1155};
1156
1157static struct snd_soc_platform_driver cs47l24_compr_platform = {
1158 .compr_ops = &cs47l24_compr_ops,
1159};
1060static int cs47l24_probe(struct platform_device *pdev)1160static int cs47l24_probe(struct platform_device *pdev)
1061{1161{
1062 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);1162 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -1120,12 +1220,25 @@ static int cs47l24_probe(struct platform_device *pdev) · 57 unmodified lines
1120 pm_runtime_enable(&pdev->dev);1220 pm_runtime_enable(&pdev->dev);
1121 pm_runtime_idle(&pdev->dev);1221 pm_runtime_idle(&pdev->dev);
1122 1222
1123 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,1223 ret = snd_soc_register_platform(&pdev->dev, &cs47l24_compr_platform);
1224 if (ret < 0) {
1225 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
1226 return ret;
1227 }
1228 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_cs47l24,
1124 cs47l24_dai, ARRAY_SIZE(cs47l24_dai));1229 cs47l24_dai, ARRAY_SIZE(cs47l24_dai));
1230
1231 if (ret < 0) {
1232 dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
1233 snd_soc_unregister_platform(&pdev->dev);
1234 }
1235
1236 return ret;
1125}1237}
1126 1238
1127static int cs47l24_remove(struct platform_device *pdev)1239static int cs47l24_remove(struct platform_device *pdev)
1128{1240{
1241 snd_soc_unregister_platform(&pdev->dev);
1129 snd_soc_unregister_codec(&pdev->dev);1242 snd_soc_unregister_codec(&pdev->dev);
1130 pm_runtime_disable(&pdev->dev);1243 pm_runtime_disable(&pdev->dev);
1131 1244
sound/soc/codecs/hdac_hdmi.c+1096−123
@@ -22,11 +22,17 @@ · 21 unmodified lines
22#include <linux/module.h>22#include <linux/module.h>
23#include <linux/pm_runtime.h>23#include <linux/pm_runtime.h>
24#include <linux/hdmi.h>24#include <linux/hdmi.h>
25#include <drm/drm_edid.h>
25#include <sound/pcm_params.h>26#include <sound/pcm_params.h>
27#include <sound/jack.h>
26#include <sound/soc.h>28#include <sound/soc.h>
27#include <sound/hdaudio_ext.h>29#include <sound/hdaudio_ext.h>
28#include <sound/hda_i915.h>30#include <sound/hda_i915.h>
31#include <sound/pcm_drm_eld.h>
29#include "../../hda/local.h"32#include "../../hda/local.h"
33#include "hdac_hdmi.h"
34
35#define NAME_SIZE 32
30 36
31#define AMP_OUT_MUTE 0xb08037#define AMP_OUT_MUTE 0xb080
32#define AMP_OUT_UNMUTE 0xb00038#define AMP_OUT_UNMUTE 0xb000
@@ -34,6 +40,11 @@ · 1 unmodified line
34 40
35#define HDA_MAX_CONNECTIONS 3241#define HDA_MAX_CONNECTIONS 32
36 42
43#define HDA_MAX_CVTS 3
44
45#define ELD_MAX_SIZE 256
46#define ELD_FIXED_BYTES 20
47
37struct hdac_hdmi_cvt_params {48struct hdac_hdmi_cvt_params {
38 unsigned int channels_min;49 unsigned int channels_min;
39 unsigned int channels_max;50 unsigned int channels_max;
@@ -45,14 +56,34 @@ struct hdac_hdmi_cvt_params { · 5 unmodified lines
45struct hdac_hdmi_cvt {56struct hdac_hdmi_cvt {
46 struct list_head head;57 struct list_head head;
47 hda_nid_t nid;58 hda_nid_t nid;
59 const char *name;
48 struct hdac_hdmi_cvt_params params;60 struct hdac_hdmi_cvt_params params;
49};61};
50 62
63struct hdac_hdmi_eld {
64 bool monitor_present;
65 bool eld_valid;
66 int eld_size;
67 char eld_buffer[ELD_MAX_SIZE];
68};
69
51struct hdac_hdmi_pin {70struct hdac_hdmi_pin {
52 struct list_head head;71 struct list_head head;
53 hda_nid_t nid;72 hda_nid_t nid;
54 int num_mux_nids;73 int num_mux_nids;
55 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];74 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
75 struct hdac_hdmi_eld eld;
76 struct hdac_ext_device *edev;
77 int repoll_count;
78 struct delayed_work work;
79};
80
81struct hdac_hdmi_pcm {
82 struct list_head head;
83 int pcm_id;
84 struct hdac_hdmi_pin *pin;
85 struct hdac_hdmi_cvt *cvt;
86 struct snd_jack *jack;
56};87};
57 88
58struct hdac_hdmi_dai_pin_map {89struct hdac_hdmi_dai_pin_map {
@@ -62,11 +93,13 @@ struct hdac_hdmi_dai_pin_map { · 3 unmodified lines
62};93};
63 94
64struct hdac_hdmi_priv {95struct hdac_hdmi_priv {
65 struct hdac_hdmi_dai_pin_map dai_map[3];96 struct hdac_hdmi_dai_pin_map dai_map[HDA_MAX_CVTS];
66 struct list_head pin_list;97 struct list_head pin_list;
67 struct list_head cvt_list;98 struct list_head cvt_list;
99 struct list_head pcm_list;
68 int num_pin;100 int num_pin;
69 int num_cvt;101 int num_cvt;
102 struct mutex pin_mutex;
70};103};
71 104
72static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)105static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev)
@@ -76,6 +109,119 @@ static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev) · 3 unmodified lines
76 return to_ehdac_device(hdac);109 return to_ehdac_device(hdac);
77}110}
78 111
112static unsigned int sad_format(const u8 *sad)
113{
114 return ((sad[0] >> 0x3) & 0x1f);
115}
116
117static unsigned int sad_sample_bits_lpcm(const u8 *sad)
118{
119 return (sad[2] & 7);
120}
121
122static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
123 void *eld)
124{
125 u64 formats = SNDRV_PCM_FMTBIT_S16;
126 int i;
127 const u8 *sad, *eld_buf = eld;
128
129 sad = drm_eld_sad(eld_buf);
130 if (!sad)
131 goto format_constraint;
132
133 for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
134 if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */
135
136 /*
137 * the controller support 20 and 24 bits in 32 bit
138 * container so we set S32
139 */
140 if (sad_sample_bits_lpcm(sad) & 0x6)
141 formats |= SNDRV_PCM_FMTBIT_S32;
142 }
143 }
144
145format_constraint:
146 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
147 formats);
148
149}
150
151 /* HDMI ELD routines */
152static unsigned int hdac_hdmi_get_eld_data(struct hdac_device *codec,
153 hda_nid_t nid, int byte_index)
154{
155 unsigned int val;
156
157 val = snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD,
158 byte_index);
159
160 dev_dbg(&codec->dev, "HDMI: ELD data byte %d: 0x%x\n",
161 byte_index, val);
162
163 return val;
164}
165
166static int hdac_hdmi_get_eld_size(struct hdac_device *codec, hda_nid_t nid)
167{
168 return snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
169 AC_DIPSIZE_ELD_BUF);
170}
171
172/*
173 * This function queries the ELD size and ELD data and fills in the buffer
174 * passed by user
175 */
176static int hdac_hdmi_get_eld(struct hdac_device *codec, hda_nid_t nid,
177 unsigned char *buf, int *eld_size)
178{
179 int i, size, ret = 0;
180
181 /*
182 * ELD size is initialized to zero in caller function. If no errors and
183 * ELD is valid, actual eld_size is assigned.
184 */
185
186 size = hdac_hdmi_get_eld_size(codec, nid);
187 if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
188 dev_err(&codec->dev, "HDMI: invalid ELD buf size %d\n", size);
189 return -ERANGE;
190 }
191
192 /* set ELD buffer */
193 for (i = 0; i < size; i++) {
194 unsigned int val = hdac_hdmi_get_eld_data(codec, nid, i);
195 /*
196 * Graphics driver might be writing to ELD buffer right now.
197 * Just abort. The caller will repoll after a while.
198 */
199 if (!(val & AC_ELDD_ELD_VALID)) {
200 dev_err(&codec->dev,
201 "HDMI: invalid ELD data byte %d\n", i);
202 ret = -EINVAL;
203 goto error;
204 }
205 val &= AC_ELDD_ELD_DATA;
206 /*
207 * The first byte cannot be zero. This can happen on some DVI
208 * connections. Some Intel chips may also need some 250ms delay
209 * to return non-zero ELD data, even when the graphics driver
210 * correctly writes ELD content before setting ELD_valid bit.
211 */
212 if (!val && !i) {
213 dev_err(&codec->dev, "HDMI: 0 ELD data\n");
214 ret = -EINVAL;
215 goto error;
216 }
217 buf[i] = val;
218 }
219
220 *eld_size = size;
221error:
222 return ret;
223}
224
79static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,225static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
80 hda_nid_t cvt_nid, hda_nid_t pin_nid,226 hda_nid_t cvt_nid, hda_nid_t pin_nid,
81 u32 stream_tag, int format)227 u32 stream_tag, int format)
@@ -107,27 +253,74 @@ hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid, · 25 unmodified lines
107 AC_VERB_SET_HDMI_DIP_INDEX, val);253 AC_VERB_SET_HDMI_DIP_INDEX, val);
108}254}
109 255
256struct dp_audio_infoframe {
257 u8 type; /* 0x84 */
258 u8 len; /* 0x1b */
259 u8 ver; /* 0x11 << 2 */
260
261 u8 CC02_CT47; /* match with HDMI infoframe from this on */
262 u8 SS01_SF24;
263 u8 CXT04;
264 u8 CA;
265 u8 LFEPBL01_LSV36_DM_INH7;
266};
267
110static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,268static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
111 hda_nid_t cvt_nid, hda_nid_t pin_nid)269 hda_nid_t cvt_nid, hda_nid_t pin_nid)
112{270{
113 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];271 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
114 struct hdmi_audio_infoframe frame;272 struct hdmi_audio_infoframe frame;
115 u8 *dip = (u8 *)&frame;273 struct dp_audio_infoframe dp_ai;
274 struct hdac_hdmi_priv *hdmi = hdac->private_data;
275 struct hdac_hdmi_pin *pin;
276 u8 *dip;
116 int ret;277 int ret;
117 int i;278 int i;
279 const u8 *eld_buf;
280 u8 conn_type;
281 int channels = 2;
118 282
119 hdmi_audio_infoframe_init(&frame);283 list_for_each_entry(pin, &hdmi->pin_list, head) {
284 if (pin->nid == pin_nid)
285 break;
286 }
120 287
121 /* Default stereo for now */288 eld_buf = pin->eld.eld_buffer;
122 frame.channels = 2;289 conn_type = drm_eld_get_conn_type(eld_buf);
123 290
124 /* setup channel count */291 /* setup channel count */
125 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,292 snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
126 AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);293 AC_VERB_SET_CVT_CHAN_COUNT, channels - 1);
127 294
128 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));295 switch (conn_type) {
129 if (ret < 0)296 case DRM_ELD_CONN_TYPE_HDMI:
130 return ret;297 hdmi_audio_infoframe_init(&frame);
298
299 /* Default stereo for now */
300 frame.channels = channels;
301
302 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
303 if (ret < 0)
304 return ret;
305
306 break;
307
308 case DRM_ELD_CONN_TYPE_DP:
309 memset(&dp_ai, 0, sizeof(dp_ai));
310 dp_ai.type = 0x84;
311 dp_ai.len = 0x1b;
312 dp_ai.ver = 0x11 << 2;
313 dp_ai.CC02_CT47 = channels - 1;
314 dp_ai.CA = 0;
315
316 dip = (u8 *)&dp_ai;
317 break;
318
319 default:
320 dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n",
321 conn_type);
322 return -EIO;
323 }
131 324
132 /* stop infoframe transmission */325 /* stop infoframe transmission */
133 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);326 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
@@ -137,9 +330,15 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, · 3 unmodified lines
137 330
138 /* Fill infoframe. Index auto-incremented */331 /* Fill infoframe. Index auto-incremented */
139 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);332 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
140 for (i = 0; i < sizeof(frame); i++)333 if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
141 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,334 for (i = 0; i < sizeof(buffer); i++)
335 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
336 AC_VERB_SET_HDMI_DIP_DATA, buffer[i]);
337 } else {
338 for (i = 0; i < sizeof(dp_ai); i++)
339 snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
142 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);340 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
341 }
143 342
144 /* Start infoframe */343 /* Start infoframe */
145 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);344 hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
@@ -174,11 +373,6 @@ static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream, · 28 unmodified lines
174 struct hdac_ext_dma_params *dd;373 struct hdac_ext_dma_params *dd;
175 int ret;374 int ret;
176 375
177 if (dai->id > 0) {
178 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
179 return -ENODEV;
180 }
181
182 dai_map = &hdmi->dai_map[dai->id];376 dai_map = &hdmi->dai_map[dai->id];
183 377
184 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);378 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
@@ -198,16 +392,30 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, · 13 unmodified lines
198 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)392 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
199{393{
200 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);394 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
395 struct hdac_hdmi_priv *hdmi = hdac->private_data;
396 struct hdac_hdmi_dai_pin_map *dai_map;
397 struct hdac_hdmi_pin *pin;
201 struct hdac_ext_dma_params *dd;398 struct hdac_ext_dma_params *dd;
202 399
203 if (dai->id > 0) {400 dai_map = &hdmi->dai_map[dai->id];
204 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");401 pin = dai_map->pin;
402
403 if (!pin)
404 return -ENODEV;
405
406 if ((!pin->eld.monitor_present) || (!pin->eld.eld_valid)) {
407 dev_err(&hdac->hdac.dev, "device is not configured for this pin: %d\n",
408 pin->nid);
205 return -ENODEV;409 return -ENODEV;
206 }410 }
207 411
208 dd = kzalloc(sizeof(*dd), GFP_KERNEL);412 dd = snd_soc_dai_get_dma_data(dai, substream);
209 if (!dd)413 if (!dd) {
210 return -ENOMEM;414 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
415 if (!dd)
416 return -ENOMEM;
417 }
418
211 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),419 dd->format = snd_hdac_calc_stream_format(params_rate(hparams),
212 params_channels(hparams), params_format(hparams),420 params_channels(hparams), params_format(hparams),
213 24, 0);421 24, 0);
@@ -227,50 +435,187 @@ static int hdac_hdmi_playback_cleanup(struct snd_pcm_substream *substream, · 13 unmodified lines
227 435
228 dai_map = &hdmi->dai_map[dai->id];436 dai_map = &hdmi->dai_map[dai->id];
229 437
438 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);
439
440 if (dd) {
441 snd_soc_dai_set_dma_data(dai, substream, NULL);
442 kfree(dd);
443 }
444
445 return 0;
446}
447
448static void hdac_hdmi_enable_cvt(struct hdac_ext_device *edev,
449 struct hdac_hdmi_dai_pin_map *dai_map)
450{
451 /* Enable transmission */
230 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,452 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 0);453 AC_VERB_SET_DIGI_CONVERT_1, 1);
454
455 /* Category Code (CC) to zero */
232 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,456 snd_hdac_codec_write(&edev->hdac, dai_map->cvt->nid, 0,
233 AC_VERB_SET_STREAM_FORMAT, 0);457 AC_VERB_SET_DIGI_CONVERT_2, 0);
458}
234 459
235 dd = (struct hdac_ext_dma_params *)snd_soc_dai_get_dma_data(dai, substream);460static int hdac_hdmi_enable_pin(struct hdac_ext_device *hdac,
236 snd_soc_dai_set_dma_data(dai, substream, NULL);461 struct hdac_hdmi_dai_pin_map *dai_map)
462{
463 int mux_idx;
464 struct hdac_hdmi_pin *pin = dai_map->pin;
465
466 for (mux_idx = 0; mux_idx < pin->num_mux_nids; mux_idx++) {
467 if (pin->mux_nids[mux_idx] == dai_map->cvt->nid) {
468 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
469 AC_VERB_SET_CONNECT_SEL, mux_idx);
470 break;
471 }
472 }
473
474 if (mux_idx == pin->num_mux_nids)
475 return -EIO;
476
477 /* Enable out path for this pin widget */
478 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
479 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
237 480
238 kfree(dd);481 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);
482
483 snd_hdac_codec_write(&hdac->hdac, pin->nid, 0,
484 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
239 485
240 return 0;486 return 0;
241}487}
242 488
489static int hdac_hdmi_query_pin_connlist(struct hdac_ext_device *hdac,
490 struct hdac_hdmi_pin *pin)
491{
492 if (!(get_wcaps(&hdac->hdac, pin->nid) & AC_WCAP_CONN_LIST)) {
493 dev_warn(&hdac->hdac.dev,
494 "HDMI: pin %d wcaps %#x does not support connection list\n",
495 pin->nid, get_wcaps(&hdac->hdac, pin->nid));
496 return -EINVAL;
497 }
498
499 pin->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid,
500 pin->mux_nids, HDA_MAX_CONNECTIONS);
501 if (pin->num_mux_nids == 0)
502 dev_warn(&hdac->hdac.dev, "No connections found for pin: %d\n",
503 pin->nid);
504
505 dev_dbg(&hdac->hdac.dev, "num_mux_nids %d for pin: %d\n",
506 pin->num_mux_nids, pin->nid);
507
508 return pin->num_mux_nids;
509}
510
511/*
512 * Query pcm list and return pin widget to which stream is routed.
513 *
514 * Also query connection list of the pin, to validate the cvt to pin map.
515 *
516 * Same stream rendering to multiple pins simultaneously can be done
517 * possibly, but not supported for now in driver. So return the first pin
518 * connected.
519 */
520static struct hdac_hdmi_pin *hdac_hdmi_get_pin_from_cvt(
521 struct hdac_ext_device *edev,
522 struct hdac_hdmi_priv *hdmi,
523 struct hdac_hdmi_cvt *cvt)
524{
525 struct hdac_hdmi_pcm *pcm;
526 struct hdac_hdmi_pin *pin = NULL;
527 int ret, i;
528
529 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
530 if (pcm->cvt == cvt) {
531 pin = pcm->pin;
532 break;
533 }
534 }
535
536 if (pin) {
537 ret = hdac_hdmi_query_pin_connlist(edev, pin);
538 if (ret < 0)
539 return NULL;
540
541 for (i = 0; i < pin->num_mux_nids; i++) {
542 if (pin->mux_nids[i] == cvt->nid)
543 return pin;
544 }
545 }
546
547 return NULL;
548}
549
550/*
551 * This tries to get a valid pin and set the HW constraints based on the
552 * ELD. Even if a valid pin is not found return success so that device open
553 * doesn't fail.
554 */
243static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,555static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
244 struct snd_soc_dai *dai)556 struct snd_soc_dai *dai)
245{557{
246 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);558 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
247 struct hdac_hdmi_priv *hdmi = hdac->private_data;559 struct hdac_hdmi_priv *hdmi = hdac->private_data;
248 struct hdac_hdmi_dai_pin_map *dai_map;560 struct hdac_hdmi_dai_pin_map *dai_map;
249 int val;561 struct hdac_hdmi_cvt *cvt;
250 562 struct hdac_hdmi_pin *pin;
251 if (dai->id > 0) {563 int ret;
252 dev_err(&hdac->hdac.dev, "Only one dai supported as of now\n");
253 return -ENODEV;
254 }
255 564
256 dai_map = &hdmi->dai_map[dai->id];565 dai_map = &hdmi->dai_map[dai->id];
257 566
258 val = snd_hdac_codec_read(&hdac->hdac, dai_map->pin->nid, 0,567 cvt = dai_map->cvt;
259 AC_VERB_GET_PIN_SENSE, 0);568 pin = hdac_hdmi_get_pin_from_cvt(hdac, hdmi, cvt);
260 dev_info(&hdac->hdac.dev, "Val for AC_VERB_GET_PIN_SENSE: %x\n", val);
261 569
262 if ((!(val & AC_PINSENSE_PRESENCE)) || (!(val & AC_PINSENSE_ELDV))) {570 /*
263 dev_err(&hdac->hdac.dev, "Monitor presence invalid with val: %x\n", val);571 * To make PA and other userland happy.
264 return -ENODEV;572 * userland scans devices so returning error does not help.
573 */
574 if (!pin)
575 return 0;
576
577 if ((!pin->eld.monitor_present) ||
578 (!pin->eld.eld_valid)) {
579
580 dev_warn(&hdac->hdac.dev,
581 "Failed: montior present? %d ELD valid?: %d for pin: %d\n",
582 pin->eld.monitor_present, pin->eld.eld_valid, pin->nid);
583
584 return 0;
265 }585 }
266 586
267 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D0);587 dai_map->pin = pin;
268 588
269 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,589 hdac_hdmi_enable_cvt(hdac, dai_map);
270 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);590 ret = hdac_hdmi_enable_pin(hdac, dai_map);
591 if (ret < 0)
592 return ret;
271 593
272 snd_pcm_hw_constraint_step(substream->runtime, 0,594 ret = hdac_hdmi_eld_limit_formats(substream->runtime,
273 SNDRV_PCM_HW_PARAM_CHANNELS, 2);595 pin->eld.eld_buffer);
596 if (ret < 0)
597 return ret;
598
599 return snd_pcm_hw_constraint_eld(substream->runtime,
600 pin->eld.eld_buffer);
601}
602
603static int hdac_hdmi_trigger(struct snd_pcm_substream *substream, int cmd,
604 struct snd_soc_dai *dai)
605{
606 struct hdac_hdmi_dai_pin_map *dai_map;
607 struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai);
608 struct hdac_hdmi_priv *hdmi = hdac->private_data;
609 int ret;
610
611 dai_map = &hdmi->dai_map[dai->id];
612 if (cmd == SNDRV_PCM_TRIGGER_RESUME) {
613 ret = hdac_hdmi_enable_pin(hdac, dai_map);
614 if (ret < 0)
615 return ret;
616
617 return hdac_hdmi_playback_prepare(substream, dai);
618 }
274 619
275 return 0;620 return 0;
276}621}
@@ -284,10 +629,19 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, · 7 unmodified lines
284 629
285 dai_map = &hdmi->dai_map[dai->id];630 dai_map = &hdmi->dai_map[dai->id];
286 631
287 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);632 if (dai_map->pin) {
633 snd_hdac_codec_write(&hdac->hdac, dai_map->cvt->nid, 0,
634 AC_VERB_SET_CHANNEL_STREAMID, 0);
635 snd_hdac_codec_write(&hdac->hdac, dai_map->cvt->nid, 0,
636 AC_VERB_SET_STREAM_FORMAT, 0);
637
638 hdac_hdmi_set_power_state(hdac, dai_map, AC_PWRST_D3);
288 639
289 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,640 snd_hdac_codec_write(&hdac->hdac, dai_map->pin->nid, 0,
290 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);641 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
642
643 dai_map->pin = NULL;
644 }
291}645}
292 646
293static int647static int
@@ -310,85 +664,326 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt) · 16 unmodified lines
310 return err;664 return err;
311}665}
312 666
313static void hdac_hdmi_fill_widget_info(struct snd_soc_dapm_widget *w,667static int hdac_hdmi_fill_widget_info(struct device *dev,
314 enum snd_soc_dapm_type id,668 struct snd_soc_dapm_widget *w,
315 const char *wname, const char *stream)669 enum snd_soc_dapm_type id, void *priv,
670 const char *wname, const char *stream,
671 struct snd_kcontrol_new *wc, int numkc)
316{672{
317 w->id = id;673 w->id = id;
318 w->name = wname;674 w->name = devm_kstrdup(dev, wname, GFP_KERNEL);
675 if (!w->name)
676 return -ENOMEM;
677
319 w->sname = stream;678 w->sname = stream;
320 w->reg = SND_SOC_NOPM;679 w->reg = SND_SOC_NOPM;
321 w->shift = 0;680 w->shift = 0;
322 w->kcontrol_news = NULL;681 w->kcontrol_news = wc;
323 w->num_kcontrols = 0;682 w->num_kcontrols = numkc;
324 w->priv = NULL;683 w->priv = priv;
684
685 return 0;
325}686}
326 687
327static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,688static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
328 const char *sink, const char *control, const char *src)689 const char *sink, const char *control, const char *src,
690 int (*handler)(struct snd_soc_dapm_widget *src,
691 struct snd_soc_dapm_widget *sink))
329{692{
330 route->sink = sink;693 route->sink = sink;
331 route->source = src;694 route->source = src;
332 route->control = control;695 route->control = control;
333 route->connected = NULL;696 route->connected = handler;
334}697}
335 698
336static void create_fill_widget_route_map(struct snd_soc_dapm_context *dapm,699static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev,
337 struct hdac_hdmi_dai_pin_map *dai_map)700 struct hdac_hdmi_pin *pin)
338{701{
339 struct snd_soc_dapm_route route[1];702 struct hdac_hdmi_priv *hdmi = edev->private_data;
340 struct snd_soc_dapm_widget widgets[2] = { {0} };703 struct hdac_hdmi_pcm *pcm = NULL;
341 704
342 memset(&route, 0, sizeof(route));705 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
706 if (pcm->pin == pin)
707 return pcm;
708 }
343 709
344 hdac_hdmi_fill_widget_info(&widgets[0], snd_soc_dapm_output,710 return NULL;
345 "hif1 Output", NULL);711}
346 hdac_hdmi_fill_widget_info(&widgets[1], snd_soc_dapm_aif_in,
347 "Coverter 1", "hif1");
348 712
349 hdac_hdmi_fill_route(&route[0], "hif1 Output", NULL, "Coverter 1");713/*
714 * Based on user selection, map the PINs with the PCMs.
715 */
716static int hdac_hdmi_set_pin_mux(struct snd_kcontrol *kcontrol,
717 struct snd_ctl_elem_value *ucontrol)
718{
719 int ret;
720 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
721 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
722 struct snd_soc_dapm_context *dapm = w->dapm;
723 struct hdac_hdmi_pin *pin = w->priv;
724 struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
725 struct hdac_hdmi_priv *hdmi = edev->private_data;
726 struct hdac_hdmi_pcm *pcm = NULL;
727 const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]];
350 728
351 snd_soc_dapm_new_controls(dapm, widgets, ARRAY_SIZE(widgets));729 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
352 snd_soc_dapm_add_routes(dapm, route, ARRAY_SIZE(route));730 if (ret < 0)
731 return ret;
732
733 mutex_lock(&hdmi->pin_mutex);
734 list_for_each_entry(pcm, &hdmi->pcm_list, head) {
735 if (pcm->pin == pin)
736 pcm->pin = NULL;
737
738 /*
739 * Jack status is not reported during device probe as the
740 * PCMs are not registered by then. So report it here.
741 */
742 if (!strcmp(cvt_name, pcm->cvt->name) && !pcm->pin) {
743 pcm->pin = pin;
744 if (pin->eld.monitor_present && pin->eld.eld_valid) {
745 dev_dbg(&edev->hdac.dev,
746 "jack report for pcm=%d\n",
747 pcm->pcm_id);
748
749 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
750 }
751 mutex_unlock(&hdmi->pin_mutex);
752 return ret;
753 }
754 }
755 mutex_unlock(&hdmi->pin_mutex);
756
757 return ret;
353}758}
354 759
355static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)760/*
761 * Ideally the Mux inputs should be based on the num_muxs enumerated, but
762 * the display driver seem to be programming the connection list for the pin
763 * widget runtime.
764 *
765 * So programming all the possible inputs for the mux, the user has to take
766 * care of selecting the right one and leaving all other inputs selected to
767 * "NONE"
768 */
769static int hdac_hdmi_create_pin_muxs(struct hdac_ext_device *edev,
770 struct hdac_hdmi_pin *pin,
771 struct snd_soc_dapm_widget *widget,
772 const char *widget_name)
773{
774 struct hdac_hdmi_priv *hdmi = edev->private_data;
775 struct snd_kcontrol_new *kc;
776 struct hdac_hdmi_cvt *cvt;
777 struct soc_enum *se;
778 char kc_name[NAME_SIZE];
779 char mux_items[NAME_SIZE];
780 /* To hold inputs to the Pin mux */
781 char *items[HDA_MAX_CONNECTIONS];
782 int i = 0;
783 int num_items = hdmi->num_cvt + 1;
784
785 kc = devm_kzalloc(&edev->hdac.dev, sizeof(*kc), GFP_KERNEL);
786 if (!kc)
787 return -ENOMEM;
788
789 se = devm_kzalloc(&edev->hdac.dev, sizeof(*se), GFP_KERNEL);
790 if (!se)
791 return -ENOMEM;
792
793 sprintf(kc_name, "Pin %d Input", pin->nid);
794 kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
795 if (!kc->name)
796 return -ENOMEM;
797
798 kc->private_value = (long)se;
799 kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
800 kc->access = 0;
801 kc->info = snd_soc_info_enum_double;
802 kc->put = hdac_hdmi_set_pin_mux;
803 kc->get = snd_soc_dapm_get_enum_double;
804
805 se->reg = SND_SOC_NOPM;
806
807 /* enum texts: ["NONE", "cvt #", "cvt #", ...] */
808 se->items = num_items;
809 se->mask = roundup_pow_of_two(se->items) - 1;
810
811 sprintf(mux_items, "NONE");
812 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
813 if (!items[i])
814 return -ENOMEM;
815
816 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
817 i++;
818 sprintf(mux_items, "cvt %d", cvt->nid);
819 items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL);
820 if (!items[i])
821 return -ENOMEM;
822 }
823
824 se->texts = devm_kmemdup(&edev->hdac.dev, items,
825 (num_items * sizeof(char *)), GFP_KERNEL);
826 if (!se->texts)
827 return -ENOMEM;
828
829 return hdac_hdmi_fill_widget_info(&edev->hdac.dev, widget,
830 snd_soc_dapm_mux, pin, widget_name, NULL, kc, 1);
831}
832
833/* Add cvt <- input <- mux route map */
834static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_ext_device *edev,
835 struct snd_soc_dapm_widget *widgets,
836 struct snd_soc_dapm_route *route, int rindex)
837{
838 struct hdac_hdmi_priv *hdmi = edev->private_data;
839 const struct snd_kcontrol_new *kc;
840 struct soc_enum *se;
841 int mux_index = hdmi->num_cvt + hdmi->num_pin;
842 int i, j;
843
844 for (i = 0; i < hdmi->num_pin; i++) {
845 kc = widgets[mux_index].kcontrol_news;
846 se = (struct soc_enum *)kc->private_value;
847 for (j = 0; j < hdmi->num_cvt; j++) {
848 hdac_hdmi_fill_route(&route[rindex],
849 widgets[mux_index].name,
850 se->texts[j + 1],
851 widgets[j].name, NULL);
852
853 rindex++;
854 }
855
856 mux_index++;
857 }
858}
859
860/*
861 * Widgets are added in the below sequence
862 * Converter widgets for num converters enumerated
863 * Pin widgets for num pins enumerated
864 * Pin mux widgets to represent connenction list of pin widget
865 *
866 * Total widgets elements = num_cvt + num_pin + num_pin;
867 *
868 * Routes are added as below:
869 * pin mux -> pin (based on num_pins)
870 * cvt -> "Input sel control" -> pin_mux
871 *
872 * Total route elements:
873 * num_pins + (pin_muxes * num_cvt)
874 */
875static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
356{876{
877 struct snd_soc_dapm_widget *widgets;
878 struct snd_soc_dapm_route *route;
879 struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev);
357 struct hdac_hdmi_priv *hdmi = edev->private_data;880 struct hdac_hdmi_priv *hdmi = edev->private_data;
358 struct hdac_hdmi_dai_pin_map *dai_map = &hdmi->dai_map[0];881 struct snd_soc_dai_driver *dai_drv = dapm->component->dai_drv;
882 char widget_name[NAME_SIZE];
359 struct hdac_hdmi_cvt *cvt;883 struct hdac_hdmi_cvt *cvt;
360 struct hdac_hdmi_pin *pin;884 struct hdac_hdmi_pin *pin;
885 int ret, i = 0, num_routes = 0;
361 886
362 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))887 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))
363 return -EINVAL;888 return -EINVAL;
364 889
365 /*890 widgets = devm_kzalloc(dapm->dev,
366 * Currently on board only 1 pin and 1 converter is enabled for891 (sizeof(*widgets) * ((2 * hdmi->num_pin) + hdmi->num_cvt)),
367 * simplification, more will be added eventually892 GFP_KERNEL);
368 * So using fixed map for dai_id:pin:cvt
369 */
370 cvt = list_first_entry(&hdmi->cvt_list, struct hdac_hdmi_cvt, head);
371 pin = list_first_entry(&hdmi->pin_list, struct hdac_hdmi_pin, head);
372 893
373 dai_map->dai_id = 0;894 if (!widgets)
374 dai_map->pin = pin;895 return -ENOMEM;
375 896
376 dai_map->cvt = cvt;897 /* DAPM widgets to represent each converter widget */
898 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
899 sprintf(widget_name, "Converter %d", cvt->nid);
900 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
901 snd_soc_dapm_aif_in, &cvt->nid,
902 widget_name, dai_drv[i].playback.stream_name, NULL, 0);
903 if (ret < 0)
904 return ret;
905 i++;
906 }
377 907
378 /* Enable out path for this pin widget */908 list_for_each_entry(pin, &hdmi->pin_list, head) {
379 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,909 sprintf(widget_name, "hif%d Output", pin->nid);
380 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);910 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],
911 snd_soc_dapm_output, &pin->nid,
912 widget_name, NULL, NULL, 0);
913 if (ret < 0)
914 return ret;
915 i++;
916 }
381 917
382 /* Enable transmission */918 /* DAPM widgets to represent the connection list to pin widget */
383 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,919 list_for_each_entry(pin, &hdmi->pin_list, head) {
384 AC_VERB_SET_DIGI_CONVERT_1, 1);920 sprintf(widget_name, "Pin %d Mux", pin->nid);
921 ret = hdac_hdmi_create_pin_muxs(edev, pin, &widgets[i],
922 widget_name);
923 if (ret < 0)
924 return ret;
925 i++;
385 926
386 /* Category Code (CC) to zero */927 /* For cvt to pin_mux mapping */
387 snd_hdac_codec_write(&edev->hdac, cvt->nid, 0,928 num_routes += hdmi->num_cvt;
388 AC_VERB_SET_DIGI_CONVERT_2, 0);929
930 /* For pin_mux to pin mapping */
931 num_routes++;
932 }
389 933
390 snd_hdac_codec_write(&edev->hdac, pin->nid, 0,934 route = devm_kzalloc(dapm->dev, (sizeof(*route) * num_routes),
391 AC_VERB_SET_CONNECT_SEL, 0);935 GFP_KERNEL);
936 if (!route)
937 return -ENOMEM;
938
939 i = 0;
940 /* Add pin <- NULL <- mux route map */
941 list_for_each_entry(pin, &hdmi->pin_list, head) {
942 int sink_index = i + hdmi->num_cvt;
943 int src_index = sink_index + hdmi->num_pin;
944
945 hdac_hdmi_fill_route(&route[i],
946 widgets[sink_index].name, NULL,
947 widgets[src_index].name, NULL);
948 i++;
949
950 }
951
952 hdac_hdmi_add_pinmux_cvt_route(edev, widgets, route, i);
953
954 snd_soc_dapm_new_controls(dapm, widgets,
955 ((2 * hdmi->num_pin) + hdmi->num_cvt));
956
957 snd_soc_dapm_add_routes(dapm, route, num_routes);
958 snd_soc_dapm_new_widgets(dapm->card);
959
960 return 0;
961
962}
963
964static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev)
965{
966 struct hdac_hdmi_priv *hdmi = edev->private_data;
967 struct hdac_hdmi_dai_pin_map *dai_map;
968 struct hdac_hdmi_cvt *cvt;
969 int dai_id = 0;
970
971 if (list_empty(&hdmi->cvt_list))
972 return -EINVAL;
973
974 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
975 dai_map = &hdmi->dai_map[dai_id];
976 dai_map->dai_id = dai_id;
977 dai_map->cvt = cvt;
978
979 dai_id++;
980
981 if (dai_id == HDA_MAX_CVTS) {
982 dev_warn(&edev->hdac.dev,
983 "Max dais supported: %d\n", dai_id);
984 break;
985 }
986 }
392 987
393 return 0;988 return 0;
394}989}
@@ -397,12 +992,15 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) · 2 unmodified lines
397{992{
398 struct hdac_hdmi_priv *hdmi = edev->private_data;993 struct hdac_hdmi_priv *hdmi = edev->private_data;
399 struct hdac_hdmi_cvt *cvt;994 struct hdac_hdmi_cvt *cvt;
995 char name[NAME_SIZE];
400 996
401 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);997 cvt = kzalloc(sizeof(*cvt), GFP_KERNEL);
402 if (!cvt)998 if (!cvt)
403 return -ENOMEM;999 return -ENOMEM;
404 1000
405 cvt->nid = nid;1001 cvt->nid = nid;
1002 sprintf(name, "cvt %d", cvt->nid);
1003 cvt->name = kstrdup(name, GFP_KERNEL);
406 1004
407 list_add_tail(&cvt->head, &hdmi->cvt_list);1005 list_add_tail(&cvt->head, &hdmi->cvt_list);
408 hdmi->num_cvt++;1006 hdmi->num_cvt++;
@@ -410,6 +1008,106 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) · 1 unmodified line
410 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);1008 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
411}1009}
412 1010
1011static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
1012{
1013 struct hdac_ext_device *edev = pin->edev;
1014 struct hdac_hdmi_priv *hdmi = edev->private_data;
1015 struct hdac_hdmi_pcm *pcm;
1016 int val;
1017
1018 pin->repoll_count = repoll;
1019
1020 pm_runtime_get_sync(&edev->hdac.dev);
1021 val = snd_hdac_codec_read(&edev->hdac, pin->nid, 0,
1022 AC_VERB_GET_PIN_SENSE, 0);
1023
1024 dev_dbg(&edev->hdac.dev, "Pin sense val %x for pin: %d\n",
1025 val, pin->nid);
1026
1027
1028 mutex_lock(&hdmi->pin_mutex);
1029 pin->eld.monitor_present = !!(val & AC_PINSENSE_PRESENCE);
1030 pin->eld.eld_valid = !!(val & AC_PINSENSE_ELDV);
1031
1032 pcm = hdac_hdmi_get_pcm(edev, pin);
1033
1034 if (!pin->eld.monitor_present || !pin->eld.eld_valid) {
1035
1036 dev_dbg(&edev->hdac.dev, "%s: disconnect for pin %d\n",
1037 __func__, pin->nid);
1038
1039 /*
1040 * PCMs are not registered during device probe, so don't
1041 * report jack here. It will be done in usermode mux
1042 * control select.
1043 */
1044 if (pcm) {
1045 dev_dbg(&edev->hdac.dev,
1046 "jack report for pcm=%d\n", pcm->pcm_id);
1047
1048 snd_jack_report(pcm->jack, 0);
1049 }
1050
1051 mutex_unlock(&hdmi->pin_mutex);
1052 goto put_hdac_device;
1053 }
1054
1055 if (pin->eld.monitor_present && pin->eld.eld_valid) {
1056 /* TODO: use i915 component for reading ELD later */
1057 if (hdac_hdmi_get_eld(&edev->hdac, pin->nid,
1058 pin->eld.eld_buffer,
1059 &pin->eld.eld_size) == 0) {
1060
1061 if (pcm) {
1062 dev_dbg(&edev->hdac.dev,
1063 "jack report for pcm=%d\n",
1064 pcm->pcm_id);
1065
1066 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
1067 }
1068
1069 print_hex_dump_bytes("ELD: ", DUMP_PREFIX_OFFSET,
1070 pin->eld.eld_buffer, pin->eld.eld_size);
1071 } else {
1072 pin->eld.monitor_present = false;
1073 pin->eld.eld_valid = false;
1074
1075 if (pcm) {
1076 dev_dbg(&edev->hdac.dev,
1077 "jack report for pcm=%d\n",
1078 pcm->pcm_id);
1079
1080 snd_jack_report(pcm->jack, 0);
1081 }
1082 }
1083 }
1084
1085 mutex_unlock(&hdmi->pin_mutex);
1086
1087 /*
1088 * Sometimes the pin_sense may present invalid monitor
1089 * present and eld_valid. If ELD data is not valid, loop few
1090 * more times to get correct pin sense and valid ELD.
1091 */
1092 if ((!pin->eld.monitor_present || !pin->eld.eld_valid) && repoll)
1093 schedule_delayed_work(&pin->work, msecs_to_jiffies(300));
1094
1095put_hdac_device:
1096 pm_runtime_put_sync(&edev->hdac.dev);
1097}
1098
1099static void hdac_hdmi_repoll_eld(struct work_struct *work)
1100{
1101 struct hdac_hdmi_pin *pin =
1102 container_of(to_delayed_work(work), struct hdac_hdmi_pin, work);
1103
1104 /* picked from legacy HDA driver */
1105 if (pin->repoll_count++ > 6)
1106 pin->repoll_count = 0;
1107
1108 hdac_hdmi_present_sense(pin, pin->repoll_count);
1109}
1110
413static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)1111static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
414{1112{
415 struct hdac_hdmi_priv *hdmi = edev->private_data;1113 struct hdac_hdmi_priv *hdmi = edev->private_data;
@@ -424,6 +1122,120 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) · 8 unmodified lines
424 list_add_tail(&pin->head, &hdmi->pin_list);1122 list_add_tail(&pin->head, &hdmi->pin_list);
425 hdmi->num_pin++;1123 hdmi->num_pin++;
426 1124
1125 pin->edev = edev;
1126 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
1127
1128 return 0;
1129}
1130
1131#define INTEL_VENDOR_NID 0x08
1132#define INTEL_GET_VENDOR_VERB 0xf81
1133#define INTEL_SET_VENDOR_VERB 0x781
1134#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
1135#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
1136
1137static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
1138{
1139 unsigned int vendor_param;
1140
1141 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1142 INTEL_GET_VENDOR_VERB, 0);
1143 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
1144 return;
1145
1146 vendor_param |= INTEL_EN_ALL_PIN_CVTS;
1147 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1148 INTEL_SET_VENDOR_VERB, vendor_param);
1149 if (vendor_param == -1)
1150 return;
1151}
1152
1153static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
1154{
1155 unsigned int vendor_param;
1156
1157 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1158 INTEL_GET_VENDOR_VERB, 0);
1159 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
1160 return;
1161
1162 /* enable DP1.2 mode */
1163 vendor_param |= INTEL_EN_DP12;
1164 vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
1165 INTEL_SET_VENDOR_VERB, vendor_param);
1166 if (vendor_param == -1)
1167 return;
1168
1169}
1170
1171static struct snd_soc_dai_ops hdmi_dai_ops = {
1172 .startup = hdac_hdmi_pcm_open,
1173 .shutdown = hdac_hdmi_pcm_close,
1174 .hw_params = hdac_hdmi_set_hw_params,
1175 .prepare = hdac_hdmi_playback_prepare,
1176 .trigger = hdac_hdmi_trigger,
1177 .hw_free = hdac_hdmi_playback_cleanup,
1178};
1179
1180/*
1181 * Each converter can support a stream independently. So a dai is created
1182 * based on the number of converter queried.
1183 */
1184static int hdac_hdmi_create_dais(struct hdac_device *hdac,
1185 struct snd_soc_dai_driver **dais,
1186 struct hdac_hdmi_priv *hdmi, int num_dais)
1187{
1188 struct snd_soc_dai_driver *hdmi_dais;
1189 struct hdac_hdmi_cvt *cvt;
1190 char name[NAME_SIZE], dai_name[NAME_SIZE];
1191 int i = 0;
1192 u32 rates, bps;
1193 unsigned int rate_max = 384000, rate_min = 8000;
1194 u64 formats;
1195 int ret;
1196
1197 hdmi_dais = devm_kzalloc(&hdac->dev,
1198 (sizeof(*hdmi_dais) * num_dais),
1199 GFP_KERNEL);
1200 if (!hdmi_dais)
1201 return -ENOMEM;
1202
1203 list_for_each_entry(cvt, &hdmi->cvt_list, head) {
1204 ret = snd_hdac_query_supported_pcm(hdac, cvt->nid,
1205 &rates, &formats, &bps);
1206 if (ret)
1207 return ret;
1208
1209 sprintf(dai_name, "intel-hdmi-hifi%d", i+1);
1210 hdmi_dais[i].name = devm_kstrdup(&hdac->dev,
1211 dai_name, GFP_KERNEL);
1212
1213 if (!hdmi_dais[i].name)
1214 return -ENOMEM;
1215
1216 snprintf(name, sizeof(name), "hifi%d", i+1);
1217 hdmi_dais[i].playback.stream_name =
1218 devm_kstrdup(&hdac->dev, name, GFP_KERNEL);
1219 if (!hdmi_dais[i].playback.stream_name)
1220 return -ENOMEM;
1221
1222 /*
1223 * Set caps based on capability queried from the converter.
1224 * It will be constrained runtime based on ELD queried.
1225 */
1226 hdmi_dais[i].playback.formats = formats;
1227 hdmi_dais[i].playback.rates = rates;
1228 hdmi_dais[i].playback.rate_max = rate_max;
1229 hdmi_dais[i].playback.rate_min = rate_min;
1230 hdmi_dais[i].playback.channels_min = 2;
1231 hdmi_dais[i].playback.channels_max = 2;
1232 hdmi_dais[i].ops = &hdmi_dai_ops;
1233
1234 i++;
1235 }
1236
1237 *dais = hdmi_dais;
1238
427 return 0;1239 return 0;
428}1240}
429 1241
@@ -431,7 +1243,8 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) · 1 unmodified line
431 * Parse all nodes and store the cvt/pin nids in array1243 * Parse all nodes and store the cvt/pin nids in array
432 * Add one time initialization for pin and cvt widgets1244 * Add one time initialization for pin and cvt widgets
433 */1245 */
434static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev)1246static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
1247 struct snd_soc_dai_driver **dais, int *num_dais)
435{1248{
436 hda_nid_t nid;1249 hda_nid_t nid;
437 int i, num_nodes;1250 int i, num_nodes;
@@ -439,6 +1252,9 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev) · 1 unmodified line
439 struct hdac_hdmi_priv *hdmi = edev->private_data;1252 struct hdac_hdmi_priv *hdmi = edev->private_data;
440 int ret;1253 int ret;
441 1254
1255 hdac_hdmi_skl_enable_all_pins(hdac);
1256 hdac_hdmi_skl_enable_dp12(hdac);
1257
442 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);1258 num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid);
443 if (!nid || num_nodes <= 0) {1259 if (!nid || num_nodes <= 0) {
444 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");1260 dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n");
@@ -479,19 +1295,107 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev) · 34 unmodified lines
479 if (!hdmi->num_pin || !hdmi->num_cvt)1295 if (!hdmi->num_pin || !hdmi->num_cvt)
480 return -EIO;1296 return -EIO;
481 1297
1298 ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
1299 if (ret) {
1300 dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
1301 ret);
1302 return ret;
1303 }
1304
1305 *num_dais = hdmi->num_cvt;
1306
482 return hdac_hdmi_init_dai_map(edev);1307 return hdac_hdmi_init_dai_map(edev);
483}1308}
484 1309
1310static void hdac_hdmi_eld_notify_cb(void *aptr, int port)
1311{
1312 struct hdac_ext_device *edev = aptr;
1313 struct hdac_hdmi_priv *hdmi = edev->private_data;
1314 struct hdac_hdmi_pin *pin;
1315 struct snd_soc_codec *codec = edev->scodec;
1316
1317 /* Don't know how this mapping is derived */
1318 hda_nid_t pin_nid = port + 0x04;
1319
1320 dev_dbg(&edev->hdac.dev, "%s: for pin: %d\n", __func__, pin_nid);
1321
1322 /*
1323 * skip notification during system suspend (but not in runtime PM);
1324 * the state will be updated at resume. Also since the ELD and
1325 * connection states are updated in anyway at the end of the resume,
1326 * we can skip it when received during PM process.
1327 */
1328 if (snd_power_get_state(codec->component.card->snd_card) !=
1329 SNDRV_CTL_POWER_D0)
1330 return;
1331
1332 if (atomic_read(&edev->hdac.in_pm))
1333 return;
1334
1335 list_for_each_entry(pin, &hdmi->pin_list, head) {
1336 if (pin->nid == pin_nid)
1337 hdac_hdmi_present_sense(pin, 1);
1338 }
1339}
1340
1341static struct i915_audio_component_audio_ops aops = {
1342 .pin_eld_notify = hdac_hdmi_eld_notify_cb,
1343};
1344
1345int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
1346{
1347 char jack_name[NAME_SIZE];
1348 struct snd_soc_codec *codec = dai->codec;
1349 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1350 struct snd_soc_dapm_context *dapm =
1351 snd_soc_component_get_dapm(&codec->component);
1352 struct hdac_hdmi_priv *hdmi = edev->private_data;
1353 struct hdac_hdmi_pcm *pcm;
1354
1355 /*
1356 * this is a new PCM device, create new pcm and
1357 * add to the pcm list
1358 */
1359 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
1360 if (!pcm)
1361 return -ENOMEM;
1362 pcm->pcm_id = device;
1363 pcm->cvt = hdmi->dai_map[dai->id].cvt;
1364
1365 list_add_tail(&pcm->head, &hdmi->pcm_list);
1366
1367 sprintf(jack_name, "HDMI/DP, pcm=%d Jack", device);
1368
1369 return snd_jack_new(dapm->card->snd_card, jack_name,
1370 SND_JACK_AVOUT, &pcm->jack, true, false);
1371}
1372EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
1373
485static int hdmi_codec_probe(struct snd_soc_codec *codec)1374static int hdmi_codec_probe(struct snd_soc_codec *codec)
486{1375{
487 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);1376 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
488 struct hdac_hdmi_priv *hdmi = edev->private_data;1377 struct hdac_hdmi_priv *hdmi = edev->private_data;
489 struct snd_soc_dapm_context *dapm =1378 struct snd_soc_dapm_context *dapm =
490 snd_soc_component_get_dapm(&codec->component);1379 snd_soc_component_get_dapm(&codec->component);
1380 struct hdac_hdmi_pin *pin;
1381 int ret;
491 1382
492 edev->scodec = codec;1383 edev->scodec = codec;
493 1384
494 create_fill_widget_route_map(dapm, &hdmi->dai_map[0]);1385 ret = create_fill_widget_route_map(dapm);
1386 if (ret < 0)
1387 return ret;
1388
1389 aops.audio_ptr = edev;
1390 ret = snd_hdac_i915_register_notifier(&aops);
1391 if (ret < 0) {
1392 dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n",
1393 ret);
1394 return ret;
1395 }
1396
1397 list_for_each_entry(pin, &hdmi->pin_list, head)
1398 hdac_hdmi_present_sense(pin, 1);
495 1399
496 /* Imp: Store the card pointer in hda_codec */1400 /* Imp: Store the card pointer in hda_codec */
497 edev->card = dapm->card->snd_card;1401 edev->card = dapm->card->snd_card;
@@ -515,44 +1419,73 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) · 17 unmodified lines
515 return 0;1419 return 0;
516}1420}
517 1421
1422#ifdef CONFIG_PM
1423static int hdmi_codec_resume(struct snd_soc_codec *codec)
1424{
1425 struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec);
1426 struct hdac_hdmi_priv *hdmi = edev->private_data;
1427 struct hdac_hdmi_pin *pin;
1428 struct hdac_device *hdac = &edev->hdac;
1429 struct hdac_bus *bus = hdac->bus;
1430 int err;
1431 unsigned long timeout;
1432
1433 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1434 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1435
1436 /* Power up afg */
1437 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)) {
1438
1439 snd_hdac_codec_write(hdac, hdac->afg, 0,
1440 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1441
1442 /* Wait till power state is set to D0 */
1443 timeout = jiffies + msecs_to_jiffies(1000);
1444 while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0)
1445 && time_before(jiffies, timeout)) {
1446 msleep(50);
1447 }
1448 }
1449
1450 /*
1451 * As the ELD notify callback request is not entertained while the
1452 * device is in suspend state. Need to manually check detection of
1453 * all pins here.
1454 */
1455 list_for_each_entry(pin, &hdmi->pin_list, head)
1456 hdac_hdmi_present_sense(pin, 1);
1457
1458 /*
1459 * Codec power is turned ON during controller resume.
1460 * Turn it OFF here
1461 */
1462 err = snd_hdac_display_power(bus, false);
1463 if (err < 0) {
1464 dev_err(bus->dev,
1465 "Cannot turn OFF display power on i915, err: %d\n",
1466 err);
1467 return err;
1468 }
1469
1470 return 0;
1471}
1472#else
1473#define hdmi_codec_resume NULL
1474#endif
1475
518static struct snd_soc_codec_driver hdmi_hda_codec = {1476static struct snd_soc_codec_driver hdmi_hda_codec = {
519 .probe = hdmi_codec_probe,1477 .probe = hdmi_codec_probe,
520 .remove = hdmi_codec_remove,1478 .remove = hdmi_codec_remove,
1479 .resume = hdmi_codec_resume,
521 .idle_bias_off = true,1480 .idle_bias_off = true,
522};1481};
523 1482
524static struct snd_soc_dai_ops hdmi_dai_ops = {
525 .startup = hdac_hdmi_pcm_open,
526 .shutdown = hdac_hdmi_pcm_close,
527 .hw_params = hdac_hdmi_set_hw_params,
528 .prepare = hdac_hdmi_playback_prepare,
529 .hw_free = hdac_hdmi_playback_cleanup,
530};
531
532static struct snd_soc_dai_driver hdmi_dais[] = {
533 { .name = "intel-hdmi-hif1",
534 .playback = {
535 .stream_name = "hif1",
536 .channels_min = 2,
537 .channels_max = 2,
538 .rates = SNDRV_PCM_RATE_32000 |
539 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
540 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
541 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
542 .formats = SNDRV_PCM_FMTBIT_S16_LE |
543 SNDRV_PCM_FMTBIT_S20_3LE |
544 SNDRV_PCM_FMTBIT_S24_LE |
545 SNDRV_PCM_FMTBIT_S32_LE,
546
547 },
548 .ops = &hdmi_dai_ops,
549 },
550};
551
552static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)1483static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
553{1484{
554 struct hdac_device *codec = &edev->hdac;1485 struct hdac_device *codec = &edev->hdac;
555 struct hdac_hdmi_priv *hdmi_priv;1486 struct hdac_hdmi_priv *hdmi_priv;
1487 struct snd_soc_dai_driver *hdmi_dais = NULL;
1488 int num_dais = 0;
556 int ret = 0;1489 int ret = 0;
557 1490
558 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);1491 hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL);
@@ -565,14 +1498,31 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) · 6 unmodified lines
565 1498
566 INIT_LIST_HEAD(&hdmi_priv->pin_list);1499 INIT_LIST_HEAD(&hdmi_priv->pin_list);
567 INIT_LIST_HEAD(&hdmi_priv->cvt_list);1500 INIT_LIST_HEAD(&hdmi_priv->cvt_list);
1501 INIT_LIST_HEAD(&hdmi_priv->pcm_list);
1502 mutex_init(&hdmi_priv->pin_mutex);
568 1503
569 ret = hdac_hdmi_parse_and_map_nid(edev);1504 /*
570 if (ret < 0)1505 * Turned off in the runtime_suspend during the first explicit
1506 * pm_runtime_suspend call.
1507 */
1508 ret = snd_hdac_display_power(edev->hdac.bus, true);
1509 if (ret < 0) {
1510 dev_err(&edev->hdac.dev,
1511 "Cannot turn on display power on i915 err: %d\n",
1512 ret);
571 return ret;1513 return ret;
1514 }
1515
1516 ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais);
1517 if (ret < 0) {
1518 dev_err(&codec->dev,
1519 "Failed in parse and map nid with err: %d\n", ret);
1520 return ret;
1521 }
572 1522
573 /* ASoC specific initialization */1523 /* ASoC specific initialization */
574 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,1524 return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec,
575 hdmi_dais, ARRAY_SIZE(hdmi_dais));1525 hdmi_dais, num_dais);
576}1526}
577 1527
578static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)1528static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev)
@@ -580,11 +1530,20 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) · 1 unmodified line
580 struct hdac_hdmi_priv *hdmi = edev->private_data;1530 struct hdac_hdmi_priv *hdmi = edev->private_data;
581 struct hdac_hdmi_pin *pin, *pin_next;1531 struct hdac_hdmi_pin *pin, *pin_next;
582 struct hdac_hdmi_cvt *cvt, *cvt_next;1532 struct hdac_hdmi_cvt *cvt, *cvt_next;
1533 struct hdac_hdmi_pcm *pcm, *pcm_next;
583 1534
584 snd_soc_unregister_codec(&edev->hdac.dev);1535 snd_soc_unregister_codec(&edev->hdac.dev);
585 1536
1537 list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) {
1538 pcm->cvt = NULL;
1539 pcm->pin = NULL;
1540 list_del(&pcm->head);
1541 kfree(pcm);
1542 }
1543
586 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {1544 list_for_each_entry_safe(cvt, cvt_next, &hdmi->cvt_list, head) {
587 list_del(&cvt->head);1545 list_del(&cvt->head);
1546 kfree(cvt->name);
588 kfree(cvt);1547 kfree(cvt);
589 }1548 }
590 1549
@@ -602,6 +1561,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 11 unmodified lines
602 struct hdac_ext_device *edev = to_hda_ext_device(dev);1561 struct hdac_ext_device *edev = to_hda_ext_device(dev);
603 struct hdac_device *hdac = &edev->hdac;1562 struct hdac_device *hdac = &edev->hdac;
604 struct hdac_bus *bus = hdac->bus;1563 struct hdac_bus *bus = hdac->bus;
1564 unsigned long timeout;
605 int err;1565 int err;
606 1566
607 dev_dbg(dev, "Enter: %s\n", __func__);1567 dev_dbg(dev, "Enter: %s\n", __func__);
@@ -611,10 +1571,19 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) · 3 unmodified lines
611 return 0;1571 return 0;
612 1572
613 /* Power down afg */1573 /* Power down afg */
614 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3))1574 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3)) {
615 snd_hdac_codec_write(hdac, hdac->afg, 0,1575 snd_hdac_codec_write(hdac, hdac->afg, 0,
616 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);1576 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
617 1577
1578 /* Wait till power state is set to D3 */
1579 timeout = jiffies + msecs_to_jiffies(1000);
1580 while (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D3)
1581 && time_before(jiffies, timeout)) {
1582
1583 msleep(50);
1584 }
1585 }
1586
618 err = snd_hdac_display_power(bus, false);1587 err = snd_hdac_display_power(bus, false);
619 if (err < 0) {1588 if (err < 0) {
620 dev_err(bus->dev, "Cannot turn on display power on i915\n");1589 dev_err(bus->dev, "Cannot turn on display power on i915\n");
@@ -643,6 +1612,9 @@ static int hdac_hdmi_runtime_resume(struct device *dev) · 22 unmodified lines
643 return err;1612 return err;
644 }1613 }
645 1614
1615 hdac_hdmi_skl_enable_all_pins(&edev->hdac);
1616 hdac_hdmi_skl_enable_dp12(&edev->hdac);
1617
646 /* Power up afg */1618 /* Power up afg */
647 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))1619 if (!snd_hdac_check_power_state(hdac, hdac->afg, AC_PWRST_D0))
648 snd_hdac_codec_write(hdac, hdac->afg, 0,1620 snd_hdac_codec_write(hdac, hdac->afg, 0,
@@ -661,6 +1633,7 @@ static const struct dev_pm_ops hdac_hdmi_pm = { · 12 unmodified lines
661 1633
662static const struct hda_device_id hdmi_list[] = {1634static const struct hda_device_id hdmi_list[] = {
663 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),1635 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
1636 HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),
664 {}1637 {}
665};1638};
666 1639
sound/soc/codecs/hdac_hdmi.h+6−0
@@ -0,0 +1,6 @@
1#ifndef __HDAC_HDMI_H__
2#define __HDAC_HDMI_H__
3
4int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm);
5
6#endif /* __HDAC_HDMI_H__ */
sound/soc/codecs/max9867.c+546−0
@@ -0,0 +1,546 @@
1/*
2 * max9867.c -- max9867 ALSA SoC Audio driver
3 *
4 * Copyright 2013-15 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/delay.h>
12#include <linux/i2c.h>
13#include <linux/module.h>
14#include <linux/regmap.h>
15#include <sound/pcm_params.h>
16#include <sound/soc.h>
17#include <sound/tlv.h>
18#include "max9867.h"
19
20static const char *const max9867_spmode[] = {
21 "Stereo Diff", "Mono Diff",
22 "Stereo Cap", "Mono Cap",
23 "Stereo Single", "Mono Single",
24 "Stereo Single Fast", "Mono Single Fast"
25};
26static const char *const max9867_sidetone_text[] = {
27 "None", "Left", "Right", "LeftRight", "LeftRightDiv2",
28};
29static const char *const max9867_filter_text[] = {"IIR", "FIR"};
30
31static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
32 max9867_filter_text);
33static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
34 max9867_spmode);
35static SOC_ENUM_SINGLE_DECL(max9867_sidetone, MAX9867_DACGAIN, 6,
36 max9867_sidetone_text);
37static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0);
38static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1);
39static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1);
40static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1);
41static const unsigned int max98088_micboost_tlv[] = {
42 TLV_DB_RANGE_HEAD(2),
43 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
44 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
45};
46
47static const struct snd_kcontrol_new max9867_snd_controls[] = {
48 SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL,
49 MAX9867_RIGHTVOL, 0, 63, 1),
50 SOC_DOUBLE_R_TLV("Capture Volume", MAX9867_LEFTMICGAIN,
51 MAX9867_RIGHTMICGAIN,
52 0, 15, 1, max9860_capture_tlv),
53 SOC_DOUBLE_R_TLV("Mic Volume", MAX9867_LEFTMICGAIN,
54 MAX9867_RIGHTMICGAIN, 0, 31, 1, max9860_mic_tlv),
55 SOC_DOUBLE_R_TLV("Mic Boost Volume", MAX9867_LEFTMICGAIN,
56 MAX9867_RIGHTMICGAIN, 5, 3, 0, max98088_micboost_tlv),
57 SOC_ENUM("Digital Sidetone Src", max9867_sidetone),
58 SOC_SINGLE("Sidetone Volume", MAX9867_DACGAIN, 0, 31, 1),
59 SOC_SINGLE("DAC Volume", MAX9867_DACLEVEL, 4, 3, 0),
60 SOC_SINGLE("DAC Attenuation", MAX9867_DACLEVEL, 0, 15, 1),
61 SOC_SINGLE_TLV("ADC Left Volume", MAX9867_ADCLEVEL,
62 4, 15, 1, max9860_adc_left_tlv),
63 SOC_SINGLE_TLV("ADC Right Volume", MAX9867_ADCLEVEL,
64 0, 15, 1, max9860_adc_right_tlv),
65 SOC_ENUM("Speaker Mode", max9867_spkmode),
66 SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
67 SOC_SINGLE("ZCD Switch", MAX9867_MODECONFIG, 5, 1, 0),
68 SOC_ENUM("DSP Filter", max9867_filter),
69};
70
71static const char *const max9867_mux[] = {"None", "Mic", "Line", "Mic_Line"};
72
73static SOC_ENUM_SINGLE_DECL(max9867_mux_enum,
74 MAX9867_INPUTCONFIG, MAX9867_INPUT_SHIFT,
75 max9867_mux);
76
77static const struct snd_kcontrol_new max9867_dapm_mux_controls =
78 SOC_DAPM_ENUM("Route", max9867_mux_enum);
79
80static const struct snd_kcontrol_new max9867_left_dapm_control =
81 SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 6, 1, 0);
82static const struct snd_kcontrol_new max9867_right_dapm_control =
83 SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 5, 1, 0);
84static const struct snd_kcontrol_new max9867_line_dapm_control =
85 SOC_DAPM_SINGLE("Switch", MAX9867_LEFTLINELVL, 6, 1, 1);
86
87static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
88 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
89 SND_SOC_DAPM_DAC("Left DAC", NULL, MAX9867_PWRMAN, 3, 0),
90 SND_SOC_DAPM_DAC("Right DAC", NULL, MAX9867_PWRMAN, 2, 0),
91 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
92 SND_SOC_DAPM_OUTPUT("HPOUT"),
93
94 SND_SOC_DAPM_AIF_IN("DAI_IN", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
95 SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
96 SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
97 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
98 &max9867_dapm_mux_controls),
99
100 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
101 SND_SOC_DAPM_SWITCH("Left Line", MAX9867_LEFTLINELVL, 6, 1,
102 &max9867_left_dapm_control),
103 SND_SOC_DAPM_SWITCH("Right Line", MAX9867_RIGTHLINELVL, 6, 1,
104 &max9867_right_dapm_control),
105 SND_SOC_DAPM_SWITCH("Line Mixer", SND_SOC_NOPM, 0, 0,
106 &max9867_line_dapm_control),
107 SND_SOC_DAPM_INPUT("LINE_IN"),
108};
109
110static const struct snd_soc_dapm_route max9867_audio_map[] = {
111 {"Left DAC", NULL, "DAI_OUT"},
112 {"Right DAC", NULL, "DAI_OUT"},
113 {"Output Mixer", NULL, "Left DAC"},
114 {"Output Mixer", NULL, "Right DAC"},
115 {"HPOUT", NULL, "Output Mixer"},
116
117 {"Left ADC", NULL, "DAI_IN"},
118 {"Right ADC", NULL, "DAI_IN"},
119 {"Input Mixer", NULL, "Left ADC"},
120 {"Input Mixer", NULL, "Right ADC"},
121 {"Input Mux", "Line", "Input Mixer"},
122 {"Input Mux", "Mic", "Input Mixer"},
123 {"Input Mux", "Mic_Line", "Input Mixer"},
124 {"Right Line", "Switch", "Input Mux"},
125 {"Left Line", "Switch", "Input Mux"},
126 {"LINE_IN", NULL, "Left Line"},
127 {"LINE_IN", NULL, "Right Line"},
128};
129
130enum rates {
131 pcm_rate_8, pcm_rate_16, pcm_rate_24,
132 pcm_rate_32, pcm_rate_44,
133 pcm_rate_48, max_pcm_rate,
134};
135
136struct ni_div_rates {
137 u32 mclk;
138 u16 ni[max_pcm_rate];
139} ni_div[] = {
140 {11289600, {0x116A, 0x22D4, 0x343F, 0x45A9, 0x6000, 0x687D} },
141 {12000000, {0x1062, 0x20C5, 0x3127, 0x4189, 0x5A51, 0x624E} },
142 {12288000, {0x1000, 0x2000, 0x3000, 0x4000, 0x5833, 0x6000} },
143 {13000000, {0x0F20, 0x1E3F, 0x2D5F, 0x3C7F, 0x535F, 0x5ABE} },
144 {19200000, {0x0A3D, 0x147B, 0x1EB8, 0x28F6, 0x3873, 0x3D71} },
145 {24000000, {0x1062, 0x20C5, 0x1893, 0x4189, 0x5A51, 0x624E} },
146 {26000000, {0x0F20, 0x1E3F, 0x16AF, 0x3C7F, 0x535F, 0x5ABE} },
147 {27000000, {0x0E90, 0x1D21, 0x15D8, 0x3A41, 0x5048, 0x5762} },
148};
149
150static inline int get_ni_value(int mclk, int rate)
151{
152 int i, ret = 0;
153
154 /* find the closest rate index*/
155 for (i = 0; i < ARRAY_SIZE(ni_div); i++) {
156 if (ni_div[i].mclk >= mclk)
157 break;
158 }
159 if (i == ARRAY_SIZE(ni_div))
160 return -EINVAL;
161
162 switch (rate) {
163 case 8000:
164 return ni_div[i].ni[pcm_rate_8];
165 case 16000:
166 return ni_div[i].ni[pcm_rate_16];
167 case 32000:
168 return ni_div[i].ni[pcm_rate_32];
169 case 44100:
170 return ni_div[i].ni[pcm_rate_44];
171 case 48000:
172 return ni_div[i].ni[pcm_rate_48];
173 default:
174 pr_err("%s wrong rate %d\n", __func__, rate);
175 ret = -EINVAL;
176 }
177 return ret;
178}
179
180static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
182{
183 struct snd_soc_codec *codec = dai->codec;
184 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
185 unsigned int ni_h, ni_l;
186 int value;
187
188 value = get_ni_value(max9867->sysclk, params_rate(params));
189 if (value < 0)
190 return value;
191
192 ni_h = (0xFF00 & value) >> 8;
193 ni_l = 0x00FF & value;
194 /* set up the ni value */
195 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
196 MAX9867_NI_HIGH_MASK, ni_h);
197 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
198 MAX9867_NI_LOW_MASK, ni_l);
199 if (!max9867->master) {
200 /*
201 * digital pll locks on to any externally supplied LRCLK signal
202 * and also enable rapid lock mode.
203 */
204 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
205 MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
206 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
207 MAX9867_PLL, MAX9867_PLL);
208 } else {
209 unsigned long int bclk_rate, pclk_bclk_ratio;
210 int bclk_value;
211
212 bclk_rate = params_rate(params) * 2 * params_width(params);
213 pclk_bclk_ratio = max9867->pclk/bclk_rate;
214 switch (params_width(params)) {
215 case 8:
216 case 16:
217 switch (pclk_bclk_ratio) {
218 case 2:
219 bclk_value = MAX9867_IFC1B_PCLK_2;
220 break;
221 case 4:
222 bclk_value = MAX9867_IFC1B_PCLK_4;
223 break;
224 case 8:
225 bclk_value = MAX9867_IFC1B_PCLK_8;
226 break;
227 case 16:
228 bclk_value = MAX9867_IFC1B_PCLK_16;
229 break;
230 default:
231 dev_err(codec->dev,
232 "unsupported sampling rate\n");
233 return -EINVAL;
234 }
235 break;
236 case 24:
237 bclk_value = MAX9867_IFC1B_24BIT;
238 break;
239 case 32:
240 bclk_value = MAX9867_IFC1B_32BIT;
241 break;
242 default:
243 dev_err(codec->dev, "unsupported sampling rate\n");
244 return -EINVAL;
245 }
246 regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
247 MAX9867_IFC1B_BCLK_MASK, bclk_value);
248 }
249 return 0;
250}
251
252static int max9867_prepare(struct snd_pcm_substream *substream,
253 struct snd_soc_dai *dai)
254{
255 struct snd_soc_codec *codec = dai->codec;
256 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
257
258 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
259 MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
260 return 0;
261}
262
263static int max9867_mute(struct snd_soc_dai *dai, int mute)
264{
265 struct snd_soc_codec *codec = dai->codec;
266 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
267
268 if (mute)
269 regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
270 MAX9867_DAC_MUTE_MASK, MAX9867_DAC_MUTE_MASK);
271 else
272 regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
273 MAX9867_DAC_MUTE_MASK, 0);
274 return 0;
275}
276
277static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
278 int clk_id, unsigned int freq, int dir)
279{
280 struct snd_soc_codec *codec = codec_dai->codec;
281 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
282 int value = 0;
283
284 /* Set the prescaler based on the master clock frequency*/
285 if (freq >= 10000000 && freq <= 20000000) {
286 value |= MAX9867_PSCLK_10_20;
287 max9867->pclk = freq;
288 } else if (freq >= 20000000 && freq <= 40000000) {
289 value |= MAX9867_PSCLK_20_40;
290 max9867->pclk = freq/2;
291 } else if (freq >= 40000000 && freq <= 60000000) {
292 value |= MAX9867_PSCLK_40_60;
293 max9867->pclk = freq/4;
294 } else {
295 pr_err("bad clock frequency %d", freq);
296 return -EINVAL;
297 }
298 value = value << MAX9867_PSCLK_SHIFT;
299 max9867->sysclk = freq;
300 /* exact integer mode is not supported */
301 value &= ~MAX9867_FREQ_MASK;
302 regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
303 MAX9867_PSCLK_MASK, value);
304 return 0;
305}
306
307static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
308 unsigned int fmt)
309{
310 struct snd_soc_codec *codec = codec_dai->codec;
311 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
312 u8 iface1A = 0, iface1B = 0;
313 int ret;
314
315 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
316 case SND_SOC_DAIFMT_CBM_CFM:
317 max9867->master = 1;
318 iface1A |= MAX9867_MASTER;
319 break;
320 case SND_SOC_DAIFMT_CBS_CFS:
321 max9867->master = 0;
322 iface1A &= ~MAX9867_MASTER;
323 break;
324 default:
325 return -EINVAL;
326 }
327
328 /* for i2s compatible mode */
329 iface1A |= MAX9867_I2S_DLY;
330 /* SDOUT goes to hiz state after all data is transferred */
331 iface1A |= MAX9867_SDOUT_HIZ;
332
333 /* Clock inversion bits, BCI and WCI */
334 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
335 case SND_SOC_DAIFMT_NB_NF:
336 break;
337 case SND_SOC_DAIFMT_IB_IF:
338 iface1A |= MAX9867_WCI_MODE | MAX9867_BCI_MODE;
339 break;
340 case SND_SOC_DAIFMT_IB_NF:
341 iface1A |= MAX9867_BCI_MODE;
342 break;
343 case SND_SOC_DAIFMT_NB_IF:
344 iface1A |= MAX9867_WCI_MODE;
345 break;
346 default:
347 return -EINVAL;
348 }
349
350 ret = regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
351 ret = regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
352 return 0;
353}
354
355static struct snd_soc_dai_ops max9867_dai_ops = {
356 .set_fmt = max9867_dai_set_fmt,
357 .set_sysclk = max9867_set_dai_sysclk,
358 .prepare = max9867_prepare,
359 .digital_mute = max9867_mute,
360 .hw_params = max9867_dai_hw_params,
361};
362
363#define MAX9867_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
364 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
365#define MAX9867_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
366
367static struct snd_soc_dai_driver max9867_dai[] = {
368 {
369 .name = "max9867-aif1",
370 .playback = {
371 .stream_name = "HiFi Playback",
372 .channels_min = 1,
373 .channels_max = 2,
374 .rates = MAX9867_RATES,
375 .formats = MAX9867_FORMATS,
376 },
377 .capture = {
378 .stream_name = "HiFi Capture",
379 .channels_min = 1,
380 .channels_max = 2,
381 .rates = MAX9867_RATES,
382 .formats = MAX9867_FORMATS,
383 },
384 .ops = &max9867_dai_ops,
385 }
386};
387
388#ifdef CONFIG_PM_SLEEP
389static int max9867_suspend(struct device *dev)
390{
391 struct max9867_priv *max9867 = dev_get_drvdata(dev);
392
393 /* Drop down to power saving mode when system is suspended */
394 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
395 MAX9867_SHTDOWN_MASK, ~MAX9867_SHTDOWN_MASK);
396 return 0;
397}
398
399static int max9867_resume(struct device *dev)
400{
401 struct max9867_priv *max9867 = dev_get_drvdata(dev);
402
403 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
404 MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
405 return 0;
406}
407#endif
408
409static int max9867_probe(struct snd_soc_codec *codec)
410{
411 struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
412
413 dev_dbg(codec->dev, "max98090_probe\n");
414 max9867->codec = codec;
415 return 0;
416}
417
418static struct snd_soc_codec_driver max9867_codec = {
419 .probe = max9867_probe,
420 .controls = max9867_snd_controls,
421 .num_controls = ARRAY_SIZE(max9867_snd_controls),
422 .dapm_routes = max9867_audio_map,
423 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
424 .dapm_widgets = max9867_dapm_widgets,
425 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
426};
427
428static bool max9867_volatile_register(struct device *dev, unsigned int reg)
429{
430 switch (reg) {
431 case MAX9867_STATUS:
432 case MAX9867_JACKSTATUS:
433 case MAX9867_AUXHIGH:
434 case MAX9867_AUXLOW:
435 return true;
436 default:
437 return false;
438 }
439}
440
441static const struct reg_default max9867_reg[] = {
442 { 0x04, 0x00 },
443 { 0x05, 0x00 },
444 { 0x06, 0x00 },
445 { 0x07, 0x00 },
446 { 0x08, 0x00 },
447 { 0x09, 0x00 },
448 { 0x0A, 0x00 },
449 { 0x0B, 0x00 },
450 { 0x0C, 0x00 },
451 { 0x0D, 0x00 },
452 { 0x0E, 0x00 },
453 { 0x0F, 0x00 },
454 { 0x10, 0x00 },
455 { 0x11, 0x00 },
456 { 0x12, 0x00 },
457 { 0x13, 0x00 },
458 { 0x14, 0x00 },
459 { 0x15, 0x00 },
460 { 0x16, 0x00 },
461 { 0x17, 0x00 },
462};
463
464static const struct regmap_config max9867_regmap = {
465 .reg_bits = 8,
466 .val_bits = 8,
467 .max_register = MAX9867_REVISION,
468 .reg_defaults = max9867_reg,
469 .num_reg_defaults = ARRAY_SIZE(max9867_reg),
470 .volatile_reg = max9867_volatile_register,
471 .cache_type = REGCACHE_RBTREE,
472};
473
474static int max9867_i2c_probe(struct i2c_client *i2c,
475 const struct i2c_device_id *id)
476{
477 struct max9867_priv *max9867;
478 int ret = 0, reg;
479
480 max9867 = devm_kzalloc(&i2c->dev,
481 sizeof(*max9867), GFP_KERNEL);
482 if (!max9867)
483 return -ENOMEM;
484
485 i2c_set_clientdata(i2c, max9867);
486 max9867->regmap = devm_regmap_init_i2c(i2c, &max9867_regmap);
487 if (IS_ERR(max9867->regmap)) {
488 ret = PTR_ERR(max9867->regmap);
489 dev_err(&i2c->dev,
490 "Failed to allocate regmap: %d\n", ret);
491 return ret;
492 }
493 ret = regmap_read(max9867->regmap,
494 MAX9867_REVISION, &reg);
495 if (ret < 0) {
496 dev_err(&i2c->dev, "Failed to read: %d\n", ret);
497 return ret;
498 }
499 dev_info(&i2c->dev, "device revision: %x\n", reg);
500 ret = snd_soc_register_codec(&i2c->dev, &max9867_codec,
501 max9867_dai, ARRAY_SIZE(max9867_dai));
502 if (ret < 0) {
503 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
504 return ret;
505 }
506 return ret;
507}
508
509static int max9867_i2c_remove(struct i2c_client *client)
510{
511 snd_soc_unregister_codec(&client->dev);
512 return 0;
513}
514
515static const struct i2c_device_id max9867_i2c_id[] = {
516 { "max9867", 0 },
517 { }
518};
519
520static const struct of_device_id max9867_of_match[] = {
521 { .compatible = "maxim,max9867", },
522 { }
523};
524
525MODULE_DEVICE_TABLE(i2c, max9867_i2c_id);
526
527static const struct dev_pm_ops max9867_pm_ops = {
528 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume)
529};
530
531static struct i2c_driver max9867_i2c_driver = {
532 .driver = {
533 .name = "max9867",
534 .of_match_table = of_match_ptr(max9867_of_match),
535 .pm = &max9867_pm_ops,
536 },
537 .probe = max9867_i2c_probe,
538 .remove = max9867_i2c_remove,
539 .id_table = max9867_i2c_id,
540};
541
542module_i2c_driver(max9867_i2c_driver);
543
544MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
545MODULE_DESCRIPTION("ALSA SoC MAX9867 driver");
546MODULE_LICENSE("GPL");
sound/soc/codecs/max9867.h+83−0
@@ -0,0 +1,83 @@
1/*
2 * max9867.h -- MAX9867 ALSA SoC Audio driver
3 *
4 * Copyright 2013-2015 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX9867_H
12#define _MAX9867_H
13
14/* MAX9867 register space */
15
16#define MAX9867_STATUS 0x00
17#define MAX9867_JACKSTATUS 0x01
18#define MAX9867_AUXHIGH 0x02
19#define MAX9867_AUXLOW 0x03
20#define MAX9867_INTEN 0x04
21#define MAX9867_SYSCLK 0x05
22#define MAX9867_FREQ_MASK 0xF
23#define MAX9867_PSCLK_SHIFT 0x4
24#define MAX9867_PSCLK_WIDTH 0x2
25#define MAX9867_PSCLK_MASK (0x03<<MAX9867_PSCLK_SHIFT)
26#define MAX9867_PSCLK_10_20 0x1
27#define MAX9867_PSCLK_20_40 0x2
28#define MAX9867_PSCLK_40_60 0x3
29#define MAX9867_AUDIOCLKHIGH 0x06
30#define MAX9867_NI_HIGH_WIDTH 0x7
31#define MAX9867_NI_HIGH_MASK 0x7F
32#define MAX9867_NI_LOW_MASK 0x7F
33#define MAX9867_NI_LOW_SHIFT 0x1
34#define MAX9867_PLL (1<<7)
35#define MAX9867_AUDIOCLKLOW 0x07
36#define MAX9867_RAPID_LOCK 0x01
37#define MAX9867_IFC1A 0x08
38#define MAX9867_MASTER (1<<7)
39#define MAX9867_I2S_DLY (1<<4)
40#define MAX9867_SDOUT_HIZ (1<<3)
41#define MAX9867_TDM_MODE (1<<2)
42#define MAX9867_WCI_MODE (1<<6)
43#define MAX9867_BCI_MODE (1<<5)
44#define MAX9867_IFC1B 0x09
45#define MAX9867_IFC1B_BCLK_MASK 7
46#define MAX9867_IFC1B_32BIT 0x01
47#define MAX9867_IFC1B_24BIT 0x02
48#define MAX9867_IFC1B_PCLK_2 4
49#define MAX9867_IFC1B_PCLK_4 5
50#define MAX9867_IFC1B_PCLK_8 6
51#define MAX9867_IFC1B_PCLK_16 7
52#define MAX9867_CODECFLTR 0x0a
53#define MAX9867_DACGAIN 0x0b
54#define MAX9867_DACLEVEL 0x0c
55#define MAX9867_DAC_MUTE_SHIFT 0x6
56#define MAX9867_DAC_MUTE_WIDTH 0x1
57#define MAX9867_DAC_MUTE_MASK (0x1<<MAX9867_DAC_MUTE_SHIFT)
58#define MAX9867_ADCLEVEL 0x0d
59#define MAX9867_LEFTLINELVL 0x0e
60#define MAX9867_RIGTHLINELVL 0x0f
61#define MAX9867_LEFTVOL 0x10
62#define MAX9867_RIGHTVOL 0x11
63#define MAX9867_LEFTMICGAIN 0x12
64#define MAX9867_RIGHTMICGAIN 0x13
65#define MAX9867_INPUTCONFIG 0x14
66#define MAX9867_INPUT_SHIFT 0x6
67#define MAX9867_MICCONFIG 0x15
68#define MAX9867_MODECONFIG 0x16
69#define MAX9867_PWRMAN 0x17
70#define MAX9867_SHTDOWN_MASK (1<<7)
71#define MAX9867_REVISION 0xff
72
73#define MAX9867_CACHEREGNUM 10
74
75/* codec private data */
76struct max9867_priv {
77 struct regmap *regmap;
78 struct snd_soc_codec *codec;
79 unsigned int sysclk;
80 unsigned int pclk;
81 unsigned int master;
82};
83#endif
sound/soc/codecs/max98926.c+606−0
@@ -0,0 +1,606 @@
1/*
2 * max98926.c -- ALSA SoC MAX98926 driver
3 * Copyright 2013-15 Maxim Integrated Products
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/delay.h>
9#include <linux/i2c.h>
10#include <linux/module.h>
11#include <linux/regmap.h>
12#include <linux/slab.h>
13#include <linux/cdev.h>
14#include <sound/pcm.h>
15#include <sound/pcm_params.h>
16#include <sound/soc.h>
17#include <sound/tlv.h>
18#include "max98926.h"
19
20static const char * const max98926_boost_voltage_txt[] = {
21 "8.5V", "8.25V", "8.0V", "7.75V", "7.5V", "7.25V", "7.0V", "6.75V",
22 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
23};
24
25static const char * const max98926_boost_current_txt[] = {
26 "0.6", "0.8", "1.0", "1.2", "1.4", "1.6", "1.8", "2.0",
27 "2.2", "2.4", "2.6", "2.8", "3.2", "3.6", "4.0", "4.4"
28};
29
30static const char *const max98926_dai_txt[] = {
31 "Left", "Right", "LeftRight", "LeftRightDiv2",
32};
33
34static const char *const max98926_pdm_ch_text[] = {
35 "Current", "Voltage",
36};
37
38static const char *const max98926_hpf_cutoff_txt[] = {
39 "Disable", "DC Block", "100Hz",
40 "200Hz", "400Hz", "800Hz",
41};
42
43static const struct reg_default max98926_reg[] = {
44 { 0x0B, 0x00 }, /* IRQ Enable0 */
45 { 0x0C, 0x00 }, /* IRQ Enable1 */
46 { 0x0D, 0x00 }, /* IRQ Enable2 */
47 { 0x0E, 0x00 }, /* IRQ Clear0 */
48 { 0x0F, 0x00 }, /* IRQ Clear1 */
49 { 0x10, 0x00 }, /* IRQ Clear2 */
50 { 0x11, 0xC0 }, /* Map0 */
51 { 0x12, 0x00 }, /* Map1 */
52 { 0x13, 0x00 }, /* Map2 */
53 { 0x14, 0xF0 }, /* Map3 */
54 { 0x15, 0x00 }, /* Map4 */
55 { 0x16, 0xAB }, /* Map5 */
56 { 0x17, 0x89 }, /* Map6 */
57 { 0x18, 0x00 }, /* Map7 */
58 { 0x19, 0x00 }, /* Map8 */
59 { 0x1A, 0x04 }, /* DAI Clock Mode 1 */
60 { 0x1B, 0x00 }, /* DAI Clock Mode 2 */
61 { 0x1C, 0x00 }, /* DAI Clock Divider Denominator MSBs */
62 { 0x1D, 0x00 }, /* DAI Clock Divider Denominator LSBs */
63 { 0x1E, 0xF0 }, /* DAI Clock Divider Numerator MSBs */
64 { 0x1F, 0x00 }, /* DAI Clock Divider Numerator LSBs */
65 { 0x20, 0x50 }, /* Format */
66 { 0x21, 0x00 }, /* TDM Slot Select */
67 { 0x22, 0x00 }, /* DOUT Configuration VMON */
68 { 0x23, 0x00 }, /* DOUT Configuration IMON */
69 { 0x24, 0x00 }, /* DOUT Configuration VBAT */
70 { 0x25, 0x00 }, /* DOUT Configuration VBST */
71 { 0x26, 0x00 }, /* DOUT Configuration FLAG */
72 { 0x27, 0xFF }, /* DOUT HiZ Configuration 1 */
73 { 0x28, 0xFF }, /* DOUT HiZ Configuration 2 */
74 { 0x29, 0xFF }, /* DOUT HiZ Configuration 3 */
75 { 0x2A, 0xFF }, /* DOUT HiZ Configuration 4 */
76 { 0x2B, 0x02 }, /* DOUT Drive Strength */
77 { 0x2C, 0x90 }, /* Filters */
78 { 0x2D, 0x00 }, /* Gain */
79 { 0x2E, 0x02 }, /* Gain Ramping */
80 { 0x2F, 0x00 }, /* Speaker Amplifier */
81 { 0x30, 0x0A }, /* Threshold */
82 { 0x31, 0x00 }, /* ALC Attack */
83 { 0x32, 0x80 }, /* ALC Atten and Release */
84 { 0x33, 0x00 }, /* ALC Infinite Hold Release */
85 { 0x34, 0x92 }, /* ALC Configuration */
86 { 0x35, 0x01 }, /* Boost Converter */
87 { 0x36, 0x00 }, /* Block Enable */
88 { 0x37, 0x00 }, /* Configuration */
89 { 0x38, 0x00 }, /* Global Enable */
90 { 0x3A, 0x00 }, /* Boost Limiter */
91};
92
93static const struct soc_enum max98926_voltage_enum[] = {
94 SOC_ENUM_SINGLE(MAX98926_DAI_CLK_DIV_N_LSBS, 0,
95 ARRAY_SIZE(max98926_pdm_ch_text),
96 max98926_pdm_ch_text),
97};
98
99static const struct snd_kcontrol_new max98926_voltage_control =
100 SOC_DAPM_ENUM("Route", max98926_voltage_enum);
101
102static const struct soc_enum max98926_current_enum[] = {
103 SOC_ENUM_SINGLE(MAX98926_DAI_CLK_DIV_N_LSBS,
104 MAX98926_PDM_SOURCE_1_SHIFT,
105 ARRAY_SIZE(max98926_pdm_ch_text),
106 max98926_pdm_ch_text),
107};
108
109static const struct snd_kcontrol_new max98926_current_control =
110 SOC_DAPM_ENUM("Route", max98926_current_enum);
111
112static const struct snd_kcontrol_new max98926_mixer_controls[] = {
113 SOC_DAPM_SINGLE("PCM Single Switch", MAX98926_SPK_AMP,
114 MAX98926_INSELECT_MODE_SHIFT, 0, 0),
115 SOC_DAPM_SINGLE("PDM Single Switch", MAX98926_SPK_AMP,
116 MAX98926_INSELECT_MODE_SHIFT, 1, 0),
117};
118
119static const struct snd_kcontrol_new max98926_dai_controls[] = {
120 SOC_DAPM_SINGLE("Left", MAX98926_GAIN,
121 MAX98926_DAC_IN_SEL_SHIFT, 0, 0),
122 SOC_DAPM_SINGLE("Right", MAX98926_GAIN,
123 MAX98926_DAC_IN_SEL_SHIFT, 1, 0),
124 SOC_DAPM_SINGLE("LeftRight", MAX98926_GAIN,
125 MAX98926_DAC_IN_SEL_SHIFT, 2, 0),
126 SOC_DAPM_SINGLE("(Left+Right)/2 Switch", MAX98926_GAIN,
127 MAX98926_DAC_IN_SEL_SHIFT, 3, 0),
128};
129
130static const struct snd_soc_dapm_widget max98926_dapm_widgets[] = {
131 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0,
132 SND_SOC_NOPM, 0, 0),
133 SND_SOC_DAPM_DAC("Amp Enable", NULL, MAX98926_BLOCK_ENABLE,
134 MAX98926_SPK_EN_SHIFT, 0),
135 SND_SOC_DAPM_SUPPLY("Global Enable", MAX98926_GLOBAL_ENABLE,
136 MAX98926_EN_SHIFT, 0, NULL, 0),
137 SND_SOC_DAPM_SUPPLY("VI Enable", MAX98926_BLOCK_ENABLE,
138 MAX98926_ADC_IMON_EN_WIDTH |
139 MAX98926_ADC_VMON_EN_SHIFT,
140 0, NULL, 0),
141 SND_SOC_DAPM_PGA("BST Enable", MAX98926_BLOCK_ENABLE,
142 MAX98926_BST_EN_SHIFT, 0, NULL, 0),
143 SND_SOC_DAPM_OUTPUT("BE_OUT"),
144 SND_SOC_DAPM_MIXER("PCM Sel", MAX98926_SPK_AMP,
145 MAX98926_INSELECT_MODE_SHIFT, 0,
146 &max98926_mixer_controls[0],
147 ARRAY_SIZE(max98926_mixer_controls)),
148 SND_SOC_DAPM_MIXER("DAI Sel",
149 MAX98926_GAIN, MAX98926_DAC_IN_SEL_SHIFT, 0,
150 &max98926_dai_controls[0],
151 ARRAY_SIZE(max98926_dai_controls)),
152 SND_SOC_DAPM_MUX("PDM CH1 Source",
153 MAX98926_DAI_CLK_DIV_N_LSBS,
154 MAX98926_PDM_CURRENT_SHIFT,
155 0, &max98926_current_control),
156 SND_SOC_DAPM_MUX("PDM CH0 Source",
157 MAX98926_DAI_CLK_DIV_N_LSBS,
158 MAX98926_PDM_VOLTAGE_SHIFT,
159 0, &max98926_voltage_control),
160};
161
162static const struct snd_soc_dapm_route max98926_audio_map[] = {
163 {"VI Enable", NULL, "DAI_OUT"},
164 {"DAI Sel", "Left", "VI Enable"},
165 {"DAI Sel", "Right", "VI Enable"},
166 {"DAI Sel", "LeftRight", "VI Enable"},
167 {"DAI Sel", "LeftRightDiv2", "VI Enable"},
168 {"PCM Sel", "PCM", "DAI Sel"},
169
170 {"PDM CH1 Source", "Current", "DAI_OUT"},
171 {"PDM CH1 Source", "Voltage", "DAI_OUT"},
172 {"PDM CH0 Source", "Current", "DAI_OUT"},
173 {"PDM CH0 Source", "Voltage", "DAI_OUT"},
174 {"PCM Sel", "Analog", "PDM CH1 Source"},
175 {"PCM Sel", "Analog", "PDM CH0 Source"},
176 {"Amp Enable", NULL, "PCM Sel"},
177
178 {"BST Enable", NULL, "Amp Enable"},
179 {"BE_OUT", NULL, "BST Enable"},
180};
181
182static bool max98926_volatile_register(struct device *dev, unsigned int reg)
183{
184 switch (reg) {
185 case MAX98926_VBAT_DATA:
186 case MAX98926_VBST_DATA:
187 case MAX98926_LIVE_STATUS0:
188 case MAX98926_LIVE_STATUS1:
189 case MAX98926_LIVE_STATUS2:
190 case MAX98926_STATE0:
191 case MAX98926_STATE1:
192 case MAX98926_STATE2:
193 case MAX98926_FLAG0:
194 case MAX98926_FLAG1:
195 case MAX98926_FLAG2:
196 case MAX98926_VERSION:
197 return true;
198 default:
199 return false;
200 }
201}
202
203static bool max98926_readable_register(struct device *dev, unsigned int reg)
204{
205 switch (reg) {
206 case MAX98926_IRQ_CLEAR0:
207 case MAX98926_IRQ_CLEAR1:
208 case MAX98926_IRQ_CLEAR2:
209 case MAX98926_ALC_HOLD_RLS:
210 return false;
211 default:
212 return true;
213 }
214};
215
216DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0);
217DECLARE_TLV_DB_RANGE(max98926_current_tlv,
218 0, 11, TLV_DB_SCALE_ITEM(20, 20, 0),
219 12, 15, TLV_DB_SCALE_ITEM(320, 40, 0),
220);
221
222static SOC_ENUM_SINGLE_DECL(max98926_dac_hpf_cutoff,
223 MAX98926_FILTERS, MAX98926_DAC_HPF_SHIFT,
224 max98926_hpf_cutoff_txt);
225
226static SOC_ENUM_SINGLE_DECL(max98926_boost_voltage,
227 MAX98926_CONFIGURATION, MAX98926_BST_VOUT_SHIFT,
228 max98926_boost_voltage_txt);
229
230static const struct snd_kcontrol_new max98926_snd_controls[] = {
231 SOC_SINGLE_TLV("Speaker Volume", MAX98926_GAIN,
232 MAX98926_SPK_GAIN_SHIFT,
233 (1<<MAX98926_SPK_GAIN_WIDTH)-1, 0,
234 max98926_spk_tlv),
235 SOC_SINGLE("Ramp Switch", MAX98926_GAIN_RAMPING,
236 MAX98926_SPK_RMP_EN_SHIFT, 1, 0),
237 SOC_SINGLE("ZCD Switch", MAX98926_GAIN_RAMPING,
238 MAX98926_SPK_ZCD_EN_SHIFT, 1, 0),
239 SOC_SINGLE("ALC Switch", MAX98926_THRESHOLD,
240 MAX98926_ALC_EN_SHIFT, 1, 0),
241 SOC_SINGLE("ALC Threshold", MAX98926_THRESHOLD,
242 MAX98926_ALC_TH_SHIFT,
243 (1<<MAX98926_ALC_TH_WIDTH)-1, 0),
244 SOC_ENUM("Boost Output Voltage", max98926_boost_voltage),
245 SOC_SINGLE_TLV("Boost Current Limit", MAX98926_BOOST_LIMITER,
246 MAX98926_BST_ILIM_SHIFT,
247 (1<<MAX98926_BST_ILIM_SHIFT)-1, 0,
248 max98926_current_tlv),
249 SOC_ENUM("DAC HPF Cutoff", max98926_dac_hpf_cutoff),
250 SOC_DOUBLE("PDM Channel One", MAX98926_DAI_CLK_DIV_N_LSBS,
251 MAX98926_PDM_CHANNEL_1_SHIFT,
252 MAX98926_PDM_CHANNEL_1_HIZ, 1, 0),
253 SOC_DOUBLE("PDM Channel Zero", MAX98926_DAI_CLK_DIV_N_LSBS,
254 MAX98926_PDM_CHANNEL_0_SHIFT,
255 MAX98926_PDM_CHANNEL_0_HIZ, 1, 0),
256};
257
258static const struct {
259 int rate;
260 int sr;
261} rate_table[] = {
262 {
263 .rate = 8000,
264 .sr = 0,
265 },
266 {
267 .rate = 11025,
268 .sr = 1,
269 },
270 {
271 .rate = 12000,
272 .sr = 2,
273 },
274 {
275 .rate = 16000,
276 .sr = 3,
277 },
278 {
279 .rate = 22050,
280 .sr = 4,
281 },
282 {
283 .rate = 24000,
284 .sr = 5,
285 },
286 {
287 .rate = 32000,
288 .sr = 6,
289 },
290 {
291 .rate = 44100,
292 .sr = 7,
293 },
294 {
295 .rate = 48000,
296 .sr = 8,
297 },
298};
299
300static void max98926_set_sense_data(struct max98926_priv *max98926)
301{
302 regmap_update_bits(max98926->regmap,
303 MAX98926_DOUT_CFG_VMON,
304 MAX98926_DAI_VMON_EN_MASK,
305 MAX98926_DAI_VMON_EN_MASK);
306 regmap_update_bits(max98926->regmap,
307 MAX98926_DOUT_CFG_IMON,
308 MAX98926_DAI_IMON_EN_MASK,
309 MAX98926_DAI_IMON_EN_MASK);
310
311 if (!max98926->interleave_mode) {
312 /* set VMON slots */
313 regmap_update_bits(max98926->regmap,
314 MAX98926_DOUT_CFG_VMON,
315 MAX98926_DAI_VMON_SLOT_MASK,
316 max98926->v_slot);
317 /* set IMON slots */
318 regmap_update_bits(max98926->regmap,
319 MAX98926_DOUT_CFG_IMON,
320 MAX98926_DAI_IMON_SLOT_MASK,
321 max98926->i_slot);
322 } else {
323 /* enable interleave mode */
324 regmap_update_bits(max98926->regmap,
325 MAX98926_FORMAT,
326 MAX98926_DAI_INTERLEAVE_MASK,
327 MAX98926_DAI_INTERLEAVE_MASK);
328 /* set interleave slots */
329 regmap_update_bits(max98926->regmap,
330 MAX98926_DOUT_CFG_VBAT,
331 MAX98926_DAI_INTERLEAVE_SLOT_MASK,
332 max98926->v_slot);
333 }
334}
335
336static int max98926_dai_set_fmt(struct snd_soc_dai *codec_dai,
337 unsigned int fmt)
338{
339 struct snd_soc_codec *codec = codec_dai->codec;
340 struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
341 unsigned int invert = 0;
342
343 dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
344
345 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
346 case SND_SOC_DAIFMT_CBS_CFS:
347 max98926_set_sense_data(max98926);
348 break;
349 default:
350 dev_err(codec->dev, "DAI clock mode unsupported");
351 return -EINVAL;
352 }
353
354 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
355 case SND_SOC_DAIFMT_NB_NF:
356 break;
357 case SND_SOC_DAIFMT_NB_IF:
358 invert = MAX98926_DAI_WCI_MASK;
359 break;
360 case SND_SOC_DAIFMT_IB_NF:
361 invert = MAX98926_DAI_BCI_MASK;
362 break;
363 case SND_SOC_DAIFMT_IB_IF:
364 invert = MAX98926_DAI_BCI_MASK | MAX98926_DAI_WCI_MASK;
365 break;
366 default:
367 dev_err(codec->dev, "DAI invert mode unsupported");
368 return -EINVAL;
369 }
370
371 regmap_write(max98926->regmap,
372 MAX98926_FORMAT, MAX98926_DAI_DLY_MASK);
373 regmap_update_bits(max98926->regmap, MAX98926_FORMAT,
374 MAX98926_DAI_BCI_MASK, invert);
375 return 0;
376}
377
378static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
379 struct snd_pcm_hw_params *params,
380 struct snd_soc_dai *dai)
381{
382 int dai_sr = -EINVAL;
383 int rate = params_rate(params), i;
384 struct snd_soc_codec *codec = dai->codec;
385 struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
386 int blr_clk_ratio;
387
388 switch (params_format(params)) {
389 case SNDRV_PCM_FORMAT_S16_LE:
390 regmap_update_bits(max98926->regmap,
391 MAX98926_FORMAT,
392 MAX98926_DAI_CHANSZ_MASK,
393 MAX98926_DAI_CHANSZ_16);
394 max98926->ch_size = 16;
395 break;
396 case SNDRV_PCM_FORMAT_S24_LE:
397 regmap_update_bits(max98926->regmap,
398 MAX98926_FORMAT,
399 MAX98926_DAI_CHANSZ_MASK,
400 MAX98926_DAI_CHANSZ_24);
401 max98926->ch_size = 24;
402 break;
403 case SNDRV_PCM_FORMAT_S32_LE:
404 regmap_update_bits(max98926->regmap,
405 MAX98926_FORMAT,
406 MAX98926_DAI_CHANSZ_MASK,
407 MAX98926_DAI_CHANSZ_32);
408 max98926->ch_size = 32;
409 break;
410 default:
411 dev_dbg(codec->dev, "format unsupported %d",
412 params_format(params));
413 return -EINVAL;
414 }
415
416 /* BCLK/LRCLK ratio calculation */
417 blr_clk_ratio = params_channels(params) * max98926->ch_size;
418
419 switch (blr_clk_ratio) {
420 case 32:
421 regmap_update_bits(max98926->regmap,
422 MAX98926_DAI_CLK_MODE2,
423 MAX98926_DAI_BSEL_MASK,
424 MAX98926_DAI_BSEL_32);
425 break;
426 case 48:
427 regmap_update_bits(max98926->regmap,
428 MAX98926_DAI_CLK_MODE2,
429 MAX98926_DAI_BSEL_MASK,
430 MAX98926_DAI_BSEL_48);
431 break;
432 case 64:
433 regmap_update_bits(max98926->regmap,
434 MAX98926_DAI_CLK_MODE2,
435 MAX98926_DAI_BSEL_MASK,
436 MAX98926_DAI_BSEL_64);
437 break;
438 default:
439 return -EINVAL;
440 }
441
442 /* find the closest rate */
443 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
444 if (rate_table[i].rate >= rate) {
445 dai_sr = rate_table[i].sr;
446 break;
447 }
448 }
449 if (dai_sr < 0)
450 return -EINVAL;
451
452 /* set DAI_SR to correct LRCLK frequency */
453 regmap_update_bits(max98926->regmap,
454 MAX98926_DAI_CLK_MODE2,
455 MAX98926_DAI_SR_MASK, dai_sr << MAX98926_DAI_SR_SHIFT);
456 return 0;
457}
458
459#define MAX98926_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
460 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
461
462static struct snd_soc_dai_ops max98926_dai_ops = {
463 .set_fmt = max98926_dai_set_fmt,
464 .hw_params = max98926_dai_hw_params,
465};
466
467static struct snd_soc_dai_driver max98926_dai[] = {
468{
469 .name = "max98926-aif1",
470 .playback = {
471 .stream_name = "HiFi Playback",
472 .channels_min = 1,
473 .channels_max = 2,
474 .rates = SNDRV_PCM_RATE_8000_48000,
475 .formats = MAX98926_FORMATS,
476 },
477 .capture = {
478 .stream_name = "HiFi Capture",
479 .channels_min = 1,
480 .channels_max = 2,
481 .rates = SNDRV_PCM_RATE_8000_48000,
482 .formats = MAX98926_FORMATS,
483 },
484 .ops = &max98926_dai_ops,
485}
486};
487
488static int max98926_probe(struct snd_soc_codec *codec)
489{
490 struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec);
491
492 max98926->codec = codec;
493 codec->control_data = max98926->regmap;
494 /* Hi-Z all the slots */
495 regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0);
496 return 0;
497}
498
499static struct snd_soc_codec_driver soc_codec_dev_max98926 = {
500 .probe = max98926_probe,
501 .controls = max98926_snd_controls,
502 .num_controls = ARRAY_SIZE(max98926_snd_controls),
503 .dapm_routes = max98926_audio_map,
504 .num_dapm_routes = ARRAY_SIZE(max98926_audio_map),
505 .dapm_widgets = max98926_dapm_widgets,
506 .num_dapm_widgets = ARRAY_SIZE(max98926_dapm_widgets),
507};
508
509static const struct regmap_config max98926_regmap = {
510 .reg_bits = 8,
511 .val_bits = 8,
512 .max_register = MAX98926_VERSION,
513 .reg_defaults = max98926_reg,
514 .num_reg_defaults = ARRAY_SIZE(max98926_reg),
515 .volatile_reg = max98926_volatile_register,
516 .readable_reg = max98926_readable_register,
517 .cache_type = REGCACHE_RBTREE,
518};
519
520static int max98926_i2c_probe(struct i2c_client *i2c,
521 const struct i2c_device_id *id)
522{
523 int ret, reg;
524 u32 value;
525 struct max98926_priv *max98926;
526
527 max98926 = devm_kzalloc(&i2c->dev,
528 sizeof(*max98926), GFP_KERNEL);
529 if (!max98926)
530 return -ENOMEM;
531
532 i2c_set_clientdata(i2c, max98926);
533 max98926->regmap = devm_regmap_init_i2c(i2c, &max98926_regmap);
534 if (IS_ERR(max98926->regmap)) {
535 ret = PTR_ERR(max98926->regmap);
536 dev_err(&i2c->dev,
537 "Failed to allocate regmap: %d\n", ret);
538 goto err_out;
539 }
540 if (of_property_read_bool(i2c->dev.of_node, "interleave-mode"))
541 max98926->interleave_mode = true;
542
543 if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {
544 if (value > MAX98926_DAI_VMON_SLOT_1E_1F) {
545 dev_err(&i2c->dev, "vmon slot number is wrong:\n");
546 return -EINVAL;
547 }
548 max98926->v_slot = value;
549 }
550 if (!of_property_read_u32(i2c->dev.of_node, "imon-slot-no", &value)) {
551 if (value > MAX98926_DAI_IMON_SLOT_1E_1F) {
552 dev_err(&i2c->dev, "imon slot number is wrong:\n");
553 return -EINVAL;
554 }
555 max98926->i_slot = value;
556 }
557 ret = regmap_read(max98926->regmap,
558 MAX98926_VERSION, &reg);
559 if (ret < 0) {
560 dev_err(&i2c->dev, "Failed to read: %x\n", reg);
561 return ret;
562 }
563
564 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98926,
565 max98926_dai, ARRAY_SIZE(max98926_dai));
566 if (ret < 0)
567 dev_err(&i2c->dev,
568 "Failed to register codec: %d\n", ret);
569 dev_info(&i2c->dev, "device version: %x\n", reg);
570err_out:
571 return ret;
572}
573
574static int max98926_i2c_remove(struct i2c_client *client)
575{
576 snd_soc_unregister_codec(&client->dev);
577 return 0;
578}
579
580static const struct i2c_device_id max98926_i2c_id[] = {
581 { "max98926", 0 },
582 { }
583};
584MODULE_DEVICE_TABLE(i2c, max98926_i2c_id);
585
586static const struct of_device_id max98926_of_match[] = {
587 { .compatible = "maxim,max98926", },
588 { }
589};
590MODULE_DEVICE_TABLE(of, max98926_of_match);
591
592static struct i2c_driver max98926_i2c_driver = {
593 .driver = {
594 .name = "max98926",
595 .of_match_table = of_match_ptr(max98926_of_match),
596 .pm = NULL,
597 },
598 .probe = max98926_i2c_probe,
599 .remove = max98926_i2c_remove,
600 .id_table = max98926_i2c_id,
601};
602
603module_i2c_driver(max98926_i2c_driver)
604MODULE_DESCRIPTION("ALSA SoC MAX98926 driver");
605MODULE_AUTHOR("Anish kumar <anish.kumar@maximintegrated.com>");
606MODULE_LICENSE("GPL");
sound/soc/codecs/max98926.h+848−0
@@ -0,0 +1,848 @@
1/*
2 * max98926.h -- MAX98926 ALSA SoC Audio driver
3 * Copyright 2013-2015 Maxim Integrated Products
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _MAX98926_H
10#define _MAX98926_H
11
12#define MAX98926_CHIP_VERSION 0x40
13#define MAX98926_CHIP_VERSION1 0x50
14
15#define MAX98926_VBAT_DATA 0x00
16#define MAX98926_VBST_DATA 0x01
17#define MAX98926_LIVE_STATUS0 0x02
18#define MAX98926_LIVE_STATUS1 0x03
19#define MAX98926_LIVE_STATUS2 0x04
20#define MAX98926_STATE0 0x05
21#define MAX98926_STATE1 0x06
22#define MAX98926_STATE2 0x07
23#define MAX98926_FLAG0 0x08
24#define MAX98926_FLAG1 0x09
25#define MAX98926_FLAG2 0x0A
26#define MAX98926_IRQ_ENABLE0 0x0B
27#define MAX98926_IRQ_ENABLE1 0x0C
28#define MAX98926_IRQ_ENABLE2 0x0D
29#define MAX98926_IRQ_CLEAR0 0x0E
30#define MAX98926_IRQ_CLEAR1 0x0F
31#define MAX98926_IRQ_CLEAR2 0x10
32#define MAX98926_MAP0 0x11
33#define MAX98926_MAP1 0x12
34#define MAX98926_MAP2 0x13
35#define MAX98926_MAP3 0x14
36#define MAX98926_MAP4 0x15
37#define MAX98926_MAP5 0x16
38#define MAX98926_MAP6 0x17
39#define MAX98926_MAP7 0x18
40#define MAX98926_MAP8 0x19
41#define MAX98926_DAI_CLK_MODE1 0x1A
42#define MAX98926_DAI_CLK_MODE2 0x1B
43#define MAX98926_DAI_CLK_DIV_M_MSBS 0x1C
44#define MAX98926_DAI_CLK_DIV_M_LSBS 0x1D
45#define MAX98926_DAI_CLK_DIV_N_MSBS 0x1E
46#define MAX98926_DAI_CLK_DIV_N_LSBS 0x1F
47#define MAX98926_FORMAT 0x20
48#define MAX98926_TDM_SLOT_SELECT 0x21
49#define MAX98926_DOUT_CFG_VMON 0x22
50#define MAX98926_DOUT_CFG_IMON 0x23
51#define MAX98926_DOUT_CFG_VBAT 0x24
52#define MAX98926_DOUT_CFG_VBST 0x25
53#define MAX98926_DOUT_CFG_FLAG 0x26
54#define MAX98926_DOUT_HIZ_CFG1 0x27
55#define MAX98926_DOUT_HIZ_CFG2 0x28
56#define MAX98926_DOUT_HIZ_CFG3 0x29
57#define MAX98926_DOUT_HIZ_CFG4 0x2A
58#define MAX98926_DOUT_DRV_STRENGTH 0x2B
59#define MAX98926_FILTERS 0x2C
60#define MAX98926_GAIN 0x2D
61#define MAX98926_GAIN_RAMPING 0x2E
62#define MAX98926_SPK_AMP 0x2F
63#define MAX98926_THRESHOLD 0x30
64#define MAX98926_ALC_ATTACK 0x31
65#define MAX98926_ALC_ATTEN_RLS 0x32
66#define MAX98926_ALC_HOLD_RLS 0x33
67#define MAX98926_ALC_CONFIGURATION 0x34
68#define MAX98926_BOOST_CONVERTER 0x35
69#define MAX98926_BLOCK_ENABLE 0x36
70#define MAX98926_CONFIGURATION 0x37
71#define MAX98926_GLOBAL_ENABLE 0x38
72#define MAX98926_BOOST_LIMITER 0x3A
73#define MAX98926_VERSION 0xFF
74
75#define MAX98926_REG_CNT (MAX98926_R03A_BOOST_LIMITER+1)
76
77#define MAX98926_PDM_CURRENT_MASK (1<<7)
78#define MAX98926_PDM_CURRENT_SHIFT 7
79#define MAX98926_PDM_VOLTAGE_MASK (1<<3)
80#define MAX98926_PDM_VOLTAGE_SHIFT 3
81#define MAX98926_PDM_CHANNEL_0_MASK (1<<2)
82#define MAX98926_PDM_CHANNEL_0_SHIFT 2
83#define MAX98926_PDM_CHANNEL_1_MASK (1<<6)
84#define MAX98926_PDM_CHANNEL_1_SHIFT 6
85#define MAX98926_PDM_CHANNEL_1_HIZ 5
86#define MAX98926_PDM_CHANNEL_0_HIZ 1
87#define MAX98926_PDM_SOURCE_0_SHIFT 0
88#define MAX98926_PDM_SOURCE_0_MASK (1<<0)
89#define MAX98926_PDM_SOURCE_1_MASK (1<<4)
90#define MAX98926_PDM_SOURCE_1_SHIFT 4
91
92/* MAX98926 Register Bit Fields */
93
94/* MAX98926_R002_LIVE_STATUS0 */
95#define MAX98926_THERMWARN_STATUS_MASK (1<<3)
96#define MAX98926_THERMWARN_STATUS_SHIFT 3
97#define MAX98926_THERMWARN_STATUS_WIDTH 1
98#define MAX98926_THERMSHDN_STATUS_MASK (1<<1)
99#define MAX98926_THERMSHDN_STATUS_SHIFT 1
100#define MAX98926_THERMSHDN_STATUS_WIDTH 1
101
102/* MAX98926_R003_LIVE_STATUS1 */
103#define MAX98926_SPKCURNT_STATUS_MASK (1<<5)
104#define MAX98926_SPKCURNT_STATUS_SHIFT 5
105#define MAX98926_SPKCURNT_STATUS_WIDTH 1
106#define MAX98926_WATCHFAIL_STATUS_MASK (1<<4)
107#define MAX98926_WATCHFAIL_STATUS_SHIFT 4
108#define MAX98926_WATCHFAIL_STATUS_WIDTH 1
109#define MAX98926_ALCINFH_STATUS_MASK (1<<3)
110#define MAX98926_ALCINFH_STATUS_SHIFT 3
111#define MAX98926_ALCINFH_STATUS_WIDTH 1
112#define MAX98926_ALCACT_STATUS_MASK (1<<2)
113#define MAX98926_ALCACT_STATUS_SHIFT 2
114#define MAX98926_ALCACT_STATUS_WIDTH 1
115#define MAX98926_ALCMUT_STATUS_MASK (1<<1)
116#define MAX98926_ALCMUT_STATUS_SHIFT 1
117#define MAX98926_ALCMUT_STATUS_WIDTH 1
118#define MAX98926_ACLP_STATUS_MASK (1<<0)
119#define MAX98926_ACLP_STATUS_SHIFT 0
120#define MAX98926_ACLP_STATUS_WIDTH 1
121
122/* MAX98926_R004_LIVE_STATUS2 */
123#define MAX98926_SLOTOVRN_STATUS_MASK (1<<6)
124#define MAX98926_SLOTOVRN_STATUS_SHIFT 6
125#define MAX98926_SLOTOVRN_STATUS_WIDTH 1
126#define MAX98926_INVALSLOT_STATUS_MASK (1<<5)
127#define MAX98926_INVALSLOT_STATUS_SHIFT 5
128#define MAX98926_INVALSLOT_STATUS_WIDTH 1
129#define MAX98926_SLOTCNFLT_STATUS_MASK (1<<4)
130#define MAX98926_SLOTCNFLT_STATUS_SHIFT 4
131#define MAX98926_SLOTCNFLT_STATUS_WIDTH 1
132#define MAX98926_VBSTOVFL_STATUS_MASK (1<<3)
133#define MAX98926_VBSTOVFL_STATUS_SHIFT 3
134#define MAX98926_VBSTOVFL_STATUS_WIDTH 1
135#define MAX98926_VBATOVFL_STATUS_MASK (1<<2)
136#define MAX98926_VBATOVFL_STATUS_SHIFT 2
137#define MAX98926_VBATOVFL_STATUS_WIDTH 1
138#define MAX98926_IMONOVFL_STATUS_MASK (1<<1)
139#define MAX98926_IMONOVFL_STATUS_SHIFT 1
140#define MAX98926_IMONOVFL_STATUS_WIDTH 1
141#define MAX98926_VMONOVFL_STATUS_MASK (1<<0)
142#define MAX98926_VMONOVFL_STATUS_SHIFT 0
143#define MAX98926_VMONOVFL_STATUS_WIDTH 1
144
145/* MAX98926_R005_STATE0 */
146#define MAX98926_THERMWARN_END_STATE_MASK (1<<3)
147#define MAX98926_THERMWARN_END_STATE_SHIFT 3
148#define MAX98926_THERMWARN_END_STATE_WIDTH 1
149#define MAX98926_THERMWARN_BGN_STATE_MASK (1<<2)
150#define MAX98926_THERMWARN_BGN_STATE_SHIFT 1
151#define MAX98926_THERMWARN_BGN_STATE_WIDTH 1
152#define MAX98926_THERMSHDN_END_STATE_MASK (1<<1)
153#define MAX98926_THERMSHDN_END_STATE_SHIFT 1
154#define MAX98926_THERMSHDN_END_STATE_WIDTH 1
155#define MAX98926_THERMSHDN_BGN_STATE_MASK (1<<0)
156#define MAX98926_THERMSHDN_BGN_STATE_SHIFT 0
157#define MAX98926_THERMSHDN_BGN_STATE_WIDTH 1
158
159/* MAX98926_R006_STATE1 */
160#define MAX98926_SPRCURNT_STATE_MASK (1<<5)
161#define MAX98926_SPRCURNT_STATE_SHIFT 5
162#define MAX98926_SPRCURNT_STATE_WIDTH 1
163#define MAX98926_WATCHFAIL_STATE_MASK (1<<4)
164#define MAX98926_WATCHFAIL_STATE_SHIFT 4
165#define MAX98926_WATCHFAIL_STATE_WIDTH 1
166#define MAX98926_ALCINFH_STATE_MASK (1<<3)
167#define MAX98926_ALCINFH_STATE_SHIFT 3
168#define MAX98926_ALCINFH_STATE_WIDTH 1
169#define MAX98926_ALCACT_STATE_MASK (1<<2)
170#define MAX98926_ALCACT_STATE_SHIFT 2
171#define MAX98926_ALCACT_STATE_WIDTH 1
172#define MAX98926_ALCMUT_STATE_MASK (1<<1)
173#define MAX98926_ALCMUT_STATE_SHIFT 1
174#define MAX98926_ALCMUT_STATE_WIDTH 1
175#define MAX98926_ALCP_STATE_MASK (1<<0)
176#define MAX98926_ALCP_STATE_SHIFT 0
177#define MAX98926_ALCP_STATE_WIDTH 1
178
179/* MAX98926_R007_STATE2 */
180#define MAX98926_SLOTOVRN_STATE_MASK (1<<6)
181#define MAX98926_SLOTOVRN_STATE_SHIFT 6
182#define MAX98926_SLOTOVRN_STATE_WIDTH 1
183#define MAX98926_INVALSLOT_STATE_MASK (1<<5)
184#define MAX98926_INVALSLOT_STATE_SHIFT 5
185#define MAX98926_INVALSLOT_STATE_WIDTH 1
186#define MAX98926_SLOTCNFLT_STATE_MASK (1<<4)
187#define MAX98926_SLOTCNFLT_STATE_SHIFT 4
188#define MAX98926_SLOTCNFLT_STATE_WIDTH 1
189#define MAX98926_VBSTOVFL_STATE_MASK (1<<3)
190#define MAX98926_VBSTOVFL_STATE_SHIFT 3
191#define MAX98926_VBSTOVFL_STATE_WIDTH 1
192#define MAX98926_VBATOVFL_STATE_MASK (1<<2)
193#define MAX98926_VBATOVFL_STATE_SHIFT 2
194#define MAX98926_VBATOVFL_STATE_WIDTH 1
195#define MAX98926_IMONOVFL_STATE_MASK (1<<1)
196#define MAX98926_IMONOVFL_STATE_SHIFT 1
197#define MAX98926_IMONOVFL_STATE_WIDTH 1
198#define MAX98926_VMONOVFL_STATE_MASK (1<<0)
199#define MAX98926_VMONOVFL_STATE_SHIFT 0
200#define MAX98926_VMONOVFL_STATE_WIDTH 1
201
202/* MAX98926_R008_FLAG0 */
203#define MAX98926_THERMWARN_END_FLAG_MASK (1<<3)
204#define MAX98926_THERMWARN_END_FLAG_SHIFT 3
205#define MAX98926_THERMWARN_END_FLAG_WIDTH 1
206#define MAX98926_THERMWARN_BGN_FLAG_MASK (1<<2)
207#define MAX98926_THERMWARN_BGN_FLAG_SHIFT 2
208#define MAX98926_THERMWARN_BGN_FLAG_WIDTH 1
209#define MAX98926_THERMSHDN_END_FLAG_MASK (1<<1)
210#define MAX98926_THERMSHDN_END_FLAG_SHIFT 1
211#define MAX98926_THERMSHDN_END_FLAG_WIDTH 1
212#define MAX98926_THERMSHDN_BGN_FLAG_MASK (1<<0)
213#define MAX98926_THERMSHDN_BGN_FLAG_SHIFT 0
214#define MAX98926_THERMSHDN_BGN_FLAG_WIDTH 1
215
216/* MAX98926_R009_FLAG1 */
217#define MAX98926_SPKCURNT_FLAG_MASK (1<<5)
218#define MAX98926_SPKCURNT_FLAG_SHIFT 5
219#define MAX98926_SPKCURNT_FLAG_WIDTH 1
220#define MAX98926_WATCHFAIL_FLAG_MASK (1<<4)
221#define MAX98926_WATCHFAIL_FLAG_SHIFT 4
222#define MAX98926_WATCHFAIL_FLAG_WIDTH 1
223#define MAX98926_ALCINFH_FLAG_MASK (1<<3)
224#define MAX98926_ALCINFH_FLAG_SHIFT 3
225#define MAX98926_ALCINFH_FLAG_WIDTH 1
226#define MAX98926_ALCACT_FLAG_MASK (1<<2)
227#define MAX98926_ALCACT_FLAG_SHIFT 2
228#define MAX98926_ALCACT_FLAG_WIDTH 1
229#define MAX98926_ALCMUT_FLAG_MASK (1<<1)
230#define MAX98926_ALCMUT_FLAG_SHIFT 1
231#define MAX98926_ALCMUT_FLAG_WIDTH 1
232#define MAX98926_ALCP_FLAG_MASK (1<<0)
233#define MAX98926_ALCP_FLAG_SHIFT 0
234#define MAX98926_ALCP_FLAG_WIDTH 1
235
236/* MAX98926_R00A_FLAG2 */
237#define MAX98926_SLOTOVRN_FLAG_MASK (1<<6)
238#define MAX98926_SLOTOVRN_FLAG_SHIFT 6
239#define MAX98926_SLOTOVRN_FLAG_WIDTH 1
240#define MAX98926_INVALSLOT_FLAG_MASK (1<<5)
241#define MAX98926_INVALSLOT_FLAG_SHIFT 5
242#define MAX98926_INVALSLOT_FLAG_WIDTH 1
243#define MAX98926_SLOTCNFLT_FLAG_MASK (1<<4)
244#define MAX98926_SLOTCNFLT_FLAG_SHIFT 4
245#define MAX98926_SLOTCNFLT_FLAG_WIDTH 1
246#define MAX98926_VBSTOVFL_FLAG_MASK (1<<3)
247#define MAX98926_VBSTOVFL_FLAG_SHIFT 3
248#define MAX98926_VBSTOVFL_FLAG_WIDTH 1
249#define MAX98926_VBATOVFL_FLAG_MASK (1<<2)
250#define MAX98926_VBATOVFL_FLAG_SHIFT 2
251#define MAX98926_VBATOVFL_FLAG_WIDTH 1
252#define MAX98926_IMONOVFL_FLAG_MASK (1<<1)
253#define MAX98926_IMONOVFL_FLAG_SHIFT 1
254#define MAX98926_IMONOVFL_FLAG_WIDTH 1
255#define MAX98926_VMONOVFL_FLAG_MASK (1<<0)
256#define MAX98926_VMONOVFL_FLAG_SHIFT 0
257#define MAX98926_VMONOVFL_FLAG_WIDTH 1
258
259/* MAX98926_R00B_IRQ_ENABLE0 */
260#define MAX98926_THERMWARN_END_EN_MASK (1<<3)
261#define MAX98926_THERMWARN_END_EN_SHIFT 3
262#define MAX98926_THERMWARN_END_EN_WIDTH 1
263#define MAX98926_THERMWARN_BGN_EN_MASK (1<<2)
264#define MAX98926_THERMWARN_BGN_EN_SHIFT 2
265#define MAX98926_THERMWARN_BGN_EN_WIDTH 1
266#define MAX98926_THERMSHDN_END_EN_MASK (1<<1)
267#define MAX98926_THERMSHDN_END_EN_SHIFT 1
268#define MAX98926_THERMSHDN_END_EN_WIDTH 1
269#define MAX98926_THERMSHDN_BGN_EN_MASK (1<<0)
270#define MAX98926_THERMSHDN_BGN_EN_SHIFT 0
271#define MAX98926_THERMSHDN_BGN_EN_WIDTH 1
272
273/* MAX98926_R00C_IRQ_ENABLE1 */
274#define MAX98926_SPKCURNT_EN_MASK (1<<5)
275#define MAX98926_SPKCURNT_EN_SHIFT 5
276#define MAX98926_SPKCURNT_EN_WIDTH 1
277#define MAX98926_WATCHFAIL_EN_MASK (1<<4)
278#define MAX98926_WATCHFAIL_EN_SHIFT 4
279#define MAX98926_WATCHFAIL_EN_WIDTH 1
280#define MAX98926_ALCINFH_EN_MASK (1<<3)
281#define MAX98926_ALCINFH_EN_SHIFT 3
282#define MAX98926_ALCINFH_EN_WIDTH 1
283#define MAX98926_ALCACT_EN_MASK (1<<2)
284#define MAX98926_ALCACT_EN_SHIFT 2
285#define MAX98926_ALCACT_EN_WIDTH 1
286#define MAX98926_ALCMUT_EN_MASK (1<<1)
287#define MAX98926_ALCMUT_EN_SHIFT 1
288#define MAX98926_ALCMUT_EN_WIDTH 1
289#define MAX98926_ALCP_EN_MASK (1<<0)
290#define MAX98926_ALCP_EN_SHIFT 0
291#define MAX98926_ALCP_EN_WIDTH 1
292
293/* MAX98926_R00D_IRQ_ENABLE2 */
294#define MAX98926_SLOTOVRN_EN_MASK (1<<6)
295#define MAX98926_SLOTOVRN_EN_SHIFT 6
296#define MAX98926_SLOTOVRN_EN_WIDTH 1
297#define MAX98926_INVALSLOT_EN_MASK (1<<5)
298#define MAX98926_INVALSLOT_EN_SHIFT 5
299#define MAX98926_INVALSLOT_EN_WIDTH 1
300#define MAX98926_SLOTCNFLT_EN_MASK (1<<4)
301#define MAX98926_SLOTCNFLT_EN_SHIFT 4
302#define MAX98926_SLOTCNFLT_EN_WIDTH 1
303#define MAX98926_VBSTOVFL_EN_MASK (1<<3)
304#define MAX98926_VBSTOVFL_EN_SHIFT 3
305#define MAX98926_VBSTOVFL_EN_WIDTH 1
306#define MAX98926_VBATOVFL_EN_MASK (1<<2)
307#define MAX98926_VBATOVFL_EN_SHIFT 2
308#define MAX98926_VBATOVFL_EN_WIDTH 1
309#define MAX98926_IMONOVFL_EN_MASK (1<<1)
310#define MAX98926_IMONOVFL_EN_SHIFT 1
311#define MAX98926_IMONOVFL_EN_WIDTH 1
312#define MAX98926_VMONOVFL_EN_MASK (1<<0)
313#define MAX98926_VMONOVFL_EN_SHIFT 0
314#define MAX98926_VMONOVFL_EN_WIDTH 1
315
316/* MAX98926_R00E_IRQ_CLEAR0 */
317#define MAX98926_THERMWARN_END_CLR_MASK (1<<3)
318#define MAX98926_THERMWARN_END_CLR_SHIFT 3
319#define MAX98926_THERMWARN_END_CLR_WIDTH 1
320#define MAX98926_THERMWARN_BGN_CLR_MASK (1<<2)
321#define MAX98926_THERMWARN_BGN_CLR_SHIFT 2
322#define MAX98926_THERMWARN_BGN_CLR_WIDTH 1
323#define MAX98926_THERMSHDN_END_CLR_MASK (1<<1)
324#define MAX98926_THERMSHDN_END_CLR_SHIFT 1
325#define MAX98926_THERMSHDN_END_CLR_WIDTH 1
326#define MAX98926_THERMSHDN_BGN_CLR_MASK (1<<0)
327#define MAX98926_THERMSHDN_BGN_CLR_SHIFT 0
328#define MAX98926_THERMSHDN_BGN_CLR_WIDTH 1
329
330/* MAX98926_R00F_IRQ_CLEAR1 */
331#define MAX98926_SPKCURNT_CLR_MASK (1<<5)
332#define MAX98926_SPKCURNT_CLR_SHIFT 5
333#define MAX98926_SPKCURNT_CLR_WIDTH 1
334#define MAX98926_WATCHFAIL_CLR_MASK (1<<4)
335#define MAX98926_WATCHFAIL_CLR_SHIFT 4
336#define MAX98926_WATCHFAIL_CLR_WIDTH 1
337#define MAX98926_ALCINFH_CLR_MASK (1<<3)
338#define MAX98926_ALCINFH_CLR_SHIFT 3
339#define MAX98926_ALCINFH_CLR_WIDTH 1
340#define MAX98926_ALCACT_CLR_MASK (1<<2)
341#define MAX98926_ALCACT_CLR_SHIFT 2
342#define MAX98926_ALCACT_CLR_WIDTH 1
343#define MAX98926_ALCMUT_CLR_MASK (1<<1)
344#define MAX98926_ALCMUT_CLR_SHIFT 1
345#define MAX98926_ALCMUT_CLR_WIDTH 1
346#define MAX98926_ALCP_CLR_MASK (1<<0)
347#define MAX98926_ALCP_CLR_SHIFT 0
348#define MAX98926_ALCP_CLR_WIDTH 1
349
350/* MAX98926_R010_IRQ_CLEAR2 */
351#define MAX98926_SLOTOVRN_CLR_MASK (1<<6)
352#define MAX98926_SLOTOVRN_CLR_SHIFT 6
353#define MAX98926_SLOTOVRN_CLR_WIDTH 1
354#define MAX98926_INVALSLOT_CLR_MASK (1<<5)
355#define MAX98926_INVALSLOT_CLR_SHIFT 5
356#define MAX98926_INVALSLOT_CLR_WIDTH 1
357#define MAX98926_SLOTCNFLT_CLR_MASK (1<<4)
358#define MAX98926_SLOTCNFLT_CLR_SHIFT 4
359#define MAX98926_SLOTCNFLT_CLR_WIDTH 1
360#define MAX98926_VBSTOVFL_CLR_MASK (1<<3)
361#define MAX98926_VBSTOVFL_CLR_SHIFT 3
362#define MAX98926_VBSTOVFL_CLR_WIDTH 1
363#define MAX98926_VBATOVFL_CLR_MASK (1<<2)
364#define MAX98926_VBATOVFL_CLR_SHIFT 2
365#define MAX98926_VBATOVFL_CLR_WIDTH 1
366#define MAX98926_IMONOVFL_CLR_MASK (1<<1)
367#define MAX98926_IMONOVFL_CLR_SHIFT 1
368#define MAX98926_IMONOVFL_CLR_WIDTH 1
369#define MAX98926_VMONOVFL_CLR_MASK (1<<0)
370#define MAX98926_VMONOVFL_CLR_SHIFT 0
371#define MAX98926_VMONOVFL_CLR_WIDTH 1
372
373/* MAX98926_R011_MAP0 */
374#define MAX98926_ER_THERMWARN_EN_MASK (1<<7)
375#define MAX98926_ER_THERMWARN_EN_SHIFT 7
376#define MAX98926_ER_THERMWARN_EN_WIDTH 1
377#define MAX98926_ER_THERMWARN_MAP_MASK (0x07<<4)
378#define MAX98926_ER_THERMWARN_MAP_SHIFT 4
379#define MAX98926_ER_THERMWARN_MAP_WIDTH 3
380
381/* MAX98926_R012_MAP1 */
382#define MAX98926_ER_ALCMUT_EN_MASK (1<<7)
383#define MAX98926_ER_ALCMUT_EN_SHIFT 7
384#define MAX98926_ER_ALCMUT_EN_WIDTH 1
385#define MAX98926_ER_ALCMUT_MAP_MASK (0x07<<4)
386#define MAX98926_ER_ALCMUT_MAP_SHIFT 4
387#define MAX98926_ER_ALCMUT_MAP_WIDTH 3
388#define MAX98926_ER_ALCP_EN_MASK (1<<3)
389#define MAX98926_ER_ALCP_EN_SHIFT 3
390#define MAX98926_ER_ALCP_EN_WIDTH 1
391#define MAX98926_ER_ALCP_MAP_MASK (0x07<<0)
392#define MAX98926_ER_ALCP_MAP_SHIFT 0
393#define MAX98926_ER_ALCP_MAP_WIDTH 3
394
395/* MAX98926_R013_MAP2 */
396#define MAX98926_ER_ALCINFH_EN_MASK (1<<7)
397#define MAX98926_ER_ALCINFH_EN_SHIFT 7
398#define MAX98926_ER_ALCINFH_EN_WIDTH 1
399#define MAX98926_ER_ALCINFH_MAP_MASK (0x07<<4)
400#define MAX98926_ER_ALCINFH_MAP_SHIFT 4
401#define MAX98926_ER_ALCINFH_MAP_WIDTH 3
402#define MAX98926_ER_ALCACT_EN_MASK (1<<3)
403#define MAX98926_ER_ALCACT_EN_SHIFT 3
404#define MAX98926_ER_ALCACT_EN_WIDTH 1
405#define MAX98926_ER_ALCACT_MAP_MASK (0x07<<0)
406#define MAX98926_ER_ALCACT_MAP_SHIFT 0
407#define MAX98926_ER_ALCACT_MAP_WIDTH 3
408
409/* MAX98926_R014_MAP3 */
410#define MAX98926_ER_SPKCURNT_EN_MASK (1<<7)
411#define MAX98926_ER_SPKCURNT_EN_SHIFT 7
412#define MAX98926_ER_SPKCURNT_EN_WIDTH 1
413#define MAX98926_ER_SPKCURNT_MAP_MASK (0x07<<4)
414#define MAX98926_ER_SPKCURNT_MAP_SHIFT 4
415#define MAX98926_ER_SPKCURNT_MAP_WIDTH 3
416
417/* MAX98926_R015_MAP4 */
418/* RESERVED */
419
420/* MAX98926_R016_MAP5 */
421#define MAX98926_ER_IMONOVFL_EN_MASK (1<<7)
422#define MAX98926_ER_IMONOVFL_EN_SHIFT 7
423#define MAX98926_ER_IMONOVFL_EN_WIDTH 1
424#define MAX98926_ER_IMONOVFL_MAP_MASK (0x07<<4)
425#define MAX98926_ER_IMONOVFL_MAP_SHIFT 4
426#define MAX98926_ER_IMONOVFL_MAP_WIDTH 3
427#define MAX98926_ER_VMONOVFL_EN_MASK (1<<3)
428#define MAX98926_ER_VMONOVFL_EN_SHIFT 3
429#define MAX98926_ER_VMONOVFL_EN_WIDTH 1
430#define MAX98926_ER_VMONOVFL_MAP_MASK (0x07<<0)
431#define MAX98926_ER_VMONOVFL_MAP_SHIFT 0
432#define MAX98926_ER_VMONOVFL_MAP_WIDTH 3
433
434/* MAX98926_R017_MAP6 */
435#define MAX98926_ER_VBSTOVFL_EN_MASK (1<<7)
436#define MAX98926_ER_VBSTOVFL_EN_SHIFT 7
437#define MAX98926_ER_VBSTOVFL_EN_WIDTH 1
438#define MAX98926_ER_VBSTOVFL_MAP_MASK (0x07<<4)
439#define MAX98926_ER_VBSTOVFL_MAP_SHIFT 4
440#define MAX98926_ER_VBSTOVFL_MAP_WIDTH 3
441#define MAX98926_ER_VBATOVFL_EN_MASK (1<<3)
442#define MAX98926_ER_VBATOVFL_EN_SHIFT 3
443#define MAX98926_ER_VBATOVFL_EN_WIDTH 1
444#define MAX98926_ER_VBATOVFL_MAP_MASK (0x07<<0)
445#define MAX98926_ER_VBATOVFL_MAP_SHIFT 0
446#define MAX98926_ER_VBATOVFL_MAP_WIDTH 3
447
448/* MAX98926_R018_MAP7 */
449#define MAX98926_ER_INVALSLOT_EN_MASK (1<<7)
450#define MAX98926_ER_INVALSLOT_EN_SHIFT 7
451#define MAX98926_ER_INVALSLOT_EN_WIDTH 1
452#define MAX98926_ER_INVALSLOT_MAP_MASK (0x07<<4)
453#define MAX98926_ER_INVALSLOT_MAP_SHIFT 4
454#define MAX98926_ER_INVALSLOT_MAP_WIDTH 3
455#define MAX98926_ER_SLOTCNFLT_EN_MASK (1<<3)
456#define MAX98926_ER_SLOTCNFLT_EN_SHIFT 3
457#define MAX98926_ER_SLOTCNFLT_EN_WIDTH 1
458#define MAX98926_ER_SLOTCNFLT_MAP_MASK (0x07<<0)
459#define MAX98926_ER_SLOTCNFLT_MAP_SHIFT 0
460#define MAX98926_ER_SLOTCNFLT_MAP_WIDTH 3
461
462/* MAX98926_R019_MAP8 */
463#define MAX98926_ER_SLOTOVRN_EN_MASK (1<<3)
464#define MAX98926_ER_SLOTOVRN_EN_SHIFT 3
465#define MAX98926_ER_SLOTOVRN_EN_WIDTH 1
466#define MAX98926_ER_SLOTOVRN_MAP_MASK (0x07<<0)
467#define MAX98926_ER_SLOTOVRN_MAP_SHIFT 0
468#define MAX98926_ER_SLOTOVRN_MAP_WIDTH 3
469
470/* MAX98926_R01A_DAI_CLK_MODE1 */
471#define MAX98926_DAI_CLK_SOURCE_MASK (1<<6)
472#define MAX98926_DAI_CLK_SOURCE_SHIFT 6
473#define MAX98926_DAI_CLK_SOURCE_WIDTH 1
474#define MAX98926_MDLL_MULT_MASK (0x0F<<0)
475#define MAX98926_MDLL_MULT_SHIFT 0
476#define MAX98926_MDLL_MULT_WIDTH 4
477
478#define MAX98926_MDLL_MULT_MCLKx8 6
479#define MAX98926_MDLL_MULT_MCLKx16 8
480
481/* MAX98926_R01B_DAI_CLK_MODE2 */
482#define MAX98926_DAI_SR_MASK (0x0F<<4)
483#define MAX98926_DAI_SR_SHIFT 4
484#define MAX98926_DAI_SR_WIDTH 4
485#define MAX98926_DAI_MAS_MASK (1<<3)
486#define MAX98926_DAI_MAS_SHIFT 3
487#define MAX98926_DAI_MAS_WIDTH 1
488#define MAX98926_DAI_BSEL_MASK (0x07<<0)
489#define MAX98926_DAI_BSEL_SHIFT 0
490#define MAX98926_DAI_BSEL_WIDTH 3
491
492#define MAX98926_DAI_BSEL_32 (0 << MAX98926_DAI_BSEL_SHIFT)
493#define MAX98926_DAI_BSEL_48 (1 << MAX98926_DAI_BSEL_SHIFT)
494#define MAX98926_DAI_BSEL_64 (2 << MAX98926_DAI_BSEL_SHIFT)
495#define MAX98926_DAI_BSEL_256 (6 << MAX98926_DAI_BSEL_SHIFT)
496
497/* MAX98926_R01C_DAI_CLK_DIV_M_MSBS */
498#define MAX98926_DAI_M_MSBS_MASK (0xFF<<0)
499#define MAX98926_DAI_M_MSBS_SHIFT 0
500#define MAX98926_DAI_M_MSBS_WIDTH 8
501
502/* MAX98926_R01D_DAI_CLK_DIV_M_LSBS */
503#define MAX98926_DAI_M_LSBS_MASK (0xFF<<0)
504#define MAX98926_DAI_M_LSBS_SHIFT 0
505#define MAX98926_DAI_M_LSBS_WIDTH 8
506
507/* MAX98926_R01E_DAI_CLK_DIV_N_MSBS */
508#define MAX98926_DAI_N_MSBS_MASK (0x7F<<0)
509#define MAX98926_DAI_N_MSBS_SHIFT 0
510#define MAX98926_DAI_N_MSBS_WIDTH 7
511
512/* MAX98926_R01F_DAI_CLK_DIV_N_LSBS */
513#define MAX98926_DAI_N_LSBS_MASK (0xFF<<0)
514#define MAX98926_DAI_N_LSBS_SHIFT 0
515#define MAX98926_DAI_N_LSBS_WIDTH 8
516
517/* MAX98926_R020_FORMAT */
518#define MAX98926_DAI_CHANSZ_MASK (0x03<<6)
519#define MAX98926_DAI_CHANSZ_SHIFT 6
520#define MAX98926_DAI_CHANSZ_WIDTH 2
521#define MAX98926_DAI_INTERLEAVE_MASK (1<<5)
522#define MAX98926_DAI_INTERLEAVE_SHIFT 5
523#define MAX98926_DAI_INTERLEAVE_WIDTH 1
524#define MAX98926_DAI_EXTBCLK_HIZ_MASK (1<<4)
525#define MAX98926_DAI_EXTBCLK_HIZ_SHIFT 4
526#define MAX98926_DAI_EXTBCLK_HIZ_WIDTH 1
527#define MAX98926_DAI_WCI_MASK (1<<3)
528#define MAX98926_DAI_WCI_SHIFT 3
529#define MAX98926_DAI_WCI_WIDTH 1
530#define MAX98926_DAI_BCI_MASK (1<<2)
531#define MAX98926_DAI_BCI_SHIFT 2
532#define MAX98926_DAI_BCI_WIDTH 1
533#define MAX98926_DAI_DLY_MASK (1<<1)
534#define MAX98926_DAI_DLY_SHIFT 1
535#define MAX98926_DAI_DLY_WIDTH 1
536#define MAX98926_DAI_TDM_MASK (1<<0)
537#define MAX98926_DAI_TDM_SHIFT 0
538#define MAX98926_DAI_TDM_WIDTH 1
539
540#define MAX98926_DAI_CHANSZ_16 (1 << MAX98926_DAI_CHANSZ_SHIFT)
541#define MAX98926_DAI_CHANSZ_24 (2 << MAX98926_DAI_CHANSZ_SHIFT)
542#define MAX98926_DAI_CHANSZ_32 (3 << MAX98926_DAI_CHANSZ_SHIFT)
543
544/* MAX98926_R021_TDM_SLOT_SELECT */
545#define MAX98926_DAI_DO_EN_MASK (1<<7)
546#define MAX98926_DAI_DO_EN_SHIFT 7
547#define MAX98926_DAI_DO_EN_WIDTH 1
548#define MAX98926_DAI_DIN_EN_MASK (1<<6)
549#define MAX98926_DAI_DIN_EN_SHIFT 6
550#define MAX98926_DAI_DIN_EN_WIDTH 1
551#define MAX98926_DAI_INR_SOURCE_MASK (0x07<<3)
552#define MAX98926_DAI_INR_SOURCE_SHIFT 3
553#define MAX98926_DAI_INR_SOURCE_WIDTH 3
554#define MAX98926_DAI_INL_SOURCE_MASK (0x07<<0)
555#define MAX98926_DAI_INL_SOURCE_SHIFT 0
556#define MAX98926_DAI_INL_SOURCE_WIDTH 3
557
558/* MAX98926_R022_DOUT_CFG_VMON */
559#define MAX98926_DAI_VMON_EN_MASK (1<<5)
560#define MAX98926_DAI_VMON_EN_SHIFT 5
561#define MAX98926_DAI_VMON_EN_WIDTH 1
562#define MAX98926_DAI_VMON_SLOT_MASK (0x1F<<0)
563#define MAX98926_DAI_VMON_SLOT_SHIFT 0
564#define MAX98926_DAI_VMON_SLOT_WIDTH 5
565
566#define MAX98926_DAI_VMON_SLOT_00_01 (0 << MAX98926_DAI_VMON_SLOT_SHIFT)
567#define MAX98926_DAI_VMON_SLOT_01_02 (1 << MAX98926_DAI_VMON_SLOT_SHIFT)
568#define MAX98926_DAI_VMON_SLOT_02_03 (2 << MAX98926_DAI_VMON_SLOT_SHIFT)
569#define MAX98926_DAI_VMON_SLOT_03_04 (3 << MAX98926_DAI_VMON_SLOT_SHIFT)
570#define MAX98926_DAI_VMON_SLOT_04_05 (4 << MAX98926_DAI_VMON_SLOT_SHIFT)
571#define MAX98926_DAI_VMON_SLOT_05_06 (5 << MAX98926_DAI_VMON_SLOT_SHIFT)
572#define MAX98926_DAI_VMON_SLOT_06_07 (6 << MAX98926_DAI_VMON_SLOT_SHIFT)
573#define MAX98926_DAI_VMON_SLOT_07_08 (7 << MAX98926_DAI_VMON_SLOT_SHIFT)
574#define MAX98926_DAI_VMON_SLOT_08_09 (8 << MAX98926_DAI_VMON_SLOT_SHIFT)
575#define MAX98926_DAI_VMON_SLOT_09_0A (9 << MAX98926_DAI_VMON_SLOT_SHIFT)
576#define MAX98926_DAI_VMON_SLOT_0A_0B (10 << MAX98926_DAI_VMON_SLOT_SHIFT)
577#define MAX98926_DAI_VMON_SLOT_0B_0C (11 << MAX98926_DAI_VMON_SLOT_SHIFT)
578#define MAX98926_DAI_VMON_SLOT_0C_0D (12 << MAX98926_DAI_VMON_SLOT_SHIFT)
579#define MAX98926_DAI_VMON_SLOT_0D_0E (13 << MAX98926_DAI_VMON_SLOT_SHIFT)
580#define MAX98926_DAI_VMON_SLOT_0E_0F (14 << MAX98926_DAI_VMON_SLOT_SHIFT)
581#define MAX98926_DAI_VMON_SLOT_0F_10 (15 << MAX98926_DAI_VMON_SLOT_SHIFT)
582#define MAX98926_DAI_VMON_SLOT_10_11 (16 << MAX98926_DAI_VMON_SLOT_SHIFT)
583#define MAX98926_DAI_VMON_SLOT_11_12 (17 << MAX98926_DAI_VMON_SLOT_SHIFT)
584#define MAX98926_DAI_VMON_SLOT_12_13 (18 << MAX98926_DAI_VMON_SLOT_SHIFT)
585#define MAX98926_DAI_VMON_SLOT_13_14 (19 << MAX98926_DAI_VMON_SLOT_SHIFT)
586#define MAX98926_DAI_VMON_SLOT_14_15 (20 << MAX98926_DAI_VMON_SLOT_SHIFT)
587#define MAX98926_DAI_VMON_SLOT_15_16 (21 << MAX98926_DAI_VMON_SLOT_SHIFT)
588#define MAX98926_DAI_VMON_SLOT_16_17 (22 << MAX98926_DAI_VMON_SLOT_SHIFT)
589#define MAX98926_DAI_VMON_SLOT_17_18 (23 << MAX98926_DAI_VMON_SLOT_SHIFT)
590#define MAX98926_DAI_VMON_SLOT_18_19 (24 << MAX98926_DAI_VMON_SLOT_SHIFT)
591#define MAX98926_DAI_VMON_SLOT_19_1A (25 << MAX98926_DAI_VMON_SLOT_SHIFT)
592#define MAX98926_DAI_VMON_SLOT_1A_1B (26 << MAX98926_DAI_VMON_SLOT_SHIFT)
593#define MAX98926_DAI_VMON_SLOT_1B_1C (27 << MAX98926_DAI_VMON_SLOT_SHIFT)
594#define MAX98926_DAI_VMON_SLOT_1C_1D (28 << MAX98926_DAI_VMON_SLOT_SHIFT)
595#define MAX98926_DAI_VMON_SLOT_1D_1E (29 << MAX98926_DAI_VMON_SLOT_SHIFT)
596#define MAX98926_DAI_VMON_SLOT_1E_1F (30 << MAX98926_DAI_VMON_SLOT_SHIFT)
597
598/* MAX98926_R023_DOUT_CFG_IMON */
599#define MAX98926_DAI_IMON_EN_MASK (1<<5)
600#define MAX98926_DAI_IMON_EN_SHIFT 5
601#define MAX98926_DAI_IMON_EN_WIDTH 1
602#define MAX98926_DAI_IMON_SLOT_MASK (0x1F<<0)
603#define MAX98926_DAI_IMON_SLOT_SHIFT 0
604#define MAX98926_DAI_IMON_SLOT_WIDTH 5
605
606#define MAX98926_DAI_IMON_SLOT_00_01 (0 << MAX98926_DAI_IMON_SLOT_SHIFT)
607#define MAX98926_DAI_IMON_SLOT_01_02 (1 << MAX98926_DAI_IMON_SLOT_SHIFT)
608#define MAX98926_DAI_IMON_SLOT_02_03 (2 << MAX98926_DAI_IMON_SLOT_SHIFT)
609#define MAX98926_DAI_IMON_SLOT_03_04 (3 << MAX98926_DAI_IMON_SLOT_SHIFT)
610#define MAX98926_DAI_IMON_SLOT_04_05 (4 << MAX98926_DAI_IMON_SLOT_SHIFT)
611#define MAX98926_DAI_IMON_SLOT_05_06 (5 << MAX98926_DAI_IMON_SLOT_SHIFT)
612#define MAX98926_DAI_IMON_SLOT_06_07 (6 << MAX98926_DAI_IMON_SLOT_SHIFT)
613#define MAX98926_DAI_IMON_SLOT_07_08 (7 << MAX98926_DAI_IMON_SLOT_SHIFT)
614#define MAX98926_DAI_IMON_SLOT_08_09 (8 << MAX98926_DAI_IMON_SLOT_SHIFT)
615#define MAX98926_DAI_IMON_SLOT_09_0A (9 << MAX98926_DAI_IMON_SLOT_SHIFT)
616#define MAX98926_DAI_IMON_SLOT_0A_0B (10 << MAX98926_DAI_IMON_SLOT_SHIFT)
617#define MAX98926_DAI_IMON_SLOT_0B_0C (11 << MAX98926_DAI_IMON_SLOT_SHIFT)
618#define MAX98926_DAI_IMON_SLOT_0C_0D (12 << MAX98926_DAI_IMON_SLOT_SHIFT)
619#define MAX98926_DAI_IMON_SLOT_0D_0E (13 << MAX98926_DAI_IMON_SLOT_SHIFT)
620#define MAX98926_DAI_IMON_SLOT_0E_0F (14 << MAX98926_DAI_IMON_SLOT_SHIFT)
621#define MAX98926_DAI_IMON_SLOT_0F_10 (15 << MAX98926_DAI_IMON_SLOT_SHIFT)
622#define MAX98926_DAI_IMON_SLOT_10_11 (16 << MAX98926_DAI_IMON_SLOT_SHIFT)
623#define MAX98926_DAI_IMON_SLOT_11_12 (17 << MAX98926_DAI_IMON_SLOT_SHIFT)
624#define MAX98926_DAI_IMON_SLOT_12_13 (18 << MAX98926_DAI_IMON_SLOT_SHIFT)
625#define MAX98926_DAI_IMON_SLOT_13_14 (19 << MAX98926_DAI_IMON_SLOT_SHIFT)
626#define MAX98926_DAI_IMON_SLOT_14_15 (20 << MAX98926_DAI_IMON_SLOT_SHIFT)
627#define MAX98926_DAI_IMON_SLOT_15_16 (21 << MAX98926_DAI_IMON_SLOT_SHIFT)
628#define MAX98926_DAI_IMON_SLOT_16_17 (22 << MAX98926_DAI_IMON_SLOT_SHIFT)
629#define MAX98926_DAI_IMON_SLOT_17_18 (23 << MAX98926_DAI_IMON_SLOT_SHIFT)
630#define MAX98926_DAI_IMON_SLOT_18_19 (24 << MAX98926_DAI_IMON_SLOT_SHIFT)
631#define MAX98926_DAI_IMON_SLOT_19_1A (25 << MAX98926_DAI_IMON_SLOT_SHIFT)
632#define MAX98926_DAI_IMON_SLOT_1A_1B (26 << MAX98926_DAI_IMON_SLOT_SHIFT)
633#define MAX98926_DAI_IMON_SLOT_1B_1C (27 << MAX98926_DAI_IMON_SLOT_SHIFT)
634#define MAX98926_DAI_IMON_SLOT_1C_1D (28 << MAX98926_DAI_IMON_SLOT_SHIFT)
635#define MAX98926_DAI_IMON_SLOT_1D_1E (29 << MAX98926_DAI_IMON_SLOT_SHIFT)
636#define MAX98926_DAI_IMON_SLOT_1E_1F (30 << MAX98926_DAI_IMON_SLOT_SHIFT)
637
638/* MAX98926_R024_DOUT_CFG_VBAT */
639#define MAX98926_DAI_INTERLEAVE_SLOT_MASK (0x1F<<0)
640#define MAX98926_DAI_INTERLEAVE_SLOT_SHIFT 0
641#define MAX98926_DAI_INTERLEAVE_SLOT_WIDTH 5
642
643/* MAX98926_R025_DOUT_CFG_VBST */
644#define MAX98926_DAI_VBST_EN_MASK (1<<5)
645#define MAX98926_DAI_VBST_EN_SHIFT 5
646#define MAX98926_DAI_VBST_EN_WIDTH 1
647#define MAX98926_DAI_VBST_SLOT_MASK (0x1F<<0)
648#define MAX98926_DAI_VBST_SLOT_SHIFT 0
649#define MAX98926_DAI_VBST_SLOT_WIDTH 5
650
651/* MAX98926_R026_DOUT_CFG_FLAG */
652#define MAX98926_DAI_FLAG_EN_MASK (1<<5)
653#define MAX98926_DAI_FLAG_EN_SHIFT 5
654#define MAX98926_DAI_FLAG_EN_WIDTH 1
655#define MAX98926_DAI_FLAG_SLOT_MASK (0x1F<<0)
656#define MAX98926_DAI_FLAG_SLOT_SHIFT 0
657#define MAX98926_DAI_FLAG_SLOT_WIDTH 5
658
659/* MAX98926_R027_DOUT_HIZ_CFG1 */
660#define MAX98926_DAI_SLOT_HIZ_CFG1_MASK (0xFF<<0)
661#define MAX98926_DAI_SLOT_HIZ_CFG1_SHIFT 0
662#define MAX98926_DAI_SLOT_HIZ_CFG1_WIDTH 8
663
664/* MAX98926_R028_DOUT_HIZ_CFG2 */
665#define MAX98926_DAI_SLOT_HIZ_CFG2_MASK (0xFF<<0)
666#define MAX98926_DAI_SLOT_HIZ_CFG2_SHIFT 0
667#define MAX98926_DAI_SLOT_HIZ_CFG2_WIDTH 8
668
669/* MAX98926_R029_DOUT_HIZ_CFG3 */
670#define MAX98926_DAI_SLOT_HIZ_CFG3_MASK (0xFF<<0)
671#define MAX98926_DAI_SLOT_HIZ_CFG3_SHIFT 0
672#define MAX98926_DAI_SLOT_HIZ_CFG3_WIDTH 8
673
674/* MAX98926_R02A_DOUT_HIZ_CFG4 */
675#define MAX98926_DAI_SLOT_HIZ_CFG4_MASK (0xFF<<0)
676#define MAX98926_DAI_SLOT_HIZ_CFG4_SHIFT 0
677#define MAX98926_DAI_SLOT_HIZ_CFG4_WIDTH 8
678
679/* MAX98926_R02B_DOUT_DRV_STRENGTH */
680#define MAX98926_DAI_OUT_DRIVE_MASK (0x03<<0)
681#define MAX98926_DAI_OUT_DRIVE_SHIFT 0
682#define MAX98926_DAI_OUT_DRIVE_WIDTH 2
683
684/* MAX98926_R02C_FILTERS */
685#define MAX98926_ADC_DITHER_EN_MASK (1<<7)
686#define MAX98926_ADC_DITHER_EN_SHIFT 7
687#define MAX98926_ADC_DITHER_EN_WIDTH 1
688#define MAX98926_IV_DCB_EN_MASK (1<<6)
689#define MAX98926_IV_DCB_EN_SHIFT 6
690#define MAX98926_IV_DCB_EN_WIDTH 1
691#define MAX98926_DAC_DITHER_EN_MASK (1<<4)
692#define MAX98926_DAC_DITHER_EN_SHIFT 4
693#define MAX98926_DAC_DITHER_EN_WIDTH 1
694#define MAX98926_DAC_FILTER_MODE_MASK (1<<3)
695#define MAX98926_DAC_FILTER_MODE_SHIFT 3
696#define MAX98926_DAC_FILTER_MODE_WIDTH 1
697#define MAX98926_DAC_HPF_MASK (0x07<<0)
698#define MAX98926_DAC_HPF_SHIFT 0
699#define MAX98926_DAC_HPF_WIDTH 3
700#define MAX98926_DAC_HPF_DISABLE (0 << MAX98926_DAC_HPF_SHIFT)
701#define MAX98926_DAC_HPF_DC_BLOCK (1 << MAX98926_DAC_HPF_SHIFT)
702#define MAX98926_DAC_HPF_EN_100 (2 << MAX98926_DAC_HPF_SHIFT)
703#define MAX98926_DAC_HPF_EN_200 (3 << MAX98926_DAC_HPF_SHIFT)
704#define MAX98926_DAC_HPF_EN_400 (4 << MAX98926_DAC_HPF_SHIFT)
705#define MAX98926_DAC_HPF_EN_800 (5 << MAX98926_DAC_HPF_SHIFT)
706
707/* MAX98926_R02D_GAIN */
708#define MAX98926_DAC_IN_SEL_MASK (0x03<<5)
709#define MAX98926_DAC_IN_SEL_SHIFT 5
710#define MAX98926_DAC_IN_SEL_WIDTH 2
711#define MAX98926_SPK_GAIN_MASK (0x1F<<0)
712#define MAX98926_SPK_GAIN_SHIFT 0
713#define MAX98926_SPK_GAIN_WIDTH 5
714
715#define MAX98926_DAC_IN_SEL_LEFT_DAI (0 << MAX98926_DAC_IN_SEL_SHIFT)
716#define MAX98926_DAC_IN_SEL_RIGHT_DAI (1 << MAX98926_DAC_IN_SEL_SHIFT)
717#define MAX98926_DAC_IN_SEL_SUMMED_DAI (2 << MAX98926_DAC_IN_SEL_SHIFT)
718#define MAX98926_DAC_IN_SEL_DIV2_SUMMED_DAI (3 << MAX98926_DAC_IN_SEL_SHIFT)
719
720/* MAX98926_R02E_GAIN_RAMPING */
721#define MAX98926_SPK_RMP_EN_MASK (1<<1)
722#define MAX98926_SPK_RMP_EN_SHIFT 1
723#define MAX98926_SPK_RMP_EN_WIDTH 1
724#define MAX98926_SPK_ZCD_EN_MASK (1<<0)
725#define MAX98926_SPK_ZCD_EN_SHIFT 0
726#define MAX98926_SPK_ZCD_EN_WIDTH 1
727
728/* MAX98926_R02F_SPK_AMP */
729#define MAX98926_SPK_MODE_MASK (1<<0)
730#define MAX98926_SPK_MODE_SHIFT 0
731#define MAX98926_SPK_MODE_WIDTH 1
732#define MAX98926_INSELECT_MODE_MASK (1<<1)
733#define MAX98926_INSELECT_MODE_SHIFT 1
734#define MAX98926_INSELECT_MODE_WIDTH 1
735
736/* MAX98926_R030_THRESHOLD */
737#define MAX98926_ALC_EN_MASK (1<<5)
738#define MAX98926_ALC_EN_SHIFT 5
739#define MAX98926_ALC_EN_WIDTH 1
740#define MAX98926_ALC_TH_MASK (0x1F<<0)
741#define MAX98926_ALC_TH_SHIFT 0
742#define MAX98926_ALC_TH_WIDTH 5
743
744/* MAX98926_R031_ALC_ATTACK */
745#define MAX98926_ALC_ATK_STEP_MASK (0x0F<<4)
746#define MAX98926_ALC_ATK_STEP_SHIFT 4
747#define MAX98926_ALC_ATK_STEP_WIDTH 4
748#define MAX98926_ALC_ATK_RATE_MASK (0x7<<0)
749#define MAX98926_ALC_ATK_RATE_SHIFT 0
750#define MAX98926_ALC_ATK_RATE_WIDTH 3
751
752/* MAX98926_R032_ALC_ATTEN_RLS */
753#define MAX98926_ALC_MAX_ATTEN_MASK (0x0F<<4)
754#define MAX98926_ALC_MAX_ATTEN_SHIFT 4
755#define MAX98926_ALC_MAX_ATTEN_WIDTH 4
756#define MAX98926_ALC_RLS_RATE_MASK (0x7<<0)
757#define MAX98926_ALC_RLS_RATE_SHIFT 0
758#define MAX98926_ALC_RLS_RATE_WIDTH 3
759
760/* MAX98926_R033_ALC_HOLD_RLS */
761#define MAX98926_ALC_RLS_TGR_MASK (1<<0)
762#define MAX98926_ALC_RLS_TGR_SHIFT 0
763#define MAX98926_ALC_RLS_TGR_WIDTH 1
764
765/* MAX98926_R034_ALC_CONFIGURATION */
766#define MAX98926_ALC_MUTE_EN_MASK (1<<7)
767#define MAX98926_ALC_MUTE_EN_SHIFT 7
768#define MAX98926_ALC_MUTE_EN_WIDTH 1
769#define MAX98926_ALC_MUTE_DLY_MASK (0x07<<4)
770#define MAX98926_ALC_MUTE_DLY_SHIFT 4
771#define MAX98926_ALC_MUTE_DLY_WIDTH 3
772#define MAX98926_ALC_RLS_DBT_MASK (0x07<<0)
773#define MAX98926_ALC_RLS_DBT_SHIFT 0
774#define MAX98926_ALC_RLS_DBT_WIDTH 3
775
776/* MAX98926_R035_BOOST_CONVERTER */
777#define MAX98926_BST_SYNC_MASK (1<<7)
778#define MAX98926_BST_SYNC_SHIFT 7
779#define MAX98926_BST_SYNC_WIDTH 1
780#define MAX98926_BST_PHASE_MASK (0x03<<4)
781#define MAX98926_BST_PHASE_SHIFT 4
782#define MAX98926_BST_PHASE_WIDTH 2
783#define MAX98926_BST_SKIP_MODE_MASK (0x03<<0)
784#define MAX98926_BST_SKIP_MODE_SHIFT 0
785#define MAX98926_BST_SKIP_MODE_WIDTH 2
786
787/* MAX98926_R036_BLOCK_ENABLE */
788#define MAX98926_BST_EN_MASK (1<<7)
789#define MAX98926_BST_EN_SHIFT 7
790#define MAX98926_BST_EN_WIDTH 1
791#define MAX98926_WATCH_EN_MASK (1<<6)
792#define MAX98926_WATCH_EN_SHIFT 6
793#define MAX98926_WATCH_EN_WIDTH 1
794#define MAX98926_CLKMON_EN_MASK (1<<5)
795#define MAX98926_CLKMON_EN_SHIFT 5
796#define MAX98926_CLKMON_EN_WIDTH 1
797#define MAX98926_SPK_EN_MASK (1<<4)
798#define MAX98926_SPK_EN_SHIFT 4
799#define MAX98926_SPK_EN_WIDTH 1
800#define MAX98926_ADC_VBST_EN_MASK (1<<3)
801#define MAX98926_ADC_VBST_EN_SHIFT 3
802#define MAX98926_ADC_VBST_EN_WIDTH 1
803#define MAX98926_ADC_VBAT_EN_MASK (1<<2)
804#define MAX98926_ADC_VBAT_EN_SHIFT 2
805#define MAX98926_ADC_VBAT_EN_WIDTH 1
806#define MAX98926_ADC_IMON_EN_MASK (1<<1)
807#define MAX98926_ADC_IMON_EN_SHIFT 1
808#define MAX98926_ADC_IMON_EN_WIDTH 1
809#define MAX98926_ADC_VMON_EN_MASK (1<<0)
810#define MAX98926_ADC_VMON_EN_SHIFT 0
811#define MAX98926_ADC_VMON_EN_WIDTH 1
812
813/* MAX98926_R037_CONFIGURATION */
814#define MAX98926_BST_VOUT_MASK (0x0F<<4)
815#define MAX98926_BST_VOUT_SHIFT 4
816#define MAX98926_BST_VOUT_WIDTH 4
817#define MAX98926_THERMWARN_LEVEL_MASK (0x03<<2)
818#define MAX98926_THERMWARN_LEVEL_SHIFT 2
819#define MAX98926_THERMWARN_LEVEL_WIDTH 2
820#define MAX98926_WATCH_TIME_MASK (0x03<<0)
821#define MAX98926_WATCH_TIME_SHIFT 0
822#define MAX98926_WATCH_TIME_WIDTH 2
823
824/* MAX98926_R038_GLOBAL_ENABLE */
825#define MAX98926_EN_MASK (1<<7)
826#define MAX98926_EN_SHIFT 7
827#define MAX98926_EN_WIDTH 1
828
829/* MAX98926_R03A_BOOST_LIMITER */
830#define MAX98926_BST_ILIM_MASK (0xF<<4)
831#define MAX98926_BST_ILIM_SHIFT 4
832#define MAX98926_BST_ILIM_WIDTH 4
833
834/* MAX98926_R0FF_VERSION */
835#define MAX98926_REV_ID_MASK (0xFF<<0)
836#define MAX98926_REV_ID_SHIFT 0
837#define MAX98926_REV_ID_WIDTH 8
838
839struct max98926_priv {
840 struct regmap *regmap;
841 struct snd_soc_codec *codec;
842 unsigned int sysclk;
843 unsigned int v_slot;
844 unsigned int i_slot;
845 unsigned int ch_size;
846 unsigned int interleave_mode;
847};
848#endif
sound/soc/codecs/nau8825.c+126−43
@@ -84,6 +84,7 @@ static const struct nau8825_fll_attr fll_pre_scalar[] = { · 83 unmodified lines
84 84
85static const struct reg_default nau8825_reg_defaults[] = {85static const struct reg_default nau8825_reg_defaults[] = {
86 { NAU8825_REG_ENA_CTRL, 0x00ff },86 { NAU8825_REG_ENA_CTRL, 0x00ff },
87 { NAU8825_REG_IIC_ADDR_SET, 0x0 },
87 { NAU8825_REG_CLK_DIVIDER, 0x0050 },88 { NAU8825_REG_CLK_DIVIDER, 0x0050 },
88 { NAU8825_REG_FLL1, 0x0 },89 { NAU8825_REG_FLL1, 0x0 },
89 { NAU8825_REG_FLL2, 0x3126 },90 { NAU8825_REG_FLL2, 0x3126 },
@@ -158,8 +159,7 @@ static const struct reg_default nau8825_reg_defaults[] = { · 68 unmodified lines
158static bool nau8825_readable_reg(struct device *dev, unsigned int reg)159static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
159{160{
160 switch (reg) {161 switch (reg) {
161 case NAU8825_REG_ENA_CTRL:162 case NAU8825_REG_ENA_CTRL ... NAU8825_REG_FLL_VCO_RSV:
162 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:
165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
@@ -184,8 +184,7 @@ static bool nau8825_readable_reg(struct device *dev, unsigned int reg) · 18 unmodified lines
184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)
185{185{
186 switch (reg) {186 switch (reg) {
187 case NAU8825_REG_RESET ... NAU8825_REG_ENA_CTRL:187 case NAU8825_REG_RESET ... NAU8825_REG_FLL_VCO_RSV:
188 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
189 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:188 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
190 case NAU8825_REG_INTERRUPT_MASK:189 case NAU8825_REG_INTERRUPT_MASK:
191 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:190 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:
@@ -227,10 +226,42 @@ static bool nau8825_volatile_reg(struct device *dev, unsigned int reg) · 35 unmodified lines
227static int nau8825_pump_event(struct snd_soc_dapm_widget *w,226static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
228 struct snd_kcontrol *kcontrol, int event)227 struct snd_kcontrol *kcontrol, int event)
229{228{
229 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
230 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
231
230 switch (event) {232 switch (event) {
231 case SND_SOC_DAPM_POST_PMU:233 case SND_SOC_DAPM_POST_PMU:
232 /* Prevent startup click by letting charge pump to ramp up */234 /* Prevent startup click by letting charge pump to ramp up */
233 msleep(10);235 msleep(10);
236 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
237 NAU8825_JAMNODCLOW, NAU8825_JAMNODCLOW);
238 break;
239 case SND_SOC_DAPM_PRE_PMD:
240 regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
241 NAU8825_JAMNODCLOW, 0);
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 return 0;
248}
249
250static int nau8825_output_dac_event(struct snd_soc_dapm_widget *w,
251 struct snd_kcontrol *kcontrol, int event)
252{
253 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
254 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
255
256 switch (event) {
257 case SND_SOC_DAPM_PRE_PMU:
258 /* Disables the TESTDAC to let DAC signal pass through. */
259 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
260 NAU8825_BIAS_TESTDAC_EN, 0);
261 break;
262 case SND_SOC_DAPM_POST_PMD:
263 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
264 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
234 break;265 break;
235 default:266 default:
236 return -EINVAL;267 return -EINVAL;
@@ -316,10 +347,10 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { · 79 unmodified lines
316 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,347 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,
317 NAU8825_SAR_ADC_EN_SFT, 0),348 NAU8825_SAR_ADC_EN_SFT, 0),
318 349
319 SND_SOC_DAPM_DAC("ADACL", NULL, NAU8825_REG_RDAC, 12, 0),350 SND_SOC_DAPM_PGA_S("ADACL", 2, NAU8825_REG_RDAC, 12, 0, NULL, 0),
320 SND_SOC_DAPM_DAC("ADACR", NULL, NAU8825_REG_RDAC, 13, 0),351 SND_SOC_DAPM_PGA_S("ADACR", 2, NAU8825_REG_RDAC, 13, 0, NULL, 0),
321 SND_SOC_DAPM_SUPPLY("ADACL Clock", NAU8825_REG_RDAC, 8, 0, NULL, 0),352 SND_SOC_DAPM_PGA_S("ADACL Clock", 3, NAU8825_REG_RDAC, 8, 0, NULL, 0),
322 SND_SOC_DAPM_SUPPLY("ADACR Clock", NAU8825_REG_RDAC, 9, 0, NULL, 0),353 SND_SOC_DAPM_PGA_S("ADACR Clock", 3, NAU8825_REG_RDAC, 9, 0, NULL, 0),
323 354
324 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,355 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,
325 NAU8825_ENABLE_DACR_SFT, 0),356 NAU8825_ENABLE_DACR_SFT, 0),
@@ -330,29 +361,48 @@ static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = { · 4 unmodified lines
330 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),361 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),
331 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),362 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),
332 363
333 SND_SOC_DAPM_PGA("HP amp L", NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),364 SND_SOC_DAPM_PGA_S("HP amp L", 0,
334 SND_SOC_DAPM_PGA("HP amp R", NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),365 NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),
335 SND_SOC_DAPM_SUPPLY("HP amp power", NAU8825_REG_CLASSG_CTRL, 0, 0, NULL,366 SND_SOC_DAPM_PGA_S("HP amp R", 0,
336 0),367 NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),
337 368
338 SND_SOC_DAPM_SUPPLY("Charge Pump", NAU8825_REG_CHARGE_PUMP, 5, 0,369 SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8825_REG_CHARGE_PUMP, 5, 0,
339 nau8825_pump_event, SND_SOC_DAPM_POST_PMU),370 nau8825_pump_event, SND_SOC_DAPM_POST_PMU |
371 SND_SOC_DAPM_PRE_PMD),
340 372
341 SND_SOC_DAPM_PGA("Output Driver R Stage 1",373 SND_SOC_DAPM_PGA_S("Output Driver R Stage 1", 4,
342 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),374 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),
343 SND_SOC_DAPM_PGA("Output Driver L Stage 1",375 SND_SOC_DAPM_PGA_S("Output Driver L Stage 1", 4,
344 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),376 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),
345 SND_SOC_DAPM_PGA("Output Driver R Stage 2",377 SND_SOC_DAPM_PGA_S("Output Driver R Stage 2", 5,
346 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),378 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
347 SND_SOC_DAPM_PGA("Output Driver L Stage 2",379 SND_SOC_DAPM_PGA_S("Output Driver L Stage 2", 5,
348 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),380 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
349 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 1,381 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 6,
350 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),382 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
351 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 1,383 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 6,
352 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),384 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
353 385
354 SND_SOC_DAPM_PGA_S("Output DACL", 2, NAU8825_REG_CHARGE_PUMP, 8, 1, NULL, 0),386 SND_SOC_DAPM_PGA_S("Output DACL", 7,
355 SND_SOC_DAPM_PGA_S("Output DACR", 2, NAU8825_REG_CHARGE_PUMP, 9, 1, NULL, 0),387 NAU8825_REG_CHARGE_PUMP, 8, 1, nau8825_output_dac_event,
388 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
389 SND_SOC_DAPM_PGA_S("Output DACR", 7,
390 NAU8825_REG_CHARGE_PUMP, 9, 1, nau8825_output_dac_event,
391 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
392
393 /* HPOL/R are ungrounded by disabling 16 Ohm pull-downs on playback */
394 SND_SOC_DAPM_PGA_S("HPOL Pulldown", 8,
395 NAU8825_REG_HSD_CTRL, 0, 1, NULL, 0),
396 SND_SOC_DAPM_PGA_S("HPOR Pulldown", 8,
397 NAU8825_REG_HSD_CTRL, 1, 1, NULL, 0),
398
399 /* High current HPOL/R boost driver */
400 SND_SOC_DAPM_PGA_S("HP Boost Driver", 9,
401 NAU8825_REG_BOOST, 9, 1, NULL, 0),
402
403 /* Class G operation control*/
404 SND_SOC_DAPM_PGA_S("Class G", 10,
405 NAU8825_REG_CLASSG_CTRL, 0, 0, NULL, 0),
356 406
357 SND_SOC_DAPM_OUTPUT("HPOL"),407 SND_SOC_DAPM_OUTPUT("HPOL"),
358 SND_SOC_DAPM_OUTPUT("HPOR"),408 SND_SOC_DAPM_OUTPUT("HPOR"),
@@ -375,24 +425,27 @@ static const struct snd_soc_dapm_route nau8825_dapm_routes[] = { · 16 unmodified lines
375 {"DACR Mux", "DACR", "DDACR"},425 {"DACR Mux", "DACR", "DDACR"},
376 {"HP amp L", NULL, "DACL Mux"},426 {"HP amp L", NULL, "DACL Mux"},
377 {"HP amp R", NULL, "DACR Mux"},427 {"HP amp R", NULL, "DACR Mux"},
378 {"HP amp L", NULL, "HP amp power"},428 {"Charge Pump", NULL, "HP amp L"},
379 {"HP amp R", NULL, "HP amp power"},429 {"Charge Pump", NULL, "HP amp R"},
380 {"ADACL", NULL, "HP amp L"},430 {"ADACL", NULL, "Charge Pump"},
381 {"ADACR", NULL, "HP amp R"},431 {"ADACR", NULL, "Charge Pump"},
382 {"ADACL", NULL, "ADACL Clock"},432 {"ADACL Clock", NULL, "ADACL"},
383 {"ADACR", NULL, "ADACR Clock"},433 {"ADACR Clock", NULL, "ADACR"},
384 {"Output Driver L Stage 1", NULL, "ADACL"},434 {"Output Driver L Stage 1", NULL, "ADACL Clock"},
385 {"Output Driver R Stage 1", NULL, "ADACR"},435 {"Output Driver R Stage 1", NULL, "ADACR Clock"},
386 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},436 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},
387 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},437 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},
388 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},438 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},
389 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},439 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},
390 {"Output DACL", NULL, "Output Driver L Stage 3"},440 {"Output DACL", NULL, "Output Driver L Stage 3"},
391 {"Output DACR", NULL, "Output Driver R Stage 3"},441 {"Output DACR", NULL, "Output Driver R Stage 3"},
392 {"HPOL", NULL, "Output DACL"},442 {"HPOL Pulldown", NULL, "Output DACL"},
393 {"HPOR", NULL, "Output DACR"},443 {"HPOR Pulldown", NULL, "Output DACR"},
394 {"HPOL", NULL, "Charge Pump"},444 {"HP Boost Driver", NULL, "HPOL Pulldown"},
395 {"HPOR", NULL, "Charge Pump"},445 {"HP Boost Driver", NULL, "HPOR Pulldown"},
446 {"Class G", NULL, "HP Boost Driver"},
447 {"HPOL", NULL, "Class G"},
448 {"HPOR", NULL, "Class G"},
396};449};
397 450
398static int nau8825_hw_params(struct snd_pcm_substream *substream,451static int nau8825_hw_params(struct snd_pcm_substream *substream,
@@ -659,11 +712,10 @@ static int nau8825_jack_insert(struct nau8825 *nau8825) · 260 unmodified lines
659 break;712 break;
660 }713 }
661 714
662 if (type & SND_JACK_HEADPHONE) {715 /* Leaving HPOL/R grounded after jack insert by default. They will be
663 /* Unground HPL/R */716 * ungrounded as part of the widget power up sequence at the beginning
664 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0x3, 0);717 * of playback to reduce pop.
665 }718 */
666
667 return type;719 return type;
668}720}
669 721
@@ -768,6 +820,8 @@ static void nau8825_init_regs(struct nau8825 *nau8825) · 98 unmodified lines
768{820{
769 struct regmap *regmap = nau8825->regmap;821 struct regmap *regmap = nau8825->regmap;
770 822
823 /* Latch IIC LSB value */
824 regmap_write(regmap, NAU8825_REG_IIC_ADDR_SET, 0x0001);
771 /* Enable Bias/Vmid */825 /* Enable Bias/Vmid */
772 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,826 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
773 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);827 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);
@@ -780,10 +834,10 @@ static void nau8825_init_regs(struct nau8825 *nau8825) · 6 unmodified lines
780 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);834 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);
781 /* Disable Boost Driver, Automatic Short circuit protection enable */835 /* Disable Boost Driver, Automatic Short circuit protection enable */
782 regmap_update_bits(regmap, NAU8825_REG_BOOST,836 regmap_update_bits(regmap, NAU8825_REG_BOOST,
783 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |837 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
784 NAU8825_SHORT_SHUTDOWN_EN,838 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN,
785 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |839 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_DIS |
786 NAU8825_SHORT_SHUTDOWN_EN);840 NAU8825_HP_BOOST_G_DIS | NAU8825_SHORT_SHUTDOWN_EN);
787 841
788 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,842 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
789 NAU8825_JKDET_OUTPUT_EN,843 NAU8825_JKDET_OUTPUT_EN,
@@ -822,6 +876,35 @@ static void nau8825_init_regs(struct nau8825 *nau8825) · 32 unmodified lines
822 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);876 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);
823 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,877 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
824 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);878 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);
879 /* Disable DACR/L power */
880 regmap_update_bits(regmap, NAU8825_REG_CHARGE_PUMP,
881 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL,
882 NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL);
883 /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input
884 * signal to avoid any glitches due to power up transients in both
885 * the analog and digital DAC circuit.
886 */
887 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
888 NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN);
889 /* CICCLP off */
890 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
891 NAU8825_DAC_CLIP_OFF, NAU8825_DAC_CLIP_OFF);
892
893 /* Class AB bias current to 2x, DAC Capacitor enable MSB/LSB */
894 regmap_update_bits(regmap, NAU8825_REG_ANALOG_CONTROL_2,
895 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
896 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB,
897 NAU8825_HP_NON_CLASSG_CURRENT_2xADJ |
898 NAU8825_DAC_CAPACITOR_MSB | NAU8825_DAC_CAPACITOR_LSB);
899 /* Class G timer 64ms */
900 regmap_update_bits(regmap, NAU8825_REG_CLASSG_CTRL,
901 NAU8825_CLASSG_TIMER_MASK,
902 0x20 << NAU8825_CLASSG_TIMER_SFT);
903 /* DAC clock delay 2ns, VREF */
904 regmap_update_bits(regmap, NAU8825_REG_RDAC,
905 NAU8825_RDAC_CLK_DELAY_MASK | NAU8825_RDAC_VREF_MASK,
906 (0x2 << NAU8825_RDAC_CLK_DELAY_SFT) |
907 (0x3 << NAU8825_RDAC_VREF_SFT));
825}908}
826 909
827static const struct regmap_config nau8825_regmap_config = {910static const struct regmap_config nau8825_regmap_config = {
sound/soc/codecs/nau8825.h+15−1
@@ -14,6 +14,7 @@ · 13 unmodified lines
14 14
15#define NAU8825_REG_RESET 0x0015#define NAU8825_REG_RESET 0x00
16#define NAU8825_REG_ENA_CTRL 0x0116#define NAU8825_REG_ENA_CTRL 0x01
17#define NAU8825_REG_IIC_ADDR_SET 0x02
17#define NAU8825_REG_CLK_DIVIDER 0x0318#define NAU8825_REG_CLK_DIVIDER 0x03
18#define NAU8825_REG_FLL1 0x0419#define NAU8825_REG_FLL1 0x04
19#define NAU8825_REG_FLL2 0x0520#define NAU8825_REG_FLL2 0x05
@@ -129,7 +130,7 @@ · 109 unmodified lines
129 130
130/* HSD_CTRL (0xc) */131/* HSD_CTRL (0xc) */
131#define NAU8825_HSD_AUTO_MODE (1 << 6)132#define NAU8825_HSD_AUTO_MODE (1 << 6)
132/* 0 - short to GND, 1 - open */133/* 0 - open, 1 - short to GND */
133#define NAU8825_SPKR_DWN1R (1 << 1)134#define NAU8825_SPKR_DWN1R (1 << 1)
134#define NAU8825_SPKR_DWN1L (1 << 0)135#define NAU8825_SPKR_DWN1L (1 << 0)
135 136
@@ -251,12 +252,18 @@ · 115 unmodified lines
251/* DACR_CTRL (0x34) */252/* DACR_CTRL (0x34) */
252#define NAU8825_DACR_CH_SEL_SFT 9253#define NAU8825_DACR_CH_SEL_SFT 9
253 254
255/* CLASSG_CTRL (0x50) */
256#define NAU8825_CLASSG_TIMER_SFT 8
257#define NAU8825_CLASSG_TIMER_MASK (0x3f << NAU8825_CLASSG_TIMER_SFT)
258#define NAU8825_CLASSG_EN (1 << 0)
259
254/* I2C_DEVICE_ID (0x58) */260/* I2C_DEVICE_ID (0x58) */
255#define NAU8825_GPIO2JD1 (1 << 7)261#define NAU8825_GPIO2JD1 (1 << 7)
256#define NAU8825_SOFTWARE_ID_MASK 0x3262#define NAU8825_SOFTWARE_ID_MASK 0x3
257#define NAU8825_SOFTWARE_ID_NAU8825 0x0263#define NAU8825_SOFTWARE_ID_NAU8825 0x0
258 264
259/* BIAS_ADJ (0x66) */265/* BIAS_ADJ (0x66) */
266#define NAU8825_BIAS_TESTDAC_EN (0x3 << 8)
260#define NAU8825_BIAS_VMID (1 << 6)267#define NAU8825_BIAS_VMID (1 << 6)
261#define NAU8825_BIAS_VMID_SEL_SFT 4268#define NAU8825_BIAS_VMID_SEL_SFT 4
262#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)269#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)
@@ -274,6 +281,12 @@ · 11 unmodified lines
274#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8)281#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8)
275#define NAU8825_POWERUP_ADCL (1 << 6)282#define NAU8825_POWERUP_ADCL (1 << 6)
276 283
284/* RDAC (0x73) */
285#define NAU8825_RDAC_CLK_DELAY_SFT 4
286#define NAU8825_RDAC_CLK_DELAY_MASK (0x7 << NAU8825_RDAC_CLK_DELAY_SFT)
287#define NAU8825_RDAC_VREF_SFT 2
288#define NAU8825_RDAC_VREF_MASK (0x3 << NAU8825_RDAC_VREF_SFT)
289
277/* MIC_BIAS (0x74) */290/* MIC_BIAS (0x74) */
278#define NAU8825_MICBIAS_JKSLV (1 << 14)291#define NAU8825_MICBIAS_JKSLV (1 << 14)
279#define NAU8825_MICBIAS_JKR2 (1 << 12)292#define NAU8825_MICBIAS_JKR2 (1 << 12)
@@ -284,6 +297,7 @@ · 4 unmodified lines
284/* BOOST (0x76) */297/* BOOST (0x76) */
285#define NAU8825_PRECHARGE_DIS (1 << 13)298#define NAU8825_PRECHARGE_DIS (1 << 13)
286#define NAU8825_GLOBAL_BIAS_EN (1 << 12)299#define NAU8825_GLOBAL_BIAS_EN (1 << 12)
300#define NAU8825_HP_BOOST_DIS (1 << 9)
287#define NAU8825_HP_BOOST_G_DIS (1 << 8)301#define NAU8825_HP_BOOST_G_DIS (1 << 8)
288#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6)302#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6)
289 303
sound/soc/codecs/pcm179x-i2c.c+73−0
@@ -0,0 +1,73 @@
1/*
2 * PCM179X ASoC I2C driver
3 *
4 * Copyright (c) Teenage Engineering AB 2016
5 *
6 * Jacob Siverskog <jacob@teenage.engineering>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/i2c.h>
22#include <linux/regmap.h>
23
24#include "pcm179x.h"
25
26static int pcm179x_i2c_probe(struct i2c_client *client,
27 const struct i2c_device_id *id)
28{
29 struct regmap *regmap;
30 int ret;
31
32 regmap = devm_regmap_init_i2c(client, &pcm179x_regmap_config);
33 if (IS_ERR(regmap)) {
34 ret = PTR_ERR(regmap);
35 dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret);
36 return ret;
37 }
38
39 return pcm179x_common_init(&client->dev, regmap);
40}
41
42static int pcm179x_i2c_remove(struct i2c_client *client)
43{
44 return pcm179x_common_exit(&client->dev);
45}
46
47static const struct of_device_id pcm179x_of_match[] = {
48 { .compatible = "ti,pcm1792a", },
49 { }
50};
51MODULE_DEVICE_TABLE(of, pcm179x_of_match);
52
53static const struct i2c_device_id pcm179x_i2c_ids[] = {
54 { "pcm179x", 0 },
55 { }
56};
57MODULE_DEVICE_TABLE(i2c, pcm179x_i2c_ids);
58
59static struct i2c_driver pcm179x_i2c_driver = {
60 .driver = {
61 .name = "pcm179x",
62 .of_match_table = of_match_ptr(pcm179x_of_match),
63 },
64 .id_table = pcm179x_i2c_ids,
65 .probe = pcm179x_i2c_probe,
66 .remove = pcm179x_i2c_remove,
67};
68
69module_i2c_driver(pcm179x_i2c_driver);
70
71MODULE_DESCRIPTION("ASoC PCM179X I2C driver");
72MODULE_AUTHOR("Jacob Siverskog <jacob@teenage.engineering>");
73MODULE_LICENSE("GPL");
sound/soc/codecs/pcm179x-spi.c+72−0
@@ -0,0 +1,72 @@
1/*
2 * PCM179X ASoC SPI driver
3 *
4 * Copyright (c) Amarula Solutions B.V. 2013
5 *
6 * Michael Trimarchi <michael@amarulasolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/spi/spi.h>
22#include <linux/regmap.h>
23
24#include "pcm179x.h"
25
26static int pcm179x_spi_probe(struct spi_device *spi)
27{
28 struct regmap *regmap;
29 int ret;
30
31 regmap = devm_regmap_init_spi(spi, &pcm179x_regmap_config);
32 if (IS_ERR(regmap)) {
33 ret = PTR_ERR(regmap);
34 dev_err(&spi->dev, "Failed to allocate regmap: %d\n", ret);
35 return ret;
36 }
37
38 return pcm179x_common_init(&spi->dev, regmap);
39}
40
41static int pcm179x_spi_remove(struct spi_device *spi)
42{
43 return pcm179x_common_exit(&spi->dev);
44}
45
46static const struct of_device_id pcm179x_of_match[] = {
47 { .compatible = "ti,pcm1792a", },
48 { }
49};
50MODULE_DEVICE_TABLE(of, pcm179x_of_match);
51
52static const struct spi_device_id pcm179x_spi_ids[] = {
53 { "pcm179x", 0 },
54 { },
55};
56MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids);
57
58static struct spi_driver pcm179x_spi_driver = {
59 .driver = {
60 .name = "pcm179x",
61 .of_match_table = of_match_ptr(pcm179x_of_match),
62 },
63 .id_table = pcm179x_spi_ids,
64 .probe = pcm179x_spi_probe,
65 .remove = pcm179x_spi_remove,
66};
67
68module_spi_driver(pcm179x_spi_driver);
69
70MODULE_DESCRIPTION("ASoC PCM179X SPI driver");
71MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
72MODULE_LICENSE("GPL");
sound/soc/codecs/pcm179x.c+14−42
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include <linux/slab.h>20#include <linux/slab.h>
21#include <linux/kernel.h>21#include <linux/kernel.h>
22#include <linux/device.h>22#include <linux/device.h>
23#include <linux/spi/spi.h>
24 23
25#include <sound/core.h>24#include <sound/core.h>
26#include <sound/pcm.h>25#include <sound/pcm.h>
@@ -29,7 +28,6 @@ · 2 unmodified lines
29#include <sound/soc.h>28#include <sound/soc.h>
30#include <sound/tlv.h>29#include <sound/tlv.h>
31#include <linux/of.h>30#include <linux/of.h>
32#include <linux/of_device.h>
33 31
34#include "pcm179x.h"32#include "pcm179x.h"
35 33
@@ -189,18 +187,14 @@ static struct snd_soc_dai_driver pcm179x_dai = { · 153 unmodified lines
189 .stream_name = "Playback",187 .stream_name = "Playback",
190 .channels_min = 2,188 .channels_min = 2,
191 .channels_max = 2,189 .channels_max = 2,
192 .rates = PCM1792A_RATES,190 .rates = SNDRV_PCM_RATE_CONTINUOUS,
191 .rate_min = 10000,
192 .rate_max = 200000,
193 .formats = PCM1792A_FORMATS, },193 .formats = PCM1792A_FORMATS, },
194 .ops = &pcm179x_dai_ops,194 .ops = &pcm179x_dai_ops,
195};195};
196 196
197static const struct of_device_id pcm179x_of_match[] = {197const struct regmap_config pcm179x_regmap_config = {
198 { .compatible = "ti,pcm1792a", },
199 { }
200};
201MODULE_DEVICE_TABLE(of, pcm179x_of_match);
202
203static const struct regmap_config pcm179x_regmap = {
204 .reg_bits = 8,198 .reg_bits = 8,
205 .val_bits = 8,199 .val_bits = 8,
206 .max_register = 23,200 .max_register = 23,
@@ -209,6 +203,7 @@ static const struct regmap_config pcm179x_regmap = { · 2 unmodified lines
209 .writeable_reg = pcm179x_writeable_reg,203 .writeable_reg = pcm179x_writeable_reg,
210 .readable_reg = pcm179x_accessible_reg,204 .readable_reg = pcm179x_accessible_reg,
211};205};
206EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
212 207
213static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {208static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
214 .controls = pcm179x_controls,209 .controls = pcm179x_controls,
@@ -219,52 +214,29 @@ static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { · 4 unmodified lines
219 .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes),214 .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes),
220};215};
221 216
222static int pcm179x_spi_probe(struct spi_device *spi)217int pcm179x_common_init(struct device *dev, struct regmap *regmap)
223{218{
224 struct pcm179x_private *pcm179x;219 struct pcm179x_private *pcm179x;
225 int ret;
226 220
227 pcm179x = devm_kzalloc(&spi->dev, sizeof(struct pcm179x_private),221 pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private),
228 GFP_KERNEL);222 GFP_KERNEL);
229 if (!pcm179x)223 if (!pcm179x)
230 return -ENOMEM;224 return -ENOMEM;
231 225
232 spi_set_drvdata(spi, pcm179x);226 pcm179x->regmap = regmap;
233 227 dev_set_drvdata(dev, pcm179x);
234 pcm179x->regmap = devm_regmap_init_spi(spi, &pcm179x_regmap);
235 if (IS_ERR(pcm179x->regmap)) {
236 ret = PTR_ERR(pcm179x->regmap);
237 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
238 return ret;
239 }
240 228
241 return snd_soc_register_codec(&spi->dev,229 return snd_soc_register_codec(dev,
242 &soc_codec_dev_pcm179x, &pcm179x_dai, 1);230 &soc_codec_dev_pcm179x, &pcm179x_dai, 1);
243}231}
232EXPORT_SYMBOL_GPL(pcm179x_common_init);
244 233
245static int pcm179x_spi_remove(struct spi_device *spi)234int pcm179x_common_exit(struct device *dev)
246{235{
247 snd_soc_unregister_codec(&spi->dev);236 snd_soc_unregister_codec(dev);
248 return 0;237 return 0;
249}238}
250 239EXPORT_SYMBOL_GPL(pcm179x_common_exit);
251static const struct spi_device_id pcm179x_spi_ids[] = {
252 { "pcm179x", 0 },
253 { },
254};
255MODULE_DEVICE_TABLE(spi, pcm179x_spi_ids);
256
257static struct spi_driver pcm179x_codec_driver = {
258 .driver = {
259 .name = "pcm179x",
260 .of_match_table = of_match_ptr(pcm179x_of_match),
261 },
262 .id_table = pcm179x_spi_ids,
263 .probe = pcm179x_spi_probe,
264 .remove = pcm179x_spi_remove,
265};
266
267module_spi_driver(pcm179x_codec_driver);
268 240
269MODULE_DESCRIPTION("ASoC PCM179X driver");241MODULE_DESCRIPTION("ASoC PCM179X driver");
270MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");242MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
sound/soc/codecs/pcm179x.h+5−4
@@ -17,11 +17,12 @@ · 16 unmodified lines
17#ifndef __PCM179X_H__17#ifndef __PCM179X_H__
18#define __PCM179X_H__18#define __PCM179X_H__
19 19
20#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \
21 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
22 SNDRV_PCM_RATE_192000)
23
24#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \20#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
25 SNDRV_PCM_FMTBIT_S16_LE)21 SNDRV_PCM_FMTBIT_S16_LE)
26 22
23extern const struct regmap_config pcm179x_regmap_config;
24
25int pcm179x_common_init(struct device *dev, struct regmap *regmap);
26int pcm179x_common_exit(struct device *dev);
27
27#endif28#endif
sound/soc/codecs/pcm3168a.c+6−2
@@ -299,10 +299,15 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai, · 298 unmodified lines
299 int clk_id, unsigned int freq, int dir)299 int clk_id, unsigned int freq, int dir)
300{300{
301 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);301 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(dai->codec);
302 int ret;
302 303
303 if (freq > PCM1368A_MAX_SYSCLK)304 if (freq > PCM1368A_MAX_SYSCLK)
304 return -EINVAL;305 return -EINVAL;
305 306
307 ret = clk_set_rate(pcm3168a->scki, freq);
308 if (ret)
309 return ret;
310
306 pcm3168a->sysclk = freq;311 pcm3168a->sysclk = freq;
307 312
308 return 0;313 return 0;
@@ -395,13 +400,12 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, · 86 unmodified lines
395 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);400 struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
396 bool tx, master_mode;401 bool tx, master_mode;
397 u32 val, mask, shift, reg;402 u32 val, mask, shift, reg;
398 unsigned int rate, channels, fmt, ratio, max_ratio;403 unsigned int rate, fmt, ratio, max_ratio;
399 int i, min_frame_size;404 int i, min_frame_size;
400 snd_pcm_format_t format;405 snd_pcm_format_t format;
401 406
402 rate = params_rate(params);407 rate = params_rate(params);
403 format = params_format(params);408 format = params_format(params);
404 channels = params_channels(params);
405 409
406 ratio = pcm3168a->sysclk / rate;410 ratio = pcm3168a->sysclk / rate;
407 411
sound/soc/codecs/rt298.c+6−1
@@ -1224,7 +1224,12 @@ static int rt298_i2c_probe(struct i2c_client *i2c, · 1223 unmodified lines
1224 regmap_write(rt298->regmap, RT298_MISC_CTRL1, 0x0000);1224 regmap_write(rt298->regmap, RT298_MISC_CTRL1, 0x0000);
1225 regmap_update_bits(rt298->regmap,1225 regmap_update_bits(rt298->regmap,
1226 RT298_WIND_FILTER_CTRL, 0x0082, 0x0082);1226 RT298_WIND_FILTER_CTRL, 0x0082, 0x0082);
1227 regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2);1227
1228 regmap_write(rt298->regmap, RT298_UNSOLICITED_INLINE_CMD, 0x81);
1229 regmap_write(rt298->regmap, RT298_UNSOLICITED_HP_OUT, 0x82);
1230 regmap_write(rt298->regmap, RT298_UNSOLICITED_MIC1, 0x84);
1231 regmap_update_bits(rt298->regmap, RT298_IRQ_FLAG_CTRL, 0x2, 0x2);
1232
1228 rt298->is_hp_in = -1;1233 rt298->is_hp_in = -1;
1229 1234
1230 if (rt298->i2c->irq) {1235 if (rt298->i2c->irq) {
sound/soc/codecs/rt298.h+8−0
@@ -34,6 +34,7 @@ · 33 unmodified lines
34#define RT298_HP_OUT 0x2134#define RT298_HP_OUT 0x21
35#define RT298_MIXER_IN1 0x2235#define RT298_MIXER_IN1 0x22
36#define RT298_MIXER_IN2 0x2336#define RT298_MIXER_IN2 0x23
37#define RT298_INLINE_CMD 0x55
37 38
38#define RT298_SET_PIN_SFT 639#define RT298_SET_PIN_SFT 6
39#define RT298_SET_PIN_ENABLE 0x4040#define RT298_SET_PIN_ENABLE 0x40
@@ -124,6 +125,12 @@ · 84 unmodified lines
124 VERB_CMD(AC_VERB_SET_COEF_INDEX, RT298_VENDOR_REGISTERS, 0)125 VERB_CMD(AC_VERB_SET_COEF_INDEX, RT298_VENDOR_REGISTERS, 0)
125#define RT298_PROC_COEF\126#define RT298_PROC_COEF\
126 VERB_CMD(AC_VERB_SET_PROC_COEF, RT298_VENDOR_REGISTERS, 0)127 VERB_CMD(AC_VERB_SET_PROC_COEF, RT298_VENDOR_REGISTERS, 0)
128#define RT298_UNSOLICITED_INLINE_CMD\
129 VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT298_INLINE_CMD, 0)
130#define RT298_UNSOLICITED_HP_OUT\
131 VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT298_HP_OUT, 0)
132#define RT298_UNSOLICITED_MIC1\
133 VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT298_MIC1, 0)
127 134
128/* Index registers */135/* Index registers */
129#define RT298_A_BIAS_CTRL1 0x01136#define RT298_A_BIAS_CTRL1 0x01
@@ -148,6 +155,7 @@ · 18 unmodified lines
148#define RT298_DEPOP_CTRL2 0x67155#define RT298_DEPOP_CTRL2 0x67
149#define RT298_DEPOP_CTRL3 0x68156#define RT298_DEPOP_CTRL3 0x68
150#define RT298_DEPOP_CTRL4 0x69157#define RT298_DEPOP_CTRL4 0x69
158#define RT298_IRQ_FLAG_CTRL 0x7c
151 159
152/* SPDIF (0x06) */160/* SPDIF (0x06) */
153#define RT298_SPDIF_SEL_SFT 0161#define RT298_SPDIF_SEL_SFT 0
sound/soc/codecs/rt5514.c+982−0
@@ -0,0 +1,982 @@
1/*
2 * rt5514.c -- RT5514 ALSA SoC audio codec driver
3 *
4 * Copyright 2015 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/fs.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/regmap.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <linux/firmware.h>
22#include <linux/gpio.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "rl6231.h"
32#include "rt5514.h"
33
34static const struct reg_sequence rt5514_i2c_patch[] = {
35 {0x1800101c, 0x00000000},
36 {0x18001100, 0x0000031f},
37 {0x18001104, 0x00000007},
38 {0x18001108, 0x00000000},
39 {0x1800110c, 0x00000000},
40 {0x18001110, 0x00000000},
41 {0x18001114, 0x00000001},
42 {0x18001118, 0x00000000},
43 {0x18002f08, 0x00000006},
44 {0x18002f00, 0x00055149},
45 {0x18002f00, 0x0005514b},
46 {0x18002f00, 0x00055149},
47 {0xfafafafa, 0x00000001},
48 {0x18002f10, 0x00000001},
49 {0x18002f10, 0x00000000},
50 {0x18002f10, 0x00000001},
51 {0xfafafafa, 0x00000001},
52 {0x18002000, 0x000010ec},
53 {0xfafafafa, 0x00000000},
54};
55
56static const struct reg_sequence rt5514_patch[] = {
57 {RT5514_DIG_IO_CTRL, 0x00000040},
58 {RT5514_CLK_CTRL1, 0x38020041},
59 {RT5514_SRC_CTRL, 0x44000eee},
60 {RT5514_ANA_CTRL_LDO10, 0x00028604},
61 {RT5514_ANA_CTRL_ADCFED, 0x00000800},
62};
63
64static const struct reg_default rt5514_reg[] = {
65 {RT5514_RESET, 0x00000000},
66 {RT5514_PWR_ANA1, 0x00808880},
67 {RT5514_PWR_ANA2, 0x00220000},
68 {RT5514_I2S_CTRL1, 0x00000330},
69 {RT5514_I2S_CTRL2, 0x20000000},
70 {RT5514_VAD_CTRL6, 0xc00007d2},
71 {RT5514_EXT_VAD_CTRL, 0x80000080},
72 {RT5514_DIG_IO_CTRL, 0x00000040},
73 {RT5514_PAD_CTRL1, 0x00804000},
74 {RT5514_DMIC_DATA_CTRL, 0x00000005},
75 {RT5514_DIG_SOURCE_CTRL, 0x00000002},
76 {RT5514_SRC_CTRL, 0x44000eee},
77 {RT5514_DOWNFILTER2_CTRL1, 0x0000882f},
78 {RT5514_PLL_SOURCE_CTRL, 0x00000004},
79 {RT5514_CLK_CTRL1, 0x38020041},
80 {RT5514_CLK_CTRL2, 0x00000000},
81 {RT5514_PLL3_CALIB_CTRL1, 0x00400200},
82 {RT5514_PLL3_CALIB_CTRL5, 0x40220012},
83 {RT5514_DELAY_BUF_CTRL1, 0x7fff006a},
84 {RT5514_DELAY_BUF_CTRL3, 0x00000000},
85 {RT5514_DOWNFILTER0_CTRL1, 0x00020c2f},
86 {RT5514_DOWNFILTER0_CTRL2, 0x00020c2f},
87 {RT5514_DOWNFILTER0_CTRL3, 0x00000362},
88 {RT5514_DOWNFILTER1_CTRL1, 0x00020c2f},
89 {RT5514_DOWNFILTER1_CTRL2, 0x00020c2f},
90 {RT5514_DOWNFILTER1_CTRL3, 0x00000362},
91 {RT5514_ANA_CTRL_LDO10, 0x00028604},
92 {RT5514_ANA_CTRL_LDO18_16, 0x02000345},
93 {RT5514_ANA_CTRL_ADC12, 0x0000a2a8},
94 {RT5514_ANA_CTRL_ADC21, 0x00001180},
95 {RT5514_ANA_CTRL_ADC22, 0x0000aaa8},
96 {RT5514_ANA_CTRL_ADC23, 0x00151427},
97 {RT5514_ANA_CTRL_MICBST, 0x00002000},
98 {RT5514_ANA_CTRL_ADCFED, 0x00000800},
99 {RT5514_ANA_CTRL_INBUF, 0x00000143},
100 {RT5514_ANA_CTRL_VREF, 0x00008d50},
101 {RT5514_ANA_CTRL_PLL3, 0x0000000e},
102 {RT5514_ANA_CTRL_PLL1_1, 0x00000000},
103 {RT5514_ANA_CTRL_PLL1_2, 0x00030220},
104 {RT5514_DMIC_LP_CTRL, 0x00000000},
105 {RT5514_MISC_CTRL_DSP, 0x00000000},
106 {RT5514_DSP_CTRL1, 0x00055149},
107 {RT5514_DSP_CTRL3, 0x00000006},
108 {RT5514_DSP_CTRL4, 0x00000001},
109 {RT5514_VENDOR_ID1, 0x00000001},
110 {RT5514_VENDOR_ID2, 0x10ec5514},
111};
112
113static bool rt5514_volatile_register(struct device *dev, unsigned int reg)
114{
115 switch (reg) {
116 case RT5514_VENDOR_ID1:
117 case RT5514_VENDOR_ID2:
118 return true;
119
120 default:
121 return false;
122 }
123}
124
125static bool rt5514_readable_register(struct device *dev, unsigned int reg)
126{
127 switch (reg) {
128 case RT5514_RESET:
129 case RT5514_PWR_ANA1:
130 case RT5514_PWR_ANA2:
131 case RT5514_I2S_CTRL1:
132 case RT5514_I2S_CTRL2:
133 case RT5514_VAD_CTRL6:
134 case RT5514_EXT_VAD_CTRL:
135 case RT5514_DIG_IO_CTRL:
136 case RT5514_PAD_CTRL1:
137 case RT5514_DMIC_DATA_CTRL:
138 case RT5514_DIG_SOURCE_CTRL:
139 case RT5514_SRC_CTRL:
140 case RT5514_DOWNFILTER2_CTRL1:
141 case RT5514_PLL_SOURCE_CTRL:
142 case RT5514_CLK_CTRL1:
143 case RT5514_CLK_CTRL2:
144 case RT5514_PLL3_CALIB_CTRL1:
145 case RT5514_PLL3_CALIB_CTRL5:
146 case RT5514_DELAY_BUF_CTRL1:
147 case RT5514_DELAY_BUF_CTRL3:
148 case RT5514_DOWNFILTER0_CTRL1:
149 case RT5514_DOWNFILTER0_CTRL2:
150 case RT5514_DOWNFILTER0_CTRL3:
151 case RT5514_DOWNFILTER1_CTRL1:
152 case RT5514_DOWNFILTER1_CTRL2:
153 case RT5514_DOWNFILTER1_CTRL3:
154 case RT5514_ANA_CTRL_LDO10:
155 case RT5514_ANA_CTRL_LDO18_16:
156 case RT5514_ANA_CTRL_ADC12:
157 case RT5514_ANA_CTRL_ADC21:
158 case RT5514_ANA_CTRL_ADC22:
159 case RT5514_ANA_CTRL_ADC23:
160 case RT5514_ANA_CTRL_MICBST:
161 case RT5514_ANA_CTRL_ADCFED:
162 case RT5514_ANA_CTRL_INBUF:
163 case RT5514_ANA_CTRL_VREF:
164 case RT5514_ANA_CTRL_PLL3:
165 case RT5514_ANA_CTRL_PLL1_1:
166 case RT5514_ANA_CTRL_PLL1_2:
167 case RT5514_DMIC_LP_CTRL:
168 case RT5514_MISC_CTRL_DSP:
169 case RT5514_DSP_CTRL1:
170 case RT5514_DSP_CTRL3:
171 case RT5514_DSP_CTRL4:
172 case RT5514_VENDOR_ID1:
173 case RT5514_VENDOR_ID2:
174 return true;
175
176 default:
177 return false;
178 }
179}
180
181static bool rt5514_i2c_readable_register(struct device *dev,
182 unsigned int reg)
183{
184 switch (reg) {
185 case RT5514_DSP_MAPPING | RT5514_RESET:
186 case RT5514_DSP_MAPPING | RT5514_PWR_ANA1:
187 case RT5514_DSP_MAPPING | RT5514_PWR_ANA2:
188 case RT5514_DSP_MAPPING | RT5514_I2S_CTRL1:
189 case RT5514_DSP_MAPPING | RT5514_I2S_CTRL2:
190 case RT5514_DSP_MAPPING | RT5514_VAD_CTRL6:
191 case RT5514_DSP_MAPPING | RT5514_EXT_VAD_CTRL:
192 case RT5514_DSP_MAPPING | RT5514_DIG_IO_CTRL:
193 case RT5514_DSP_MAPPING | RT5514_PAD_CTRL1:
194 case RT5514_DSP_MAPPING | RT5514_DMIC_DATA_CTRL:
195 case RT5514_DSP_MAPPING | RT5514_DIG_SOURCE_CTRL:
196 case RT5514_DSP_MAPPING | RT5514_SRC_CTRL:
197 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER2_CTRL1:
198 case RT5514_DSP_MAPPING | RT5514_PLL_SOURCE_CTRL:
199 case RT5514_DSP_MAPPING | RT5514_CLK_CTRL1:
200 case RT5514_DSP_MAPPING | RT5514_CLK_CTRL2:
201 case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL1:
202 case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
203 case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
204 case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
205 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
206 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
207 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
208 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL1:
209 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL2:
210 case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL3:
211 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO10:
212 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO18_16:
213 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC12:
214 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC21:
215 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC22:
216 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC23:
217 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_MICBST:
218 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADCFED:
219 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_INBUF:
220 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_VREF:
221 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL3:
222 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_1:
223 case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_2:
224 case RT5514_DSP_MAPPING | RT5514_DMIC_LP_CTRL:
225 case RT5514_DSP_MAPPING | RT5514_MISC_CTRL_DSP:
226 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL1:
227 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL3:
228 case RT5514_DSP_MAPPING | RT5514_DSP_CTRL4:
229 case RT5514_DSP_MAPPING | RT5514_VENDOR_ID1:
230 case RT5514_DSP_MAPPING | RT5514_VENDOR_ID2:
231 return true;
232
233 default:
234 return false;
235 }
236}
237
238/* {-3, 0, +3, +4.5, +7.5, +9.5, +12, +14, +17} dB */
239static const DECLARE_TLV_DB_RANGE(bst_tlv,
240 0, 2, TLV_DB_SCALE_ITEM(-300, 300, 0),
241 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0),
242 4, 4, TLV_DB_SCALE_ITEM(750, 0, 0),
243 5, 5, TLV_DB_SCALE_ITEM(950, 0, 0),
244 6, 6, TLV_DB_SCALE_ITEM(1200, 0, 0),
245 7, 7, TLV_DB_SCALE_ITEM(1400, 0, 0),
246 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0)
247);
248
249static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
250
251static const struct snd_kcontrol_new rt5514_snd_controls[] = {
252 SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
253 RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
254 SOC_DOUBLE_R_TLV("ADC1 Capture Volume", RT5514_DOWNFILTER0_CTRL1,
255 RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
256 adc_vol_tlv),
257 SOC_DOUBLE_R_TLV("ADC2 Capture Volume", RT5514_DOWNFILTER1_CTRL1,
258 RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 127, 0,
259 adc_vol_tlv),
260};
261
262/* ADC Mixer*/
263static const struct snd_kcontrol_new rt5514_sto1_adc_l_mix[] = {
264 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER0_CTRL1,
265 RT5514_AD_DMIC_MIX_BIT, 1, 1),
266 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER0_CTRL1,
267 RT5514_AD_AD_MIX_BIT, 1, 1),
268};
269
270static const struct snd_kcontrol_new rt5514_sto1_adc_r_mix[] = {
271 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER0_CTRL2,
272 RT5514_AD_DMIC_MIX_BIT, 1, 1),
273 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER0_CTRL2,
274 RT5514_AD_AD_MIX_BIT, 1, 1),
275};
276
277static const struct snd_kcontrol_new rt5514_sto2_adc_l_mix[] = {
278 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER1_CTRL1,
279 RT5514_AD_DMIC_MIX_BIT, 1, 1),
280 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER1_CTRL1,
281 RT5514_AD_AD_MIX_BIT, 1, 1),
282};
283
284static const struct snd_kcontrol_new rt5514_sto2_adc_r_mix[] = {
285 SOC_DAPM_SINGLE("DMIC Switch", RT5514_DOWNFILTER1_CTRL2,
286 RT5514_AD_DMIC_MIX_BIT, 1, 1),
287 SOC_DAPM_SINGLE("ADC Switch", RT5514_DOWNFILTER1_CTRL2,
288 RT5514_AD_AD_MIX_BIT, 1, 1),
289};
290
291/* DMIC Source */
292static const char * const rt5514_dmic_src[] = {
293 "DMIC1", "DMIC2"
294};
295
296static const SOC_ENUM_SINGLE_DECL(
297 rt5514_stereo1_dmic_enum, RT5514_DIG_SOURCE_CTRL,
298 RT5514_AD0_DMIC_INPUT_SEL_SFT, rt5514_dmic_src);
299
300static const struct snd_kcontrol_new rt5514_sto1_dmic_mux =
301 SOC_DAPM_ENUM("Stereo1 DMIC Source", rt5514_stereo1_dmic_enum);
302
303static const SOC_ENUM_SINGLE_DECL(
304 rt5514_stereo2_dmic_enum, RT5514_DIG_SOURCE_CTRL,
305 RT5514_AD1_DMIC_INPUT_SEL_SFT, rt5514_dmic_src);
306
307static const struct snd_kcontrol_new rt5514_sto2_dmic_mux =
308 SOC_DAPM_ENUM("Stereo2 DMIC Source", rt5514_stereo2_dmic_enum);
309
310/**
311 * rt5514_calc_dmic_clk - Calculate the frequency divider parameter of dmic.
312 *
313 * @rate: base clock rate.
314 *
315 * Choose divider parameter that gives the highest possible DMIC frequency in
316 * 1MHz - 3MHz range.
317 */
318static int rt5514_calc_dmic_clk(struct snd_soc_codec *codec, int rate)
319{
320 int div[] = {2, 3, 4, 8, 12, 16, 24, 32};
321 int i;
322
323 if (rate < 1000000 * div[0]) {
324 pr_warn("Base clock rate %d is too low\n", rate);
325 return -EINVAL;
326 }
327
328 for (i = 0; i < ARRAY_SIZE(div); i++) {
329 /* find divider that gives DMIC frequency below 3.072MHz */
330 if (3072000 * div[i] >= rate)
331 return i;
332 }
333
334 dev_warn(codec->dev, "Base clock rate %d is too high\n", rate);
335 return -EINVAL;
336}
337
338static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w,
339 struct snd_kcontrol *kcontrol, int event)
340{
341 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
342 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
343 int idx;
344
345 idx = rt5514_calc_dmic_clk(codec, rt5514->sysclk);
346 if (idx < 0)
347 dev_err(codec->dev, "Failed to set DMIC clock\n");
348 else
349 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1,
350 RT5514_CLK_DMIC_OUT_SEL_MASK,
351 idx << RT5514_CLK_DMIC_OUT_SEL_SFT);
352
353 return idx;
354}
355
356static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
357 struct snd_soc_dapm_widget *sink)
358{
359 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
360 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
361
362 if (rt5514->sysclk_src == RT5514_SCLK_S_PLL1)
363 return 1;
364 else
365 return 0;
366}
367
368static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = {
369 /* Input Lines */
370 SND_SOC_DAPM_INPUT("DMIC1L"),
371 SND_SOC_DAPM_INPUT("DMIC1R"),
372 SND_SOC_DAPM_INPUT("DMIC2L"),
373 SND_SOC_DAPM_INPUT("DMIC2R"),
374
375 SND_SOC_DAPM_INPUT("AMICL"),
376 SND_SOC_DAPM_INPUT("AMICR"),
377
378 SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
379 SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
380
381 SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
382 rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
383
384 SND_SOC_DAPM_SUPPLY("ADC CLK", RT5514_CLK_CTRL1,
385 RT5514_CLK_AD_ANA1_EN_BIT, 0, NULL, 0),
386
387 SND_SOC_DAPM_SUPPLY("LDO18 IN", RT5514_PWR_ANA1,
388 RT5514_POW_LDO18_IN_BIT, 0, NULL, 0),
389 SND_SOC_DAPM_SUPPLY("LDO18 ADC", RT5514_PWR_ANA1,
390 RT5514_POW_LDO18_ADC_BIT, 0, NULL, 0),
391 SND_SOC_DAPM_SUPPLY("LDO21", RT5514_PWR_ANA1, RT5514_POW_LDO21_BIT, 0,
392 NULL, 0),
393 SND_SOC_DAPM_SUPPLY("BG LDO18 IN", RT5514_PWR_ANA1,
394 RT5514_POW_BG_LDO18_IN_BIT, 0, NULL, 0),
395 SND_SOC_DAPM_SUPPLY("BG LDO21", RT5514_PWR_ANA1,
396 RT5514_POW_BG_LDO21_BIT, 0, NULL, 0),
397 SND_SOC_DAPM_SUPPLY("BG MBIAS", RT5514_PWR_ANA2,
398 RT5514_POW_BG_MBIAS_BIT, 0, NULL, 0),
399 SND_SOC_DAPM_SUPPLY("MBIAS", RT5514_PWR_ANA2, RT5514_POW_MBIAS_BIT, 0,
400 NULL, 0),
401 SND_SOC_DAPM_SUPPLY("VREF2", RT5514_PWR_ANA2, RT5514_POW_VREF2_BIT, 0,
402 NULL, 0),
403 SND_SOC_DAPM_SUPPLY("VREF1", RT5514_PWR_ANA2, RT5514_POW_VREF1_BIT, 0,
404 NULL, 0),
405 SND_SOC_DAPM_SUPPLY("ADC Power", SND_SOC_NOPM, 0, 0, NULL, 0),
406
407
408 SND_SOC_DAPM_SUPPLY("LDO16L", RT5514_PWR_ANA2, RT5514_POWL_LDO16_BIT, 0,
409 NULL, 0),
410 SND_SOC_DAPM_SUPPLY("ADC1L", RT5514_PWR_ANA2, RT5514_POW_ADC1_L_BIT, 0,
411 NULL, 0),
412 SND_SOC_DAPM_SUPPLY("BSTL2", RT5514_PWR_ANA2, RT5514_POW2_BSTL_BIT, 0,
413 NULL, 0),
414 SND_SOC_DAPM_SUPPLY("BSTL", RT5514_PWR_ANA2, RT5514_POW_BSTL_BIT, 0,
415 NULL, 0),
416 SND_SOC_DAPM_SUPPLY("ADCFEDL", RT5514_PWR_ANA2, RT5514_POW_ADCFEDL_BIT,
417 0, NULL, 0),
418 SND_SOC_DAPM_SUPPLY("ADCL Power", SND_SOC_NOPM, 0, 0, NULL, 0),
419
420 SND_SOC_DAPM_SUPPLY("LDO16R", RT5514_PWR_ANA2, RT5514_POWR_LDO16_BIT, 0,
421 NULL, 0),
422 SND_SOC_DAPM_SUPPLY("ADC1R", RT5514_PWR_ANA2, RT5514_POW_ADC1_R_BIT, 0,
423 NULL, 0),
424 SND_SOC_DAPM_SUPPLY("BSTR2", RT5514_PWR_ANA2, RT5514_POW2_BSTR_BIT, 0,
425 NULL, 0),
426 SND_SOC_DAPM_SUPPLY("BSTR", RT5514_PWR_ANA2, RT5514_POW_BSTR_BIT, 0,
427 NULL, 0),
428 SND_SOC_DAPM_SUPPLY("ADCFEDR", RT5514_PWR_ANA2, RT5514_POW_ADCFEDR_BIT,
429 0, NULL, 0),
430 SND_SOC_DAPM_SUPPLY("ADCR Power", SND_SOC_NOPM, 0, 0, NULL, 0),
431
432 SND_SOC_DAPM_SUPPLY("PLL1 LDO ENABLE", RT5514_ANA_CTRL_PLL1_2,
433 RT5514_EN_LDO_PLL1_BIT, 0, NULL, 0),
434 SND_SOC_DAPM_SUPPLY("PLL1 LDO", RT5514_PWR_ANA2,
435 RT5514_POW_PLL1_LDO_BIT, 0, NULL, 0),
436 SND_SOC_DAPM_SUPPLY("PLL1", RT5514_PWR_ANA2, RT5514_POW_PLL1_BIT, 0,
437 NULL, 0),
438
439 /* ADC Mux */
440 SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
441 &rt5514_sto1_dmic_mux),
442 SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0,
443 &rt5514_sto2_dmic_mux),
444
445 /* ADC Mixer */
446 SND_SOC_DAPM_SUPPLY("adc stereo1 filter", RT5514_CLK_CTRL1,
447 RT5514_CLK_AD0_EN_BIT, 0, NULL, 0),
448 SND_SOC_DAPM_SUPPLY("adc stereo2 filter", RT5514_CLK_CTRL1,
449 RT5514_CLK_AD1_EN_BIT, 0, NULL, 0),
450
451 SND_SOC_DAPM_MIXER("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
452 rt5514_sto1_adc_l_mix, ARRAY_SIZE(rt5514_sto1_adc_l_mix)),
453 SND_SOC_DAPM_MIXER("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
454 rt5514_sto1_adc_r_mix, ARRAY_SIZE(rt5514_sto1_adc_r_mix)),
455 SND_SOC_DAPM_MIXER("Sto2 ADC MIXL", SND_SOC_NOPM, 0, 0,
456 rt5514_sto2_adc_l_mix, ARRAY_SIZE(rt5514_sto2_adc_l_mix)),
457 SND_SOC_DAPM_MIXER("Sto2 ADC MIXR", SND_SOC_NOPM, 0, 0,
458 rt5514_sto2_adc_r_mix, ARRAY_SIZE(rt5514_sto2_adc_r_mix)),
459
460 SND_SOC_DAPM_ADC("Stereo1 ADC MIXL", NULL, RT5514_DOWNFILTER0_CTRL1,
461 RT5514_AD_AD_MUTE_BIT, 1),
462 SND_SOC_DAPM_ADC("Stereo1 ADC MIXR", NULL, RT5514_DOWNFILTER0_CTRL2,
463 RT5514_AD_AD_MUTE_BIT, 1),
464 SND_SOC_DAPM_ADC("Stereo2 ADC MIXL", NULL, RT5514_DOWNFILTER1_CTRL1,
465 RT5514_AD_AD_MUTE_BIT, 1),
466 SND_SOC_DAPM_ADC("Stereo2 ADC MIXR", NULL, RT5514_DOWNFILTER1_CTRL2,
467 RT5514_AD_AD_MUTE_BIT, 1),
468
469 /* ADC PGA */
470 SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
471 SND_SOC_DAPM_PGA("Stereo2 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
472
473 /* Audio Interface */
474 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
475};
476
477static const struct snd_soc_dapm_route rt5514_dapm_routes[] = {
478 { "DMIC1", NULL, "DMIC1L" },
479 { "DMIC1", NULL, "DMIC1R" },
480 { "DMIC2", NULL, "DMIC2L" },
481 { "DMIC2", NULL, "DMIC2R" },
482
483 { "DMIC1L", NULL, "DMIC CLK" },
484 { "DMIC1R", NULL, "DMIC CLK" },
485 { "DMIC2L", NULL, "DMIC CLK" },
486 { "DMIC2R", NULL, "DMIC CLK" },
487
488 { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
489 { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
490
491 { "Sto1 ADC MIXL", "DMIC Switch", "Stereo1 DMIC Mux" },
492 { "Sto1 ADC MIXL", "ADC Switch", "AMICL" },
493 { "Sto1 ADC MIXR", "DMIC Switch", "Stereo1 DMIC Mux" },
494 { "Sto1 ADC MIXR", "ADC Switch", "AMICR" },
495
496 { "ADC Power", NULL, "LDO18 IN" },
497 { "ADC Power", NULL, "LDO18 ADC" },
498 { "ADC Power", NULL, "LDO21" },
499 { "ADC Power", NULL, "BG LDO18 IN" },
500 { "ADC Power", NULL, "BG LDO21" },
501 { "ADC Power", NULL, "BG MBIAS" },
502 { "ADC Power", NULL, "MBIAS" },
503 { "ADC Power", NULL, "VREF2" },
504 { "ADC Power", NULL, "VREF1" },
505
506 { "ADCL Power", NULL, "LDO16L" },
507 { "ADCL Power", NULL, "ADC1L" },
508 { "ADCL Power", NULL, "BSTL2" },
509 { "ADCL Power", NULL, "BSTL" },
510 { "ADCL Power", NULL, "ADCFEDL" },
511
512 { "ADCR Power", NULL, "LDO16R" },
513 { "ADCR Power", NULL, "ADC1R" },
514 { "ADCR Power", NULL, "BSTR2" },
515 { "ADCR Power", NULL, "BSTR" },
516 { "ADCR Power", NULL, "ADCFEDR" },
517
518 { "AMICL", NULL, "ADC CLK" },
519 { "AMICL", NULL, "ADC Power" },
520 { "AMICL", NULL, "ADCL Power" },
521 { "AMICR", NULL, "ADC CLK" },
522 { "AMICR", NULL, "ADC Power" },
523 { "AMICR", NULL, "ADCR Power" },
524
525 { "PLL1 LDO", NULL, "PLL1 LDO ENABLE" },
526 { "PLL1", NULL, "PLL1 LDO" },
527
528 { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
529 { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
530
531 { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXL" },
532 { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" },
533 { "Stereo1 ADC MIX", NULL, "adc stereo1 filter" },
534 { "adc stereo1 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll },
535
536 { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" },
537 { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" },
538
539 { "Sto2 ADC MIXL", "DMIC Switch", "Stereo2 DMIC Mux" },
540 { "Sto2 ADC MIXL", "ADC Switch", "AMICL" },
541 { "Sto2 ADC MIXR", "DMIC Switch", "Stereo2 DMIC Mux" },
542 { "Sto2 ADC MIXR", "ADC Switch", "AMICR" },
543
544 { "Stereo2 ADC MIXL", NULL, "Sto2 ADC MIXL" },
545 { "Stereo2 ADC MIXR", NULL, "Sto2 ADC MIXR" },
546
547 { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXL" },
548 { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXR" },
549 { "Stereo2 ADC MIX", NULL, "adc stereo2 filter" },
550 { "adc stereo2 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll },
551
552 { "AIF1TX", NULL, "Stereo1 ADC MIX"},
553 { "AIF1TX", NULL, "Stereo2 ADC MIX"},
554};
555
556static int rt5514_hw_params(struct snd_pcm_substream *substream,
557 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
558{
559 struct snd_soc_codec *codec = dai->codec;
560 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
561 int pre_div, bclk_ms, frame_size;
562 unsigned int val_len = 0;
563
564 rt5514->lrck = params_rate(params);
565 pre_div = rl6231_get_clk_info(rt5514->sysclk, rt5514->lrck);
566 if (pre_div < 0) {
567 dev_err(codec->dev, "Unsupported clock setting\n");
568 return -EINVAL;
569 }
570
571 frame_size = snd_soc_params_to_frame_size(params);
572 if (frame_size < 0) {
573 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
574 return -EINVAL;
575 }
576
577 bclk_ms = frame_size > 32;
578 rt5514->bclk = rt5514->lrck * (32 << bclk_ms);
579
580 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
581 rt5514->bclk, rt5514->lrck);
582 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
583 bclk_ms, pre_div, dai->id);
584
585 switch (params_format(params)) {
586 case SNDRV_PCM_FORMAT_S16_LE:
587 break;
588 case SNDRV_PCM_FORMAT_S20_3LE:
589 val_len = RT5514_I2S_DL_20;
590 break;
591 case SNDRV_PCM_FORMAT_S24_LE:
592 val_len = RT5514_I2S_DL_24;
593 break;
594 case SNDRV_PCM_FORMAT_S8:
595 val_len = RT5514_I2S_DL_8;
596 break;
597 default:
598 return -EINVAL;
599 }
600
601 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_I2S_DL_MASK,
602 val_len);
603 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
604 RT5514_CLK_SYS_DIV_OUT_MASK | RT5514_SEL_ADC_OSR_MASK,
605 pre_div << RT5514_CLK_SYS_DIV_OUT_SFT |
606 pre_div << RT5514_SEL_ADC_OSR_SFT);
607
608 return 0;
609}
610
611static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
612{
613 struct snd_soc_codec *codec = dai->codec;
614 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
615 unsigned int reg_val = 0;
616
617 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
618 case SND_SOC_DAIFMT_NB_NF:
619 break;
620
621 case SND_SOC_DAIFMT_NB_IF:
622 reg_val |= RT5514_I2S_LR_INV;
623 break;
624
625 case SND_SOC_DAIFMT_IB_NF:
626 reg_val |= RT5514_I2S_BP_INV;
627 break;
628
629 case SND_SOC_DAIFMT_IB_IF:
630 reg_val |= RT5514_I2S_BP_INV | RT5514_I2S_LR_INV;
631 break;
632
633 default:
634 return -EINVAL;
635 }
636
637 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
638 case SND_SOC_DAIFMT_I2S:
639 break;
640
641 case SND_SOC_DAIFMT_LEFT_J:
642 reg_val |= RT5514_I2S_DF_LEFT;
643 break;
644
645 case SND_SOC_DAIFMT_DSP_A:
646 reg_val |= RT5514_I2S_DF_PCM_A;
647 break;
648
649 case SND_SOC_DAIFMT_DSP_B:
650 reg_val |= RT5514_I2S_DF_PCM_B;
651 break;
652
653 default:
654 return -EINVAL;
655 }
656
657 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1,
658 RT5514_I2S_DF_MASK | RT5514_I2S_BP_MASK | RT5514_I2S_LR_MASK,
659 reg_val);
660
661 return 0;
662}
663
664static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai,
665 int clk_id, unsigned int freq, int dir)
666{
667 struct snd_soc_codec *codec = dai->codec;
668 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
669 unsigned int reg_val = 0;
670
671 if (freq == rt5514->sysclk && clk_id == rt5514->sysclk_src)
672 return 0;
673
674 switch (clk_id) {
675 case RT5514_SCLK_S_MCLK:
676 reg_val |= RT5514_CLK_SYS_PRE_SEL_MCLK;
677 break;
678
679 case RT5514_SCLK_S_PLL1:
680 reg_val |= RT5514_CLK_SYS_PRE_SEL_PLL;
681 break;
682
683 default:
684 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
685 return -EINVAL;
686 }
687
688 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
689 RT5514_CLK_SYS_PRE_SEL_MASK, reg_val);
690
691 rt5514->sysclk = freq;
692 rt5514->sysclk_src = clk_id;
693
694 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
695
696 return 0;
697}
698
699static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
700 unsigned int freq_in, unsigned int freq_out)
701{
702 struct snd_soc_codec *codec = dai->codec;
703 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
704 struct rl6231_pll_code pll_code;
705 int ret;
706
707 if (!freq_in || !freq_out) {
708 dev_dbg(codec->dev, "PLL disabled\n");
709
710 rt5514->pll_in = 0;
711 rt5514->pll_out = 0;
712 regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2,
713 RT5514_CLK_SYS_PRE_SEL_MASK,
714 RT5514_CLK_SYS_PRE_SEL_MCLK);
715
716 return 0;
717 }
718
719 if (source == rt5514->pll_src && freq_in == rt5514->pll_in &&
720 freq_out == rt5514->pll_out)
721 return 0;
722
723 switch (source) {
724 case RT5514_PLL1_S_MCLK:
725 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL,
726 RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_MCLK);
727 break;
728
729 case RT5514_PLL1_S_BCLK:
730 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL,
731 RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_SCLK);
732 break;
733
734 default:
735 dev_err(codec->dev, "Unknown PLL source %d\n", source);
736 return -EINVAL;
737 }
738
739 ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
740 if (ret < 0) {
741 dev_err(codec->dev, "Unsupport input clock %d\n", freq_in);
742 return ret;
743 }
744
745 dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n",
746 pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
747 pll_code.n_code, pll_code.k_code);
748
749 regmap_write(rt5514->regmap, RT5514_ANA_CTRL_PLL1_1,
750 pll_code.k_code << RT5514_PLL_K_SFT |
751 pll_code.n_code << RT5514_PLL_N_SFT |
752 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5514_PLL_M_SFT);
753 regmap_update_bits(rt5514->regmap, RT5514_ANA_CTRL_PLL1_2,
754 RT5514_PLL_M_BP, pll_code.m_bp << RT5514_PLL_M_BP_SFT);
755
756 rt5514->pll_in = freq_in;
757 rt5514->pll_out = freq_out;
758 rt5514->pll_src = source;
759
760 return 0;
761}
762
763static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
764 unsigned int rx_mask, int slots, int slot_width)
765{
766 struct snd_soc_codec *codec = dai->codec;
767 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
768 unsigned int val = 0;
769
770 if (rx_mask || tx_mask)
771 val |= RT5514_TDM_MODE;
772
773 if (slots == 4)
774 val |= RT5514_TDMSLOT_SEL_RX_4CH | RT5514_TDMSLOT_SEL_TX_4CH;
775
776
777 switch (slot_width) {
778 case 20:
779 val |= RT5514_CH_LEN_RX_20 | RT5514_CH_LEN_TX_20;
780 break;
781
782 case 24:
783 val |= RT5514_CH_LEN_RX_24 | RT5514_CH_LEN_TX_24;
784 break;
785
786 case 32:
787 val |= RT5514_CH_LEN_RX_32 | RT5514_CH_LEN_TX_32;
788 break;
789
790 case 16:
791 default:
792 break;
793 }
794
795 regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_TDM_MODE |
796 RT5514_TDMSLOT_SEL_RX_MASK | RT5514_TDMSLOT_SEL_TX_MASK |
797 RT5514_CH_LEN_RX_MASK | RT5514_CH_LEN_TX_MASK, val);
798
799 return 0;
800}
801
802static int rt5514_probe(struct snd_soc_codec *codec)
803{
804 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
805
806 rt5514->codec = codec;
807
808 return 0;
809}
810
811static int rt5514_i2c_read(void *context, unsigned int reg, unsigned int *val)
812{
813 struct i2c_client *client = context;
814 struct rt5514_priv *rt5514 = i2c_get_clientdata(client);
815
816 regmap_read(rt5514->i2c_regmap, reg | RT5514_DSP_MAPPING, val);
817
818 return 0;
819}
820
821static int rt5514_i2c_write(void *context, unsigned int reg, unsigned int val)
822{
823 struct i2c_client *client = context;
824 struct rt5514_priv *rt5514 = i2c_get_clientdata(client);
825
826 regmap_write(rt5514->i2c_regmap, reg | RT5514_DSP_MAPPING, val);
827
828 return 0;
829}
830
831#define RT5514_STEREO_RATES SNDRV_PCM_RATE_8000_192000
832#define RT5514_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
833 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
834
835struct snd_soc_dai_ops rt5514_aif_dai_ops = {
836 .hw_params = rt5514_hw_params,
837 .set_fmt = rt5514_set_dai_fmt,
838 .set_sysclk = rt5514_set_dai_sysclk,
839 .set_pll = rt5514_set_dai_pll,
840 .set_tdm_slot = rt5514_set_tdm_slot,
841};
842
843struct snd_soc_dai_driver rt5514_dai[] = {
844 {
845 .name = "rt5514-aif1",
846 .id = 0,
847 .capture = {
848 .stream_name = "AIF1 Capture",
849 .channels_min = 1,
850 .channels_max = 4,
851 .rates = RT5514_STEREO_RATES,
852 .formats = RT5514_FORMATS,
853 },
854 .ops = &rt5514_aif_dai_ops,
855 }
856};
857
858static struct snd_soc_codec_driver soc_codec_dev_rt5514 = {
859 .probe = rt5514_probe,
860 .idle_bias_off = true,
861 .controls = rt5514_snd_controls,
862 .num_controls = ARRAY_SIZE(rt5514_snd_controls),
863 .dapm_widgets = rt5514_dapm_widgets,
864 .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets),
865 .dapm_routes = rt5514_dapm_routes,
866 .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes),
867};
868
869static const struct regmap_config rt5514_i2c_regmap = {
870 .name = "i2c",
871 .reg_bits = 32,
872 .val_bits = 32,
873
874 .max_register = RT5514_DSP_MAPPING | RT5514_VENDOR_ID2,
875 .readable_reg = rt5514_i2c_readable_register,
876
877 .cache_type = REGCACHE_NONE,
878};
879
880static const struct regmap_config rt5514_regmap = {
881 .reg_bits = 16,
882 .val_bits = 32,
883
884 .max_register = RT5514_VENDOR_ID2,
885 .volatile_reg = rt5514_volatile_register,
886 .readable_reg = rt5514_readable_register,
887 .reg_read = rt5514_i2c_read,
888 .reg_write = rt5514_i2c_write,
889
890 .cache_type = REGCACHE_RBTREE,
891 .reg_defaults = rt5514_reg,
892 .num_reg_defaults = ARRAY_SIZE(rt5514_reg),
893 .use_single_rw = true,
894};
895
896static const struct i2c_device_id rt5514_i2c_id[] = {
897 { "rt5514", 0 },
898 { }
899};
900MODULE_DEVICE_TABLE(i2c, rt5514_i2c_id);
901
902#if defined(CONFIG_OF)
903static const struct of_device_id rt5514_of_match[] = {
904 { .compatible = "realtek,rt5514", },
905 {},
906};
907MODULE_DEVICE_TABLE(of, rt5514_of_match);
908#endif
909
910static int rt5514_i2c_probe(struct i2c_client *i2c,
911 const struct i2c_device_id *id)
912{
913 struct rt5514_priv *rt5514;
914 int ret;
915 unsigned int val;
916
917 rt5514 = devm_kzalloc(&i2c->dev, sizeof(struct rt5514_priv),
918 GFP_KERNEL);
919 if (rt5514 == NULL)
920 return -ENOMEM;
921
922 i2c_set_clientdata(i2c, rt5514);
923
924 rt5514->i2c_regmap = devm_regmap_init_i2c(i2c, &rt5514_i2c_regmap);
925 if (IS_ERR(rt5514->i2c_regmap)) {
926 ret = PTR_ERR(rt5514->i2c_regmap);
927 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
928 ret);
929 return ret;
930 }
931
932 rt5514->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt5514_regmap);
933 if (IS_ERR(rt5514->regmap)) {
934 ret = PTR_ERR(rt5514->regmap);
935 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
936 ret);
937 return ret;
938 }
939
940 regmap_read(rt5514->regmap, RT5514_VENDOR_ID2, &val);
941 if (val != RT5514_DEVICE_ID) {
942 dev_err(&i2c->dev,
943 "Device with ID register %x is not rt5514\n", val);
944 return -ENODEV;
945 }
946
947 ret = regmap_register_patch(rt5514->i2c_regmap, rt5514_i2c_patch,
948 ARRAY_SIZE(rt5514_i2c_patch));
949 if (ret != 0)
950 dev_warn(&i2c->dev, "Failed to apply i2c_regmap patch: %d\n",
951 ret);
952
953 ret = regmap_register_patch(rt5514->regmap, rt5514_patch,
954 ARRAY_SIZE(rt5514_patch));
955 if (ret != 0)
956 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
957
958 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5514,
959 rt5514_dai, ARRAY_SIZE(rt5514_dai));
960}
961
962static int rt5514_i2c_remove(struct i2c_client *i2c)
963{
964 snd_soc_unregister_codec(&i2c->dev);
965
966 return 0;
967}
968
969struct i2c_driver rt5514_i2c_driver = {
970 .driver = {
971 .name = "rt5514",
972 .of_match_table = of_match_ptr(rt5514_of_match),
973 },
974 .probe = rt5514_i2c_probe,
975 .remove = rt5514_i2c_remove,
976 .id_table = rt5514_i2c_id,
977};
978module_i2c_driver(rt5514_i2c_driver);
979
980MODULE_DESCRIPTION("ASoC RT5514 driver");
981MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
982MODULE_LICENSE("GPL v2");
sound/soc/codecs/rt5514.h+252−0
@@ -0,0 +1,252 @@
1/*
2 * rt5514.h -- RT5514 ALSA SoC audio driver
3 *
4 * Copyright 2015 Realtek Microelectronics
5 * Author: Oder Chiou <oder_chiou@realtek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __RT5514_H__
13#define __RT5514_H__
14
15#define RT5514_DEVICE_ID 0x10ec5514
16
17#define RT5514_RESET 0x2000
18#define RT5514_PWR_ANA1 0x2004
19#define RT5514_PWR_ANA2 0x2008
20#define RT5514_I2S_CTRL1 0x2010
21#define RT5514_I2S_CTRL2 0x2014
22#define RT5514_VAD_CTRL6 0x2030
23#define RT5514_EXT_VAD_CTRL 0x206c
24#define RT5514_DIG_IO_CTRL 0x2070
25#define RT5514_PAD_CTRL1 0x2080
26#define RT5514_DMIC_DATA_CTRL 0x20a0
27#define RT5514_DIG_SOURCE_CTRL 0x20a4
28#define RT5514_SRC_CTRL 0x20ac
29#define RT5514_DOWNFILTER2_CTRL1 0x20d0
30#define RT5514_PLL_SOURCE_CTRL 0x2100
31#define RT5514_CLK_CTRL1 0x2104
32#define RT5514_CLK_CTRL2 0x2108
33#define RT5514_PLL3_CALIB_CTRL1 0x2110
34#define RT5514_PLL3_CALIB_CTRL5 0x2124
35#define RT5514_DELAY_BUF_CTRL1 0x2140
36#define RT5514_DELAY_BUF_CTRL3 0x2148
37#define RT5514_DOWNFILTER0_CTRL1 0x2190
38#define RT5514_DOWNFILTER0_CTRL2 0x2194
39#define RT5514_DOWNFILTER0_CTRL3 0x2198
40#define RT5514_DOWNFILTER1_CTRL1 0x21a0
41#define RT5514_DOWNFILTER1_CTRL2 0x21a4
42#define RT5514_DOWNFILTER1_CTRL3 0x21a8
43#define RT5514_ANA_CTRL_LDO10 0x2200
44#define RT5514_ANA_CTRL_LDO18_16 0x2204
45#define RT5514_ANA_CTRL_ADC12 0x2210
46#define RT5514_ANA_CTRL_ADC21 0x2214
47#define RT5514_ANA_CTRL_ADC22 0x2218
48#define RT5514_ANA_CTRL_ADC23 0x221c
49#define RT5514_ANA_CTRL_MICBST 0x2220
50#define RT5514_ANA_CTRL_ADCFED 0x2224
51#define RT5514_ANA_CTRL_INBUF 0x2228
52#define RT5514_ANA_CTRL_VREF 0x222c
53#define RT5514_ANA_CTRL_PLL3 0x2240
54#define RT5514_ANA_CTRL_PLL1_1 0x2260
55#define RT5514_ANA_CTRL_PLL1_2 0x2264
56#define RT5514_DMIC_LP_CTRL 0x2e00
57#define RT5514_MISC_CTRL_DSP 0x2e04
58#define RT5514_DSP_CTRL1 0x2f00
59#define RT5514_DSP_CTRL3 0x2f08
60#define RT5514_DSP_CTRL4 0x2f10
61#define RT5514_VENDOR_ID1 0x2ff0
62#define RT5514_VENDOR_ID2 0x2ff4
63
64#define RT5514_DSP_MAPPING 0x18000000
65
66/* RT5514_PWR_ANA1 (0x2004) */
67#define RT5514_POW_LDO18_IN (0x1 << 5)
68#define RT5514_POW_LDO18_IN_BIT 5
69#define RT5514_POW_LDO18_ADC (0x1 << 4)
70#define RT5514_POW_LDO18_ADC_BIT 4
71#define RT5514_POW_LDO21 (0x1 << 3)
72#define RT5514_POW_LDO21_BIT 3
73#define RT5514_POW_BG_LDO18_IN (0x1 << 2)
74#define RT5514_POW_BG_LDO18_IN_BIT 2
75#define RT5514_POW_BG_LDO21 (0x1 << 1)
76#define RT5514_POW_BG_LDO21_BIT 1
77
78/* RT5514_PWR_ANA2 (0x2008) */
79#define RT5514_POW_PLL1 (0x1 << 18)
80#define RT5514_POW_PLL1_BIT 18
81#define RT5514_POW_PLL1_LDO (0x1 << 16)
82#define RT5514_POW_PLL1_LDO_BIT 16
83#define RT5514_POW_BG_MBIAS (0x1 << 15)
84#define RT5514_POW_BG_MBIAS_BIT 15
85#define RT5514_POW_MBIAS (0x1 << 14)
86#define RT5514_POW_MBIAS_BIT 14
87#define RT5514_POW_VREF2 (0x1 << 13)
88#define RT5514_POW_VREF2_BIT 13
89#define RT5514_POW_VREF1 (0x1 << 12)
90#define RT5514_POW_VREF1_BIT 12
91#define RT5514_POWR_LDO16 (0x1 << 11)
92#define RT5514_POWR_LDO16_BIT 11
93#define RT5514_POWL_LDO16 (0x1 << 10)
94#define RT5514_POWL_LDO16_BIT 10
95#define RT5514_POW_ADC2 (0x1 << 9)
96#define RT5514_POW_ADC2_BIT 9
97#define RT5514_POW_INPUT_BUF (0x1 << 8)
98#define RT5514_POW_INPUT_BUF_BIT 8
99#define RT5514_POW_ADC1_R (0x1 << 7)
100#define RT5514_POW_ADC1_R_BIT 7
101#define RT5514_POW_ADC1_L (0x1 << 6)
102#define RT5514_POW_ADC1_L_BIT 6
103#define RT5514_POW2_BSTR (0x1 << 5)
104#define RT5514_POW2_BSTR_BIT 5
105#define RT5514_POW2_BSTL (0x1 << 4)
106#define RT5514_POW2_BSTL_BIT 4
107#define RT5514_POW_BSTR (0x1 << 3)
108#define RT5514_POW_BSTR_BIT 3
109#define RT5514_POW_BSTL (0x1 << 2)
110#define RT5514_POW_BSTL_BIT 2
111#define RT5514_POW_ADCFEDR (0x1 << 1)
112#define RT5514_POW_ADCFEDR_BIT 1
113#define RT5514_POW_ADCFEDL (0x1 << 0)
114#define RT5514_POW_ADCFEDL_BIT 0
115
116/* RT5514_I2S_CTRL1 (0x2010) */
117#define RT5514_TDM_MODE (0x1 << 28)
118#define RT5514_TDM_MODE_SFT 28
119#define RT5514_I2S_LR_MASK (0x1 << 26)
120#define RT5514_I2S_LR_SFT 26
121#define RT5514_I2S_LR_NOR (0x0 << 26)
122#define RT5514_I2S_LR_INV (0x1 << 26)
123#define RT5514_I2S_BP_MASK (0x1 << 25)
124#define RT5514_I2S_BP_SFT 25
125#define RT5514_I2S_BP_NOR (0x0 << 25)
126#define RT5514_I2S_BP_INV (0x1 << 25)
127#define RT5514_I2S_DF_MASK (0x7 << 16)
128#define RT5514_I2S_DF_SFT 16
129#define RT5514_I2S_DF_I2S (0x0 << 16)
130#define RT5514_I2S_DF_LEFT (0x1 << 16)
131#define RT5514_I2S_DF_PCM_A (0x2 << 16)
132#define RT5514_I2S_DF_PCM_B (0x3 << 16)
133#define RT5514_TDMSLOT_SEL_RX_MASK (0x3 << 10)
134#define RT5514_TDMSLOT_SEL_RX_SFT 10
135#define RT5514_TDMSLOT_SEL_RX_4CH (0x1 << 10)
136#define RT5514_CH_LEN_RX_MASK (0x3 << 8)
137#define RT5514_CH_LEN_RX_SFT 8
138#define RT5514_CH_LEN_RX_16 (0x0 << 8)
139#define RT5514_CH_LEN_RX_20 (0x1 << 8)
140#define RT5514_CH_LEN_RX_24 (0x2 << 8)
141#define RT5514_CH_LEN_RX_32 (0x3 << 8)
142#define RT5514_TDMSLOT_SEL_TX_MASK (0x3 << 6)
143#define RT5514_TDMSLOT_SEL_TX_SFT 6
144#define RT5514_TDMSLOT_SEL_TX_4CH (0x1 << 6)
145#define RT5514_CH_LEN_TX_MASK (0x3 << 4)
146#define RT5514_CH_LEN_TX_SFT 4
147#define RT5514_CH_LEN_TX_16 (0x0 << 4)
148#define RT5514_CH_LEN_TX_20 (0x1 << 4)
149#define RT5514_CH_LEN_TX_24 (0x2 << 4)
150#define RT5514_CH_LEN_TX_32 (0x3 << 4)
151#define RT5514_I2S_DL_MASK (0x3 << 0)
152#define RT5514_I2S_DL_SFT 0
153#define RT5514_I2S_DL_16 (0x0 << 0)
154#define RT5514_I2S_DL_20 (0x1 << 0)
155#define RT5514_I2S_DL_24 (0x2 << 0)
156#define RT5514_I2S_DL_8 (0x3 << 0)
157
158/* RT5514_DIG_SOURCE_CTRL (0x20a4) */
159#define RT5514_AD1_DMIC_INPUT_SEL (0x1 << 1)
160#define RT5514_AD1_DMIC_INPUT_SEL_SFT 1
161#define RT5514_AD0_DMIC_INPUT_SEL (0x1 << 0)
162#define RT5514_AD0_DMIC_INPUT_SEL_SFT 0
163
164/* RT5514_PLL_SOURCE_CTRL (0x2100) */
165#define RT5514_PLL_1_SEL_MASK (0x7 << 12)
166#define RT5514_PLL_1_SEL_SFT 12
167#define RT5514_PLL_1_SEL_SCLK (0x3 << 12)
168#define RT5514_PLL_1_SEL_MCLK (0x4 << 12)
169
170/* RT5514_CLK_CTRL1 (0x2104) */
171#define RT5514_CLK_AD_ANA1_EN (0x1 << 31)
172#define RT5514_CLK_AD_ANA1_EN_BIT 31
173#define RT5514_CLK_AD1_EN (0x1 << 24)
174#define RT5514_CLK_AD1_EN_BIT 24
175#define RT5514_CLK_AD0_EN (0x1 << 23)
176#define RT5514_CLK_AD0_EN_BIT 23
177#define RT5514_CLK_DMIC_OUT_SEL_MASK (0x7 << 8)
178#define RT5514_CLK_DMIC_OUT_SEL_SFT 8
179
180/* RT5514_CLK_CTRL2 (0x2108) */
181#define RT5514_CLK_SYS_DIV_OUT_MASK (0x7 << 8)
182#define RT5514_CLK_SYS_DIV_OUT_SFT 8
183#define RT5514_SEL_ADC_OSR_MASK (0x7 << 4)
184#define RT5514_SEL_ADC_OSR_SFT 4
185#define RT5514_CLK_SYS_PRE_SEL_MASK (0x3 << 0)
186#define RT5514_CLK_SYS_PRE_SEL_SFT 0
187#define RT5514_CLK_SYS_PRE_SEL_MCLK (0x2 << 0)
188#define RT5514_CLK_SYS_PRE_SEL_PLL (0x3 << 0)
189
190/* RT5514_DOWNFILTER_CTRL (0x2190 0x2194 0x21a0 0x21a4) */
191#define RT5514_AD_DMIC_MIX (0x1 << 11)
192#define RT5514_AD_DMIC_MIX_BIT 11
193#define RT5514_AD_AD_MIX (0x1 << 10)
194#define RT5514_AD_AD_MIX_BIT 10
195#define RT5514_AD_AD_MUTE (0x1 << 7)
196#define RT5514_AD_AD_MUTE_BIT 7
197#define RT5514_AD_GAIN_MASK (0x7f << 0)
198#define RT5514_AD_GAIN_SFT 0
199
200/* RT5514_ANA_CTRL_MICBST (0x2220) */
201#define RT5514_SEL_BSTL_MASK (0xf << 4)
202#define RT5514_SEL_BSTL_SFT 4
203#define RT5514_SEL_BSTR_MASK (0xf << 0)
204#define RT5514_SEL_BSTR_SFT 0
205
206/* RT5514_ANA_CTRL_PLL1_1 (0x2260) */
207#define RT5514_PLL_K_MAX 0x1f
208#define RT5514_PLL_K_MASK (RT5514_PLL_K_MAX << 16)
209#define RT5514_PLL_K_SFT 16
210#define RT5514_PLL_N_MAX 0x1ff
211#define RT5514_PLL_N_MASK (RT5514_PLL_N_MAX << 7)
212#define RT5514_PLL_N_SFT 4
213#define RT5514_PLL_M_MAX 0xf
214#define RT5514_PLL_M_MASK (RT5514_PLL_M_MAX << 0)
215#define RT5514_PLL_M_SFT 0
216
217/* RT5514_ANA_CTRL_PLL1_2 (0x2264) */
218#define RT5514_PLL_M_BP (0x1 << 2)
219#define RT5514_PLL_M_BP_SFT 2
220#define RT5514_PLL_K_BP (0x1 << 1)
221#define RT5514_PLL_K_BP_SFT 1
222#define RT5514_EN_LDO_PLL1 (0x1 << 0)
223#define RT5514_EN_LDO_PLL1_BIT 0
224
225#define RT5514_PLL_INP_MAX 40000000
226#define RT5514_PLL_INP_MIN 256000
227
228/* System Clock Source */
229enum {
230 RT5514_SCLK_S_MCLK,
231 RT5514_SCLK_S_PLL1,
232};
233
234/* PLL1 Source */
235enum {
236 RT5514_PLL1_S_MCLK,
237 RT5514_PLL1_S_BCLK,
238};
239
240struct rt5514_priv {
241 struct snd_soc_codec *codec;
242 struct regmap *i2c_regmap, *regmap;
243 int sysclk;
244 int sysclk_src;
245 int lrck;
246 int bclk;
247 int pll_src;
248 int pll_in;
249 int pll_out;
250};
251
252#endif /* __RT5514_H__ */
sound/soc/codecs/rt5616.c+228−186
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <linux/module.h>12#include <linux/module.h>
13#include <linux/moduleparam.h>13#include <linux/moduleparam.h>
14#include <linux/init.h>14#include <linux/init.h>
15#include <linux/clk.h>
15#include <linux/delay.h>16#include <linux/delay.h>
16#include <linux/pm.h>17#include <linux/pm.h>
17#include <linux/i2c.h>18#include <linux/i2c.h>
@@ -53,6 +54,7 @@ static const struct reg_sequence init_list[] = { · 35 unmodified lines
53 {RT5616_PR_BASE + 0x21, 0x4040},54 {RT5616_PR_BASE + 0x21, 0x4040},
54 {RT5616_PR_BASE + 0x23, 0x0004},55 {RT5616_PR_BASE + 0x23, 0x0004},
55};56};
57
56#define RT5616_INIT_REG_LEN ARRAY_SIZE(init_list)58#define RT5616_INIT_REG_LEN ARRAY_SIZE(init_list)
57 59
58static const struct reg_default rt5616_reg[] = {60static const struct reg_default rt5616_reg[] = {
@@ -143,6 +145,7 @@ struct rt5616_priv { · 84 unmodified lines
143 struct snd_soc_codec *codec;145 struct snd_soc_codec *codec;
144 struct delayed_work patch_work;146 struct delayed_work patch_work;
145 struct regmap *regmap;147 struct regmap *regmap;
148 struct clk *mclk;
146 149
147 int sysclk;150 int sysclk;
148 int sysclk_src;151 int sysclk_src;
@@ -162,9 +165,8 @@ static bool rt5616_volatile_register(struct device *dev, unsigned int reg) · 13 unmodified lines
162 165
163 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {166 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
164 if (reg >= rt5616_ranges[i].range_min &&167 if (reg >= rt5616_ranges[i].range_min &&
165 reg <= rt5616_ranges[i].range_max) {168 reg <= rt5616_ranges[i].range_max)
166 return true;169 return true;
167 }
168 }170 }
169 171
170 switch (reg) {172 switch (reg) {
@@ -190,9 +192,8 @@ static bool rt5616_readable_register(struct device *dev, unsigned int reg) · 19 unmodified lines
190 192
191 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {193 for (i = 0; i < ARRAY_SIZE(rt5616_ranges); i++) {
192 if (reg >= rt5616_ranges[i].range_min &&194 if (reg >= rt5616_ranges[i].range_min &&
193 reg <= rt5616_ranges[i].range_max) {195 reg <= rt5616_ranges[i].range_max)
194 return true;196 return true;
195 }
196 }197 }
197 198
198 switch (reg) {199 switch (reg) {
@@ -307,45 +308,47 @@ static unsigned int bst_tlv[] = { · 108 unmodified lines
307static const struct snd_kcontrol_new rt5616_snd_controls[] = {308static const struct snd_kcontrol_new rt5616_snd_controls[] = {
308 /* Headphone Output Volume */309 /* Headphone Output Volume */
309 SOC_DOUBLE("HP Playback Switch", RT5616_HP_VOL,310 SOC_DOUBLE("HP Playback Switch", RT5616_HP_VOL,
310 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),311 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
312 SOC_DOUBLE("HPVOL Playback Switch", RT5616_HP_VOL,
313 RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1),
311 SOC_DOUBLE_TLV("HP Playback Volume", RT5616_HP_VOL,314 SOC_DOUBLE_TLV("HP Playback Volume", RT5616_HP_VOL,
312 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),315 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
313 /* OUTPUT Control */316 /* OUTPUT Control */
314 SOC_DOUBLE("OUT Playback Switch", RT5616_LOUT_CTRL1,317 SOC_DOUBLE("OUT Playback Switch", RT5616_LOUT_CTRL1,
315 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),318 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
316 SOC_DOUBLE("OUT Channel Switch", RT5616_LOUT_CTRL1,319 SOC_DOUBLE("OUT Channel Switch", RT5616_LOUT_CTRL1,
317 RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1),320 RT5616_VOL_L_SFT, RT5616_VOL_R_SFT, 1, 1),
318 SOC_DOUBLE_TLV("OUT Playback Volume", RT5616_LOUT_CTRL1,321 SOC_DOUBLE_TLV("OUT Playback Volume", RT5616_LOUT_CTRL1,
319 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),322 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT, 39, 1, out_vol_tlv),
320 323
321 /* DAC Digital Volume */324 /* DAC Digital Volume */
322 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5616_DAC1_DIG_VOL,325 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5616_DAC1_DIG_VOL,
323 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,326 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
324 175, 0, dac_vol_tlv),327 175, 0, dac_vol_tlv),
325 /* IN1/IN2 Control */328 /* IN1/IN2 Control */
326 SOC_SINGLE_TLV("IN1 Boost Volume", RT5616_IN1_IN2,329 SOC_SINGLE_TLV("IN1 Boost Volume", RT5616_IN1_IN2,
327 RT5616_BST_SFT1, 8, 0, bst_tlv),330 RT5616_BST_SFT1, 8, 0, bst_tlv),
328 SOC_SINGLE_TLV("IN2 Boost Volume", RT5616_IN1_IN2,331 SOC_SINGLE_TLV("IN2 Boost Volume", RT5616_IN1_IN2,
329 RT5616_BST_SFT2, 8, 0, bst_tlv),332 RT5616_BST_SFT2, 8, 0, bst_tlv),
330 /* INL/INR Volume Control */333 /* INL/INR Volume Control */
331 SOC_DOUBLE_TLV("IN Capture Volume", RT5616_INL1_INR1_VOL,334 SOC_DOUBLE_TLV("IN Capture Volume", RT5616_INL1_INR1_VOL,
332 RT5616_INL_VOL_SFT, RT5616_INR_VOL_SFT,335 RT5616_INL_VOL_SFT, RT5616_INR_VOL_SFT,
333 31, 1, in_vol_tlv),336 31, 1, in_vol_tlv),
334 /* ADC Digital Volume Control */337 /* ADC Digital Volume Control */
335 SOC_DOUBLE("ADC Capture Switch", RT5616_ADC_DIG_VOL,338 SOC_DOUBLE("ADC Capture Switch", RT5616_ADC_DIG_VOL,
336 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),339 RT5616_L_MUTE_SFT, RT5616_R_MUTE_SFT, 1, 1),
337 SOC_DOUBLE_TLV("ADC Capture Volume", RT5616_ADC_DIG_VOL,340 SOC_DOUBLE_TLV("ADC Capture Volume", RT5616_ADC_DIG_VOL,
338 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,341 RT5616_L_VOL_SFT, RT5616_R_VOL_SFT,
339 127, 0, adc_vol_tlv),342 127, 0, adc_vol_tlv),
340 343
341 /* ADC Boost Volume Control */344 /* ADC Boost Volume Control */
342 SOC_DOUBLE_TLV("ADC Boost Volume", RT5616_ADC_BST_VOL,345 SOC_DOUBLE_TLV("ADC Boost Volume", RT5616_ADC_BST_VOL,
343 RT5616_ADC_L_BST_SFT, RT5616_ADC_R_BST_SFT,346 RT5616_ADC_L_BST_SFT, RT5616_ADC_R_BST_SFT,
344 3, 0, adc_bst_tlv),347 3, 0, adc_bst_tlv),
345};348};
346 349
347static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,350static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
348 struct snd_soc_dapm_widget *sink)351 struct snd_soc_dapm_widget *sink)
349{352{
350 unsigned int val;353 unsigned int val;
351 354
@@ -462,20 +465,20 @@ static const struct snd_kcontrol_new rt5616_lout_mix[] = { · 110 unmodified lines
462};465};
463 466
464static int rt5616_adc_event(struct snd_soc_dapm_widget *w,467static int rt5616_adc_event(struct snd_soc_dapm_widget *w,
465 struct snd_kcontrol *kcontrol, int event)468 struct snd_kcontrol *kcontrol, int event)
466{469{
467 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);470 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
468 471
469 switch (event) {472 switch (event) {
470 case SND_SOC_DAPM_POST_PMU:473 case SND_SOC_DAPM_POST_PMU:
471 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,474 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
472 RT5616_L_MUTE | RT5616_R_MUTE, 0);475 RT5616_L_MUTE | RT5616_R_MUTE, 0);
473 break;476 break;
474 477
475 case SND_SOC_DAPM_POST_PMD:478 case SND_SOC_DAPM_POST_PMD:
476 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,479 snd_soc_update_bits(codec, RT5616_ADC_DIG_VOL,
477 RT5616_L_MUTE | RT5616_R_MUTE,480 RT5616_L_MUTE | RT5616_R_MUTE,
478 RT5616_L_MUTE | RT5616_R_MUTE);481 RT5616_L_MUTE | RT5616_R_MUTE);
479 break;482 break;
480 483
481 default:484 default:
@@ -486,7 +489,7 @@ static int rt5616_adc_event(struct snd_soc_dapm_widget *w, · 4 unmodified lines
486}489}
487 490
488static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,491static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w,
489 struct snd_kcontrol *kcontrol, int event)492 struct snd_kcontrol *kcontrol, int event)
490{493{
491 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);494 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
492 495
@@ -494,54 +497,55 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w, · 1 unmodified line
494 case SND_SOC_DAPM_POST_PMU:497 case SND_SOC_DAPM_POST_PMU:
495 /* depop parameters */498 /* depop parameters */
496 snd_soc_update_bits(codec, RT5616_DEPOP_M2,499 snd_soc_update_bits(codec, RT5616_DEPOP_M2,
497 RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);500 RT5616_DEPOP_MASK, RT5616_DEPOP_MAN);
498 snd_soc_update_bits(codec, RT5616_DEPOP_M1,501 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
499 RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |502 RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
500 RT5616_HP_CB_MASK, RT5616_HP_CP_PU |503 RT5616_HP_CB_MASK, RT5616_HP_CP_PU |
501 RT5616_HP_SG_DIS | RT5616_HP_CB_PU);504 RT5616_HP_SG_DIS | RT5616_HP_CB_PU);
502 snd_soc_write(codec, RT5616_PR_BASE +505 snd_soc_write(codec, RT5616_PR_BASE +
503 RT5616_HP_DCC_INT1, 0x9f00);506 RT5616_HP_DCC_INT1, 0x9f00);
504 /* headphone amp power on */507 /* headphone amp power on */
505 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,508 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
506 RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);509 RT5616_PWR_FV1 | RT5616_PWR_FV2, 0);
507 snd_soc_update_bits(codec, RT5616_PWR_VOL,510 snd_soc_update_bits(codec, RT5616_PWR_VOL,
508 RT5616_PWR_HV_L | RT5616_PWR_HV_R,511 RT5616_PWR_HV_L | RT5616_PWR_HV_R,
509 RT5616_PWR_HV_L | RT5616_PWR_HV_R);512 RT5616_PWR_HV_L | RT5616_PWR_HV_R);
510 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,513 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
511 RT5616_PWR_HP_L | RT5616_PWR_HP_R |514 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
512 RT5616_PWR_HA, RT5616_PWR_HP_L |515 RT5616_PWR_HA, RT5616_PWR_HP_L |
513 RT5616_PWR_HP_R | RT5616_PWR_HA);516 RT5616_PWR_HP_R | RT5616_PWR_HA);
514 msleep(50);517 msleep(50);
515 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,518 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
516 RT5616_PWR_FV1 | RT5616_PWR_FV2,519 RT5616_PWR_FV1 | RT5616_PWR_FV2,
517 RT5616_PWR_FV1 | RT5616_PWR_FV2);520 RT5616_PWR_FV1 | RT5616_PWR_FV2);
518 521
519 snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,522 snd_soc_update_bits(codec, RT5616_CHARGE_PUMP,
520 RT5616_PM_HP_MASK, RT5616_PM_HP_HV);523 RT5616_PM_HP_MASK, RT5616_PM_HP_HV);
521 snd_soc_update_bits(codec, RT5616_PR_BASE +524 snd_soc_update_bits(codec, RT5616_PR_BASE +
522 RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);525 RT5616_CHOP_DAC_ADC, 0x0200, 0x0200);
523 snd_soc_update_bits(codec, RT5616_DEPOP_M1,526 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
524 RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,527 RT5616_HP_CO_MASK | RT5616_HP_SG_MASK,
525 RT5616_HP_CO_EN | RT5616_HP_SG_EN);528 RT5616_HP_CO_EN | RT5616_HP_SG_EN);
526 break;529 break;
527 case SND_SOC_DAPM_PRE_PMD:530 case SND_SOC_DAPM_PRE_PMD:
528 snd_soc_update_bits(codec, RT5616_PR_BASE +531 snd_soc_update_bits(codec, RT5616_PR_BASE +
529 RT5616_CHOP_DAC_ADC, 0x0200, 0x0);532 RT5616_CHOP_DAC_ADC, 0x0200, 0x0);
530 snd_soc_update_bits(codec, RT5616_DEPOP_M1,533 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
531 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |534 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
532 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |535 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
533 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);536 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
534 /* headphone amp power down */537 /* headphone amp power down */
535 snd_soc_update_bits(codec, RT5616_DEPOP_M1,538 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
536 RT5616_SMT_TRIG_MASK | RT5616_HP_CD_PD_MASK |539 RT5616_SMT_TRIG_MASK |
537 RT5616_HP_CO_MASK | RT5616_HP_CP_MASK |540 RT5616_HP_CD_PD_MASK | RT5616_HP_CO_MASK |
538 RT5616_HP_SG_MASK | RT5616_HP_CB_MASK,541 RT5616_HP_CP_MASK | RT5616_HP_SG_MASK |
539 RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |542 RT5616_HP_CB_MASK,
540 RT5616_HP_CO_DIS | RT5616_HP_CP_PD |543 RT5616_SMT_TRIG_DIS | RT5616_HP_CD_PD_EN |
541 RT5616_HP_SG_EN | RT5616_HP_CB_PD);544 RT5616_HP_CO_DIS | RT5616_HP_CP_PD |
545 RT5616_HP_SG_EN | RT5616_HP_CB_PD);
542 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,546 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
543 RT5616_PWR_HP_L | RT5616_PWR_HP_R |547 RT5616_PWR_HP_L | RT5616_PWR_HP_R |
544 RT5616_PWR_HA, 0);548 RT5616_PWR_HA, 0);
545 break;549 break;
546 default:550 default:
547 return 0;551 return 0;
@@ -551,7 +555,7 @@ static int rt5616_charge_pump_event(struct snd_soc_dapm_widget *w, · 3 unmodified lines
551}555}
552 556
553static int rt5616_hp_event(struct snd_soc_dapm_widget *w,557static int rt5616_hp_event(struct snd_soc_dapm_widget *w,
554 struct snd_kcontrol *kcontrol, int event)558 struct snd_kcontrol *kcontrol, int event)
555{559{
556 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);560 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
557 561
@@ -559,57 +563,57 @@ static int rt5616_hp_event(struct snd_soc_dapm_widget *w, · 1 unmodified line
559 case SND_SOC_DAPM_POST_PMU:563 case SND_SOC_DAPM_POST_PMU:
560 /* headphone unmute sequence */564 /* headphone unmute sequence */
561 snd_soc_update_bits(codec, RT5616_DEPOP_M3,565 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
562 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |566 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
563 RT5616_CP_FQ3_MASK,567 RT5616_CP_FQ3_MASK,
564 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT) |568 RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ1_SFT |
565 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |569 RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
566 (RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT));570 RT5616_CP_FQ_192_KHZ << RT5616_CP_FQ3_SFT);
567 snd_soc_write(codec, RT5616_PR_BASE +571 snd_soc_write(codec, RT5616_PR_BASE +
568 RT5616_MAMP_INT_REG2, 0xfc00);572 RT5616_MAMP_INT_REG2, 0xfc00);
569 snd_soc_update_bits(codec, RT5616_DEPOP_M1,573 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
570 RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);574 RT5616_SMT_TRIG_MASK, RT5616_SMT_TRIG_EN);
571 snd_soc_update_bits(codec, RT5616_DEPOP_M1,575 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
572 RT5616_RSTN_MASK, RT5616_RSTN_EN);576 RT5616_RSTN_MASK, RT5616_RSTN_EN);
573 snd_soc_update_bits(codec, RT5616_DEPOP_M1,577 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
574 RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |578 RT5616_RSTN_MASK | RT5616_HP_L_SMT_MASK |
575 RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |579 RT5616_HP_R_SMT_MASK, RT5616_RSTN_DIS |
576 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);580 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
577 snd_soc_update_bits(codec, RT5616_HP_VOL,581 snd_soc_update_bits(codec, RT5616_HP_VOL,
578 RT5616_L_MUTE | RT5616_R_MUTE, 0);582 RT5616_L_MUTE | RT5616_R_MUTE, 0);
579 msleep(100);583 msleep(100);
580 snd_soc_update_bits(codec, RT5616_DEPOP_M1,584 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
581 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |585 RT5616_HP_SG_MASK | RT5616_HP_L_SMT_MASK |
582 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |586 RT5616_HP_R_SMT_MASK, RT5616_HP_SG_DIS |
583 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);587 RT5616_HP_L_SMT_DIS | RT5616_HP_R_SMT_DIS);
584 msleep(20);588 msleep(20);
585 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,589 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
586 RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);590 RT5616_HPD_PS_MASK, RT5616_HPD_PS_EN);
587 break;591 break;
588 592
589 case SND_SOC_DAPM_PRE_PMD:593 case SND_SOC_DAPM_PRE_PMD:
590 /* headphone mute sequence */594 /* headphone mute sequence */
591 snd_soc_update_bits(codec, RT5616_DEPOP_M3,595 snd_soc_update_bits(codec, RT5616_DEPOP_M3,
592 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |596 RT5616_CP_FQ1_MASK | RT5616_CP_FQ2_MASK |
593 RT5616_CP_FQ3_MASK,597 RT5616_CP_FQ3_MASK,
594 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT) |598 RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ1_SFT |
595 (RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT) |599 RT5616_CP_FQ_12_KHZ << RT5616_CP_FQ2_SFT |
596 (RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT));600 RT5616_CP_FQ_96_KHZ << RT5616_CP_FQ3_SFT);
597 snd_soc_write(codec, RT5616_PR_BASE +601 snd_soc_write(codec, RT5616_PR_BASE +
598 RT5616_MAMP_INT_REG2, 0xfc00);602 RT5616_MAMP_INT_REG2, 0xfc00);
599 snd_soc_update_bits(codec, RT5616_DEPOP_M1,603 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
600 RT5616_HP_SG_MASK, RT5616_HP_SG_EN);604 RT5616_HP_SG_MASK, RT5616_HP_SG_EN);
601 snd_soc_update_bits(codec, RT5616_DEPOP_M1,605 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
602 RT5616_RSTP_MASK, RT5616_RSTP_EN);606 RT5616_RSTP_MASK, RT5616_RSTP_EN);
603 snd_soc_update_bits(codec, RT5616_DEPOP_M1,607 snd_soc_update_bits(codec, RT5616_DEPOP_M1,
604 RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |608 RT5616_RSTP_MASK | RT5616_HP_L_SMT_MASK |
605 RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |609 RT5616_HP_R_SMT_MASK, RT5616_RSTP_DIS |
606 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);610 RT5616_HP_L_SMT_EN | RT5616_HP_R_SMT_EN);
607 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,611 snd_soc_update_bits(codec, RT5616_HP_CALIB_AMP_DET,
608 RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);612 RT5616_HPD_PS_MASK, RT5616_HPD_PS_DIS);
609 msleep(90);613 msleep(90);
610 snd_soc_update_bits(codec, RT5616_HP_VOL,614 snd_soc_update_bits(codec, RT5616_HP_VOL,
611 RT5616_L_MUTE | RT5616_R_MUTE,615 RT5616_L_MUTE | RT5616_R_MUTE,
612 RT5616_L_MUTE | RT5616_R_MUTE);616 RT5616_L_MUTE | RT5616_R_MUTE);
613 msleep(30);617 msleep(30);
614 break;618 break;
615 619
@@ -621,24 +625,24 @@ static int rt5616_hp_event(struct snd_soc_dapm_widget *w, · 5 unmodified lines
621}625}
622 626
623static int rt5616_lout_event(struct snd_soc_dapm_widget *w,627static int rt5616_lout_event(struct snd_soc_dapm_widget *w,
624 struct snd_kcontrol *kcontrol, int event)628 struct snd_kcontrol *kcontrol, int event)
625{629{
626 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);630 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
627 631
628 switch (event) {632 switch (event) {
629 case SND_SOC_DAPM_POST_PMU:633 case SND_SOC_DAPM_POST_PMU:
630 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,634 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
631 RT5616_PWR_LM, RT5616_PWR_LM);635 RT5616_PWR_LM, RT5616_PWR_LM);
632 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,636 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
633 RT5616_L_MUTE | RT5616_R_MUTE, 0);637 RT5616_L_MUTE | RT5616_R_MUTE, 0);
634 break;638 break;
635 639
636 case SND_SOC_DAPM_PRE_PMD:640 case SND_SOC_DAPM_PRE_PMD:
637 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,641 snd_soc_update_bits(codec, RT5616_LOUT_CTRL1,
638 RT5616_L_MUTE | RT5616_R_MUTE,642 RT5616_L_MUTE | RT5616_R_MUTE,
639 RT5616_L_MUTE | RT5616_R_MUTE);643 RT5616_L_MUTE | RT5616_R_MUTE);
640 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,644 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
641 RT5616_PWR_LM, 0);645 RT5616_PWR_LM, 0);
642 break;646 break;
643 647
644 default:648 default:
@@ -649,19 +653,19 @@ static int rt5616_lout_event(struct snd_soc_dapm_widget *w, · 4 unmodified lines
649}653}
650 654
651static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,655static int rt5616_bst1_event(struct snd_soc_dapm_widget *w,
652 struct snd_kcontrol *kcontrol, int event)656 struct snd_kcontrol *kcontrol, int event)
653{657{
654 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);658 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
655 659
656 switch (event) {660 switch (event) {
657 case SND_SOC_DAPM_POST_PMU:661 case SND_SOC_DAPM_POST_PMU:
658 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,662 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
659 RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);663 RT5616_PWR_BST1_OP2, RT5616_PWR_BST1_OP2);
660 break;664 break;
661 665
662 case SND_SOC_DAPM_PRE_PMD:666 case SND_SOC_DAPM_PRE_PMD:
663 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,667 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
664 RT5616_PWR_BST1_OP2, 0);668 RT5616_PWR_BST1_OP2, 0);
665 break;669 break;
666 670
667 default:671 default:
@@ -672,19 +676,19 @@ static int rt5616_bst1_event(struct snd_soc_dapm_widget *w, · 4 unmodified lines
672}676}
673 677
674static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,678static int rt5616_bst2_event(struct snd_soc_dapm_widget *w,
675 struct snd_kcontrol *kcontrol, int event)679 struct snd_kcontrol *kcontrol, int event)
676{680{
677 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);681 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
678 682
679 switch (event) {683 switch (event) {
680 case SND_SOC_DAPM_POST_PMU:684 case SND_SOC_DAPM_POST_PMU:
681 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,685 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
682 RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);686 RT5616_PWR_BST2_OP2, RT5616_PWR_BST2_OP2);
683 break;687 break;
684 688
685 case SND_SOC_DAPM_PRE_PMD:689 case SND_SOC_DAPM_PRE_PMD:
686 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,690 snd_soc_update_bits(codec, RT5616_PWR_ANLG2,
687 RT5616_PWR_BST2_OP2, 0);691 RT5616_PWR_BST2_OP2, 0);
688 break;692 break;
689 693
690 default:694 default:
@@ -696,13 +700,13 @@ static int rt5616_bst2_event(struct snd_soc_dapm_widget *w, · 5 unmodified lines
696 700
697static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = {701static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = {
698 SND_SOC_DAPM_SUPPLY("PLL1", RT5616_PWR_ANLG2,702 SND_SOC_DAPM_SUPPLY("PLL1", RT5616_PWR_ANLG2,
699 RT5616_PWR_PLL_BIT, 0, NULL, 0),703 RT5616_PWR_PLL_BIT, 0, NULL, 0),
700 /* Input Side */704 /* Input Side */
701 /* micbias */705 /* micbias */
702 SND_SOC_DAPM_SUPPLY("LDO", RT5616_PWR_ANLG1,706 SND_SOC_DAPM_SUPPLY("LDO", RT5616_PWR_ANLG1,
703 RT5616_PWR_LDO_BIT, 0, NULL, 0),707 RT5616_PWR_LDO_BIT, 0, NULL, 0),
704 SND_SOC_DAPM_SUPPLY("micbias1", RT5616_PWR_ANLG2,708 SND_SOC_DAPM_SUPPLY("micbias1", RT5616_PWR_ANLG2,
705 RT5616_PWR_MB1_BIT, 0, NULL, 0),709 RT5616_PWR_MB1_BIT, 0, NULL, 0),
706 710
707 /* Input Lines */711 /* Input Lines */
708 SND_SOC_DAPM_INPUT("MIC1"),712 SND_SOC_DAPM_INPUT("MIC1"),
@@ -714,45 +718,47 @@ static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = { · 5 unmodified lines
714 718
715 /* Boost */719 /* Boost */
716 SND_SOC_DAPM_PGA_E("BST1", RT5616_PWR_ANLG2,720 SND_SOC_DAPM_PGA_E("BST1", RT5616_PWR_ANLG2,
717 RT5616_PWR_BST1_BIT, 0, NULL, 0, rt5616_bst1_event,721 RT5616_PWR_BST1_BIT, 0, NULL, 0, rt5616_bst1_event,
718 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),722 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
719 SND_SOC_DAPM_PGA_E("BST2", RT5616_PWR_ANLG2,723 SND_SOC_DAPM_PGA_E("BST2", RT5616_PWR_ANLG2,
720 RT5616_PWR_BST2_BIT, 0, NULL, 0, rt5616_bst2_event,724 RT5616_PWR_BST2_BIT, 0, NULL, 0, rt5616_bst2_event,
721 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),725 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
722 /* Input Volume */726 /* Input Volume */
723 SND_SOC_DAPM_PGA("INL1 VOL", RT5616_PWR_VOL,727 SND_SOC_DAPM_PGA("INL1 VOL", RT5616_PWR_VOL,
724 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),728 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
725 SND_SOC_DAPM_PGA("INR1 VOL", RT5616_PWR_VOL,729 SND_SOC_DAPM_PGA("INR1 VOL", RT5616_PWR_VOL,
726 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),730 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
727 SND_SOC_DAPM_PGA("INL2 VOL", RT5616_PWR_VOL,731 SND_SOC_DAPM_PGA("INL2 VOL", RT5616_PWR_VOL,
728 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),732 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
729 SND_SOC_DAPM_PGA("INR2 VOL", RT5616_PWR_VOL,733 SND_SOC_DAPM_PGA("INR2 VOL", RT5616_PWR_VOL,
730 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),734 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
731 735
732 /* REC Mixer */736 /* REC Mixer */
733 SND_SOC_DAPM_MIXER("RECMIXL", RT5616_PWR_MIXER, RT5616_PWR_RM_L_BIT, 0,737 SND_SOC_DAPM_MIXER("RECMIXL", RT5616_PWR_MIXER, RT5616_PWR_RM_L_BIT, 0,
734 rt5616_rec_l_mix, ARRAY_SIZE(rt5616_rec_l_mix)),738 rt5616_rec_l_mix, ARRAY_SIZE(rt5616_rec_l_mix)),
735 SND_SOC_DAPM_MIXER("RECMIXR", RT5616_PWR_MIXER, RT5616_PWR_RM_R_BIT, 0,739 SND_SOC_DAPM_MIXER("RECMIXR", RT5616_PWR_MIXER, RT5616_PWR_RM_R_BIT, 0,
736 rt5616_rec_r_mix, ARRAY_SIZE(rt5616_rec_r_mix)),740 rt5616_rec_r_mix, ARRAY_SIZE(rt5616_rec_r_mix)),
737 /* ADCs */741 /* ADCs */
738 SND_SOC_DAPM_ADC_E("ADC L", NULL, RT5616_PWR_DIG1,742 SND_SOC_DAPM_ADC_E("ADC L", NULL, RT5616_PWR_DIG1,
739 RT5616_PWR_ADC_L_BIT, 0, rt5616_adc_event,743 RT5616_PWR_ADC_L_BIT, 0, rt5616_adc_event,
740 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),744 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
741 SND_SOC_DAPM_ADC_E("ADC R", NULL, RT5616_PWR_DIG1,745 SND_SOC_DAPM_ADC_E("ADC R", NULL, RT5616_PWR_DIG1,
742 RT5616_PWR_ADC_R_BIT, 0, rt5616_adc_event,746 RT5616_PWR_ADC_R_BIT, 0, rt5616_adc_event,
743 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),747 SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
744 748
745 /* ADC Mixer */749 /* ADC Mixer */
746 SND_SOC_DAPM_SUPPLY("stereo1 filter", RT5616_PWR_DIG2,750 SND_SOC_DAPM_SUPPLY("stereo1 filter", RT5616_PWR_DIG2,
747 RT5616_PWR_ADC_STO1_F_BIT, 0, NULL, 0),751 RT5616_PWR_ADC_STO1_F_BIT, 0, NULL, 0),
748 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0,752 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0,
749 rt5616_sto1_adc_l_mix, ARRAY_SIZE(rt5616_sto1_adc_l_mix)),753 rt5616_sto1_adc_l_mix,
754 ARRAY_SIZE(rt5616_sto1_adc_l_mix)),
750 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0,755 SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0,
751 rt5616_sto1_adc_r_mix, ARRAY_SIZE(rt5616_sto1_adc_r_mix)),756 rt5616_sto1_adc_r_mix,
757 ARRAY_SIZE(rt5616_sto1_adc_r_mix)),
752 758
753 /* Digital Interface */759 /* Digital Interface */
754 SND_SOC_DAPM_SUPPLY("I2S1", RT5616_PWR_DIG1,760 SND_SOC_DAPM_SUPPLY("I2S1", RT5616_PWR_DIG1,
755 RT5616_PWR_I2S1_BIT, 0, NULL, 0),761 RT5616_PWR_I2S1_BIT, 0, NULL, 0),
756 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),762 SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
757 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),763 SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
758 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),764 SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -770,68 +776,70 @@ static const struct snd_soc_dapm_widget rt5616_dapm_widgets[] = { · 11 unmodified lines
770 /* Output Side */776 /* Output Side */
771 /* DAC mixer before sound effect */777 /* DAC mixer before sound effect */
772 SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,778 SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
773 rt5616_dac_l_mix, ARRAY_SIZE(rt5616_dac_l_mix)),779 rt5616_dac_l_mix, ARRAY_SIZE(rt5616_dac_l_mix)),
774 SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,780 SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
775 rt5616_dac_r_mix, ARRAY_SIZE(rt5616_dac_r_mix)),781 rt5616_dac_r_mix, ARRAY_SIZE(rt5616_dac_r_mix)),
776 782
777 SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5616_PWR_DIG2,783 SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5616_PWR_DIG2,
778 RT5616_PWR_DAC_STO1_F_BIT, 0, NULL, 0),784 RT5616_PWR_DAC_STO1_F_BIT, 0, NULL, 0),
779 785
780 /* DAC Mixer */786 /* DAC Mixer */
781 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,787 SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
782 rt5616_sto_dac_l_mix, ARRAY_SIZE(rt5616_sto_dac_l_mix)),788 rt5616_sto_dac_l_mix,
789 ARRAY_SIZE(rt5616_sto_dac_l_mix)),
783 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,790 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
784 rt5616_sto_dac_r_mix, ARRAY_SIZE(rt5616_sto_dac_r_mix)),791 rt5616_sto_dac_r_mix,
792 ARRAY_SIZE(rt5616_sto_dac_r_mix)),
785 793
786 /* DACs */794 /* DACs */
787 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5616_PWR_DIG1,795 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5616_PWR_DIG1,
788 RT5616_PWR_DAC_L1_BIT, 0),796 RT5616_PWR_DAC_L1_BIT, 0),
789 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5616_PWR_DIG1,797 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5616_PWR_DIG1,
790 RT5616_PWR_DAC_R1_BIT, 0),798 RT5616_PWR_DAC_R1_BIT, 0),
791 /* OUT Mixer */799 /* OUT Mixer */
792 SND_SOC_DAPM_MIXER("OUT MIXL", RT5616_PWR_MIXER, RT5616_PWR_OM_L_BIT,800 SND_SOC_DAPM_MIXER("OUT MIXL", RT5616_PWR_MIXER, RT5616_PWR_OM_L_BIT,
793 0, rt5616_out_l_mix, ARRAY_SIZE(rt5616_out_l_mix)),801 0, rt5616_out_l_mix, ARRAY_SIZE(rt5616_out_l_mix)),
794 SND_SOC_DAPM_MIXER("OUT MIXR", RT5616_PWR_MIXER, RT5616_PWR_OM_R_BIT,802 SND_SOC_DAPM_MIXER("OUT MIXR", RT5616_PWR_MIXER, RT5616_PWR_OM_R_BIT,
795 0, rt5616_out_r_mix, ARRAY_SIZE(rt5616_out_r_mix)),803 0, rt5616_out_r_mix, ARRAY_SIZE(rt5616_out_r_mix)),
796 /* Output Volume */804 /* Output Volume */
797 SND_SOC_DAPM_PGA("OUTVOL L", RT5616_PWR_VOL,805 SND_SOC_DAPM_PGA("OUTVOL L", RT5616_PWR_VOL,
798 RT5616_PWR_OV_L_BIT, 0, NULL, 0),806 RT5616_PWR_OV_L_BIT, 0, NULL, 0),
799 SND_SOC_DAPM_PGA("OUTVOL R", RT5616_PWR_VOL,807 SND_SOC_DAPM_PGA("OUTVOL R", RT5616_PWR_VOL,
800 RT5616_PWR_OV_R_BIT, 0, NULL, 0),808 RT5616_PWR_OV_R_BIT, 0, NULL, 0),
801 SND_SOC_DAPM_PGA("HPOVOL L", RT5616_PWR_VOL,809 SND_SOC_DAPM_PGA("HPOVOL L", RT5616_PWR_VOL,
802 RT5616_PWR_HV_L_BIT, 0, NULL, 0),810 RT5616_PWR_HV_L_BIT, 0, NULL, 0),
803 SND_SOC_DAPM_PGA("HPOVOL R", RT5616_PWR_VOL,811 SND_SOC_DAPM_PGA("HPOVOL R", RT5616_PWR_VOL,
804 RT5616_PWR_HV_R_BIT, 0, NULL, 0),812 RT5616_PWR_HV_R_BIT, 0, NULL, 0),
805 SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,813 SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM,
806 0, 0, NULL, 0),814 0, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,815 SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM,
808 0, 0, NULL, 0),816 0, 0, NULL, 0),
809 SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,817 SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM,
810 0, 0, NULL, 0),818 0, 0, NULL, 0),
811 SND_SOC_DAPM_PGA("INL1", RT5616_PWR_VOL,819 SND_SOC_DAPM_PGA("INL1", RT5616_PWR_VOL,
812 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),820 RT5616_PWR_IN1_L_BIT, 0, NULL, 0),
813 SND_SOC_DAPM_PGA("INR1", RT5616_PWR_VOL,821 SND_SOC_DAPM_PGA("INR1", RT5616_PWR_VOL,
814 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),822 RT5616_PWR_IN1_R_BIT, 0, NULL, 0),
815 SND_SOC_DAPM_PGA("INL2", RT5616_PWR_VOL,823 SND_SOC_DAPM_PGA("INL2", RT5616_PWR_VOL,
816 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),824 RT5616_PWR_IN2_L_BIT, 0, NULL, 0),
817 SND_SOC_DAPM_PGA("INR2", RT5616_PWR_VOL,825 SND_SOC_DAPM_PGA("INR2", RT5616_PWR_VOL,
818 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),826 RT5616_PWR_IN2_R_BIT, 0, NULL, 0),
819 /* HPO/LOUT/Mono Mixer */827 /* HPO/LOUT/Mono Mixer */
820 SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,828 SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0,
821 rt5616_hpo_mix, ARRAY_SIZE(rt5616_hpo_mix)),829 rt5616_hpo_mix, ARRAY_SIZE(rt5616_hpo_mix)),
822 SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0,830 SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0,
823 rt5616_lout_mix, ARRAY_SIZE(rt5616_lout_mix)),831 rt5616_lout_mix, ARRAY_SIZE(rt5616_lout_mix)),
824 832
825 SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0,833 SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0,
826 rt5616_hp_event, SND_SOC_DAPM_PRE_PMD |834 rt5616_hp_event, SND_SOC_DAPM_PRE_PMD |
827 SND_SOC_DAPM_POST_PMU),835 SND_SOC_DAPM_POST_PMU),
828 SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0,836 SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0,
829 rt5616_lout_event, SND_SOC_DAPM_PRE_PMD |837 rt5616_lout_event, SND_SOC_DAPM_PRE_PMD |
830 SND_SOC_DAPM_POST_PMU),838 SND_SOC_DAPM_POST_PMU),
831 839
832 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, SND_SOC_NOPM, 0, 0,840 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, SND_SOC_NOPM, 0, 0,
833 rt5616_charge_pump_event, SND_SOC_DAPM_POST_PMU |841 rt5616_charge_pump_event, SND_SOC_DAPM_POST_PMU |
834 SND_SOC_DAPM_PRE_PMD),842 SND_SOC_DAPM_PRE_PMD),
835 843
836 /* Output Lines */844 /* Output Lines */
837 SND_SOC_DAPM_OUTPUT("HPOL"),845 SND_SOC_DAPM_OUTPUT("HPOL"),
@@ -950,7 +958,8 @@ static const struct snd_soc_dapm_route rt5616_dapm_routes[] = { · 112 unmodified lines
950};958};
951 959
952static int rt5616_hw_params(struct snd_pcm_substream *substream,960static int rt5616_hw_params(struct snd_pcm_substream *substream,
953 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)961 struct snd_pcm_hw_params *params,
962 struct snd_soc_dai *dai)
954{963{
955 struct snd_soc_pcm_runtime *rtd = substream->private_data;964 struct snd_soc_pcm_runtime *rtd = substream->private_data;
956 struct snd_soc_codec *codec = rtd->codec;965 struct snd_soc_codec *codec = rtd->codec;
@@ -977,7 +986,7 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream, · 20 unmodified lines
977 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",986 dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
978 rt5616->bclk[dai->id], rt5616->lrck[dai->id]);987 rt5616->bclk[dai->id], rt5616->lrck[dai->id]);
979 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",988 dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
980 bclk_ms, pre_div, dai->id);989 bclk_ms, pre_div, dai->id);
981 990
982 switch (params_format(params)) {991 switch (params_format(params)) {
983 case SNDRV_PCM_FORMAT_S16_LE:992 case SNDRV_PCM_FORMAT_S16_LE:
@@ -998,10 +1007,9 @@ static int rt5616_hw_params(struct snd_pcm_substream *substream, · 14 unmodified lines
998 mask_clk = RT5616_I2S_PD1_MASK;1007 mask_clk = RT5616_I2S_PD1_MASK;
999 val_clk = pre_div << RT5616_I2S_PD1_SFT;1008 val_clk = pre_div << RT5616_I2S_PD1_SFT;
1000 snd_soc_update_bits(codec, RT5616_I2S1_SDP,1009 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1001 RT5616_I2S_DL_MASK, val_len);1010 RT5616_I2S_DL_MASK, val_len);
1002 snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);1011 snd_soc_update_bits(codec, RT5616_ADDA_CLK1, mask_clk, val_clk);
1003 1012
1004
1005 return 0;1013 return 0;
1006}1014}
1007 1015
@@ -1050,15 +1058,14 @@ static int rt5616_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) · 42 unmodified lines
1050 }1058 }
1051 1059
1052 snd_soc_update_bits(codec, RT5616_I2S1_SDP,1060 snd_soc_update_bits(codec, RT5616_I2S1_SDP,
1053 RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |1061 RT5616_I2S_MS_MASK | RT5616_I2S_BP_MASK |
1054 RT5616_I2S_DF_MASK, reg_val);1062 RT5616_I2S_DF_MASK, reg_val);
1055
1056 1063
1057 return 0;1064 return 0;
1058}1065}
1059 1066
1060static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,1067static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai,
1061 int clk_id, unsigned int freq, int dir)1068 int clk_id, unsigned int freq, int dir)
1062{1069{
1063 struct snd_soc_codec *codec = dai->codec;1070 struct snd_soc_codec *codec = dai->codec;
1064 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);1071 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
@@ -1078,8 +1085,9 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai, · 13 unmodified lines
1078 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);1085 dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
1079 return -EINVAL;1086 return -EINVAL;
1080 }1087 }
1088
1081 snd_soc_update_bits(codec, RT5616_GLB_CLK,1089 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1082 RT5616_SCLK_SRC_MASK, reg_val);1090 RT5616_SCLK_SRC_MASK, reg_val);
1083 rt5616->sysclk = freq;1091 rt5616->sysclk = freq;
1084 rt5616->sysclk_src = clk_id;1092 rt5616->sysclk_src = clk_id;
1085 1093
@@ -1089,7 +1097,7 @@ static int rt5616_set_dai_sysclk(struct snd_soc_dai *dai, · 3 unmodified lines
1089}1097}
1090 1098
1091static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,1099static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1092 unsigned int freq_in, unsigned int freq_out)1100 unsigned int freq_in, unsigned int freq_out)
1093{1101{
1094 struct snd_soc_codec *codec = dai->codec;1102 struct snd_soc_codec *codec = dai->codec;
1095 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);1103 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
@@ -1106,19 +1114,22 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 10 unmodified lines
1106 rt5616->pll_in = 0;1114 rt5616->pll_in = 0;
1107 rt5616->pll_out = 0;1115 rt5616->pll_out = 0;
1108 snd_soc_update_bits(codec, RT5616_GLB_CLK,1116 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1109 RT5616_SCLK_SRC_MASK, RT5616_SCLK_SRC_MCLK);1117 RT5616_SCLK_SRC_MASK,
1118 RT5616_SCLK_SRC_MCLK);
1110 return 0;1119 return 0;
1111 }1120 }
1112 1121
1113 switch (source) {1122 switch (source) {
1114 case RT5616_PLL1_S_MCLK:1123 case RT5616_PLL1_S_MCLK:
1115 snd_soc_update_bits(codec, RT5616_GLB_CLK,1124 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1116 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_MCLK);1125 RT5616_PLL1_SRC_MASK,
1126 RT5616_PLL1_SRC_MCLK);
1117 break;1127 break;
1118 case RT5616_PLL1_S_BCLK1:1128 case RT5616_PLL1_S_BCLK1:
1119 case RT5616_PLL1_S_BCLK2:1129 case RT5616_PLL1_S_BCLK2:
1120 snd_soc_update_bits(codec, RT5616_GLB_CLK,1130 snd_soc_update_bits(codec, RT5616_GLB_CLK,
1121 RT5616_PLL1_SRC_MASK, RT5616_PLL1_SRC_BCLK1);1131 RT5616_PLL1_SRC_MASK,
1132 RT5616_PLL1_SRC_BCLK1);
1122 break;1133 break;
1123 default:1134 default:
1124 dev_err(codec->dev, "Unknown PLL source %d\n", source);1135 dev_err(codec->dev, "Unknown PLL source %d\n", source);
@@ -1136,10 +1147,11 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 11 unmodified lines
1136 pll_code.n_code, pll_code.k_code);1147 pll_code.n_code, pll_code.k_code);
1137 1148
1138 snd_soc_write(codec, RT5616_PLL_CTRL1,1149 snd_soc_write(codec, RT5616_PLL_CTRL1,
1139 pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);1150 pll_code.n_code << RT5616_PLL_N_SFT | pll_code.k_code);
1140 snd_soc_write(codec, RT5616_PLL_CTRL2,1151 snd_soc_write(codec, RT5616_PLL_CTRL2,
1141 (pll_code.m_bp ? 0 : pll_code.m_code) << RT5616_PLL_M_SFT |1152 (pll_code.m_bp ? 0 : pll_code.m_code) <<
1142 pll_code.m_bp << RT5616_PLL_M_BP_SFT);1153 RT5616_PLL_M_SFT |
1154 pll_code.m_bp << RT5616_PLL_M_BP_SFT);
1143 1155
1144 rt5616->pll_in = freq_in;1156 rt5616->pll_in = freq_in;
1145 rt5616->pll_out = freq_out;1157 rt5616->pll_out = freq_out;
@@ -1149,22 +1161,50 @@ static int rt5616_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 3 unmodified lines
1149}1161}
1150 1162
1151static int rt5616_set_bias_level(struct snd_soc_codec *codec,1163static int rt5616_set_bias_level(struct snd_soc_codec *codec,
1152 enum snd_soc_bias_level level)1164 enum snd_soc_bias_level level)
1153{1165{
1166 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1167 int ret;
1168
1154 switch (level) {1169 switch (level) {
1170
1171 case SND_SOC_BIAS_ON:
1172 break;
1173
1174 case SND_SOC_BIAS_PREPARE:
1175 /*
1176 * SND_SOC_BIAS_PREPARE is called while preparing for a
1177 * transition to ON or away from ON. If current bias_level
1178 * is SND_SOC_BIAS_ON, then it is preparing for a transition
1179 * away from ON. Disable the clock in that case, otherwise
1180 * enable it.
1181 */
1182 if (IS_ERR(rt5616->mclk))
1183 break;
1184
1185 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
1186 clk_disable_unprepare(rt5616->mclk);
1187 } else {
1188 ret = clk_prepare_enable(rt5616->mclk);
1189 if (ret)
1190 return ret;
1191 }
1192 break;
1193
1155 case SND_SOC_BIAS_STANDBY:1194 case SND_SOC_BIAS_STANDBY:
1156 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {1195 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1157 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,1196 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1158 RT5616_PWR_VREF1 | RT5616_PWR_MB |1197 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1159 RT5616_PWR_BG | RT5616_PWR_VREF2,1198 RT5616_PWR_BG | RT5616_PWR_VREF2,
1160 RT5616_PWR_VREF1 | RT5616_PWR_MB |1199 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1161 RT5616_PWR_BG | RT5616_PWR_VREF2);1200 RT5616_PWR_BG | RT5616_PWR_VREF2);
1162 mdelay(10);1201 mdelay(10);
1163 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,1202 snd_soc_update_bits(codec, RT5616_PWR_ANLG1,
1164 RT5616_PWR_FV1 | RT5616_PWR_FV2,1203 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1165 RT5616_PWR_FV1 | RT5616_PWR_FV2);1204 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1166 snd_soc_update_bits(codec, RT5616_D_MISC,1205 snd_soc_update_bits(codec, RT5616_D_MISC,
1167 RT5616_D_GATE_EN, RT5616_D_GATE_EN);1206 RT5616_D_GATE_EN,
1207 RT5616_D_GATE_EN);
1168 }1208 }
1169 break;1209 break;
1170 1210
@@ -1189,6 +1229,11 @@ static int rt5616_probe(struct snd_soc_codec *codec) · 18 unmodified lines
1189{1229{
1190 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);1230 struct rt5616_priv *rt5616 = snd_soc_codec_get_drvdata(codec);
1191 1231
1232 /* Check if MCLK provided */
1233 rt5616->mclk = devm_clk_get(codec->dev, "mclk");
1234 if (PTR_ERR(rt5616->mclk) == -EPROBE_DEFER)
1235 return -EPROBE_DEFER;
1236
1192 rt5616->codec = codec;1237 rt5616->codec = codec;
1193 1238
1194 return 0;1239 return 0;
@@ -1218,11 +1263,10 @@ static int rt5616_resume(struct snd_soc_codec *codec) · 23 unmodified lines
1218#define rt5616_resume NULL1263#define rt5616_resume NULL
1219#endif1264#endif
1220 1265
1221#define RT5616_STEREO_RATES SNDRV_PCM_RATE_8000_960001266#define RT5616_STEREO_RATES SNDRV_PCM_RATE_8000_192000
1222#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \1267#define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1223 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)1268 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
1224 1269
1225
1226struct snd_soc_dai_ops rt5616_aif_dai_ops = {1270struct snd_soc_dai_ops rt5616_aif_dai_ops = {
1227 .hw_params = rt5616_hw_params,1271 .hw_params = rt5616_hw_params,
1228 .set_fmt = rt5616_set_dai_fmt,1272 .set_fmt = rt5616_set_dai_fmt,
@@ -1296,15 +1340,15 @@ MODULE_DEVICE_TABLE(of, rt5616_of_match); · 67 unmodified lines
1296#endif1340#endif
1297 1341
1298static int rt5616_i2c_probe(struct i2c_client *i2c,1342static int rt5616_i2c_probe(struct i2c_client *i2c,
1299 const struct i2c_device_id *id)1343 const struct i2c_device_id *id)
1300{1344{
1301 struct rt5616_priv *rt5616;1345 struct rt5616_priv *rt5616;
1302 unsigned int val;1346 unsigned int val;
1303 int ret;1347 int ret;
1304 1348
1305 rt5616 = devm_kzalloc(&i2c->dev, sizeof(struct rt5616_priv),1349 rt5616 = devm_kzalloc(&i2c->dev, sizeof(struct rt5616_priv),
1306 GFP_KERNEL);1350 GFP_KERNEL);
1307 if (rt5616 == NULL)1351 if (!rt5616)
1308 return -ENOMEM;1352 return -ENOMEM;
1309 1353
1310 i2c_set_clientdata(i2c, rt5616);1354 i2c_set_clientdata(i2c, rt5616);
@@ -1326,14 +1370,14 @@ static int rt5616_i2c_probe(struct i2c_client *i2c, · 15 unmodified lines
1326 }1370 }
1327 regmap_write(rt5616->regmap, RT5616_RESET, 0);1371 regmap_write(rt5616->regmap, RT5616_RESET, 0);
1328 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,1372 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1329 RT5616_PWR_VREF1 | RT5616_PWR_MB |1373 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1330 RT5616_PWR_BG | RT5616_PWR_VREF2,1374 RT5616_PWR_BG | RT5616_PWR_VREF2,
1331 RT5616_PWR_VREF1 | RT5616_PWR_MB |1375 RT5616_PWR_VREF1 | RT5616_PWR_MB |
1332 RT5616_PWR_BG | RT5616_PWR_VREF2);1376 RT5616_PWR_BG | RT5616_PWR_VREF2);
1333 mdelay(10);1377 mdelay(10);
1334 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,1378 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1335 RT5616_PWR_FV1 | RT5616_PWR_FV2,1379 RT5616_PWR_FV1 | RT5616_PWR_FV2,
1336 RT5616_PWR_FV1 | RT5616_PWR_FV2);1380 RT5616_PWR_FV1 | RT5616_PWR_FV2);
1337 1381
1338 ret = regmap_register_patch(rt5616->regmap, init_list,1382 ret = regmap_register_patch(rt5616->regmap, init_list,
1339 ARRAY_SIZE(init_list));1383 ARRAY_SIZE(init_list));
@@ -1341,11 +1385,10 @@ static int rt5616_i2c_probe(struct i2c_client *i2c, · 1 unmodified line
1341 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);1385 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1342 1386
1343 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,1387 regmap_update_bits(rt5616->regmap, RT5616_PWR_ANLG1,
1344 RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);1388 RT5616_PWR_LDO_DVO_MASK, RT5616_PWR_LDO_DVO_1_2V);
1345 1389
1346 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,1390 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5616,
1347 rt5616_dai, ARRAY_SIZE(rt5616_dai));1391 rt5616_dai, ARRAY_SIZE(rt5616_dai));
1348
1349}1392}
1350 1393
1351static int rt5616_i2c_remove(struct i2c_client *i2c)1394static int rt5616_i2c_remove(struct i2c_client *i2c)
@@ -1361,7 +1404,6 @@ static void rt5616_i2c_shutdown(struct i2c_client *client) · 9 unmodified lines
1361 1404
1362 regmap_write(rt5616->regmap, RT5616_HP_VOL, 0xc8c8);1405 regmap_write(rt5616->regmap, RT5616_HP_VOL, 0xc8c8);
1363 regmap_write(rt5616->regmap, RT5616_LOUT_CTRL1, 0xc8c8);1406 regmap_write(rt5616->regmap, RT5616_LOUT_CTRL1, 0xc8c8);
1364
1365}1407}
1366 1408
1367static struct i2c_driver rt5616_i2c_driver = {1409static struct i2c_driver rt5616_i2c_driver = {
sound/soc/codecs/rt5640.c+61−30
@@ -1217,11 +1217,14 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { · 1216 unmodified lines
1217 SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0,1217 SND_SOC_DAPM_MIXER("DIG MIXR", SND_SOC_NOPM, 0, 0,
1218 rt5640_dig_r_mix, ARRAY_SIZE(rt5640_dig_r_mix)),1218 rt5640_dig_r_mix, ARRAY_SIZE(rt5640_dig_r_mix)),
1219 /* DACs */1219 /* DACs */
1220 SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1,1220 SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM,
1221 RT5640_PWR_DAC_L1_BIT, 0),1221 0, 0),
1222 SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1,1222 SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM,
1223 RT5640_PWR_DAC_R1_BIT, 0),1223 0, 0),
1224 1224 SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5640_PWR_DIG1,
1225 RT5640_PWR_DAC_L1_BIT, 0, NULL, 0),
1226 SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5640_PWR_DIG1,
1227 RT5640_PWR_DAC_R1_BIT, 0, NULL, 0),
1225 /* SPK/OUT Mixer */1228 /* SPK/OUT Mixer */
1226 SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,1229 SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
1227 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),1230 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
@@ -1298,9 +1301,9 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { · 70 unmodified lines
1298 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,1301 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
1299 rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),1302 rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)),
1300 1303
1301 SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R2_BIT,1304 SND_SOC_DAPM_DAC("DAC R2", NULL, SND_SOC_NOPM, 0,
1302 0),1305 0),
1303 SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L2_BIT,1306 SND_SOC_DAPM_DAC("DAC L2", NULL, SND_SOC_NOPM, 0,
1304 0),1307 0),
1305 1308
1306 SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,1309 SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
@@ -1317,6 +1320,10 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { · 10 unmodified lines
1317 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),1320 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
1318 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,1321 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
1319 RT5640_PWR_MA_BIT, 0, NULL, 0),1322 RT5640_PWR_MA_BIT, 0, NULL, 0),
1323 SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
1324 RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
1325 SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
1326 RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
1320 1327
1321 SND_SOC_DAPM_OUTPUT("MONOP"),1328 SND_SOC_DAPM_OUTPUT("MONOP"),
1322 SND_SOC_DAPM_OUTPUT("MONON"),1329 SND_SOC_DAPM_OUTPUT("MONON"),
@@ -1328,11 +1335,6 @@ static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = { · 5 unmodified lines
1328 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,1335 SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
1329 rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)),1336 rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)),
1330 1337
1331 SND_SOC_DAPM_SUPPLY("DAC L2 Filter", RT5640_PWR_DIG1,
1332 RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
1333 SND_SOC_DAPM_SUPPLY("DAC R2 Filter", RT5640_PWR_DIG1,
1334 RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
1335
1336 SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,1338 SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT,
1337 0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)),1339 0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)),
1338 SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,1340 SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT,
@@ -1493,8 +1495,10 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { · 154 unmodified lines
1493 1495
1494 {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"},1496 {"DAC MIXL", "Stereo ADC Switch", "Stereo ADC MIXL"},
1495 {"DAC MIXL", "INF1 Switch", "IF1 DAC L"},1497 {"DAC MIXL", "INF1 Switch", "IF1 DAC L"},
1498 {"DAC MIXL", NULL, "DAC L1 Power"},
1496 {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"},1499 {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"},
1497 {"DAC MIXR", "INF1 Switch", "IF1 DAC R"},1500 {"DAC MIXR", "INF1 Switch", "IF1 DAC R"},
1501 {"DAC MIXR", NULL, "DAC R1 Power"},
1498 1502
1499 {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"},1503 {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"},
1500 {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"},1504 {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"},
@@ -1507,8 +1511,10 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { · 6 unmodified lines
1507 1511
1508 {"DAC L1", NULL, "Stereo DAC MIXL"},1512 {"DAC L1", NULL, "Stereo DAC MIXL"},
1509 {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},1513 {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll},
1514 {"DAC L1", NULL, "DAC L1 Power"},
1510 {"DAC R1", NULL, "Stereo DAC MIXR"},1515 {"DAC R1", NULL, "Stereo DAC MIXR"},
1511 {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},1516 {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll},
1517 {"DAC R1", NULL, "DAC R1 Power"},
1512 1518
1513 {"SPK MIXL", "REC MIXL Switch", "RECMIXL"},1519 {"SPK MIXL", "REC MIXL Switch", "RECMIXL"},
1514 {"SPK MIXL", "INL Switch", "INL VOL"},1520 {"SPK MIXL", "INL Switch", "INL VOL"},
@@ -1595,8 +1601,9 @@ static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = { · 80 unmodified lines
1595 1601
1596 {"DAC L2 Mux", "IF2", "IF2 DAC L"},1602 {"DAC L2 Mux", "IF2", "IF2 DAC L"},
1597 {"DAC L2 Mux", "Base L/R", "Audio DSP"},1603 {"DAC L2 Mux", "Base L/R", "Audio DSP"},
1598 1604 {"DAC L2 Mux", NULL, "DAC L2 Power"},
1599 {"DAC R2 Mux", "IF2", "IF2 DAC R"},1605 {"DAC R2 Mux", "IF2", "IF2 DAC R"},
1606 {"DAC R2 Mux", NULL, "DAC R2 Power"},
1600 1607
1601 {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},1608 {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"},
1602 {"Stereo DAC MIXL", "ANC Switch", "ANC"},1609 {"Stereo DAC MIXL", "ANC Switch", "ANC"},
@@ -1614,8 +1621,10 @@ static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = { · 11 unmodified lines
1614 1621
1615 {"DAC L2", NULL, "Mono DAC MIXL"},1622 {"DAC L2", NULL, "Mono DAC MIXL"},
1616 {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll},1623 {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll},
1624 {"DAC L2", NULL, "DAC L2 Power"},
1617 {"DAC R2", NULL, "Mono DAC MIXR"},1625 {"DAC R2", NULL, "Mono DAC MIXR"},
1618 {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll},1626 {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll},
1627 {"DAC R2", NULL, "DAC R2 Power"},
1619 1628
1620 {"SPK MIXL", "DAC L2 Switch", "DAC L2"},1629 {"SPK MIXL", "DAC L2 Switch", "DAC L2"},
1621 {"SPK MIXR", "DAC R2 Switch", "DAC R2"},1630 {"SPK MIXR", "DAC R2 Switch", "DAC R2"},
@@ -1656,8 +1665,8 @@ static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = { · 34 unmodified lines
1656 {"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"},1665 {"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"},
1657 {"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"},1666 {"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"},
1658 1667
1659 {"IF2 DAC L", NULL, "DAC L2 Filter"},1668 {"IF2 DAC L", NULL, "DAC L2 Power"},
1660 {"IF2 DAC R", NULL, "DAC R2 Filter"},1669 {"IF2 DAC R", NULL, "DAC R2 Power"},
1661};1670};
1662 1671
1663static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)1672static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
@@ -1880,7 +1889,7 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 216 unmodified lines
1880 struct snd_soc_codec *codec = dai->codec;1889 struct snd_soc_codec *codec = dai->codec;
1881 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);1890 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1882 struct rl6231_pll_code pll_code;1891 struct rl6231_pll_code pll_code;
1883 int ret, dai_sel;1892 int ret;
1884 1893
1885 if (source == rt5640->pll_src && freq_in == rt5640->pll_in &&1894 if (source == rt5640->pll_src && freq_in == rt5640->pll_in &&
1886 freq_out == rt5640->pll_out)1895 freq_out == rt5640->pll_out)
@@ -1902,21 +1911,12 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 15 unmodified lines
1902 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);1911 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_MCLK);
1903 break;1912 break;
1904 case RT5640_PLL1_S_BCLK1:1913 case RT5640_PLL1_S_BCLK1:
1914 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1915 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
1916 break;
1905 case RT5640_PLL1_S_BCLK2:1917 case RT5640_PLL1_S_BCLK2:
1906 dai_sel = get_sdp_info(codec, dai->id);1918 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1907 if (dai_sel < 0) {1919 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
1908 dev_err(codec->dev,
1909 "Failed to get sdp info: %d\n", dai_sel);
1910 return -EINVAL;
1911 }
1912 if (dai_sel & RT5640_U_IF1) {
1913 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1914 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK1);
1915 }
1916 if (dai_sel & RT5640_U_IF2) {
1917 snd_soc_update_bits(codec, RT5640_GLB_CLK,
1918 RT5640_PLL1_SRC_MASK, RT5640_PLL1_SRC_BCLK2);
1919 }
1920 break;1920 break;
1921 default:1921 default:
1922 dev_err(codec->dev, "Unknown PLL source %d\n", source);1922 dev_err(codec->dev, "Unknown PLL source %d\n", source);
@@ -1949,7 +1949,33 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, · 26 unmodified lines
1949static int rt5640_set_bias_level(struct snd_soc_codec *codec,1949static int rt5640_set_bias_level(struct snd_soc_codec *codec,
1950 enum snd_soc_bias_level level)1950 enum snd_soc_bias_level level)
1951{1951{
1952 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1953 int ret;
1954
1952 switch (level) {1955 switch (level) {
1956 case SND_SOC_BIAS_ON:
1957 break;
1958
1959 case SND_SOC_BIAS_PREPARE:
1960 /*
1961 * SND_SOC_BIAS_PREPARE is called while preparing for a
1962 * transition to ON or away from ON. If current bias_level
1963 * is SND_SOC_BIAS_ON, then it is preparing for a transition
1964 * away from ON. Disable the clock in that case, otherwise
1965 * enable it.
1966 */
1967 if (IS_ERR(rt5640->mclk))
1968 break;
1969
1970 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON) {
1971 clk_disable_unprepare(rt5640->mclk);
1972 } else {
1973 ret = clk_prepare_enable(rt5640->mclk);
1974 if (ret)
1975 return ret;
1976 }
1977 break;
1978
1953 case SND_SOC_BIAS_STANDBY:1979 case SND_SOC_BIAS_STANDBY:
1954 if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {1980 if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
1955 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,1981 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
@@ -2088,6 +2114,11 @@ static int rt5640_probe(struct snd_soc_codec *codec) · 132 unmodified lines
2088 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);2114 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
2089 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);2115 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
2090 2116
2117 /* Check if MCLK provided */
2118 rt5640->mclk = devm_clk_get(codec->dev, "mclk");
2119 if (PTR_ERR(rt5640->mclk) == -EPROBE_DEFER)
2120 return -EPROBE_DEFER;
2121
2091 rt5640->codec = codec;2122 rt5640->codec = codec;
2092 2123
2093 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);2124 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
sound/soc/codecs/rt5640.h+2−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#ifndef _RT5640_H12#ifndef _RT5640_H
13#define _RT5640_H13#define _RT5640_H
14 14
15#include <linux/clk.h>
15#include <sound/rt5640.h>16#include <sound/rt5640.h>
16 17
17/* Info */18/* Info */
@@ -2097,6 +2098,7 @@ struct rt5640_priv { · 2079 unmodified lines
2097 struct snd_soc_codec *codec;2098 struct snd_soc_codec *codec;
2098 struct rt5640_platform_data pdata;2099 struct rt5640_platform_data pdata;
2099 struct regmap *regmap;2100 struct regmap *regmap;
2101 struct clk *mclk;
2100 2102
2101 int sysclk;2103 int sysclk;
2102 int sysclk_src;2104 int sysclk_src;
sound/soc/codecs/rt5645.c+10−5
@@ -1674,7 +1674,7 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on) · 1673 unmodified lines
1674 regmap_write(rt5645->regmap, RT5645_PR_BASE +1674 regmap_write(rt5645->regmap, RT5645_PR_BASE +
1675 RT5645_MAMP_INT_REG2, 0xfc00);1675 RT5645_MAMP_INT_REG2, 0xfc00);
1676 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);1676 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
1677 msleep(70);1677 msleep(90);
1678 rt5645->hp_on = true;1678 rt5645->hp_on = true;
1679 } else {1679 } else {
1680 /* depop parameters */1680 /* depop parameters */
@@ -3029,13 +3029,18 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, · 1348 unmodified lines
3029 RT5645_PWR_BG | RT5645_PWR_VREF2,3029 RT5645_PWR_BG | RT5645_PWR_VREF2,
3030 RT5645_PWR_VREF1 | RT5645_PWR_MB |3030 RT5645_PWR_VREF1 | RT5645_PWR_MB |
3031 RT5645_PWR_BG | RT5645_PWR_VREF2);3031 RT5645_PWR_BG | RT5645_PWR_VREF2);
3032 mdelay(10);
3032 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,3033 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
3033 RT5645_PWR_FV1 | RT5645_PWR_FV2,3034 RT5645_PWR_FV1 | RT5645_PWR_FV2,
3034 RT5645_PWR_FV1 | RT5645_PWR_FV2);3035 RT5645_PWR_FV1 | RT5645_PWR_FV2);
3035 if (rt5645->en_button_func &&3036 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
3036 snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)3037 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
3037 queue_delayed_work(system_power_efficient_wq,3038 msleep(40);
3038 &rt5645->jack_detect_work, msecs_to_jiffies(0));3039 if (rt5645->en_button_func)
3040 queue_delayed_work(system_power_efficient_wq,
3041 &rt5645->jack_detect_work,
3042 msecs_to_jiffies(0));
3043 }
3039 break;3044 break;
3040 3045
3041 case SND_SOC_BIAS_OFF:3046 case SND_SOC_BIAS_OFF:
sound/soc/codecs/rt5659.c+1−1
@@ -4176,7 +4176,7 @@ static int rt5659_i2c_remove(struct i2c_client *i2c) · 4175 unmodified lines
4176 return 0;4176 return 0;
4177}4177}
4178 4178
4179void rt5659_i2c_shutdown(struct i2c_client *client)4179static void rt5659_i2c_shutdown(struct i2c_client *client)
4180{4180{
4181 struct rt5659_priv *rt5659 = i2c_get_clientdata(client);4181 struct rt5659_priv *rt5659 = i2c_get_clientdata(client);
4182 4182
sound/soc/codecs/ssm4567.c+5−0
@@ -352,6 +352,11 @@ static int ssm4567_set_power(struct ssm4567 *ssm4567, bool enable) · 351 unmodified lines
352 regcache_cache_only(ssm4567->regmap, !enable);352 regcache_cache_only(ssm4567->regmap, !enable);
353 353
354 if (enable) {354 if (enable) {
355 ret = regmap_write(ssm4567->regmap, SSM4567_REG_SOFT_RESET,
356 0x00);
357 if (ret)
358 return ret;
359
355 ret = regmap_update_bits(ssm4567->regmap,360 ret = regmap_update_bits(ssm4567->regmap,
356 SSM4567_REG_POWER_CTRL,361 SSM4567_REG_POWER_CTRL,
357 SSM4567_POWER_SPWDN, 0x00);362 SSM4567_POWER_SPWDN, 0x00);
sound/soc/codecs/wm5102.c+88−5
@@ -619,7 +619,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w, · 618 unmodified lines
619{619{
620 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);620 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
621 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);621 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
622 unsigned int v;622 unsigned int v = 0;
623 int ret;623 int ret;
624 624
625 switch (event) {625 switch (event) {
@@ -654,7 +654,7 @@ static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w, · 28 unmodified lines
654 break;654 break;
655 }655 }
656 656
657 return wm_adsp2_early_event(w, kcontrol, event);657 return wm_adsp2_early_event(w, kcontrol, event, v);
658}658}
659 659
660static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,660static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
@@ -1408,7 +1408,7 @@ ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), · 747 unmodified lines
1408ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),1408ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
1409ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),1409ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
1410 1410
1411WM_ADSP2_E("DSP1", 0, wm5102_adsp_power_ev),1411WM_ADSP2("DSP1", 0, wm5102_adsp_power_ev),
1412 1412
1413SND_SOC_DAPM_OUTPUT("HPOUT1L"),1413SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1414SND_SOC_DAPM_OUTPUT("HPOUT1R"),1414SND_SOC_DAPM_OUTPUT("HPOUT1R"),
@@ -1599,6 +1599,9 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { · 184 unmodified lines
1599 { "Slim2 Capture", NULL, "SYSCLK" },1599 { "Slim2 Capture", NULL, "SYSCLK" },
1600 { "Slim3 Capture", NULL, "SYSCLK" },1600 { "Slim3 Capture", NULL, "SYSCLK" },
1601 1601
1602 { "Audio Trace DSP", NULL, "DSP1" },
1603 { "Audio Trace DSP", NULL, "SYSCLK" },
1604
1602 { "IN1L PGA", NULL, "IN1L" },1605 { "IN1L PGA", NULL, "IN1L" },
1603 { "IN1R PGA", NULL, "IN1R" },1606 { "IN1R PGA", NULL, "IN1R" },
1604 1607
@@ -1735,7 +1738,7 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, · 130 unmodified lines
1735 }1738 }
1736}1739}
1737 1740
1738#define WM5102_RATES SNDRV_PCM_RATE_8000_1920001741#define WM5102_RATES SNDRV_PCM_RATE_KNOT
1739 1742
1740#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\1743#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1741 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)1744 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -1864,14 +1867,67 @@ static struct snd_soc_dai_driver wm5102_dai[] = { · 122 unmodified lines
1864 },1867 },
1865 .ops = &arizona_simple_dai_ops,1868 .ops = &arizona_simple_dai_ops,
1866 },1869 },
1870 {
1871 .name = "wm5102-cpu-trace",
1872 .capture = {
1873 .stream_name = "Audio Trace CPU",
1874 .channels_min = 1,
1875 .channels_max = 6,
1876 .rates = WM5102_RATES,
1877 .formats = WM5102_FORMATS,
1878 },
1879 .compress_new = snd_soc_new_compress,
1880 },
1881 {
1882 .name = "wm5102-dsp-trace",
1883 .capture = {
1884 .stream_name = "Audio Trace DSP",
1885 .channels_min = 1,
1886 .channels_max = 4,
1887 .rates = WM5102_RATES,
1888 .formats = WM5102_FORMATS,
1889 },
1890 },
1867};1891};
1868 1892
1893static int wm5102_open(struct snd_compr_stream *stream)
1894{
1895 struct snd_soc_pcm_runtime *rtd = stream->private_data;
1896 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
1897
1898 return wm_adsp_compr_open(&priv->core.adsp[0], stream);
1899}
1900
1901static irqreturn_t wm5102_adsp2_irq(int irq, void *data)
1902{
1903 struct wm5102_priv *priv = data;
1904 struct arizona *arizona = priv->core.arizona;
1905 int ret;
1906
1907 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[0]);
1908 if (ret == -ENODEV) {
1909 dev_err(arizona->dev, "Spurious compressed data IRQ\n");
1910 return IRQ_NONE;
1911 }
1912
1913 return IRQ_HANDLED;
1914}
1915
1869static int wm5102_codec_probe(struct snd_soc_codec *codec)1916static int wm5102_codec_probe(struct snd_soc_codec *codec)
1870{1917{
1871 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);1918 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1872 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);1919 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
1920 struct arizona *arizona = priv->core.arizona;
1873 int ret;1921 int ret;
1874 1922
1923 ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
1924 "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
1925 priv);
1926 if (ret != 0) {
1927 dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
1928 return ret;
1929 }
1930
1875 ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);1931 ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
1876 if (ret)1932 if (ret)
1877 return ret;1933 return ret;
@@ -1946,6 +2002,20 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { · 68 unmodified lines
1946 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),2002 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
1947};2003};
1948 2004
2005static struct snd_compr_ops wm5102_compr_ops = {
2006 .open = wm5102_open,
2007 .free = wm_adsp_compr_free,
2008 .set_params = wm_adsp_compr_set_params,
2009 .get_caps = wm_adsp_compr_get_caps,
2010 .trigger = wm_adsp_compr_trigger,
2011 .pointer = wm_adsp_compr_pointer,
2012 .copy = wm_adsp_compr_copy,
2013};
2014
2015static struct snd_soc_platform_driver wm5102_compr_platform = {
2016 .compr_ops = &wm5102_compr_ops,
2017};
2018
1949static int wm5102_probe(struct platform_device *pdev)2019static int wm5102_probe(struct platform_device *pdev)
1950{2020{
1951 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);2021 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
@@ -2005,12 +2075,25 @@ static int wm5102_probe(struct platform_device *pdev) · 53 unmodified lines
2005 pm_runtime_enable(&pdev->dev);2075 pm_runtime_enable(&pdev->dev);
2006 pm_runtime_idle(&pdev->dev);2076 pm_runtime_idle(&pdev->dev);
2007 2077
2008 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,2078 ret = snd_soc_register_platform(&pdev->dev, &wm5102_compr_platform);
2079 if (ret < 0) {
2080 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
2081 return ret;
2082 }
2083
2084 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
2009 wm5102_dai, ARRAY_SIZE(wm5102_dai));2085 wm5102_dai, ARRAY_SIZE(wm5102_dai));
2086 if (ret < 0) {
2087 dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
2088 snd_soc_unregister_platform(&pdev->dev);
2089 }
2090
2091 return ret;
2010}2092}
2011 2093
2012static int wm5102_remove(struct platform_device *pdev)2094static int wm5102_remove(struct platform_device *pdev)
2013{2095{
2096 snd_soc_unregister_platform(&pdev->dev);
2014 snd_soc_unregister_codec(&pdev->dev);2097 snd_soc_unregister_codec(&pdev->dev);
2015 pm_runtime_disable(&pdev->dev);2098 pm_runtime_disable(&pdev->dev);
2016 2099
sound/soc/codecs/wm5110.c+64−11
@@ -191,6 +191,25 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, · 190 unmodified lines
191 return 0;191 return 0;
192}192}
193 193
194static int wm5110_adsp_power_ev(struct snd_soc_dapm_widget *w,
195 struct snd_kcontrol *kcontrol, int event)
196{
197 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
198 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
199 unsigned int v;
200 int ret;
201
202 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
203 if (ret != 0) {
204 dev_err(codec->dev, "Failed to read SYSCLK state: %d\n", ret);
205 return ret;
206 }
207
208 v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
209
210 return wm_adsp2_early_event(w, kcontrol, event, v);
211}
212
194static const struct reg_sequence wm5110_no_dre_left_enable[] = {213static const struct reg_sequence wm5110_no_dre_left_enable[] = {
195 { 0x3024, 0xE410 },214 { 0x3024, 0xE410 },
196 { 0x3025, 0x0056 },215 { 0x3025, 0x0056 },
@@ -1179,10 +1198,10 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0, · 982 unmodified lines
1179SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,1198SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
1180 NULL, 0),1199 NULL, 0),
1181 1200
1182WM_ADSP2("DSP1", 0),1201WM_ADSP2("DSP1", 0, wm5110_adsp_power_ev),
1183WM_ADSP2("DSP2", 1),1202WM_ADSP2("DSP2", 1, wm5110_adsp_power_ev),
1184WM_ADSP2("DSP3", 2),1203WM_ADSP2("DSP3", 2, wm5110_adsp_power_ev),
1185WM_ADSP2("DSP4", 3),1204WM_ADSP2("DSP4", 3, wm5110_adsp_power_ev),
1186 1205
1187SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,1206SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
1188 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),1207 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
@@ -1809,6 +1828,9 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { · 620 unmodified lines
1809 { "Voice Control DSP", NULL, "DSP3" },1828 { "Voice Control DSP", NULL, "DSP3" },
1810 { "Voice Control DSP", NULL, "SYSCLK" },1829 { "Voice Control DSP", NULL, "SYSCLK" },
1811 1830
1831 { "Audio Trace DSP", NULL, "DSP1" },
1832 { "Audio Trace DSP", NULL, "SYSCLK" },
1833
1812 { "IN1L PGA", NULL, "IN1L" },1834 { "IN1L PGA", NULL, "IN1L" },
1813 { "IN1R PGA", NULL, "IN1R" },1835 { "IN1R PGA", NULL, "IN1R" },
1814 1836
@@ -2002,7 +2024,7 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, · 187 unmodified lines
2002 }2024 }
2003}2025}
2004 2026
2005#define WM5110_RATES SNDRV_PCM_RATE_8000_1920002027#define WM5110_RATES SNDRV_PCM_RATE_KNOT
2006 2028
2007#define WM5110_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\2029#define WM5110_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2008 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)2030 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -2152,6 +2174,27 @@ static struct snd_soc_dai_driver wm5110_dai[] = { · 143 unmodified lines
2152 .formats = WM5110_FORMATS,2174 .formats = WM5110_FORMATS,
2153 },2175 },
2154 },2176 },
2177 {
2178 .name = "wm5110-cpu-trace",
2179 .capture = {
2180 .stream_name = "Audio Trace CPU",
2181 .channels_min = 1,
2182 .channels_max = 6,
2183 .rates = WM5110_RATES,
2184 .formats = WM5110_FORMATS,
2185 },
2186 .compress_new = snd_soc_new_compress,
2187 },
2188 {
2189 .name = "wm5110-dsp-trace",
2190 .capture = {
2191 .stream_name = "Audio Trace DSP",
2192 .channels_min = 1,
2193 .channels_max = 6,
2194 .rates = WM5110_RATES,
2195 .formats = WM5110_FORMATS,
2196 },
2197 },
2155};2198};
2156 2199
2157static int wm5110_open(struct snd_compr_stream *stream)2200static int wm5110_open(struct snd_compr_stream *stream)
@@ -2163,6 +2206,8 @@ static int wm5110_open(struct snd_compr_stream *stream) · 5 unmodified lines
2163 2206
2164 if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) {2207 if (strcmp(rtd->codec_dai->name, "wm5110-dsp-voicectrl") == 0) {
2165 n_adsp = 2;2208 n_adsp = 2;
2209 } else if (strcmp(rtd->codec_dai->name, "wm5110-dsp-trace") == 0) {
2210 n_adsp = 0;
2166 } else {2211 } else {
2167 dev_err(arizona->dev,2212 dev_err(arizona->dev,
2168 "No suitable compressed stream for DAI '%s'\n",2213 "No suitable compressed stream for DAI '%s'\n",
@@ -2175,12 +2220,21 @@ static int wm5110_open(struct snd_compr_stream *stream) · 6 unmodified lines
2175 2220
2176static irqreturn_t wm5110_adsp2_irq(int irq, void *data)2221static irqreturn_t wm5110_adsp2_irq(int irq, void *data)
2177{2222{
2178 struct wm5110_priv *florida = data;2223 struct wm5110_priv *priv = data;
2179 int ret;2224 struct arizona *arizona = priv->core.arizona;
2225 int serviced = 0;
2226 int i, ret;
2180 2227
2181 ret = wm_adsp_compr_handle_irq(&florida->core.adsp[2]);2228 for (i = 0; i < WM5110_NUM_ADSP; ++i) {
2182 if (ret == -ENODEV)2229 ret = wm_adsp_compr_handle_irq(&priv->core.adsp[i]);
2230 if (ret != -ENODEV)
2231 serviced++;
2232 }
2233
2234 if (!serviced) {
2235 dev_err(arizona->dev, "Spurious compressed data IRQ\n");
2183 return IRQ_NONE;2236 return IRQ_NONE;
2237 }
2184 2238
2185 return IRQ_HANDLED;2239 return IRQ_HANDLED;
2186}2240}
@@ -2366,7 +2420,7 @@ static int wm5110_probe(struct platform_device *pdev) · 179 unmodified lines
2366 ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);2420 ret = snd_soc_register_platform(&pdev->dev, &wm5110_compr_platform);
2367 if (ret < 0) {2421 if (ret < 0) {
2368 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);2422 dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
2369 goto error;2423 return ret;
2370 }2424 }
2371 2425
2372 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,2426 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
@@ -2376,7 +2430,6 @@ static int wm5110_probe(struct platform_device *pdev) · 3 unmodified lines
2376 snd_soc_unregister_platform(&pdev->dev);2430 snd_soc_unregister_platform(&pdev->dev);
2377 }2431 }
2378 2432
2379error:
2380 return ret;2433 return ret;
2381}2434}
2382 2435
sound/soc/codecs/wm8974.c+93−0
@@ -28,6 +28,11 @@ · 27 unmodified lines
28 28
29#include "wm8974.h"29#include "wm8974.h"
30 30
31struct wm8974_priv {
32 unsigned int mclk;
33 unsigned int fs;
34};
35
31static const struct reg_default wm8974_reg_defaults[] = {36static const struct reg_default wm8974_reg_defaults[] = {
32 { 0, 0x0000 }, { 1, 0x0000 }, { 2, 0x0000 }, { 3, 0x0000 },37 { 0, 0x0000 }, { 1, 0x0000 }, { 2, 0x0000 }, { 3, 0x0000 },
33 { 4, 0x0050 }, { 5, 0x0000 }, { 6, 0x0140 }, { 7, 0x0000 },38 { 4, 0x0050 }, { 5, 0x0000 }, { 6, 0x0140 }, { 7, 0x0000 },
@@ -379,6 +384,79 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai, · 345 unmodified lines
379 return 0;384 return 0;
380}385}
381 386
387static unsigned int wm8974_get_mclkdiv(unsigned int f_in, unsigned int f_out,
388 int *mclkdiv)
389{
390 unsigned int ratio = 2 * f_in / f_out;
391
392 if (ratio <= 2) {
393 *mclkdiv = WM8974_MCLKDIV_1;
394 ratio = 2;
395 } else if (ratio == 3) {
396 *mclkdiv = WM8974_MCLKDIV_1_5;
397 } else if (ratio == 4) {
398 *mclkdiv = WM8974_MCLKDIV_2;
399 } else if (ratio <= 6) {
400 *mclkdiv = WM8974_MCLKDIV_3;
401 ratio = 6;
402 } else if (ratio <= 8) {
403 *mclkdiv = WM8974_MCLKDIV_4;
404 ratio = 8;
405 } else if (ratio <= 12) {
406 *mclkdiv = WM8974_MCLKDIV_6;
407 ratio = 12;
408 } else if (ratio <= 16) {
409 *mclkdiv = WM8974_MCLKDIV_8;
410 ratio = 16;
411 } else {
412 *mclkdiv = WM8974_MCLKDIV_12;
413 ratio = 24;
414 }
415
416 return f_out * ratio / 2;
417}
418
419static int wm8974_update_clocks(struct snd_soc_dai *dai)
420{
421 struct snd_soc_codec *codec = dai->codec;
422 struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
423 unsigned int fs256;
424 unsigned int fpll = 0;
425 unsigned int f;
426 int mclkdiv;
427
428 if (!priv->mclk || !priv->fs)
429 return 0;
430
431 fs256 = 256 * priv->fs;
432
433 f = wm8974_get_mclkdiv(priv->mclk, fs256, &mclkdiv);
434
435 if (f != priv->mclk) {
436 /* The PLL performs best around 90MHz */
437 fpll = wm8974_get_mclkdiv(22500000, fs256, &mclkdiv);
438 }
439
440 wm8974_set_dai_pll(dai, 0, 0, priv->mclk, fpll);
441 wm8974_set_dai_clkdiv(dai, WM8974_MCLKDIV, mclkdiv);
442
443 return 0;
444}
445
446static int wm8974_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
447 unsigned int freq, int dir)
448{
449 struct snd_soc_codec *codec = dai->codec;
450 struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
451
452 if (dir != SND_SOC_CLOCK_IN)
453 return -EINVAL;
454
455 priv->mclk = freq;
456
457 return wm8974_update_clocks(dai);
458}
459
382static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,460static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
383 unsigned int fmt)461 unsigned int fmt)
384{462{
@@ -441,8 +519,15 @@ static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream, · 56 unmodified lines
441 struct snd_soc_dai *dai)519 struct snd_soc_dai *dai)
442{520{
443 struct snd_soc_codec *codec = dai->codec;521 struct snd_soc_codec *codec = dai->codec;
522 struct wm8974_priv *priv = snd_soc_codec_get_drvdata(codec);
444 u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;523 u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
445 u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;524 u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
525 int err;
526
527 priv->fs = params_rate(params);
528 err = wm8974_update_clocks(dai);
529 if (err)
530 return err;
446 531
447 /* bit size */532 /* bit size */
448 switch (params_width(params)) {533 switch (params_width(params)) {
@@ -547,6 +632,7 @@ static const struct snd_soc_dai_ops wm8974_ops = { · 98 unmodified lines
547 .set_fmt = wm8974_set_dai_fmt,632 .set_fmt = wm8974_set_dai_fmt,
548 .set_clkdiv = wm8974_set_dai_clkdiv,633 .set_clkdiv = wm8974_set_dai_clkdiv,
549 .set_pll = wm8974_set_dai_pll,634 .set_pll = wm8974_set_dai_pll,
635 .set_sysclk = wm8974_set_dai_sysclk,
550};636};
551 637
552static struct snd_soc_dai_driver wm8974_dai = {638static struct snd_soc_dai_driver wm8974_dai = {
@@ -606,9 +692,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { · 53 unmodified lines
606static int wm8974_i2c_probe(struct i2c_client *i2c,692static int wm8974_i2c_probe(struct i2c_client *i2c,
607 const struct i2c_device_id *id)693 const struct i2c_device_id *id)
608{694{
695 struct wm8974_priv *priv;
609 struct regmap *regmap;696 struct regmap *regmap;
610 int ret;697 int ret;
611 698
699 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
700 if (!priv)
701 return -ENOMEM;
702
703 i2c_set_clientdata(i2c, priv);
704
612 regmap = devm_regmap_init_i2c(i2c, &wm8974_regmap);705 regmap = devm_regmap_init_i2c(i2c, &wm8974_regmap);
613 if (IS_ERR(regmap))706 if (IS_ERR(regmap))
614 return PTR_ERR(regmap);707 return PTR_ERR(regmap);
sound/soc/codecs/wm8997.c+1−1
@@ -943,7 +943,7 @@ static int wm8997_set_fll(struct snd_soc_codec *codec, int fll_id, int source, · 942 unmodified lines
943 }943 }
944}944}
945 945
946#define WM8997_RATES SNDRV_PCM_RATE_8000_192000946#define WM8997_RATES SNDRV_PCM_RATE_KNOT
947 947
948#define WM8997_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\948#define WM8997_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
949 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)949 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
sound/soc/codecs/wm8998.c+1−1
@@ -1170,7 +1170,7 @@ static const struct snd_soc_dapm_route wm8998_dapm_routes[] = { · 1169 unmodified lines
1170 { "DRC1 Signal Activity", NULL, "DRC1R" },1170 { "DRC1 Signal Activity", NULL, "DRC1R" },
1171};1171};
1172 1172
1173#define WM8998_RATES SNDRV_PCM_RATE_8000_1920001173#define WM8998_RATES SNDRV_PCM_RATE_KNOT
1174 1174
1175#define WM8998_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\1175#define WM8998_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1176 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)1176 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
sound/soc/codecs/wm_adsp.c+71−60
@@ -32,9 +32,6 @@ · 31 unmodified lines
32#include <sound/initval.h>32#include <sound/initval.h>
33#include <sound/tlv.h>33#include <sound/tlv.h>
34 34
35#include <linux/mfd/arizona/registers.h>
36
37#include "arizona.h"
38#include "wm_adsp.h"35#include "wm_adsp.h"
39 36
40#define adsp_crit(_dsp, fmt, ...) \37#define adsp_crit(_dsp, fmt, ...) \
@@ -295,6 +292,8 @@ struct wm_adsp_compr { · 254 unmodified lines
295 292
296 u32 *raw_buf;293 u32 *raw_buf;
297 unsigned int copied_total;294 unsigned int copied_total;
295
296 unsigned int sample_rate;
298};297};
299 298
300#define WM_ADSP_DATA_WORD_SIZE 3299#define WM_ADSP_DATA_WORD_SIZE 3
@@ -328,7 +327,7 @@ struct wm_adsp_buffer_region_def { · 27 unmodified lines
328 unsigned int size_offset;327 unsigned int size_offset;
329};328};
330 329
331static struct wm_adsp_buffer_region_def ez2control_regions[] = {330static const struct wm_adsp_buffer_region_def default_regions[] = {
332 {331 {
333 .mem_type = WMFW_ADSP2_XM,332 .mem_type = WMFW_ADSP2_XM,
334 .base_offset = HOST_BUFFER_FIELD(X_buf_base),333 .base_offset = HOST_BUFFER_FIELD(X_buf_base),
@@ -350,10 +349,10 @@ struct wm_adsp_fw_caps { · 15 unmodified lines
350 u32 id;349 u32 id;
351 struct snd_codec_desc desc;350 struct snd_codec_desc desc;
352 int num_regions;351 int num_regions;
353 struct wm_adsp_buffer_region_def *region_defs;352 const struct wm_adsp_buffer_region_def *region_defs;
354};353};
355 354
356static const struct wm_adsp_fw_caps ez2control_caps[] = {355static const struct wm_adsp_fw_caps ctrl_caps[] = {
357 {356 {
358 .id = SND_AUDIOCODEC_BESPOKE,357 .id = SND_AUDIOCODEC_BESPOKE,
359 .desc = {358 .desc = {
@@ -362,8 +361,26 @@ static const struct wm_adsp_fw_caps ez2control_caps[] = { · 2 unmodified lines
362 .num_sample_rates = 1,361 .num_sample_rates = 1,
363 .formats = SNDRV_PCM_FMTBIT_S16_LE,362 .formats = SNDRV_PCM_FMTBIT_S16_LE,
364 },363 },
365 .num_regions = ARRAY_SIZE(ez2control_regions),364 .num_regions = ARRAY_SIZE(default_regions),
366 .region_defs = ez2control_regions,365 .region_defs = default_regions,
366 },
367};
368
369static const struct wm_adsp_fw_caps trace_caps[] = {
370 {
371 .id = SND_AUDIOCODEC_BESPOKE,
372 .desc = {
373 .max_ch = 8,
374 .sample_rates = {
375 4000, 8000, 11025, 12000, 16000, 22050,
376 24000, 32000, 44100, 48000, 64000, 88200,
377 96000, 176400, 192000
378 },
379 .num_sample_rates = 15,
380 .formats = SNDRV_PCM_FMTBIT_S16_LE,
381 },
382 .num_regions = ARRAY_SIZE(default_regions),
383 .region_defs = default_regions,
367 },384 },
368};385};
369 386
@@ -382,11 +399,16 @@ static const struct { · 12 unmodified lines
382 [WM_ADSP_FW_CTRL] = {399 [WM_ADSP_FW_CTRL] = {
383 .file = "ctrl",400 .file = "ctrl",
384 .compr_direction = SND_COMPRESS_CAPTURE,401 .compr_direction = SND_COMPRESS_CAPTURE,
385 .num_caps = ARRAY_SIZE(ez2control_caps),402 .num_caps = ARRAY_SIZE(ctrl_caps),
386 .caps = ez2control_caps,403 .caps = ctrl_caps,
387 },404 },
388 [WM_ADSP_FW_ASR] = { .file = "asr" },405 [WM_ADSP_FW_ASR] = { .file = "asr" },
389 [WM_ADSP_FW_TRACE] = { .file = "trace" },406 [WM_ADSP_FW_TRACE] = {
407 .file = "trace",
408 .compr_direction = SND_COMPRESS_CAPTURE,
409 .num_caps = ARRAY_SIZE(trace_caps),
410 .caps = trace_caps,
411 },
390 [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },412 [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" },
391 [WM_ADSP_FW_MISC] = { .file = "misc" },413 [WM_ADSP_FW_MISC] = { .file = "misc" },
392};414};
@@ -719,19 +741,19 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl, · 326 unmodified lines
719 reg = ctl->alg_region.base + ctl->offset;741 reg = ctl->alg_region.base + ctl->offset;
720 reg = wm_adsp_region_to_reg(mem, reg);742 reg = wm_adsp_region_to_reg(mem, reg);
721 743
722 scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA);744 scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA);
723 if (!scratch)745 if (!scratch)
724 return -ENOMEM;746 return -ENOMEM;
725 747
726 ret = regmap_raw_write(dsp->regmap, reg, scratch,748 ret = regmap_raw_write(dsp->regmap, reg, scratch,
727 ctl->len);749 len);
728 if (ret) {750 if (ret) {
729 adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n",751 adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n",
730 ctl->len, reg, ret);752 len, reg, ret);
731 kfree(scratch);753 kfree(scratch);
732 return ret;754 return ret;
733 }755 }
734 adsp_dbg(dsp, "Wrote %zu bytes to %x\n", ctl->len, reg);756 adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg);
735 757
736 kfree(scratch);758 kfree(scratch);
737 759
@@ -778,20 +800,20 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, · 40 unmodified lines
778 reg = ctl->alg_region.base + ctl->offset;800 reg = ctl->alg_region.base + ctl->offset;
779 reg = wm_adsp_region_to_reg(mem, reg);801 reg = wm_adsp_region_to_reg(mem, reg);
780 802
781 scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA);803 scratch = kmalloc(len, GFP_KERNEL | GFP_DMA);
782 if (!scratch)804 if (!scratch)
783 return -ENOMEM;805 return -ENOMEM;
784 806
785 ret = regmap_raw_read(dsp->regmap, reg, scratch, ctl->len);807 ret = regmap_raw_read(dsp->regmap, reg, scratch, len);
786 if (ret) {808 if (ret) {
787 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n",809 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n",
788 ctl->len, reg, ret);810 len, reg, ret);
789 kfree(scratch);811 kfree(scratch);
790 return ret;812 return ret;
791 }813 }
792 adsp_dbg(dsp, "Read %zu bytes from %x\n", ctl->len, reg);814 adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg);
793 815
794 memcpy(buf, scratch, ctl->len);816 memcpy(buf, scratch, len);
795 kfree(scratch);817 kfree(scratch);
796 818
797 return 0;819 return 0;
@@ -855,17 +877,18 @@ static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) · 57 unmodified lines
855 kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_READ;877 kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_READ;
856 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)878 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
857 kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;879 kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;
880 } else {
881 kcontrol->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
882 kcontrol->access |= SNDRV_CTL_ELEM_ACCESS_VOLATILE;
858 }883 }
859 884
860 ret = snd_soc_add_card_controls(dsp->card,885 ret = snd_soc_add_card_controls(dsp->card, kcontrol, 1);
861 kcontrol, 1);
862 if (ret < 0)886 if (ret < 0)
863 goto err_kcontrol;887 goto err_kcontrol;
864 888
865 kfree(kcontrol);889 kfree(kcontrol);
866 890
867 ctl->kcontrol = snd_soc_card_get_kcontrol(dsp->card,891 ctl->kcontrol = snd_soc_card_get_kcontrol(dsp->card, ctl->name);
868 ctl->name);
869 892
870 return 0;893 return 0;
871 894
@@ -885,9 +908,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp) · 13 unmodified lines
885 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)908 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
886 continue;909 continue;
887 910
888 ret = wm_coeff_read_control(ctl,911 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
889 ctl->cache,
890 ctl->len);
891 if (ret < 0)912 if (ret < 0)
892 return ret;913 return ret;
893 }914 }
@@ -904,9 +925,7 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp) · 10 unmodified lines
904 if (!ctl->enabled)925 if (!ctl->enabled)
905 continue;926 continue;
906 if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) {927 if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) {
907 ret = wm_coeff_write_control(ctl,928 ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len);
908 ctl->cache,
909 ctl->len);
910 if (ret < 0)929 if (ret < 0)
911 return ret;930 return ret;
912 }931 }
@@ -1502,8 +1521,7 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, · 589 unmodified lines
1502 1521
1503 ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2);1522 ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2);
1504 if (ret != 0) {1523 if (ret != 0) {
1505 adsp_err(dsp, "Failed to read algorithm list: %d\n",1524 adsp_err(dsp, "Failed to read algorithm list: %d\n", ret);
1506 ret);
1507 kfree(alg);1525 kfree(alg);
1508 return ERR_PTR(ret);1526 return ERR_PTR(ret);
1509 }1527 }
@@ -2002,8 +2020,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, · 492 unmodified lines
2002 goto err_mutex;2020 goto err_mutex;
2003 }2021 }
2004 2022
2005 val = (val & dsp->sysclk_mask)2023 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift;
2006 >> dsp->sysclk_shift;
2007 2024
2008 ret = regmap_update_bits(dsp->regmap,2025 ret = regmap_update_bits(dsp->regmap,
2009 dsp->base + ADSP1_CONTROL_31,2026 dsp->base + ADSP1_CONTROL_31,
@@ -2096,8 +2113,7 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) · 86 unmodified lines
2096 2113
2097 /* Wait for the RAM to start, should be near instantaneous */2114 /* Wait for the RAM to start, should be near instantaneous */
2098 for (count = 0; count < 10; ++count) {2115 for (count = 0; count < 10; ++count) {
2099 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,2116 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val);
2100 &val);
2101 if (ret != 0)2117 if (ret != 0)
2102 return ret;2118 return ret;
2103 2119
@@ -2123,30 +2139,9 @@ static void wm_adsp2_boot_work(struct work_struct *work) · 19 unmodified lines
2123 struct wm_adsp,2139 struct wm_adsp,
2124 boot_work);2140 boot_work);
2125 int ret;2141 int ret;
2126 unsigned int val;
2127 2142
2128 mutex_lock(&dsp->pwr_lock);2143 mutex_lock(&dsp->pwr_lock);
2129 2144
2130 /*
2131 * For simplicity set the DSP clock rate to be the
2132 * SYSCLK rate rather than making it configurable.
2133 */
2134 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
2135 if (ret != 0) {
2136 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
2137 goto err_mutex;
2138 }
2139 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
2140 >> ARIZONA_SYSCLK_FREQ_SHIFT;
2141
2142 ret = regmap_update_bits_async(dsp->regmap,
2143 dsp->base + ADSP2_CLOCKING,
2144 ADSP2_CLK_SEL_MASK, val);
2145 if (ret != 0) {
2146 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
2147 goto err_mutex;
2148 }
2149
2150 ret = wm_adsp2_ena(dsp);2145 ret = wm_adsp2_ena(dsp);
2151 if (ret != 0)2146 if (ret != 0)
2152 goto err_mutex;2147 goto err_mutex;
@@ -2186,8 +2181,21 @@ err_mutex: · 33 unmodified lines
2186 mutex_unlock(&dsp->pwr_lock);2181 mutex_unlock(&dsp->pwr_lock);
2187}2182}
2188 2183
2184static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq)
2185{
2186 int ret;
2187
2188 ret = regmap_update_bits_async(dsp->regmap,
2189 dsp->base + ADSP2_CLOCKING,
2190 ADSP2_CLK_SEL_MASK,
2191 freq << ADSP2_CLK_SEL_SHIFT);
2192 if (ret != 0)
2193 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
2194}
2195
2189int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,2196int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
2190 struct snd_kcontrol *kcontrol, int event)2197 struct snd_kcontrol *kcontrol, int event,
2198 unsigned int freq)
2191{2199{
2192 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);2200 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
2193 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);2201 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
@@ -2197,6 +2205,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, · 3 unmodified lines
2197 2205
2198 switch (event) {2206 switch (event) {
2199 case SND_SOC_DAPM_PRE_PMU:2207 case SND_SOC_DAPM_PRE_PMU:
2208 wm_adsp2_set_dspclk(dsp, freq);
2200 queue_work(system_unbound_wq, &dsp->boot_work);2209 queue_work(system_unbound_wq, &dsp->boot_work);
2201 break;2210 break;
2202 default:2211 default:
@@ -2471,6 +2480,8 @@ int wm_adsp_compr_set_params(struct snd_compr_stream *stream, · 268 unmodified lines
2471 if (!compr->raw_buf)2480 if (!compr->raw_buf)
2472 return -ENOMEM;2481 return -ENOMEM;
2473 2482
2483 compr->sample_rate = params->codec.sample_rate;
2484
2474 return 0;2485 return 0;
2475}2486}
2476EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);2487EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params);
@@ -2810,7 +2821,6 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) · 333 unmodified lines
2810 mutex_lock(&dsp->pwr_lock);2821 mutex_lock(&dsp->pwr_lock);
2811 2822
2812 if (!buf) {2823 if (!buf) {
2813 adsp_err(dsp, "Spurious buffer IRQ\n");
2814 ret = -ENODEV;2824 ret = -ENODEV;
2815 goto out;2825 goto out;
2816 }2826 }
@@ -2841,7 +2851,7 @@ int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) · 24 unmodified lines
2841 goto out;2851 goto out;
2842 }2852 }
2843 2853
2844 if (compr->stream)2854 if (compr && compr->stream)
2845 snd_compr_fragment_elapsed(compr->stream);2855 snd_compr_fragment_elapsed(compr->stream);
2846 2856
2847out:2857out:
@@ -2911,6 +2921,7 @@ int wm_adsp_compr_pointer(struct snd_compr_stream *stream, · 63 unmodified lines
2911 2921
2912 tstamp->copied_total = compr->copied_total;2922 tstamp->copied_total = compr->copied_total;
2913 tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE;2923 tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE;
2924 tstamp->sampling_rate = compr->sample_rate;
2914 2925
2915out:2926out:
2916 mutex_unlock(&dsp->pwr_lock);2927 mutex_unlock(&dsp->pwr_lock);
sound/soc/codecs/wm_adsp.h+3−5
@@ -80,7 +80,7 @@ struct wm_adsp { · 79 unmodified lines
80 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \80 SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
81 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)81 wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
82 82
83#define WM_ADSP2_E(wname, num, event_fn) \83#define WM_ADSP2(wname, num, event_fn) \
84{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \84{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
85 .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \85 .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
86 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \86 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
@@ -88,9 +88,6 @@ struct wm_adsp { · 1 unmodified line
88 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \88 .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
89 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }89 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
90 90
91#define WM_ADSP2(wname, num) \
92 WM_ADSP2_E(wname, num, wm_adsp2_early_event)
93
94extern const struct snd_kcontrol_new wm_adsp_fw_controls[];91extern const struct snd_kcontrol_new wm_adsp_fw_controls[];
95 92
96int wm_adsp1_init(struct wm_adsp *dsp);93int wm_adsp1_init(struct wm_adsp *dsp);
@@ -100,7 +97,8 @@ int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec); · 3 unmodified lines
100int wm_adsp1_event(struct snd_soc_dapm_widget *w,97int wm_adsp1_event(struct snd_soc_dapm_widget *w,
101 struct snd_kcontrol *kcontrol, int event);98 struct snd_kcontrol *kcontrol, int event);
102int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,99int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
103 struct snd_kcontrol *kcontrol, int event);100 struct snd_kcontrol *kcontrol, int event,
101 unsigned int freq);
104int wm_adsp2_event(struct snd_soc_dapm_widget *w,102int wm_adsp2_event(struct snd_soc_dapm_widget *w,
105 struct snd_kcontrol *kcontrol, int event);103 struct snd_kcontrol *kcontrol, int event);
106 104
sound/soc/davinci/Kconfig+2−1
@@ -5,7 +5,7 @@ config SND_DAVINCI_SOC · 4 unmodified lines
5 5
6config SND_EDMA_SOC6config SND_EDMA_SOC
7 tristate "SoC Audio for Texas Instruments chips using eDMA"7 tristate "SoC Audio for Texas Instruments chips using eDMA"
8 depends on SOC_AM33XX || SOC_AM43XX || ARCH_DAVINCI8 depends on TI_EDMA
9 select SND_SOC_GENERIC_DMAENGINE_PCM9 select SND_SOC_GENERIC_DMAENGINE_PCM
10 help10 help
11 Say Y or M here if you want audio support for TI SoC which uses eDMA.11 Say Y or M here if you want audio support for TI SoC which uses eDMA.
@@ -13,6 +13,7 @@ config SND_EDMA_SOC · 1 unmodified line
13 - daVinci devices13 - daVinci devices
14 - AM335x14 - AM335x
15 - AM437x/AM438x15 - AM437x/AM438x
16 - DRA7xx family
16 17
17config SND_DAVINCI_SOC_I2S18config SND_DAVINCI_SOC_I2S
18 tristate19 tristate
sound/soc/davinci/davinci-mcasp.c+12−0
@@ -77,6 +77,7 @@ struct davinci_mcasp { · 76 unmodified lines
77 u32 fifo_base;77 u32 fifo_base;
78 struct device *dev;78 struct device *dev;
79 struct snd_pcm_substream *substreams[2];79 struct snd_pcm_substream *substreams[2];
80 unsigned int dai_fmt;
80 81
81 /* McASP specific data */82 /* McASP specific data */
82 int tdm_slots;83 int tdm_slots;
@@ -398,6 +399,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, · 315 unmodified lines
398 bool fs_pol_rising;399 bool fs_pol_rising;
399 bool inv_fs = false;400 bool inv_fs = false;
400 401
402 if (!fmt)
403 return 0;
404
401 pm_runtime_get_sync(mcasp->dev);405 pm_runtime_get_sync(mcasp->dev);
402 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {406 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
403 case SND_SOC_DAIFMT_DSP_A:407 case SND_SOC_DAIFMT_DSP_A:
@@ -529,6 +533,8 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, · 125 unmodified lines
529 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);533 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
530 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);534 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
531 }535 }
536
537 mcasp->dai_fmt = fmt;
532out:538out:
533 pm_runtime_put(mcasp->dev);539 pm_runtime_put(mcasp->dev);
534 return ret;540 return ret;
@@ -1026,6 +1032,10 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, · 491 unmodified lines
1026 int period_size = params_period_size(params);1032 int period_size = params_period_size(params);
1027 int ret;1033 int ret;
1028 1034
1035 ret = davinci_mcasp_set_dai_fmt(cpu_dai, mcasp->dai_fmt);
1036 if (ret)
1037 return ret;
1038
1029 /*1039 /*
1030 * If mcasp is BCLK master, and a BCLK divider was not provided by1040 * If mcasp is BCLK master, and a BCLK divider was not provided by
1031 * the machine driver, we need to calculate the ratio.1041 * the machine driver, we need to calculate the ratio.
@@ -1517,6 +1527,8 @@ static int mcasp_reparent_fck(struct platform_device *pdev) · 485 unmodified lines
1517 if (!parent_name)1527 if (!parent_name)
1518 return 0;1528 return 0;
1519 1529
1530 dev_warn(&pdev->dev, "Update the bindings to use assigned-clocks!\n");
1531
1520 gfclk = clk_get(&pdev->dev, "fck");1532 gfclk = clk_get(&pdev->dev, "fck");
1521 if (IS_ERR(gfclk)) {1533 if (IS_ERR(gfclk)) {
1522 dev_err(&pdev->dev, "failed to get fck\n");1534 dev_err(&pdev->dev, "failed to get fck\n");
sound/soc/fsl/Kconfig+2−2
@@ -292,8 +292,8 @@ config SND_SOC_FSL_ASOC_CARD · 291 unmodified lines
292 select SND_SOC_FSL_SSI292 select SND_SOC_FSL_SSI
293 help293 help
294 ALSA SoC Audio support with ASRC feature for Freescale SoCs that have294 ALSA SoC Audio support with ASRC feature for Freescale SoCs that have
295 ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888295 ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888,
296 and SGTL5000.296 CS4271, CS4272 and SGTL5000.
297 Say Y if you want to add support for Freescale Generic ASoC Sound Card.297 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
298 298
299endif # SND_IMX_SOC299endif # SND_IMX_SOC
sound/soc/fsl/fsl-asoc-card.c+22−4
@@ -28,6 +28,8 @@ · 27 unmodified lines
28#include "../codecs/wm8962.h"28#include "../codecs/wm8962.h"
29#include "../codecs/wm8960.h"29#include "../codecs/wm8960.h"
30 30
31#define CS427x_SYSCLK_MCLK 0
32
31#define RX 033#define RX 0
32#define TX 134#define TX 1
33 35
@@ -99,19 +101,26 @@ struct fsl_asoc_card_priv { · 65 unmodified lines
99/**101/**
100 * This dapm route map exsits for DPCM link only.102 * This dapm route map exsits for DPCM link only.
101 * The other routes shall go through Device Tree.103 * The other routes shall go through Device Tree.
104 *
105 * Note: keep all ASRC routes in the second half
106 * to drop them easily for non-ASRC cases.
102 */107 */
103static const struct snd_soc_dapm_route audio_map[] = {108static const struct snd_soc_dapm_route audio_map[] = {
104 {"CPU-Playback", NULL, "ASRC-Playback"},109 /* 1st half -- Normal DAPM routes */
105 {"Playback", NULL, "CPU-Playback"},110 {"Playback", NULL, "CPU-Playback"},
106 {"ASRC-Capture", NULL, "CPU-Capture"},
107 {"CPU-Capture", NULL, "Capture"},111 {"CPU-Capture", NULL, "Capture"},
112 /* 2nd half -- ASRC DAPM routes */
113 {"CPU-Playback", NULL, "ASRC-Playback"},
114 {"ASRC-Capture", NULL, "CPU-Capture"},
108};115};
109 116
110static const struct snd_soc_dapm_route audio_map_ac97[] = {117static const struct snd_soc_dapm_route audio_map_ac97[] = {
111 {"AC97 Playback", NULL, "ASRC-Playback"},118 /* 1st half -- Normal DAPM routes */
112 {"Playback", NULL, "AC97 Playback"},119 {"Playback", NULL, "AC97 Playback"},
113 {"ASRC-Capture", NULL, "AC97 Capture"},
114 {"AC97 Capture", NULL, "Capture"},120 {"AC97 Capture", NULL, "Capture"},
121 /* 2nd half -- ASRC DAPM routes */
122 {"AC97 Playback", NULL, "ASRC-Playback"},
123 {"ASRC-Capture", NULL, "AC97 Capture"},
115};124};
116 125
117/* Add all possible widgets into here without being redundant */126/* Add all possible widgets into here without being redundant */
@@ -528,6 +537,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) · 410 unmodified lines
528 priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;537 priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
529 priv->cpu_priv.slot_width = 32;538 priv->cpu_priv.slot_width = 32;
530 priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;539 priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
540 } else if (of_device_is_compatible(np, "fsl,imx-audio-cs427x")) {
541 codec_dai_name = "cs4271-hifi";
542 priv->codec_priv.mclk_id = CS427x_SYSCLK_MCLK;
543 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
531 } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) {544 } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) {
532 codec_dai_name = "sgtl5000";545 codec_dai_name = "sgtl5000";
533 priv->codec_priv.mclk_id = SGTL5000_SYSCLK;546 priv->codec_priv.mclk_id = SGTL5000_SYSCLK;
@@ -593,6 +606,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) · 59 unmodified lines
593 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;606 priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets;
594 priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets);607 priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets);
595 608
609 /* Drop the second half of DAPM routes -- ASRC */
610 if (!asrc_pdev)
611 priv->card.num_dapm_routes /= 2;
612
596 memcpy(priv->dai_link, fsl_asoc_card_dai,613 memcpy(priv->dai_link, fsl_asoc_card_dai,
597 sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));614 sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
598 615
@@ -681,6 +698,7 @@ fail: · 82 unmodified lines
681static const struct of_device_id fsl_asoc_card_dt_ids[] = {698static const struct of_device_id fsl_asoc_card_dt_ids[] = {
682 { .compatible = "fsl,imx-audio-ac97", },699 { .compatible = "fsl,imx-audio-ac97", },
683 { .compatible = "fsl,imx-audio-cs42888", },700 { .compatible = "fsl,imx-audio-cs42888", },
701 { .compatible = "fsl,imx-audio-cs427x", },
684 { .compatible = "fsl,imx-audio-sgtl5000", },702 { .compatible = "fsl,imx-audio-sgtl5000", },
685 { .compatible = "fsl,imx-audio-wm8962", },703 { .compatible = "fsl,imx-audio-wm8962", },
686 { .compatible = "fsl,imx-audio-wm8960", },704 { .compatible = "fsl,imx-audio-wm8960", },
sound/soc/fsl/fsl_sai.c+2−1
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/of_address.h>17#include <linux/of_address.h>
18#include <linux/regmap.h>18#include <linux/regmap.h>
19#include <linux/slab.h>19#include <linux/slab.h>
20#include <linux/time.h>
20#include <sound/core.h>21#include <sound/core.h>
21#include <sound/dmaengine_pcm.h>22#include <sound/dmaengine_pcm.h>
22#include <sound/pcm_params.h>23#include <sound/pcm_params.h>
@@ -919,7 +920,7 @@ static int fsl_sai_resume(struct device *dev) · 896 unmodified lines
919 regcache_cache_only(sai->regmap, false);920 regcache_cache_only(sai->regmap, false);
920 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);921 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
921 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);922 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
922 msleep(1);923 usleep_range(1000, 2000);
923 regmap_write(sai->regmap, FSL_SAI_TCSR, 0);924 regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
924 regmap_write(sai->regmap, FSL_SAI_RCSR, 0);925 regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
925 return regcache_sync(sai->regmap);926 return regcache_sync(sai->regmap);
sound/soc/fsl/fsl_ssi.c+22−20
@@ -112,20 +112,6 @@ struct fsl_ssi_rxtx_reg_val { · 111 unmodified lines
112 struct fsl_ssi_reg_val tx;112 struct fsl_ssi_reg_val tx;
113};113};
114 114
115static const struct reg_default fsl_ssi_reg_defaults[] = {
116 {CCSR_SSI_SCR, 0x00000000},
117 {CCSR_SSI_SIER, 0x00003003},
118 {CCSR_SSI_STCR, 0x00000200},
119 {CCSR_SSI_SRCR, 0x00000200},
120 {CCSR_SSI_STCCR, 0x00040000},
121 {CCSR_SSI_SRCCR, 0x00040000},
122 {CCSR_SSI_SACNT, 0x00000000},
123 {CCSR_SSI_STMSK, 0x00000000},
124 {CCSR_SSI_SRMSK, 0x00000000},
125 {CCSR_SSI_SACCEN, 0x00000000},
126 {CCSR_SSI_SACCDIS, 0x00000000},
127};
128
129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)115static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
130{116{
131 switch (reg) {117 switch (reg) {
@@ -190,8 +176,7 @@ static const struct regmap_config fsl_ssi_regconfig = { · 58 unmodified lines
190 .val_bits = 32,176 .val_bits = 32,
191 .reg_stride = 4,177 .reg_stride = 4,
192 .val_format_endian = REGMAP_ENDIAN_NATIVE,178 .val_format_endian = REGMAP_ENDIAN_NATIVE,
193 .reg_defaults = fsl_ssi_reg_defaults,179 .num_reg_defaults_raw = CCSR_SSI_SACCDIS / sizeof(uint32_t) + 1,
194 .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults),
195 .readable_reg = fsl_ssi_readable_reg,180 .readable_reg = fsl_ssi_readable_reg,
196 .volatile_reg = fsl_ssi_volatile_reg,181 .volatile_reg = fsl_ssi_volatile_reg,
197 .precious_reg = fsl_ssi_precious_reg,182 .precious_reg = fsl_ssi_precious_reg,
@@ -201,6 +186,7 @@ static const struct regmap_config fsl_ssi_regconfig = { · 3 unmodified lines
201 186
202struct fsl_ssi_soc_data {187struct fsl_ssi_soc_data {
203 bool imx;188 bool imx;
189 bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
204 bool offline_config;190 bool offline_config;
205 u32 sisr_write_mask;191 u32 sisr_write_mask;
206};192};
@@ -303,6 +289,7 @@ static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { · 96 unmodified lines
303 289
304static struct fsl_ssi_soc_data fsl_ssi_imx21 = {290static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
305 .imx = true,291 .imx = true,
292 .imx21regs = true,
306 .offline_config = true,293 .offline_config = true,
307 .sisr_write_mask = 0,294 .sisr_write_mask = 0,
308};295};
@@ -586,8 +573,12 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) · 277 unmodified lines
586 */573 */
587 regmap_write(regs, CCSR_SSI_SACNT,574 regmap_write(regs, CCSR_SSI_SACNT,
588 CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV);575 CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV);
589 regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);576
590 regmap_write(regs, CCSR_SSI_SACCEN, 0x300);577 /* no SACC{ST,EN,DIS} regs on imx21-class SSI */
578 if (!ssi_private->soc->imx21regs) {
579 regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);
580 regmap_write(regs, CCSR_SSI_SACCEN, 0x300);
581 }
591 582
592 /*583 /*
593 * Enable SSI, Transmit and Receive. AC97 has to communicate with the584 * Enable SSI, Transmit and Receive. AC97 has to communicate with the
@@ -1397,6 +1388,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 803 unmodified lines
1397 struct resource *res;1388 struct resource *res;
1398 void __iomem *iomem;1389 void __iomem *iomem;
1399 char name[64];1390 char name[64];
1391 struct regmap_config regconfig = fsl_ssi_regconfig;
1400 1392
1401 of_id = of_match_device(fsl_ssi_ids, &pdev->dev);1393 of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
1402 if (!of_id || !of_id->data)1394 if (!of_id || !of_id->data)
@@ -1444,15 +1436,25 @@ static int fsl_ssi_probe(struct platform_device *pdev) · 41 unmodified lines
1444 return PTR_ERR(iomem);1436 return PTR_ERR(iomem);
1445 ssi_private->ssi_phys = res->start;1437 ssi_private->ssi_phys = res->start;
1446 1438
1439 if (ssi_private->soc->imx21regs) {
1440 /*
1441 * According to datasheet imx21-class SSI
1442 * don't have SACC{ST,EN,DIS} regs.
1443 */
1444 regconfig.max_register = CCSR_SSI_SRMSK;
1445 regconfig.num_reg_defaults_raw =
1446 CCSR_SSI_SRMSK / sizeof(uint32_t) + 1;
1447 }
1448
1447 ret = of_property_match_string(np, "clock-names", "ipg");1449 ret = of_property_match_string(np, "clock-names", "ipg");
1448 if (ret < 0) {1450 if (ret < 0) {
1449 ssi_private->has_ipg_clk_name = false;1451 ssi_private->has_ipg_clk_name = false;
1450 ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,1452 ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
1451 &fsl_ssi_regconfig);1453 &regconfig);
1452 } else {1454 } else {
1453 ssi_private->has_ipg_clk_name = true;1455 ssi_private->has_ipg_clk_name = true;
1454 ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,1456 ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,
1455 "ipg", iomem, &fsl_ssi_regconfig);1457 "ipg", iomem, &regconfig);
1456 }1458 }
1457 if (IS_ERR(ssi_private->regs)) {1459 if (IS_ERR(ssi_private->regs)) {
1458 dev_err(&pdev->dev, "Failed to init register map\n");1460 dev_err(&pdev->dev, "Failed to init register map\n");
sound/soc/fsl/mpc5200_psc_ac97.c+2−1
@@ -13,6 +13,7 @@ · 12 unmodified lines
13#include <linux/of_device.h>13#include <linux/of_device.h>
14#include <linux/of_platform.h>14#include <linux/of_platform.h>
15#include <linux/delay.h>15#include <linux/delay.h>
16#include <linux/time.h>
16 17
17#include <sound/pcm.h>18#include <sound/pcm.h>
18#include <sound/pcm_params.h>19#include <sound/pcm_params.h>
@@ -127,7 +128,7 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97) · 108 unmodified lines
127 128
128 mutex_unlock(&psc_dma->mutex);129 mutex_unlock(&psc_dma->mutex);
129 130
130 msleep(1);131 usleep_range(1000, 2000);
131 psc_ac97_warm_reset(ac97);132 psc_ac97_warm_reset(ac97);
132}133}
133 134
sound/soc/intel/Kconfig+4−0
@@ -163,6 +163,7 @@ config SND_SOC_INTEL_SKYLAKE · 162 unmodified lines
163 tristate163 tristate
164 select SND_HDA_EXT_CORE164 select SND_HDA_EXT_CORE
165 select SND_SOC_TOPOLOGY165 select SND_SOC_TOPOLOGY
166 select SND_HDA_I915
166 select SND_SOC_INTEL_SST167 select SND_SOC_INTEL_SST
167 168
168config SND_SOC_INTEL_SKL_RT286_MACH169config SND_SOC_INTEL_SKL_RT286_MACH
@@ -172,6 +173,7 @@ config SND_SOC_INTEL_SKL_RT286_MACH · 3 unmodified lines
172 select SND_SOC_INTEL_SKYLAKE173 select SND_SOC_INTEL_SKYLAKE
173 select SND_SOC_RT286174 select SND_SOC_RT286
174 select SND_SOC_DMIC175 select SND_SOC_DMIC
176 select SND_SOC_HDAC_HDMI
175 help177 help
176 This adds support for ASoC machine driver for Skylake platforms178 This adds support for ASoC machine driver for Skylake platforms
177 with RT286 I2S audio codec.179 with RT286 I2S audio codec.
@@ -186,6 +188,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH · 8 unmodified lines
186 select SND_SOC_NAU8825188 select SND_SOC_NAU8825
187 select SND_SOC_SSM4567189 select SND_SOC_SSM4567
188 select SND_SOC_DMIC190 select SND_SOC_DMIC
191 select SND_SOC_HDAC_HDMI
189 help192 help
190 This adds support for ASoC Onboard Codec I2S machine driver. This will193 This adds support for ASoC Onboard Codec I2S machine driver. This will
191 create an alsa sound card for NAU88L25 + SSM4567.194 create an alsa sound card for NAU88L25 + SSM4567.
@@ -200,6 +203,7 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH · 8 unmodified lines
200 select SND_SOC_NAU8825203 select SND_SOC_NAU8825
201 select SND_SOC_MAX98357A204 select SND_SOC_MAX98357A
202 select SND_SOC_DMIC205 select SND_SOC_DMIC
206 select SND_SOC_HDAC_HDMI
203 help207 help
204 This adds support for ASoC Onboard Codec I2S machine driver. This will208 This adds support for ASoC Onboard Codec I2S machine driver. This will
205 create an alsa sound card for NAU88L25 + MAX98357A.209 create an alsa sound card for NAU88L25 + MAX98357A.
sound/soc/intel/atom/sst/sst_acpi.c+4−0
@@ -342,6 +342,10 @@ static struct sst_acpi_mach sst_acpi_chv[] = { · 341 unmodified lines
342 &chv_platform_data },342 &chv_platform_data },
343 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,343 {"193C9890", "cht-bsw-max98090", "intel/fw_sst_22a8.bin", "cht-bsw", NULL,
344 &chv_platform_data },344 &chv_platform_data },
345 /* some CHT-T platforms rely on RT5640, use Baytrail machine driver */
346 {"10EC5640", "bytcr_rt5640", "intel/fw_sst_22a8.bin", "bytcr_rt5640", NULL,
347 &chv_platform_data },
348
345 {},349 {},
346};350};
347 351
sound/soc/intel/atom/sst/sst_ipc.c+0−2
@@ -318,7 +318,6 @@ void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx, · 317 unmodified lines
318 union ipc_header_high msg_high;318 union ipc_header_high msg_high;
319 u32 msg_low;319 u32 msg_low;
320 struct ipc_dsp_hdr *dsp_hdr;320 struct ipc_dsp_hdr *dsp_hdr;
321 unsigned int cmd_id;
322 321
323 msg_high = msg->mrfld_header.p.header_high;322 msg_high = msg->mrfld_header.p.header_high;
324 msg_low = msg->mrfld_header.p.header_low_payload;323 msg_low = msg->mrfld_header.p.header_low_payload;
@@ -357,7 +356,6 @@ void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx, · 32 unmodified lines
357 return;356 return;
358 /* Copy command id so that we can use to put sst to reset */357 /* Copy command id so that we can use to put sst to reset */
359 dsp_hdr = (struct ipc_dsp_hdr *)data;358 dsp_hdr = (struct ipc_dsp_hdr *)data;
360 cmd_id = dsp_hdr->cmd_id;
361 dev_dbg(sst_drv_ctx->dev, "cmd_id %d\n", dsp_hdr->cmd_id);359 dev_dbg(sst_drv_ctx->dev, "cmd_id %d\n", dsp_hdr->cmd_id);
362 if (sst_wake_up_block(sst_drv_ctx, msg_high.part.result,360 if (sst_wake_up_block(sst_drv_ctx, msg_high.part.result,
363 msg_high.part.drv_id,361 msg_high.part.drv_id,
sound/soc/intel/boards/bytcr_rt5640.c+34−16
@@ -32,6 +32,18 @@ · 31 unmodified lines
32#include "../atom/sst-atom-controls.h"32#include "../atom/sst-atom-controls.h"
33#include "../common/sst-acpi.h"33#include "../common/sst-acpi.h"
34 34
35enum {
36 BYT_RT5640_DMIC1_MAP,
37 BYT_RT5640_DMIC2_MAP,
38 BYT_RT5640_IN1_MAP,
39};
40
41#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
42#define BYT_RT5640_DMIC_EN BIT(16)
43
44static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
45 BYT_RT5640_DMIC_EN;
46
35static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {47static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
36 SND_SOC_DAPM_HP("Headphone", NULL),48 SND_SOC_DAPM_HP("Headphone", NULL),
37 SND_SOC_DAPM_MIC("Headset Mic", NULL),49 SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -70,18 +82,6 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = { · 32 unmodified lines
70 {"IN1P", NULL, "Internal Mic"},82 {"IN1P", NULL, "Internal Mic"},
71};83};
72 84
73enum {
74 BYT_RT5640_DMIC1_MAP,
75 BYT_RT5640_DMIC2_MAP,
76 BYT_RT5640_IN1_MAP,
77};
78
79#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
80#define BYT_RT5640_DMIC_EN BIT(16)
81
82static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
83 BYT_RT5640_DMIC_EN;
84
85static const struct snd_kcontrol_new byt_rt5640_controls[] = {85static const struct snd_kcontrol_new byt_rt5640_controls[] = {
86 SOC_DAPM_PIN_SWITCH("Headphone"),86 SOC_DAPM_PIN_SWITCH("Headphone"),
87 SOC_DAPM_PIN_SWITCH("Headset Mic"),87 SOC_DAPM_PIN_SWITCH("Headset Mic"),
@@ -174,7 +174,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) · 86 unmodified lines
174 return ret;174 return ret;
175 }175 }
176 176
177 dmi_check_system(byt_rt5640_quirk_table);
178 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {177 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
179 case BYT_RT5640_IN1_MAP:178 case BYT_RT5640_IN1_MAP:
180 custom_map = byt_rt5640_intmic_in1_map;179 custom_map = byt_rt5640_intmic_in1_map;
@@ -341,15 +340,34 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) · 160 unmodified lines
341{340{
342 int ret_val = 0;341 int ret_val = 0;
343 struct sst_acpi_mach *mach;342 struct sst_acpi_mach *mach;
343 const char *i2c_name = NULL;
344 int i;
345 int dai_index;
344 346
345 /* register the soc card */347 /* register the soc card */
346 byt_rt5640_card.dev = &pdev->dev;348 byt_rt5640_card.dev = &pdev->dev;
347 mach = byt_rt5640_card.dev->platform_data;349 mach = byt_rt5640_card.dev->platform_data;
348 350
351 /* fix index of codec dai */
352 dai_index = MERR_DPCM_COMPR + 1;
353 for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
354 if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
355 dai_index = i;
356 break;
357 }
358 }
359
349 /* fixup codec name based on HID */360 /* fixup codec name based on HID */
350 snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),361 i2c_name = sst_acpi_find_name_from_hid(mach->id);
351 "%s%s%s", "i2c-", mach->id, ":00");362 if (i2c_name != NULL) {
352 byt_rt5640_dais[MERR_DPCM_COMPR+1].codec_name = byt_rt5640_codec_name;363 snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
364 "%s%s", "i2c-", i2c_name);
365
366 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
367 }
368
369 /* check quirks before creating card */
370 dmi_check_system(byt_rt5640_quirk_table);
353 371
354 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);372 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
355 373
sound/soc/intel/boards/cht_bsw_max98090_ti.c+2−15
@@ -287,33 +287,20 @@ static struct snd_soc_card snd_soc_card_cht = { · 286 unmodified lines
287 .num_controls = ARRAY_SIZE(cht_mc_controls),287 .num_controls = ARRAY_SIZE(cht_mc_controls),
288};288};
289 289
290static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level,
291 void *context, void **ret)
292{
293 *(bool *)context = true;
294 return AE_OK;
295}
296
297static int snd_cht_mc_probe(struct platform_device *pdev)290static int snd_cht_mc_probe(struct platform_device *pdev)
298{291{
299 int ret_val = 0;292 int ret_val = 0;
300 bool found = false;
301 struct cht_mc_private *drv;293 struct cht_mc_private *drv;
302 294
303 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);295 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
304 if (!drv)296 if (!drv)
305 return -ENOMEM;297 return -ENOMEM;
306 298
307 if (ACPI_SUCCESS(acpi_get_devices(299 drv->ts3a227e_present = acpi_dev_present("104C227E");
308 "104C227E",300 if (!drv->ts3a227e_present) {
309 snd_acpi_codec_match,
310 &found, NULL)) && found) {
311 drv->ts3a227e_present = true;
312 } else {
313 /* no need probe TI jack detection chip */301 /* no need probe TI jack detection chip */
314 snd_soc_card_cht.aux_dev = NULL;302 snd_soc_card_cht.aux_dev = NULL;
315 snd_soc_card_cht.num_aux_devs = 0;303 snd_soc_card_cht.num_aux_devs = 0;
316 drv->ts3a227e_present = false;
317 }304 }
318 305
319 /* register the soc card */306 /* register the soc card */
sound/soc/intel/boards/cht_bsw_rt5645.c+14−14
@@ -147,6 +147,17 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { · 146 unmodified lines
147 SOC_DAPM_PIN_SWITCH("Ext Spk"),147 SOC_DAPM_PIN_SWITCH("Ext Spk"),
148};148};
149 149
150static struct snd_soc_jack_pin cht_bsw_jack_pins[] = {
151 {
152 .pin = "Headphone",
153 .mask = SND_JACK_HEADPHONE,
154 },
155 {
156 .pin = "Headset Mic",
157 .mask = SND_JACK_MICROPHONE,
158 },
159};
160
150static int cht_aif1_hw_params(struct snd_pcm_substream *substream,161static int cht_aif1_hw_params(struct snd_pcm_substream *substream,
151 struct snd_pcm_hw_params *params)162 struct snd_pcm_hw_params *params)
152{163{
@@ -202,9 +213,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) · 49 unmodified lines
202 else213 else
203 jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;214 jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE;
204 215
205 ret = snd_soc_card_jack_new(runtime->card, "Headset Jack",216 ret = snd_soc_card_jack_new(runtime->card, "Headset",
206 jack_type, &ctx->jack,217 jack_type, &ctx->jack,
207 NULL, 0);218 cht_bsw_jack_pins, ARRAY_SIZE(cht_bsw_jack_pins));
208 if (ret) {219 if (ret) {
209 dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);220 dev_err(runtime->dev, "Headset jack creation failed %d\n", ret);
210 return ret;221 return ret;
@@ -333,20 +344,12 @@ static struct cht_acpi_card snd_soc_cards[] = { · 122 unmodified lines
333 {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},344 {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650},
334};345};
335 346
336static acpi_status snd_acpi_codec_match(acpi_handle handle, u32 level,
337 void *context, void **ret)
338{
339 *(bool *)context = true;
340 return AE_OK;
341}
342
343static int snd_cht_mc_probe(struct platform_device *pdev)347static int snd_cht_mc_probe(struct platform_device *pdev)
344{348{
345 int ret_val = 0;349 int ret_val = 0;
346 int i;350 int i;
347 struct cht_mc_private *drv;351 struct cht_mc_private *drv;
348 struct snd_soc_card *card = snd_soc_cards[0].soc_card;352 struct snd_soc_card *card = snd_soc_cards[0].soc_card;
349 bool found = false;
350 char codec_name[16];353 char codec_name[16];
351 354
352 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);355 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC);
@@ -354,10 +357,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) · 1 unmodified line
354 return -ENOMEM;357 return -ENOMEM;
355 358
356 for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) {359 for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) {
357 if (ACPI_SUCCESS(acpi_get_devices(360 if (acpi_dev_present(snd_soc_cards[i].codec_id)) {
358 snd_soc_cards[i].codec_id,
359 snd_acpi_codec_match,
360 &found, NULL)) && found) {
361 dev_dbg(&pdev->dev,361 dev_dbg(&pdev->dev,
362 "found codec %s\n", snd_soc_cards[i].codec_id);362 "found codec %s\n", snd_soc_cards[i].codec_id);
363 card = snd_soc_cards[i].soc_card;363 card = snd_soc_cards[i].soc_card;
sound/soc/intel/boards/skl_nau88l25_max98357a.c+105−17
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#include <sound/pcm_params.h>22#include <sound/pcm_params.h>
23#include <sound/soc.h>23#include <sound/soc.h>
24#include "../../codecs/nau8825.h"24#include "../../codecs/nau8825.h"
25#include "../../codecs/hdac_hdmi.h"
25 26
26#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"27#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
27#define SKL_MAXIM_CODEC_DAI "HiFi"28#define SKL_MAXIM_CODEC_DAI "HiFi"
@@ -29,6 +30,16 @@ · 1 unmodified line
29static struct snd_soc_jack skylake_headset;30static struct snd_soc_jack skylake_headset;
30static struct snd_soc_card skylake_audio_card;31static struct snd_soc_card skylake_audio_card;
31 32
33enum {
34 SKL_DPCM_AUDIO_PB = 0,
35 SKL_DPCM_AUDIO_CP,
36 SKL_DPCM_AUDIO_REF_CP,
37 SKL_DPCM_AUDIO_DMIC_CP,
38 SKL_DPCM_AUDIO_HDMI1_PB,
39 SKL_DPCM_AUDIO_HDMI2_PB,
40 SKL_DPCM_AUDIO_HDMI3_PB,
41};
42
32static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)43static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
33{44{
34 struct snd_soc_pcm_runtime *rtd;45 struct snd_soc_pcm_runtime *rtd;
@@ -87,7 +98,6 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = { · 52 unmodified lines
87 SND_SOC_DAPM_MIC("Headset Mic", NULL),98 SND_SOC_DAPM_MIC("Headset Mic", NULL),
88 SND_SOC_DAPM_SPK("Spk", NULL),99 SND_SOC_DAPM_SPK("Spk", NULL),
89 SND_SOC_DAPM_MIC("SoC DMIC", NULL),100 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
90 SND_SOC_DAPM_SINK("WoV Sink"),
91 SND_SOC_DAPM_SPK("DP", NULL),101 SND_SOC_DAPM_SPK("DP", NULL),
92 SND_SOC_DAPM_SPK("HDMI", NULL),102 SND_SOC_DAPM_SPK("HDMI", NULL),
93 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,103 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
@@ -107,7 +117,6 @@ static const struct snd_soc_dapm_route skylake_map[] = { · 13 unmodified lines
107 { "MIC", NULL, "Headset Mic" },117 { "MIC", NULL, "Headset Mic" },
108 { "DMic", NULL, "SoC DMIC" },118 { "DMic", NULL, "SoC DMIC" },
109 119
110 {"WoV Sink", NULL, "hwd_in sink"},
111 {"HDMI", NULL, "hif5 Output"},120 {"HDMI", NULL, "hif5 Output"},
112 {"DP", NULL, "hif6 Output"},121 {"DP", NULL, "hif6 Output"},
113 122
@@ -124,8 +133,14 @@ static const struct snd_soc_dapm_route skylake_map[] = { · 10 unmodified lines
124 /* DMIC */133 /* DMIC */
125 { "dmic01_hifi", NULL, "DMIC01 Rx" },134 { "dmic01_hifi", NULL, "DMIC01 Rx" },
126 { "DMIC01 Rx", NULL, "DMIC AIF" },135 { "DMIC01 Rx", NULL, "DMIC AIF" },
127 { "hifi1", NULL, "iDisp Tx"},136
128 { "iDisp Tx", NULL, "iDisp_out"},137 { "hifi3", NULL, "iDisp3 Tx"},
138 { "iDisp3 Tx", NULL, "iDisp3_out"},
139 { "hifi2", NULL, "iDisp2 Tx"},
140 { "iDisp2 Tx", NULL, "iDisp2_out"},
141 { "hifi1", NULL, "iDisp1 Tx"},
142 { "iDisp1 Tx", NULL, "iDisp1_out"},
143
129 { "Headphone Jack", NULL, "Platform Clock" },144 { "Headphone Jack", NULL, "Platform Clock" },
130 { "Headset Mic", NULL, "Platform Clock" },145 { "Headset Mic", NULL, "Platform Clock" },
131};146};
@@ -171,11 +186,31 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) · 39 unmodified lines
171 nau8825_enable_jack_detect(codec, &skylake_headset);186 nau8825_enable_jack_detect(codec, &skylake_headset);
172 187
173 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");188 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
174 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
175 189
176 return ret;190 return ret;
177}191}
178 192
193static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
194{
195 struct snd_soc_dai *dai = rtd->codec_dai;
196
197 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB);
198}
199
200static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
201{
202 struct snd_soc_dai *dai = rtd->codec_dai;
203
204 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB);
205}
206
207static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
208{
209 struct snd_soc_dai *dai = rtd->codec_dai;
210
211 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB);
212}
213
179static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)214static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
180{215{
181 struct snd_soc_dapm_context *dapm;216 struct snd_soc_dapm_context *dapm;
@@ -318,7 +353,7 @@ static struct snd_soc_ops skylaye_refcap_ops = { · 136 unmodified lines
318/* skylake digital audio interface glue - connects codec <--> CPU */353/* skylake digital audio interface glue - connects codec <--> CPU */
319static struct snd_soc_dai_link skylake_dais[] = {354static struct snd_soc_dai_link skylake_dais[] = {
320 /* Front End DAI links */355 /* Front End DAI links */
321 {356 [SKL_DPCM_AUDIO_PB] = {
322 .name = "Skl Audio Port",357 .name = "Skl Audio Port",
323 .stream_name = "Audio",358 .stream_name = "Audio",
324 .cpu_dai_name = "System Pin",359 .cpu_dai_name = "System Pin",
@@ -333,7 +368,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 8 unmodified lines
333 .dpcm_playback = 1,368 .dpcm_playback = 1,
334 .ops = &skylake_nau8825_fe_ops,369 .ops = &skylake_nau8825_fe_ops,
335 },370 },
336 {371 [SKL_DPCM_AUDIO_CP] = {
337 .name = "Skl Audio Capture Port",372 .name = "Skl Audio Capture Port",
338 .stream_name = "Audio Record",373 .stream_name = "Audio Record",
339 .cpu_dai_name = "System Pin",374 .cpu_dai_name = "System Pin",
@@ -347,7 +382,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 7 unmodified lines
347 .dpcm_capture = 1,382 .dpcm_capture = 1,
348 .ops = &skylake_nau8825_fe_ops,383 .ops = &skylake_nau8825_fe_ops,
349 },384 },
350 {385 [SKL_DPCM_AUDIO_REF_CP] = {
351 .name = "Skl Audio Reference cap",386 .name = "Skl Audio Reference cap",
352 .stream_name = "Wake on Voice",387 .stream_name = "Wake on Voice",
353 .cpu_dai_name = "Reference Pin",388 .cpu_dai_name = "Reference Pin",
@@ -361,7 +396,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 7 unmodified lines
361 .dynamic = 1,396 .dynamic = 1,
362 .ops = &skylaye_refcap_ops,397 .ops = &skylaye_refcap_ops,
363 },398 },
364 {399 [SKL_DPCM_AUDIO_DMIC_CP] = {
365 .name = "Skl Audio DMIC cap",400 .name = "Skl Audio DMIC cap",
366 .stream_name = "dmiccap",401 .stream_name = "dmiccap",
367 .cpu_dai_name = "DMIC Pin",402 .cpu_dai_name = "DMIC Pin",
@@ -374,15 +409,45 @@ static struct snd_soc_dai_link skylake_dais[] = { · 6 unmodified lines
374 .dynamic = 1,409 .dynamic = 1,
375 .ops = &skylake_dmic_ops,410 .ops = &skylake_dmic_ops,
376 },411 },
377 {412 [SKL_DPCM_AUDIO_HDMI1_PB] = {
378 .name = "Skl HDMI Port",413 .name = "Skl HDMI Port1",
379 .stream_name = "Hdmi",414 .stream_name = "Hdmi1",
380 .cpu_dai_name = "HDMI Pin",415 .cpu_dai_name = "HDMI1 Pin",
416 .codec_name = "snd-soc-dummy",
417 .codec_dai_name = "snd-soc-dummy-dai",
418 .platform_name = "0000:00:1f.3",
419 .dpcm_playback = 1,
420 .init = NULL,
421 .trigger = {
422 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
423 .nonatomic = 1,
424 .dynamic = 1,
425 },
426 [SKL_DPCM_AUDIO_HDMI2_PB] = {
427 .name = "Skl HDMI Port2",
428 .stream_name = "Hdmi2",
429 .cpu_dai_name = "HDMI2 Pin",
381 .codec_name = "snd-soc-dummy",430 .codec_name = "snd-soc-dummy",
382 .codec_dai_name = "snd-soc-dummy-dai",431 .codec_dai_name = "snd-soc-dummy-dai",
383 .platform_name = "0000:00:1f.3",432 .platform_name = "0000:00:1f.3",
384 .dpcm_playback = 1,433 .dpcm_playback = 1,
385 .init = NULL,434 .init = NULL,
435 .trigger = {
436 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
437 .nonatomic = 1,
438 .dynamic = 1,
439 },
440 [SKL_DPCM_AUDIO_HDMI3_PB] = {
441 .name = "Skl HDMI Port3",
442 .stream_name = "Hdmi3",
443 .cpu_dai_name = "HDMI3 Pin",
444 .codec_name = "snd-soc-dummy",
445 .codec_dai_name = "snd-soc-dummy-dai",
446 .platform_name = "0000:00:1f.3",
447 .trigger = {
448 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
449 .dpcm_playback = 1,
450 .init = NULL,
386 .nonatomic = 1,451 .nonatomic = 1,
387 .dynamic = 1,452 .dynamic = 1,
388 },453 },
@@ -407,7 +472,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 18 unmodified lines
407 {472 {
408 /* SSP1 - Codec */473 /* SSP1 - Codec */
409 .name = "SSP1-Codec",474 .name = "SSP1-Codec",
410 .be_id = 0,475 .be_id = 1,
411 .cpu_dai_name = "SSP1 Pin",476 .cpu_dai_name = "SSP1 Pin",
412 .platform_name = "0000:00:1f.3",477 .platform_name = "0000:00:1f.3",
413 .no_pcm = 1,478 .no_pcm = 1,
@@ -424,7 +489,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 10 unmodified lines
424 },489 },
425 {490 {
426 .name = "dmic01",491 .name = "dmic01",
427 .be_id = 1,492 .be_id = 2,
428 .cpu_dai_name = "DMIC01 Pin",493 .cpu_dai_name = "DMIC01 Pin",
429 .codec_name = "dmic-codec",494 .codec_name = "dmic-codec",
430 .codec_dai_name = "dmic-hifi",495 .codec_dai_name = "dmic-hifi",
@@ -435,13 +500,36 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines
435 .no_pcm = 1,500 .no_pcm = 1,
436 },501 },
437 {502 {
438 .name = "iDisp",503 .name = "iDisp1",
439 .be_id = 3,504 .be_id = 3,
440 .cpu_dai_name = "iDisp Pin",505 .cpu_dai_name = "iDisp1 Pin",
441 .codec_name = "ehdaudio0D2",506 .codec_name = "ehdaudio0D2",
442 .codec_dai_name = "intel-hdmi-hifi1",507 .codec_dai_name = "intel-hdmi-hifi1",
443 .platform_name = "0000:00:1f.3",508 .platform_name = "0000:00:1f.3",
444 .dpcm_playback = 1,509 .dpcm_playback = 1,
510 .init = skylake_hdmi1_init,
511 .no_pcm = 1,
512 },
513 {
514 .name = "iDisp2",
515 .be_id = 4,
516 .cpu_dai_name = "iDisp2 Pin",
517 .codec_name = "ehdaudio0D2",
518 .codec_dai_name = "intel-hdmi-hifi2",
519 .platform_name = "0000:00:1f.3",
520 .init = skylake_hdmi2_init,
521 .dpcm_playback = 1,
522 .no_pcm = 1,
523 },
524 {
525 .name = "iDisp3",
526 .be_id = 5,
527 .cpu_dai_name = "iDisp3 Pin",
528 .codec_name = "ehdaudio0D2",
529 .codec_dai_name = "intel-hdmi-hifi3",
530 .platform_name = "0000:00:1f.3",
531 .init = skylake_hdmi3_init,
532 .dpcm_playback = 1,
445 .no_pcm = 1,533 .no_pcm = 1,
446 },534 },
447};535};
sound/soc/intel/boards/skl_nau88l25_ssm4567.c+112−18
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include <sound/jack.h>26#include <sound/jack.h>
27#include <sound/pcm_params.h>27#include <sound/pcm_params.h>
28#include "../../codecs/nau8825.h"28#include "../../codecs/nau8825.h"
29#include "../../codecs/hdac_hdmi.h"
29 30
30#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"31#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
31#define SKL_SSM_CODEC_DAI "ssm4567-hifi"32#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
@@ -33,6 +34,16 @@ · 1 unmodified line
33static struct snd_soc_jack skylake_headset;34static struct snd_soc_jack skylake_headset;
34static struct snd_soc_card skylake_audio_card;35static struct snd_soc_card skylake_audio_card;
35 36
37enum {
38 SKL_DPCM_AUDIO_PB = 0,
39 SKL_DPCM_AUDIO_CP,
40 SKL_DPCM_AUDIO_REF_CP,
41 SKL_DPCM_AUDIO_DMIC_CP,
42 SKL_DPCM_AUDIO_HDMI1_PB,
43 SKL_DPCM_AUDIO_HDMI2_PB,
44 SKL_DPCM_AUDIO_HDMI3_PB,
45};
46
36static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)47static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card)
37{48{
38 struct snd_soc_pcm_runtime *rtd;49 struct snd_soc_pcm_runtime *rtd;
@@ -92,7 +103,6 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = { · 53 unmodified lines
92 SND_SOC_DAPM_SPK("Left Speaker", NULL),103 SND_SOC_DAPM_SPK("Left Speaker", NULL),
93 SND_SOC_DAPM_SPK("Right Speaker", NULL),104 SND_SOC_DAPM_SPK("Right Speaker", NULL),
94 SND_SOC_DAPM_MIC("SoC DMIC", NULL),105 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
95 SND_SOC_DAPM_SINK("WoV Sink"),
96 SND_SOC_DAPM_SPK("DP", NULL),106 SND_SOC_DAPM_SPK("DP", NULL),
97 SND_SOC_DAPM_SPK("HDMI", NULL),107 SND_SOC_DAPM_SPK("HDMI", NULL),
98 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,108 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
@@ -113,8 +123,6 @@ static const struct snd_soc_dapm_route skylake_map[] = { · 14 unmodified lines
113 {"MIC", NULL, "Headset Mic"},123 {"MIC", NULL, "Headset Mic"},
114 {"DMic", NULL, "SoC DMIC"},124 {"DMic", NULL, "SoC DMIC"},
115 125
116 {"WoV Sink", NULL, "hwd_in sink"},
117
118 {"HDMI", NULL, "hif5 Output"},126 {"HDMI", NULL, "hif5 Output"},
119 {"DP", NULL, "hif6 Output"},127 {"DP", NULL, "hif6 Output"},
120 /* CODEC BE connections */128 /* CODEC BE connections */
@@ -122,6 +130,11 @@ static const struct snd_soc_dapm_route skylake_map[] = { · 1 unmodified line
122 { "Right Playback", NULL, "ssp0 Tx"},130 { "Right Playback", NULL, "ssp0 Tx"},
123 { "ssp0 Tx", NULL, "codec0_out"},131 { "ssp0 Tx", NULL, "codec0_out"},
124 132
133 /* IV feedback path */
134 { "codec0_lp_in", NULL, "ssp0 Rx"},
135 { "ssp0 Rx", NULL, "Left Capture Sense" },
136 { "ssp0 Rx", NULL, "Right Capture Sense" },
137
125 { "Playback", NULL, "ssp1 Tx"},138 { "Playback", NULL, "ssp1 Tx"},
126 { "ssp1 Tx", NULL, "codec1_out"},139 { "ssp1 Tx", NULL, "codec1_out"},
127 140
@@ -131,8 +144,14 @@ static const struct snd_soc_dapm_route skylake_map[] = { · 3 unmodified lines
131 /* DMIC */144 /* DMIC */
132 { "dmic01_hifi", NULL, "DMIC01 Rx" },145 { "dmic01_hifi", NULL, "DMIC01 Rx" },
133 { "DMIC01 Rx", NULL, "DMIC AIF" },146 { "DMIC01 Rx", NULL, "DMIC AIF" },
134 { "hifi1", NULL, "iDisp Tx"},147
135 { "iDisp Tx", NULL, "iDisp_out"},148 { "hifi3", NULL, "iDisp3 Tx"},
149 { "iDisp3 Tx", NULL, "iDisp3_out"},
150 { "hifi2", NULL, "iDisp2 Tx"},
151 { "iDisp2 Tx", NULL, "iDisp2_out"},
152 { "hifi1", NULL, "iDisp1 Tx"},
153 { "iDisp1 Tx", NULL, "iDisp1_out"},
154
136 { "Headphone Jack", NULL, "Platform Clock" },155 { "Headphone Jack", NULL, "Platform Clock" },
137 { "Headset Mic", NULL, "Platform Clock" },156 { "Headset Mic", NULL, "Platform Clock" },
138};157};
@@ -197,11 +216,32 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) · 58 unmodified lines
197 nau8825_enable_jack_detect(codec, &skylake_headset);216 nau8825_enable_jack_detect(codec, &skylake_headset);
198 217
199 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");218 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
200 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
201 219
202 return ret;220 return ret;
203}221}
204 222
223static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
224{
225 struct snd_soc_dai *dai = rtd->codec_dai;
226
227 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB);
228}
229
230static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
231{
232 struct snd_soc_dai *dai = rtd->codec_dai;
233
234 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI2_PB);
235}
236
237
238static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
239{
240 struct snd_soc_dai *dai = rtd->codec_dai;
241
242 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI3_PB);
243}
244
205static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)245static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd)
206{246{
207 struct snd_soc_dapm_context *dapm;247 struct snd_soc_dapm_context *dapm;
@@ -362,7 +402,7 @@ static struct snd_soc_ops skylaye_refcap_ops = { · 154 unmodified lines
362/* skylake digital audio interface glue - connects codec <--> CPU */402/* skylake digital audio interface glue - connects codec <--> CPU */
363static struct snd_soc_dai_link skylake_dais[] = {403static struct snd_soc_dai_link skylake_dais[] = {
364 /* Front End DAI links */404 /* Front End DAI links */
365 {405 [SKL_DPCM_AUDIO_PB] = {
366 .name = "Skl Audio Port",406 .name = "Skl Audio Port",
367 .stream_name = "Audio",407 .stream_name = "Audio",
368 .cpu_dai_name = "System Pin",408 .cpu_dai_name = "System Pin",
@@ -377,7 +417,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 8 unmodified lines
377 .dpcm_playback = 1,417 .dpcm_playback = 1,
378 .ops = &skylake_nau8825_fe_ops,418 .ops = &skylake_nau8825_fe_ops,
379 },419 },
380 {420 [SKL_DPCM_AUDIO_CP] = {
381 .name = "Skl Audio Capture Port",421 .name = "Skl Audio Capture Port",
382 .stream_name = "Audio Record",422 .stream_name = "Audio Record",
383 .cpu_dai_name = "System Pin",423 .cpu_dai_name = "System Pin",
@@ -391,7 +431,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 7 unmodified lines
391 .dpcm_capture = 1,431 .dpcm_capture = 1,
392 .ops = &skylake_nau8825_fe_ops,432 .ops = &skylake_nau8825_fe_ops,
393 },433 },
394 {434 [SKL_DPCM_AUDIO_REF_CP] = {
395 .name = "Skl Audio Reference cap",435 .name = "Skl Audio Reference cap",
396 .stream_name = "Wake on Voice",436 .stream_name = "Wake on Voice",
397 .cpu_dai_name = "Reference Pin",437 .cpu_dai_name = "Reference Pin",
@@ -405,7 +445,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 7 unmodified lines
405 .dynamic = 1,445 .dynamic = 1,
406 .ops = &skylaye_refcap_ops,446 .ops = &skylaye_refcap_ops,
407 },447 },
408 {448 [SKL_DPCM_AUDIO_DMIC_CP] = {
409 .name = "Skl Audio DMIC cap",449 .name = "Skl Audio DMIC cap",
410 .stream_name = "dmiccap",450 .stream_name = "dmiccap",
411 .cpu_dai_name = "DMIC Pin",451 .cpu_dai_name = "DMIC Pin",
@@ -418,13 +458,43 @@ static struct snd_soc_dai_link skylake_dais[] = { · 6 unmodified lines
418 .dynamic = 1,458 .dynamic = 1,
419 .ops = &skylake_dmic_ops,459 .ops = &skylake_dmic_ops,
420 },460 },
421 {461 [SKL_DPCM_AUDIO_HDMI1_PB] = {
422 .name = "Skl HDMI Port",462 .name = "Skl HDMI Port1",
423 .stream_name = "Hdmi",463 .stream_name = "Hdmi1",
424 .cpu_dai_name = "HDMI Pin",464 .cpu_dai_name = "HDMI1 Pin",
465 .codec_name = "snd-soc-dummy",
466 .codec_dai_name = "snd-soc-dummy-dai",
467 .platform_name = "0000:00:1f.3",
468 .dpcm_playback = 1,
469 .init = NULL,
470 .trigger = {
471 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
472 .nonatomic = 1,
473 .dynamic = 1,
474 },
475 [SKL_DPCM_AUDIO_HDMI2_PB] = {
476 .name = "Skl HDMI Port2",
477 .stream_name = "Hdmi2",
478 .cpu_dai_name = "HDMI2 Pin",
479 .codec_name = "snd-soc-dummy",
480 .codec_dai_name = "snd-soc-dummy-dai",
481 .platform_name = "0000:00:1f.3",
482 .dpcm_playback = 1,
483 .init = NULL,
484 .trigger = {
485 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
486 .nonatomic = 1,
487 .dynamic = 1,
488 },
489 [SKL_DPCM_AUDIO_HDMI3_PB] = {
490 .name = "Skl HDMI Port3",
491 .stream_name = "Hdmi3",
492 .cpu_dai_name = "HDMI3 Pin",
425 .codec_name = "snd-soc-dummy",493 .codec_name = "snd-soc-dummy",
426 .codec_dai_name = "snd-soc-dummy-dai",494 .codec_dai_name = "snd-soc-dummy-dai",
427 .platform_name = "0000:00:1f.3",495 .platform_name = "0000:00:1f.3",
496 .trigger = {
497 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
428 .dpcm_playback = 1,498 .dpcm_playback = 1,
429 .init = NULL,499 .init = NULL,
430 .nonatomic = 1,500 .nonatomic = 1,
@@ -448,11 +518,12 @@ static struct snd_soc_dai_link skylake_dais[] = { · 17 unmodified lines
448 .ignore_pmdown_time = 1,518 .ignore_pmdown_time = 1,
449 .be_hw_params_fixup = skylake_ssp_fixup,519 .be_hw_params_fixup = skylake_ssp_fixup,
450 .dpcm_playback = 1,520 .dpcm_playback = 1,
521 .dpcm_capture = 1,
451 },522 },
452 {523 {
453 /* SSP1 - Codec */524 /* SSP1 - Codec */
454 .name = "SSP1-Codec",525 .name = "SSP1-Codec",
455 .be_id = 0,526 .be_id = 1,
456 .cpu_dai_name = "SSP1 Pin",527 .cpu_dai_name = "SSP1 Pin",
457 .platform_name = "0000:00:1f.3",528 .platform_name = "0000:00:1f.3",
458 .no_pcm = 1,529 .no_pcm = 1,
@@ -469,7 +540,7 @@ static struct snd_soc_dai_link skylake_dais[] = { · 10 unmodified lines
469 },540 },
470 {541 {
471 .name = "dmic01",542 .name = "dmic01",
472 .be_id = 1,543 .be_id = 2,
473 .cpu_dai_name = "DMIC01 Pin",544 .cpu_dai_name = "DMIC01 Pin",
474 .codec_name = "dmic-codec",545 .codec_name = "dmic-codec",
475 .codec_dai_name = "dmic-hifi",546 .codec_dai_name = "dmic-hifi",
@@ -480,13 +551,36 @@ static struct snd_soc_dai_link skylake_dais[] = { · 4 unmodified lines
480 .no_pcm = 1,551 .no_pcm = 1,
481 },552 },
482 {553 {
483 .name = "iDisp",554 .name = "iDisp1",
484 .be_id = 3,555 .be_id = 3,
485 .cpu_dai_name = "iDisp Pin",556 .cpu_dai_name = "iDisp1 Pin",
486 .codec_name = "ehdaudio0D2",557 .codec_name = "ehdaudio0D2",
487 .codec_dai_name = "intel-hdmi-hifi1",558 .codec_dai_name = "intel-hdmi-hifi1",
488 .platform_name = "0000:00:1f.3",559 .platform_name = "0000:00:1f.3",
489 .dpcm_playback = 1,560 .dpcm_playback = 1,
561 .init = skylake_hdmi1_init,
562 .no_pcm = 1,
563 },
564 {
565 .name = "iDisp2",
566 .be_id = 4,
567 .cpu_dai_name = "iDisp2 Pin",
568 .codec_name = "ehdaudio0D2",
569 .codec_dai_name = "intel-hdmi-hifi2",
570 .platform_name = "0000:00:1f.3",
571 .init = skylake_hdmi2_init,
572 .dpcm_playback = 1,
573 .no_pcm = 1,
574 },
575 {
576 .name = "iDisp3",
577 .be_id = 5,
578 .cpu_dai_name = "iDisp3 Pin",
579 .codec_name = "ehdaudio0D2",
580 .codec_dai_name = "intel-hdmi-hifi3",
581 .platform_name = "0000:00:1f.3",
582 .init = skylake_hdmi3_init,
583 .dpcm_playback = 1,
490 .no_pcm = 1,584 .no_pcm = 1,
491 },585 },
492};586};
sound/soc/intel/boards/skl_rt286.c+104−9
@@ -26,8 +26,20 @@ · 25 unmodified lines
26#include <sound/jack.h>26#include <sound/jack.h>
27#include <sound/pcm_params.h>27#include <sound/pcm_params.h>
28#include "../../codecs/rt286.h"28#include "../../codecs/rt286.h"
29#include "../../codecs/hdac_hdmi.h"
29 30
30static struct snd_soc_jack skylake_headset;31static struct snd_soc_jack skylake_headset;
32
33enum {
34 SKL_DPCM_AUDIO_PB = 0,
35 SKL_DPCM_AUDIO_CP,
36 SKL_DPCM_AUDIO_REF_CP,
37 SKL_DPCM_AUDIO_DMIC_CP,
38 SKL_DPCM_AUDIO_HDMI1_PB,
39 SKL_DPCM_AUDIO_HDMI2_PB,
40 SKL_DPCM_AUDIO_HDMI3_PB,
41};
42
31/* Headset jack detection DAPM pins */43/* Headset jack detection DAPM pins */
32static struct snd_soc_jack_pin skylake_headset_pins[] = {44static struct snd_soc_jack_pin skylake_headset_pins[] = {
33 {45 {
@@ -52,7 +64,9 @@ static const struct snd_soc_dapm_widget skylake_widgets[] = { · 18 unmodified lines
52 SND_SOC_DAPM_MIC("Mic Jack", NULL),64 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL),65 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),66 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55 SND_SOC_DAPM_SINK("WoV Sink"),67 SND_SOC_DAPM_SPK("HDMI1", NULL),
68 SND_SOC_DAPM_SPK("HDMI2", NULL),
69 SND_SOC_DAPM_SPK("HDMI3", NULL),
56};70};
57 71
58static const struct snd_soc_dapm_route skylake_rt286_map[] = {72static const struct snd_soc_dapm_route skylake_rt286_map[] = {
@@ -70,7 +84,9 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = { · 11 unmodified lines
70 {"DMIC1 Pin", NULL, "DMIC2"},84 {"DMIC1 Pin", NULL, "DMIC2"},
71 {"DMic", NULL, "SoC DMIC"},85 {"DMic", NULL, "SoC DMIC"},
72 86
73 {"WoV Sink", NULL, "hwd_in sink"},87 {"HDMI1", NULL, "hif5 Output"},
88 {"HDMI2", NULL, "hif6 Output"},
89 {"HDMI3", NULL, "hif7 Output"},
74 90
75 /* CODEC BE connections */91 /* CODEC BE connections */
76 { "AIF1 Playback", NULL, "ssp0 Tx"},92 { "AIF1 Playback", NULL, "ssp0 Tx"},
@@ -84,8 +100,12 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = { · 7 unmodified lines
84 { "dmic01_hifi", NULL, "DMIC01 Rx" },100 { "dmic01_hifi", NULL, "DMIC01 Rx" },
85 { "DMIC01 Rx", NULL, "DMIC AIF" },101 { "DMIC01 Rx", NULL, "DMIC AIF" },
86 102
87 { "hif1", NULL, "iDisp Tx"},103 { "hifi3", NULL, "iDisp3 Tx"},
88 { "iDisp Tx", NULL, "iDisp_out"},104 { "iDisp3 Tx", NULL, "iDisp3_out"},
105 { "hifi2", NULL, "iDisp2 Tx"},
106 { "iDisp2 Tx", NULL, "iDisp2_out"},
107 { "hifi1", NULL, "iDisp1 Tx"},
108 { "iDisp1 Tx", NULL, "iDisp1_out"},
89 109
90};110};
91 111
@@ -116,11 +136,17 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) · 24 unmodified lines
116 rt286_mic_detect(codec, &skylake_headset);136 rt286_mic_detect(codec, &skylake_headset);
117 137
118 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");138 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC");
119 snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "WoV Sink");
120 139
121 return 0;140 return 0;
122}141}
123 142
143static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd)
144{
145 struct snd_soc_dai *dai = rtd->codec_dai;
146
147 return hdac_hdmi_jack_init(dai, SKL_DPCM_AUDIO_HDMI1_PB + dai->id);
148}
149
124static unsigned int rates[] = {150static unsigned int rates[] = {
125 48000,151 48000,
126};152};
@@ -249,7 +275,7 @@ static struct snd_soc_ops skylake_dmic_ops = { · 122 unmodified lines
249/* skylake digital audio interface glue - connects codec <--> CPU */275/* skylake digital audio interface glue - connects codec <--> CPU */
250static struct snd_soc_dai_link skylake_rt286_dais[] = {276static struct snd_soc_dai_link skylake_rt286_dais[] = {
251 /* Front End DAI links */277 /* Front End DAI links */
252 {278 [SKL_DPCM_AUDIO_PB] = {
253 .name = "Skl Audio Port",279 .name = "Skl Audio Port",
254 .stream_name = "Audio",280 .stream_name = "Audio",
255 .cpu_dai_name = "System Pin",281 .cpu_dai_name = "System Pin",
@@ -266,7 +292,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 10 unmodified lines
266 .dpcm_playback = 1,292 .dpcm_playback = 1,
267 .ops = &skylake_rt286_fe_ops,293 .ops = &skylake_rt286_fe_ops,
268 },294 },
269 {295 [SKL_DPCM_AUDIO_CP] = {
270 .name = "Skl Audio Capture Port",296 .name = "Skl Audio Capture Port",
271 .stream_name = "Audio Record",297 .stream_name = "Audio Record",
272 .cpu_dai_name = "System Pin",298 .cpu_dai_name = "System Pin",
@@ -282,7 +308,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 9 unmodified lines
282 .dpcm_capture = 1,308 .dpcm_capture = 1,
283 .ops = &skylake_rt286_fe_ops,309 .ops = &skylake_rt286_fe_ops,
284 },310 },
285 {311 [SKL_DPCM_AUDIO_REF_CP] = {
286 .name = "Skl Audio Reference cap",312 .name = "Skl Audio Reference cap",
287 .stream_name = "refcap",313 .stream_name = "refcap",
288 .cpu_dai_name = "Reference Pin",314 .cpu_dai_name = "Reference Pin",
@@ -295,7 +321,7 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 6 unmodified lines
295 .nonatomic = 1,321 .nonatomic = 1,
296 .dynamic = 1,322 .dynamic = 1,
297 },323 },
298 {324 [SKL_DPCM_AUDIO_DMIC_CP] = {
299 .name = "Skl Audio DMIC cap",325 .name = "Skl Audio DMIC cap",
300 .stream_name = "dmiccap",326 .stream_name = "dmiccap",
301 .cpu_dai_name = "DMIC Pin",327 .cpu_dai_name = "DMIC Pin",
@@ -308,6 +334,42 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 6 unmodified lines
308 .dynamic = 1,334 .dynamic = 1,
309 .ops = &skylake_dmic_ops,335 .ops = &skylake_dmic_ops,
310 },336 },
337 [SKL_DPCM_AUDIO_HDMI1_PB] = {
338 .name = "Skl HDMI Port1",
339 .stream_name = "Hdmi1",
340 .cpu_dai_name = "HDMI1 Pin",
341 .codec_name = "snd-soc-dummy",
342 .codec_dai_name = "snd-soc-dummy-dai",
343 .platform_name = "0000:00:1f.3",
344 .dpcm_playback = 1,
345 .init = NULL,
346 .nonatomic = 1,
347 .dynamic = 1,
348 },
349 [SKL_DPCM_AUDIO_HDMI2_PB] = {
350 .name = "Skl HDMI Port2",
351 .stream_name = "Hdmi2",
352 .cpu_dai_name = "HDMI2 Pin",
353 .codec_name = "snd-soc-dummy",
354 .codec_dai_name = "snd-soc-dummy-dai",
355 .platform_name = "0000:00:1f.3",
356 .dpcm_playback = 1,
357 .init = NULL,
358 .nonatomic = 1,
359 .dynamic = 1,
360 },
361 [SKL_DPCM_AUDIO_HDMI3_PB] = {
362 .name = "Skl HDMI Port3",
363 .stream_name = "Hdmi3",
364 .cpu_dai_name = "HDMI3 Pin",
365 .codec_name = "snd-soc-dummy",
366 .codec_dai_name = "snd-soc-dummy-dai",
367 .platform_name = "0000:00:1f.3",
368 .dpcm_playback = 1,
369 .init = NULL,
370 .nonatomic = 1,
371 .dynamic = 1,
372 },
311 373
312 /* Back End DAI links */374 /* Back End DAI links */
313 {375 {
@@ -341,6 +403,39 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = { · 27 unmodified lines
341 .dpcm_capture = 1,403 .dpcm_capture = 1,
342 .no_pcm = 1,404 .no_pcm = 1,
343 },405 },
406 {
407 .name = "iDisp1",
408 .be_id = 2,
409 .cpu_dai_name = "iDisp1 Pin",
410 .codec_name = "ehdaudio0D2",
411 .codec_dai_name = "intel-hdmi-hifi1",
412 .platform_name = "0000:00:1f.3",
413 .init = skylake_hdmi_init,
414 .dpcm_playback = 1,
415 .no_pcm = 1,
416 },
417 {
418 .name = "iDisp2",
419 .be_id = 3,
420 .cpu_dai_name = "iDisp2 Pin",
421 .codec_name = "ehdaudio0D2",
422 .codec_dai_name = "intel-hdmi-hifi2",
423 .platform_name = "0000:00:1f.3",
424 .init = skylake_hdmi_init,
425 .dpcm_playback = 1,
426 .no_pcm = 1,
427 },
428 {
429 .name = "iDisp3",
430 .be_id = 4,
431 .cpu_dai_name = "iDisp3 Pin",
432 .codec_name = "ehdaudio0D2",
433 .codec_dai_name = "intel-hdmi-hifi3",
434 .platform_name = "0000:00:1f.3",
435 .init = skylake_hdmi_init,
436 .dpcm_playback = 1,
437 .no_pcm = 1,
438 },
344};439};
345 440
346/* skylake audio machine driver for SPT + RT286S */441/* skylake audio machine driver for SPT + RT286S */
sound/soc/intel/common/sst-acpi.h+3−0
@@ -14,6 +14,9 @@ · 13 unmodified lines
14 14
15#include <linux/acpi.h>15#include <linux/acpi.h>
16 16
17/* translation fron HID to I2C name, needed for DAI codec_name */
18const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]);
19
17/* acpi match */20/* acpi match */
18struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines);21struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines);
19 22
sound/soc/intel/common/sst-dsp-priv.h+1−0
@@ -317,6 +317,7 @@ struct sst_dsp { · 316 unmodified lines
317 struct skl_cl_dev cl_dev;317 struct skl_cl_dev cl_dev;
318 u32 intr_status;318 u32 intr_status;
319 const struct firmware *fw;319 const struct firmware *fw;
320 struct snd_dma_buffer dmab;
320};321};
321 322
322/* Size optimised DRAM/IRAM memcpy */323/* Size optimised DRAM/IRAM memcpy */
sound/soc/intel/common/sst-match-acpi.c+40−5
@@ -13,17 +13,53 @@ · 12 unmodified lines
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.14 * more details.
15 */15 */
16#include <linux/acpi.h>
17#include <linux/device.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20 16
21#include "sst-acpi.h"17#include "sst-acpi.h"
22 18
19static acpi_status sst_acpi_find_name(acpi_handle handle, u32 level,
20 void *context, void **ret)
21{
22 struct acpi_device *adev;
23 const char *name = NULL;
24
25 if (acpi_bus_get_device(handle, &adev))
26 return AE_OK;
27
28 if (adev->status.present && adev->status.functional) {
29 name = acpi_dev_name(adev);
30 *(const char **)ret = name;
31 return AE_CTRL_TERMINATE;
32 }
33
34 return AE_OK;
35}
36
37const char *sst_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN])
38{
39 const char *name = NULL;
40 acpi_status status;
41
42 status = acpi_get_devices(hid, sst_acpi_find_name, NULL,
43 (void **)&name);
44
45 if (ACPI_FAILURE(status) || name[0] == '\0')
46 return NULL;
47
48 return name;
49}
50EXPORT_SYMBOL_GPL(sst_acpi_find_name_from_hid);
51
23static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,52static acpi_status sst_acpi_mach_match(acpi_handle handle, u32 level,
24 void *context, void **ret)53 void *context, void **ret)
25{54{
55 unsigned long long sta;
56 acpi_status status;
57
26 *(bool *)context = true;58 *(bool *)context = true;
59 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
60 if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
61 *(bool *)context = false;
62
27 return AE_OK;63 return AE_OK;
28}64}
29 65
@@ -37,7 +73,6 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines) · 7 unmodified lines
37 sst_acpi_mach_match,73 sst_acpi_mach_match,
38 &found, NULL)) && found)74 &found, NULL)) && found)
39 return mach;75 return mach;
40
41 return NULL;76 return NULL;
42}77}
43EXPORT_SYMBOL_GPL(sst_acpi_find_machine);78EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
sound/soc/intel/skylake/skl-messages.c+109−15
@@ -72,17 +72,47 @@ static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) · 71 unmodified lines
72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
73}73}
74 74
75static struct skl_dsp_loader_ops skl_get_loader_ops(void)
76{
77 struct skl_dsp_loader_ops loader_ops;
78
79 memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));
80
81 loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
82 loader_ops.free_dma_buf = skl_free_dma_buf;
83
84 return loader_ops;
85};
86
87static const struct skl_dsp_ops dsp_ops[] = {
88 {
89 .id = 0x9d70,
90 .loader_ops = skl_get_loader_ops,
91 .init = skl_sst_dsp_init,
92 .cleanup = skl_sst_dsp_cleanup
93 },
94};
95
96static int skl_get_dsp_ops(int pci_id)
97{
98 int i;
99
100 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
101 if (dsp_ops[i].id == pci_id)
102 return i;
103 }
104
105 return -EINVAL;
106}
107
75int skl_init_dsp(struct skl *skl)108int skl_init_dsp(struct skl *skl)
76{109{
77 void __iomem *mmio_base;110 void __iomem *mmio_base;
78 struct hdac_ext_bus *ebus = &skl->ebus;111 struct hdac_ext_bus *ebus = &skl->ebus;
79 struct hdac_bus *bus = ebus_to_hbus(ebus);112 struct hdac_bus *bus = ebus_to_hbus(ebus);
80 int irq = bus->irq;
81 struct skl_dsp_loader_ops loader_ops;113 struct skl_dsp_loader_ops loader_ops;
82 int ret;114 int irq = bus->irq;
83 115 int ret, index;
84 loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
85 loader_ops.free_dma_buf = skl_free_dma_buf;
86 116
87 /* enable ppcap interrupt */117 /* enable ppcap interrupt */
88 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);118 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
@@ -95,8 +125,14 @@ int skl_init_dsp(struct skl *skl) · 6 unmodified lines
95 return -ENXIO;125 return -ENXIO;
96 }126 }
97 127
98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,128 index = skl_get_dsp_ops(skl->pci->device);
129 if (index < 0)
130 return -EINVAL;
131
132 loader_ops = dsp_ops[index].loader_ops();
133 ret = dsp_ops[index].init(bus->dev, mmio_base, irq,
99 skl->fw_name, loader_ops, &skl->skl_sst);134 skl->fw_name, loader_ops, &skl->skl_sst);
135
100 if (ret < 0)136 if (ret < 0)
101 return ret;137 return ret;
102 138
@@ -106,18 +142,26 @@ int skl_init_dsp(struct skl *skl) · 3 unmodified lines
106 return ret;142 return ret;
107}143}
108 144
109void skl_free_dsp(struct skl *skl)145int skl_free_dsp(struct skl *skl)
110{146{
111 struct hdac_ext_bus *ebus = &skl->ebus;147 struct hdac_ext_bus *ebus = &skl->ebus;
112 struct hdac_bus *bus = ebus_to_hbus(ebus);148 struct hdac_bus *bus = ebus_to_hbus(ebus);
113 struct skl_sst *ctx = skl->skl_sst;149 struct skl_sst *ctx = skl->skl_sst;
150 int index;
114 151
115 /* disable ppcap interrupt */152 /* disable ppcap interrupt */
116 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);153 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
117 154
118 skl_sst_dsp_cleanup(bus->dev, ctx);155 index = skl_get_dsp_ops(skl->pci->device);
156 if (index < 0)
157 return -EIO;
158
159 dsp_ops[index].cleanup(bus->dev, ctx);
160
119 if (ctx->dsp->addr.lpe)161 if (ctx->dsp->addr.lpe)
120 iounmap(ctx->dsp->addr.lpe);162 iounmap(ctx->dsp->addr.lpe);
163
164 return 0;
121}165}
122 166
123int skl_suspend_dsp(struct skl *skl)167int skl_suspend_dsp(struct skl *skl)
@@ -238,9 +282,8 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig, · 114 unmodified lines
238 * Calculate the gatewat settings required for copier module, type of282 * Calculate the gatewat settings required for copier module, type of
239 * gateway and index of gateway to use283 * gateway and index of gateway to use
240 */284 */
241static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,285static u32 skl_get_node_id(struct skl_sst *ctx,
242 struct skl_module_cfg *mconfig,286 struct skl_module_cfg *mconfig)
243 struct skl_cpr_cfg *cpr_mconfig)
244{287{
245 union skl_connector_node_id node_id = {0};288 union skl_connector_node_id node_id = {0};
246 union skl_ssp_dma_node ssp_node = {0};289 union skl_ssp_dma_node ssp_node = {0};
@@ -289,13 +332,24 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, · 42 unmodified lines
289 break;332 break;
290 333
291 default:334 default:
292 cpr_mconfig->gtw_cfg.node_id = SKL_NON_GATEWAY_CPR_NODE_ID;335 node_id.val = 0xFFFFFFFF;
336 break;
337 }
338
339 return node_id.val;
340}
341
342static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
343 struct skl_module_cfg *mconfig,
344 struct skl_cpr_cfg *cpr_mconfig)
345{
346 cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig);
347
348 if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
293 cpr_mconfig->cpr_feature_mask = 0;349 cpr_mconfig->cpr_feature_mask = 0;
294 return;350 return;
295 }351 }
296 352
297 cpr_mconfig->gtw_cfg.node_id = node_id.val;
298
299 if (SKL_CONN_SOURCE == mconfig->hw_conn_type)353 if (SKL_CONN_SOURCE == mconfig->hw_conn_type)
300 cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs;354 cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs;
301 else355 else
@@ -307,6 +361,46 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, · 5 unmodified lines
307 skl_copy_copier_caps(mconfig, cpr_mconfig);361 skl_copy_copier_caps(mconfig, cpr_mconfig);
308}362}
309 363
364#define DMA_CONTROL_ID 5
365
366int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
367{
368 struct skl_dma_control *dma_ctrl;
369 struct skl_i2s_config_blob config_blob;
370 struct skl_ipc_large_config_msg msg = {0};
371 int err = 0;
372
373
374 /*
375 * if blob size is same as capablity size, then no dma control
376 * present so return
377 */
378 if (mconfig->formats_config.caps_size == sizeof(config_blob))
379 return 0;
380
381 msg.large_param_id = DMA_CONTROL_ID;
382 msg.param_data_size = sizeof(struct skl_dma_control) +
383 mconfig->formats_config.caps_size;
384
385 dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
386 if (dma_ctrl == NULL)
387 return -ENOMEM;
388
389 dma_ctrl->node_id = skl_get_node_id(ctx, mconfig);
390
391 /* size in dwords */
392 dma_ctrl->config_length = sizeof(config_blob) / 4;
393
394 memcpy(dma_ctrl->config_data, mconfig->formats_config.caps,
395 mconfig->formats_config.caps_size);
396
397 err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
398
399 kfree(dma_ctrl);
400
401 return err;
402}
403
310static void skl_setup_out_format(struct skl_sst *ctx,404static void skl_setup_out_format(struct skl_sst *ctx,
311 struct skl_module_cfg *mconfig,405 struct skl_module_cfg *mconfig,
312 struct skl_audio_data_format *out_fmt)406 struct skl_audio_data_format *out_fmt)
sound/soc/intel/skylake/skl-nhlt.c+34−0
@@ -145,3 +145,37 @@ struct nhlt_specific_cfg · 144 unmodified lines
145 145
146 return NULL;146 return NULL;
147}147}
148
149static void skl_nhlt_trim_space(struct skl *skl)
150{
151 char *s = skl->tplg_name;
152 int cnt;
153 int i;
154
155 cnt = 0;
156 for (i = 0; s[i]; i++) {
157 if (!isspace(s[i]))
158 s[cnt++] = s[i];
159 }
160
161 s[cnt] = '\0';
162}
163
164int skl_nhlt_update_topology_bin(struct skl *skl)
165{
166 struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt;
167 struct hdac_bus *bus = ebus_to_hbus(&skl->ebus);
168 struct device *dev = bus->dev;
169
170 dev_dbg(dev, "oem_id %.6s, oem_table_id %8s oem_revision %d\n",
171 nhlt->header.oem_id, nhlt->header.oem_table_id,
172 nhlt->header.oem_revision);
173
174 snprintf(skl->tplg_name, sizeof(skl->tplg_name), "%x-%.6s-%.8s-%d%s",
175 skl->pci_id, nhlt->header.oem_id, nhlt->header.oem_table_id,
176 nhlt->header.oem_revision, "-tplg.bin");
177
178 skl_nhlt_trim_space(skl);
179
180 return 0;
181}
sound/soc/intel/skylake/skl-pcm.c+98−8
@@ -206,6 +206,23 @@ static int skl_get_format(struct snd_pcm_substream *substream, · 205 unmodified lines
206 return format_val;206 return format_val;
207}207}
208 208
209static int skl_be_prepare(struct snd_pcm_substream *substream,
210 struct snd_soc_dai *dai)
211{
212 struct skl *skl = get_skl_ctx(dai->dev);
213 struct skl_sst *ctx = skl->skl_sst;
214 struct skl_module_cfg *mconfig;
215
216 if ((dai->playback_active > 1) || (dai->capture_active > 1))
217 return 0;
218
219 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream);
220 if (mconfig == NULL)
221 return -EINVAL;
222
223 return skl_dsp_set_dma_control(ctx, mconfig);
224}
225
209static int skl_pcm_prepare(struct snd_pcm_substream *substream,226static int skl_pcm_prepare(struct snd_pcm_substream *substream,
210 struct snd_soc_dai *dai)227 struct snd_soc_dai *dai)
211{228{
@@ -458,7 +475,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, · 246 unmodified lines
458 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);475 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
459 struct hdac_ext_stream *link_dev;476 struct hdac_ext_stream *link_dev;
460 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);477 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
461 struct skl_dma_params *dma_params;478 struct hdac_ext_dma_params *dma_params;
462 struct snd_soc_dai *codec_dai = rtd->codec_dai;479 struct snd_soc_dai *codec_dai = rtd->codec_dai;
463 struct skl_pipe_params p_params = {0};480 struct skl_pipe_params p_params = {0};
464 481
@@ -470,11 +487,9 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, · 5 unmodified lines
470 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);487 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
471 488
472 /* set the stream tag in the codec dai dma params */489 /* set the stream tag in the codec dai dma params */
473 dma_params = (struct skl_dma_params *)490 dma_params = snd_soc_dai_get_dma_data(codec_dai, substream);
474 snd_soc_dai_get_dma_data(codec_dai, substream);
475 if (dma_params)491 if (dma_params)
476 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag;492 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag;
477 snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params);
478 493
479 p_params.s_fmt = snd_pcm_format_width(params_format(params));494 p_params.s_fmt = snd_pcm_format_width(params_format(params));
480 p_params.ch = params_channels(params);495 p_params.ch = params_channels(params);
@@ -588,6 +603,7 @@ static struct snd_soc_dai_ops skl_dmic_dai_ops = { · 107 unmodified lines
588 603
589static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {604static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
590 .hw_params = skl_be_hw_params,605 .hw_params = skl_be_hw_params,
606 .prepare = skl_be_prepare,
591};607};
592 608
593static struct snd_soc_dai_ops skl_link_dai_ops = {609static struct snd_soc_dai_ops skl_link_dai_ops = {
@@ -660,6 +676,51 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 66 unmodified lines
660 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,676 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
661 },677 },
662},678},
679{
680 .name = "HDMI1 Pin",
681 .ops = &skl_pcm_dai_ops,
682 .playback = {
683 .stream_name = "HDMI1 Playback",
684 .channels_min = HDA_STEREO,
685 .channels_max = HDA_STEREO,
686 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
687 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
688 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
689 SNDRV_PCM_RATE_192000,
690 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
691 SNDRV_PCM_FMTBIT_S32_LE,
692 },
693},
694{
695 .name = "HDMI2 Pin",
696 .ops = &skl_pcm_dai_ops,
697 .playback = {
698 .stream_name = "HDMI2 Playback",
699 .channels_min = HDA_STEREO,
700 .channels_max = HDA_STEREO,
701 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
702 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
703 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
704 SNDRV_PCM_RATE_192000,
705 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
706 SNDRV_PCM_FMTBIT_S32_LE,
707 },
708},
709{
710 .name = "HDMI3 Pin",
711 .ops = &skl_pcm_dai_ops,
712 .playback = {
713 .stream_name = "HDMI3 Playback",
714 .channels_min = HDA_STEREO,
715 .channels_max = HDA_STEREO,
716 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
717 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
718 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
719 SNDRV_PCM_RATE_192000,
720 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
721 SNDRV_PCM_FMTBIT_S32_LE,
722 },
723},
663 724
664/* BE CPU Dais */725/* BE CPU Dais */
665{726{
@@ -699,14 +760,41 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { · 33 unmodified lines
699 },760 },
700},761},
701{762{
702 .name = "iDisp Pin",763 .name = "iDisp1 Pin",
703 .ops = &skl_link_dai_ops,764 .ops = &skl_link_dai_ops,
704 .playback = {765 .playback = {
705 .stream_name = "iDisp Tx",766 .stream_name = "iDisp1 Tx",
706 .channels_min = HDA_STEREO,767 .channels_min = HDA_STEREO,
707 .channels_max = HDA_STEREO,768 .channels_max = HDA_STEREO,
708 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,769 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
709 .formats = SNDRV_PCM_FMTBIT_S16_LE,770 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
771 SNDRV_PCM_FMTBIT_S24_LE,
772 },
773},
774{
775 .name = "iDisp2 Pin",
776 .ops = &skl_link_dai_ops,
777 .playback = {
778 .stream_name = "iDisp2 Tx",
779 .channels_min = HDA_STEREO,
780 .channels_max = HDA_STEREO,
781 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
782 SNDRV_PCM_RATE_48000,
783 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
784 SNDRV_PCM_FMTBIT_S24_LE,
785 },
786},
787{
788 .name = "iDisp3 Pin",
789 .ops = &skl_link_dai_ops,
790 .playback = {
791 .stream_name = "iDisp3 Tx",
792 .channels_min = HDA_STEREO,
793 .channels_max = HDA_STEREO,
794 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|
795 SNDRV_PCM_RATE_48000,
796 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE |
797 SNDRV_PCM_FMTBIT_S24_LE,
710 },798 },
711},799},
712{800{
@@ -863,7 +951,9 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus, · 150 unmodified lines
863 else951 else
864 delay += hstream->bufsize;952 delay += hstream->bufsize;
865 }953 }
866 delay = (hstream->bufsize == delay) ? 0 : delay;954
955 if (hstream->bufsize == delay)
956 delay = 0;
867 957
868 if (delay >= hstream->period_bytes) {958 if (delay >= hstream->period_bytes) {
869 dev_info(bus->dev,959 dev_info(bus->dev,
sound/soc/intel/skylake/skl-sst-dsp.c+7−7
@@ -34,7 +34,7 @@ void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state) · 33 unmodified lines
34 mutex_unlock(&ctx->mutex);34 mutex_unlock(&ctx->mutex);
35}35}
36 36
37static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx)37static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx)
38{38{
39 int ret;39 int ret;
40 40
@@ -60,7 +60,7 @@ static int skl_dsp_core_set_reset_state(struct sst_dsp *ctx) · 19 unmodified lines
60 return ret;60 return ret;
61}61}
62 62
63static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)63static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx)
64{64{
65 int ret;65 int ret;
66 66
@@ -87,7 +87,7 @@ static int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx) · 20 unmodified lines
87 return ret;87 return ret;
88}88}
89 89
90static bool is_skl_dsp_core_enable(struct sst_dsp *ctx)90static bool is_skl_dsp_core_enable(struct sst_dsp *ctx)
91{91{
92 int val;92 int val;
93 bool is_enable;93 bool is_enable;
@@ -140,7 +140,7 @@ static int skl_dsp_start_core(struct sst_dsp *ctx) · 46 unmodified lines
140 return ret;140 return ret;
141}141}
142 142
143static int skl_dsp_core_power_up(struct sst_dsp *ctx)143static int skl_dsp_core_power_up(struct sst_dsp *ctx)
144{144{
145 int ret;145 int ret;
146 146
@@ -166,7 +166,7 @@ static int skl_dsp_core_power_up(struct sst_dsp *ctx) · 19 unmodified lines
166 return ret;166 return ret;
167}167}
168 168
169static int skl_dsp_core_power_down(struct sst_dsp *ctx)169static int skl_dsp_core_power_down(struct sst_dsp *ctx)
170{170{
171 /* update bits */171 /* update bits */
172 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,172 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_ADSPCS,
@@ -181,7 +181,7 @@ static int skl_dsp_core_power_down(struct sst_dsp *ctx) · 8 unmodified lines
181 "Power down");181 "Power down");
182}182}
183 183
184static int skl_dsp_enable_core(struct sst_dsp *ctx)184int skl_dsp_enable_core(struct sst_dsp *ctx)
185{185{
186 int ret;186 int ret;
187 187
@@ -195,7 +195,7 @@ static int skl_dsp_enable_core(struct sst_dsp *ctx) · 7 unmodified lines
195 return skl_dsp_start_core(ctx);195 return skl_dsp_start_core(ctx);
196}196}
197 197
198int skl_dsp_disable_core(struct sst_dsp *ctx)198int skl_dsp_disable_core(struct sst_dsp *ctx)
199{199{
200 int ret;200 int ret;
201 201
sound/soc/intel/skylake/skl-sst-dsp.h+6−1
@@ -53,6 +53,10 @@ struct sst_dsp_device; · 52 unmodified lines
53/* HIPCT */53/* HIPCT */
54#define SKL_ADSP_REG_HIPCT_BUSY BIT(31)54#define SKL_ADSP_REG_HIPCT_BUSY BIT(31)
55 55
56/* FW base IDs */
57#define SKL_INSTANCE_ID 0
58#define SKL_BASE_FW_MODULE_ID 0
59
56/* Intel HD Audio SRAM Window 1 */60/* Intel HD Audio SRAM Window 1 */
57#define SKL_ADSP_SRAM1_BASE 0xA00061#define SKL_ADSP_SRAM1_BASE 0xA000
58 62
@@ -144,7 +148,8 @@ int skl_cldma_prepare(struct sst_dsp *ctx); · 85 unmodified lines
144void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);148void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
145struct sst_dsp *skl_dsp_ctx_init(struct device *dev,149struct sst_dsp *skl_dsp_ctx_init(struct device *dev,
146 struct sst_dsp_device *sst_dev, int irq);150 struct sst_dsp_device *sst_dev, int irq);
147int skl_dsp_disable_core(struct sst_dsp *ctx);151int skl_dsp_enable_core(struct sst_dsp *ctx);
152int skl_dsp_disable_core(struct sst_dsp *ctx);
148bool is_skl_dsp_running(struct sst_dsp *ctx);153bool is_skl_dsp_running(struct sst_dsp *ctx);
149irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);154irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
150int skl_dsp_wake(struct sst_dsp *ctx);155int skl_dsp_wake(struct sst_dsp *ctx);
sound/soc/intel/skylake/skl-sst.c+0−3
@@ -35,9 +35,6 @@ · 34 unmodified lines
35#define SKL_ADSP_FW_STATUS SKL_ADSP_SRAM0_BASE35#define SKL_ADSP_FW_STATUS SKL_ADSP_SRAM0_BASE
36#define SKL_ADSP_ERROR_CODE (SKL_ADSP_FW_STATUS + 0x4)36#define SKL_ADSP_ERROR_CODE (SKL_ADSP_FW_STATUS + 0x4)
37 37
38#define SKL_INSTANCE_ID 0
39#define SKL_BASE_FW_MODULE_ID 0
40
41#define SKL_NUM_MODULES 138#define SKL_NUM_MODULES 1
42 39
43static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)40static bool skl_check_fw_status(struct sst_dsp *ctx, u32 status)
sound/soc/intel/skylake/skl-topology.c+203−5
@@ -260,6 +260,65 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, · 259 unmodified lines
260 multiplier;260 multiplier;
261}261}
262 262
263static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
264 struct skl_sst *ctx)
265{
266 struct skl_module_cfg *m_cfg = w->priv;
267 int link_type, dir;
268 u32 ch, s_freq, s_fmt;
269 struct nhlt_specific_cfg *cfg;
270 struct skl *skl = get_skl_ctx(ctx->dev);
271
272 /* check if we already have blob */
273 if (m_cfg->formats_config.caps_size > 0)
274 return 0;
275
276 dev_dbg(ctx->dev, "Applying default cfg blob\n");
277 switch (m_cfg->dev_type) {
278 case SKL_DEVICE_DMIC:
279 link_type = NHLT_LINK_DMIC;
280 dir = SNDRV_PCM_STREAM_CAPTURE;
281 s_freq = m_cfg->in_fmt[0].s_freq;
282 s_fmt = m_cfg->in_fmt[0].bit_depth;
283 ch = m_cfg->in_fmt[0].channels;
284 break;
285
286 case SKL_DEVICE_I2S:
287 link_type = NHLT_LINK_SSP;
288 if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) {
289 dir = SNDRV_PCM_STREAM_PLAYBACK;
290 s_freq = m_cfg->out_fmt[0].s_freq;
291 s_fmt = m_cfg->out_fmt[0].bit_depth;
292 ch = m_cfg->out_fmt[0].channels;
293 } else {
294 dir = SNDRV_PCM_STREAM_CAPTURE;
295 s_freq = m_cfg->in_fmt[0].s_freq;
296 s_fmt = m_cfg->in_fmt[0].bit_depth;
297 ch = m_cfg->in_fmt[0].channels;
298 }
299 break;
300
301 default:
302 return -EINVAL;
303 }
304
305 /* update the blob based on virtual bus_id and default params */
306 cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type,
307 s_fmt, ch, s_freq, dir);
308 if (cfg) {
309 m_cfg->formats_config.caps_size = cfg->size;
310 m_cfg->formats_config.caps = (u32 *) &cfg->caps;
311 } else {
312 dev_err(ctx->dev, "Blob NULL for id %x type %d dirn %d\n",
313 m_cfg->vbus_id, link_type, dir);
314 dev_err(ctx->dev, "PCM: ch %d, freq %d, fmt %d\n",
315 ch, s_freq, s_fmt);
316 return -EIO;
317 }
318
319 return 0;
320}
321
263static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,322static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
264 struct skl_sst *ctx)323 struct skl_sst *ctx)
265{324{
@@ -433,6 +492,9 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) · 167 unmodified lines
433 return ret;492 return ret;
434 }493 }
435 494
495 /* update blob if blob is null for be with default value */
496 skl_tplg_update_be_blob(w, ctx);
497
436 /*498 /*
437 * apply fix/conversion to module params based on499 * apply fix/conversion to module params based on
438 * FE/BE params500 * FE/BE params
@@ -545,6 +607,66 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, · 106 unmodified lines
545 return 0;607 return 0;
546}608}
547 609
610/*
611 * Some modules require params to be set after the module is bound to
612 * all pins connected.
613 *
614 * The module provider initializes set_param flag for such modules and we
615 * send params after binding
616 */
617static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
618 struct skl_module_cfg *mcfg, struct skl_sst *ctx)
619{
620 int i, ret;
621 struct skl_module_cfg *mconfig = w->priv;
622 const struct snd_kcontrol_new *k;
623 struct soc_bytes_ext *sb;
624 struct skl_algo_data *bc;
625 struct skl_specific_cfg *sp_cfg;
626
627 /*
628 * check all out/in pins are in bind state.
629 * if so set the module param
630 */
631 for (i = 0; i < mcfg->max_out_queue; i++) {
632 if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE)
633 return 0;
634 }
635
636 for (i = 0; i < mcfg->max_in_queue; i++) {
637 if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE)
638 return 0;
639 }
640
641 if (mconfig->formats_config.caps_size > 0 &&
642 mconfig->formats_config.set_params == SKL_PARAM_BIND) {
643 sp_cfg = &mconfig->formats_config;
644 ret = skl_set_module_params(ctx, sp_cfg->caps,
645 sp_cfg->caps_size,
646 sp_cfg->param_id, mconfig);
647 if (ret < 0)
648 return ret;
649 }
650
651 for (i = 0; i < w->num_kcontrols; i++) {
652 k = &w->kcontrol_news[i];
653 if (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
654 sb = (void *) k->private_value;
655 bc = (struct skl_algo_data *)sb->dobj.private;
656
657 if (bc->set_params == SKL_PARAM_BIND) {
658 ret = skl_set_module_params(ctx,
659 (u32 *)bc->params, bc->max,
660 bc->param_id, mconfig);
661 if (ret < 0)
662 return ret;
663 }
664 }
665 }
666
667 return 0;
668}
669
548static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,670static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
549 struct skl *skl,671 struct skl *skl,
550 struct snd_soc_dapm_widget *src_w,672 struct snd_soc_dapm_widget *src_w,
@@ -579,11 +701,19 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, · 28 unmodified lines
579 sink = p->sink;701 sink = p->sink;
580 sink_mconfig = sink->priv;702 sink_mconfig = sink->priv;
581 703
704 if (src_mconfig->m_state == SKL_MODULE_UNINIT ||
705 sink_mconfig->m_state == SKL_MODULE_UNINIT)
706 continue;
707
582 /* Bind source to sink, mixin is always source */708 /* Bind source to sink, mixin is always source */
583 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);709 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
584 if (ret)710 if (ret)
585 return ret;711 return ret;
586 712
713 /* set module params after bind */
714 skl_tplg_set_module_bind_params(src_w, src_mconfig, ctx);
715 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
716
587 /* Start sinks pipe first */717 /* Start sinks pipe first */
588 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {718 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
589 if (sink_mconfig->pipe->conn_type !=719 if (sink_mconfig->pipe->conn_type !=
@@ -714,6 +844,10 @@ static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w, · 124 unmodified lines
714 if (ret)844 if (ret)
715 return ret;845 return ret;
716 846
847 /* set module params after bind */
848 skl_tplg_set_module_bind_params(source, src_mconfig, ctx);
849 skl_tplg_set_module_bind_params(sink, sink_mconfig, ctx);
850
717 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)851 if (sink_mconfig->pipe->conn_type != SKL_PIPE_CONN_TYPE_FE)
718 ret = skl_run_pipe(ctx, sink_mconfig->pipe);852 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
719 }853 }
@@ -1091,6 +1225,66 @@ skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream) · 371 unmodified lines
1091 return NULL;1225 return NULL;
1092}1226}
1093 1227
1228static struct skl_module_cfg *skl_get_mconfig_pb_cpr(
1229 struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
1230{
1231 struct snd_soc_dapm_path *p;
1232 struct skl_module_cfg *mconfig = NULL;
1233
1234 snd_soc_dapm_widget_for_each_source_path(w, p) {
1235 if (w->endpoints[SND_SOC_DAPM_DIR_OUT] > 0) {
1236 if (p->connect &&
1237 (p->sink->id == snd_soc_dapm_aif_out) &&
1238 p->source->priv) {
1239 mconfig = p->source->priv;
1240 return mconfig;
1241 }
1242 mconfig = skl_get_mconfig_pb_cpr(dai, p->source);
1243 if (mconfig)
1244 return mconfig;
1245 }
1246 }
1247 return mconfig;
1248}
1249
1250static struct skl_module_cfg *skl_get_mconfig_cap_cpr(
1251 struct snd_soc_dai *dai, struct snd_soc_dapm_widget *w)
1252{
1253 struct snd_soc_dapm_path *p;
1254 struct skl_module_cfg *mconfig = NULL;
1255
1256 snd_soc_dapm_widget_for_each_sink_path(w, p) {
1257 if (w->endpoints[SND_SOC_DAPM_DIR_IN] > 0) {
1258 if (p->connect &&
1259 (p->source->id == snd_soc_dapm_aif_in) &&
1260 p->sink->priv) {
1261 mconfig = p->sink->priv;
1262 return mconfig;
1263 }
1264 mconfig = skl_get_mconfig_cap_cpr(dai, p->sink);
1265 if (mconfig)
1266 return mconfig;
1267 }
1268 }
1269 return mconfig;
1270}
1271
1272struct skl_module_cfg *
1273skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai, int stream)
1274{
1275 struct snd_soc_dapm_widget *w;
1276 struct skl_module_cfg *mconfig;
1277
1278 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1279 w = dai->playback_widget;
1280 mconfig = skl_get_mconfig_pb_cpr(dai, w);
1281 } else {
1282 w = dai->capture_widget;
1283 mconfig = skl_get_mconfig_cap_cpr(dai, w);
1284 }
1285 return mconfig;
1286}
1287
1094static u8 skl_tplg_be_link_type(int dev_type)1288static u8 skl_tplg_be_link_type(int dev_type)
1095{1289{
1096 int ret;1290 int ret;
@@ -1464,8 +1658,7 @@ static int skl_init_algo_data(struct device *dev, struct soc_bytes_ext *be, · 367 unmodified lines
1464 if (!ac->params)1658 if (!ac->params)
1465 return -ENOMEM;1659 return -ENOMEM;
1466 1660
1467 if (dfw_ac->params)1661 memcpy(ac->params, dfw_ac->params, ac->max);
1468 memcpy(ac->params, dfw_ac->params, ac->max);
1469 }1662 }
1470 1663
1471 be->dobj.private = ac;1664 be->dobj.private = ac;
@@ -1523,11 +1716,16 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus) · 51 unmodified lines
1523 struct hdac_bus *bus = ebus_to_hbus(ebus);1716 struct hdac_bus *bus = ebus_to_hbus(ebus);
1524 struct skl *skl = ebus_to_skl(ebus);1717 struct skl *skl = ebus_to_skl(ebus);
1525 1718
1526 ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);1719 ret = request_firmware(&fw, skl->tplg_name, bus->dev);
1527 if (ret < 0) {1720 if (ret < 0) {
1528 dev_err(bus->dev, "tplg fw %s load failed with %d\n",1721 dev_err(bus->dev, "tplg fw %s load failed with %d\n",
1529 "dfw_sst.bin", ret);1722 skl->tplg_name, ret);
1530 return ret;1723 ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
1724 if (ret < 0) {
1725 dev_err(bus->dev, "Fallback tplg fw %s load failed with %d\n",
1726 "dfw_sst.bin", ret);
1727 return ret;
1728 }
1531 }1729 }
1532 1730
1533 /*1731 /*
sound/soc/intel/skylake/skl-topology.h+27−0
@@ -113,6 +113,29 @@ struct skl_cpr_gtw_cfg { · 112 unmodified lines
113 u32 config_data[1];113 u32 config_data[1];
114} __packed;114} __packed;
115 115
116struct skl_i2s_config_blob {
117 u32 gateway_attrib;
118 u32 tdm_ts_group[8];
119 u32 ssc0;
120 u32 ssc1;
121 u32 sscto;
122 u32 sspsp;
123 u32 sstsa;
124 u32 ssrsa;
125 u32 ssc2;
126 u32 sspsp2;
127 u32 ssc3;
128 u32 ssioc;
129 u32 mdivc;
130 u32 mdivr;
131} __packed;
132
133struct skl_dma_control {
134 u32 node_id;
135 u32 config_length;
136 u32 config_data[1];
137} __packed;
138
116struct skl_cpr_cfg {139struct skl_cpr_cfg {
117 struct skl_base_cfg base_cfg;140 struct skl_base_cfg base_cfg;
118 struct skl_audio_data_format out_fmt;141 struct skl_audio_data_format out_fmt;
@@ -313,6 +336,8 @@ static inline struct skl *get_skl_ctx(struct device *dev) · 194 unmodified lines
313 336
314int skl_tplg_be_update_params(struct snd_soc_dai *dai,337int skl_tplg_be_update_params(struct snd_soc_dai *dai,
315 struct skl_pipe_params *params);338 struct skl_pipe_params *params);
339int skl_dsp_set_dma_control(struct skl_sst *ctx,
340 struct skl_module_cfg *mconfig);
316void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,341void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
317 struct skl_pipe_params *params, int stream);342 struct skl_pipe_params *params, int stream);
318int skl_tplg_init(struct snd_soc_platform *platform,343int skl_tplg_init(struct snd_soc_platform *platform,
@@ -345,5 +370,7 @@ int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, · 26 unmodified lines
345int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,370int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size,
346 u32 param_id, struct skl_module_cfg *mcfg);371 u32 param_id, struct skl_module_cfg *mcfg);
347 372
373struct skl_module_cfg *skl_tplg_be_get_cpr_module(struct snd_soc_dai *dai,
374 int stream);
348enum skl_bitdepth skl_get_bit_depth(int params);375enum skl_bitdepth skl_get_bit_depth(int params);
349#endif376#endif
sound/soc/intel/skylake/skl-tplg-interface.h+2−1
@@ -144,7 +144,8 @@ enum module_pin_type { · 143 unmodified lines
144enum skl_module_param_type {144enum skl_module_param_type {
145 SKL_PARAM_DEFAULT = 0,145 SKL_PARAM_DEFAULT = 0,
146 SKL_PARAM_INIT,146 SKL_PARAM_INIT,
147 SKL_PARAM_SET147 SKL_PARAM_SET,
148 SKL_PARAM_BIND
148};149};
149 150
150struct skl_dfw_module_pin {151struct skl_dfw_module_pin {
sound/soc/intel/skylake/skl.c+88−0
@@ -28,6 +28,9 @@ · 27 unmodified lines
28#include <linux/firmware.h>28#include <linux/firmware.h>
29#include <sound/pcm.h>29#include <sound/pcm.h>
30#include "../common/sst-acpi.h"30#include "../common/sst-acpi.h"
31#include <sound/hda_register.h>
32#include <sound/hdaudio.h>
33#include <sound/hda_i915.h>
31#include "skl.h"34#include "skl.h"
32#include "skl-sst-dsp.h"35#include "skl-sst-dsp.h"
33#include "skl-sst-ipc.h"36#include "skl-sst-ipc.h"
@@ -243,6 +246,16 @@ static int skl_resume(struct device *dev) · 209 unmodified lines
243 struct hdac_bus *bus = ebus_to_hbus(ebus);246 struct hdac_bus *bus = ebus_to_hbus(ebus);
244 int ret;247 int ret;
245 248
249 /* Turned OFF in HDMI codec driver after codec reconfiguration */
250 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
251 ret = snd_hdac_display_power(bus, true);
252 if (ret < 0) {
253 dev_err(bus->dev,
254 "Cannot turn on display power on i915\n");
255 return ret;
256 }
257 }
258
246 /*259 /*
247 * resume only when we are not in suspend active, otherwise need to260 * resume only when we are not in suspend active, otherwise need to
248 * restore the device261 * restore the device
@@ -481,6 +494,27 @@ static int skl_create(struct pci_dev *pci, · 232 unmodified lines
481 return 0;494 return 0;
482}495}
483 496
497static int skl_i915_init(struct hdac_bus *bus)
498{
499 int err;
500
501 /*
502 * The HDMI codec is in GPU so we need to ensure that it is powered
503 * up and ready for probe
504 */
505 err = snd_hdac_i915_init(bus);
506 if (err < 0)
507 return err;
508
509 err = snd_hdac_display_power(bus, true);
510 if (err < 0) {
511 dev_err(bus->dev, "Cannot turn on display power on i915\n");
512 return err;
513 }
514
515 return err;
516}
517
484static int skl_first_init(struct hdac_ext_bus *ebus)518static int skl_first_init(struct hdac_ext_bus *ebus)
485{519{
486 struct skl *skl = ebus_to_skl(ebus);520 struct skl *skl = ebus_to_skl(ebus);
@@ -543,6 +577,12 @@ static int skl_first_init(struct hdac_ext_bus *ebus) · 56 unmodified lines
543 /* initialize chip */577 /* initialize chip */
544 skl_init_pci(skl);578 skl_init_pci(skl);
545 579
580 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
581 err = skl_i915_init(bus);
582 if (err < 0)
583 return err;
584 }
585
546 skl_init_chip(bus, true);586 skl_init_chip(bus, true);
547 587
548 /* codec detection */588 /* codec detection */
@@ -573,11 +613,15 @@ static int skl_probe(struct pci_dev *pci, · 24 unmodified lines
573 if (err < 0)613 if (err < 0)
574 goto out_free;614 goto out_free;
575 615
616 skl->pci_id = pci->device;
617
576 skl->nhlt = skl_nhlt_init(bus->dev);618 skl->nhlt = skl_nhlt_init(bus->dev);
577 619
578 if (skl->nhlt == NULL)620 if (skl->nhlt == NULL)
579 goto out_free;621 goto out_free;
580 622
623 skl_nhlt_update_topology_bin(skl);
624
581 pci_set_drvdata(skl->pci, ebus);625 pci_set_drvdata(skl->pci, ebus);
582 626
583 /* check if dsp is there */627 /* check if dsp is there */
@@ -613,6 +657,14 @@ static int skl_probe(struct pci_dev *pci, · 29 unmodified lines
613 if (err < 0)657 if (err < 0)
614 goto out_unregister;658 goto out_unregister;
615 659
660 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) {
661 err = snd_hdac_display_power(bus, false);
662 if (err < 0) {
663 dev_err(bus->dev, "Cannot turn off display power on i915\n");
664 return err;
665 }
666 }
667
616 /*configure PM */668 /*configure PM */
617 pm_runtime_put_noidle(bus->dev);669 pm_runtime_put_noidle(bus->dev);
618 pm_runtime_allow(bus->dev);670 pm_runtime_allow(bus->dev);
@@ -634,6 +686,31 @@ out_free: · 15 unmodified lines
634 return err;686 return err;
635}687}
636 688
689static void skl_shutdown(struct pci_dev *pci)
690{
691 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
692 struct hdac_bus *bus = ebus_to_hbus(ebus);
693 struct hdac_stream *s;
694 struct hdac_ext_stream *stream;
695 struct skl *skl;
696
697 if (ebus == NULL)
698 return;
699
700 skl = ebus_to_skl(ebus);
701
702 if (skl->init_failed)
703 return;
704
705 snd_hdac_ext_stop_streams(ebus);
706 list_for_each_entry(s, &bus->stream_list, list) {
707 stream = stream_to_hdac_ext_stream(s);
708 snd_hdac_ext_stream_decouple(ebus, stream, false);
709 }
710
711 snd_hdac_bus_stop_chip(bus);
712}
713
637static void skl_remove(struct pci_dev *pci)714static void skl_remove(struct pci_dev *pci)
638{715{
639 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);716 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
@@ -642,6 +719,9 @@ static void skl_remove(struct pci_dev *pci) · 2 unmodified lines
642 if (skl->tplg)719 if (skl->tplg)
643 release_firmware(skl->tplg);720 release_firmware(skl->tplg);
644 721
722 if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
723 snd_hdac_i915_exit(&ebus->bus);
724
645 if (pci_dev_run_wake(pci))725 if (pci_dev_run_wake(pci))
646 pm_runtime_get_noresume(&pci->dev);726 pm_runtime_get_noresume(&pci->dev);
647 pci_dev_put(pci);727 pci_dev_put(pci);
@@ -662,11 +742,18 @@ static struct sst_acpi_mach sst_skl_devdata[] = { · 14 unmodified lines
662 {}742 {}
663};743};
664 744
745static struct sst_acpi_mach sst_bxtp_devdata[] = {
746 { "INT343A", "bxt_alc298s_i2s", "intel/dsp_fw_bxtn.bin", NULL, NULL, NULL },
747};
748
665/* PCI IDs */749/* PCI IDs */
666static const struct pci_device_id skl_ids[] = {750static const struct pci_device_id skl_ids[] = {
667 /* Sunrise Point-LP */751 /* Sunrise Point-LP */
668 { PCI_DEVICE(0x8086, 0x9d70),752 { PCI_DEVICE(0x8086, 0x9d70),
669 .driver_data = (unsigned long)&sst_skl_devdata},753 .driver_data = (unsigned long)&sst_skl_devdata},
754 /* BXT-P */
755 { PCI_DEVICE(0x8086, 0x5a98),
756 .driver_data = (unsigned long)&sst_bxtp_devdata},
670 { 0, }757 { 0, }
671};758};
672MODULE_DEVICE_TABLE(pci, skl_ids);759MODULE_DEVICE_TABLE(pci, skl_ids);
@@ -677,6 +764,7 @@ static struct pci_driver skl_driver = { · 4 unmodified lines
677 .id_table = skl_ids,764 .id_table = skl_ids,
678 .probe = skl_probe,765 .probe = skl_probe,
679 .remove = skl_remove,766 .remove = skl_remove,
767 .shutdown = skl_shutdown,
680 .driver = {768 .driver = {
681 .pm = &skl_pm,769 .pm = &skl_pm,
682 },770 },
sound/soc/intel/skylake/skl.h+14−1
@@ -73,6 +73,8 @@ struct skl { · 72 unmodified lines
73 struct list_head ppl_list;73 struct list_head ppl_list;
74 74
75 const char *fw_name;75 const char *fw_name;
76 char tplg_name[64];
77 unsigned short pci_id;
76 const struct firmware *tplg;78 const struct firmware *tplg;
77 79
78 int supend_active;80 int supend_active;
@@ -88,6 +90,16 @@ struct skl_dma_params { · 9 unmodified lines
88 u8 stream_tag;90 u8 stream_tag;
89};91};
90 92
93struct skl_dsp_ops {
94 int id;
95 struct skl_dsp_loader_ops (*loader_ops)(void);
96 int (*init)(struct device *dev, void __iomem *mmio_base,
97 int irq, const char *fw_name,
98 struct skl_dsp_loader_ops loader_ops,
99 struct skl_sst **skl_sst);
100 void (*cleanup)(struct device *dev, struct skl_sst *ctx);
101};
102
91int skl_platform_unregister(struct device *dev);103int skl_platform_unregister(struct device *dev);
92int skl_platform_register(struct device *dev);104int skl_platform_register(struct device *dev);
93 105
@@ -96,8 +108,9 @@ void skl_nhlt_free(void *addr); · 2 unmodified lines
96struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,108struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
97 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);109 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
98 110
111int skl_nhlt_update_topology_bin(struct skl *skl);
99int skl_init_dsp(struct skl *skl);112int skl_init_dsp(struct skl *skl);
100void skl_free_dsp(struct skl *skl);113int skl_free_dsp(struct skl *skl);
101int skl_suspend_dsp(struct skl *skl);114int skl_suspend_dsp(struct skl *skl);
102int skl_resume_dsp(struct skl *skl);115int skl_resume_dsp(struct skl *skl);
103#endif /* __SOUND_SOC_SKL_H */116#endif /* __SOUND_SOC_SKL_H */
sound/soc/mediatek/Kconfig+21−1
@@ -17,6 +17,27 @@ config SND_SOC_MT8173_MAX98090 · 16 unmodified lines
17 Select Y if you have such device.17 Select Y if you have such device.
18 If unsure select "N".18 If unsure select "N".
19 19
20config SND_SOC_MT8173_RT5650
21 tristate "ASoC Audio driver for MT8173 with RT5650 codec"
22 depends on SND_SOC_MEDIATEK && I2C
23 select SND_SOC_RT5645
24 help
25 This adds ASoC driver for Mediatek MT8173 boards
26 with the RT5650 audio codec.
27 Select Y if you have such device.
28 If unsure select "N".
29
30config SND_SOC_MT8173_RT5650_RT5514
31 tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs"
32 depends on SND_SOC_MEDIATEK && I2C
33 select SND_SOC_RT5645
34 select SND_SOC_RT5514
35 help
36 This adds ASoC driver for Mediatek MT8173 boards
37 with the RT5650 and RT5514 codecs.
38 Select Y if you have such device.
39 If unsure select "N".
40
20config SND_SOC_MT8173_RT5650_RT567641config SND_SOC_MT8173_RT5650_RT5676
21 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"42 tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
22 depends on SND_SOC_MEDIATEK && I2C43 depends on SND_SOC_MEDIATEK && I2C
@@ -27,4 +48,3 @@ config SND_SOC_MT8173_RT5650_RT5676 · 4 unmodified lines
27 with the RT5650 and RT5676 codecs.48 with the RT5650 and RT5676 codecs.
28 Select Y if you have such device.49 Select Y if you have such device.
29 If unsure select "N".50 If unsure select "N".
30
sound/soc/mediatek/Makefile+2−0
@@ -2,4 +2,6 @@ · 1 unmodified line
2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o2obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o
3# Machine support3# Machine support
4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o4obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
6obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
5obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o7obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
sound/soc/mediatek/mt8173-rt5650-rt5514.c+258−0
@@ -0,0 +1,258 @@
1/*
2 * mt8173-rt5650-rt5514.c -- MT8173 machine driver with RT5650/5514 codecs
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22#include "../codecs/rt5645.h"
23
24#define MCLK_FOR_CODECS 12288000
25
26static const struct snd_soc_dapm_widget mt8173_rt5650_rt5514_widgets[] = {
27 SND_SOC_DAPM_SPK("Speaker", NULL),
28 SND_SOC_DAPM_MIC("Int Mic", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_MIC("Headset Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route mt8173_rt5650_rt5514_routes[] = {
34 {"Speaker", NULL, "SPOL"},
35 {"Speaker", NULL, "SPOR"},
36 {"Sub DMIC1L", NULL, "Int Mic"},
37 {"Sub DMIC1R", NULL, "Int Mic"},
38 {"Headphone", NULL, "HPOL"},
39 {"Headphone", NULL, "HPOR"},
40 {"Headset Mic", NULL, "micbias1"},
41 {"Headset Mic", NULL, "micbias2"},
42 {"IN1P", NULL, "Headset Mic"},
43 {"IN1N", NULL, "Headset Mic"},
44};
45
46static const struct snd_kcontrol_new mt8173_rt5650_rt5514_controls[] = {
47 SOC_DAPM_PIN_SWITCH("Speaker"),
48 SOC_DAPM_PIN_SWITCH("Int Mic"),
49 SOC_DAPM_PIN_SWITCH("Headphone"),
50 SOC_DAPM_PIN_SWITCH("Headset Mic"),
51};
52
53static int mt8173_rt5650_rt5514_hw_params(struct snd_pcm_substream *substream,
54 struct snd_pcm_hw_params *params)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 int i, ret;
58
59 for (i = 0; i < rtd->num_codecs; i++) {
60 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
61
62 /* pll from mclk 12.288M */
63 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
64 params_rate(params) * 512);
65 if (ret)
66 return ret;
67
68 /* sysclk from pll */
69 ret = snd_soc_dai_set_sysclk(codec_dai, 1,
70 params_rate(params) * 512,
71 SND_SOC_CLOCK_IN);
72 if (ret)
73 return ret;
74 }
75 return 0;
76}
77
78static struct snd_soc_ops mt8173_rt5650_rt5514_ops = {
79 .hw_params = mt8173_rt5650_rt5514_hw_params,
80};
81
82static struct snd_soc_jack mt8173_rt5650_rt5514_jack;
83
84static int mt8173_rt5650_rt5514_init(struct snd_soc_pcm_runtime *runtime)
85{
86 struct snd_soc_card *card = runtime->card;
87 struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
88 int ret;
89
90 rt5645_sel_asrc_clk_src(codec,
91 RT5645_DA_STEREO_FILTER |
92 RT5645_AD_STEREO_FILTER,
93 RT5645_CLK_SEL_I2S1_ASRC);
94
95 /* enable jack detection */
96 ret = snd_soc_card_jack_new(card, "Headset Jack",
97 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
98 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
99 SND_JACK_BTN_2 | SND_JACK_BTN_3,
100 &mt8173_rt5650_rt5514_jack, NULL, 0);
101 if (ret) {
102 dev_err(card->dev, "Can't new Headset Jack %d\n", ret);
103 return ret;
104 }
105
106 return rt5645_set_jack_detect(codec,
107 &mt8173_rt5650_rt5514_jack,
108 &mt8173_rt5650_rt5514_jack,
109 &mt8173_rt5650_rt5514_jack);
110}
111
112static struct snd_soc_dai_link_component mt8173_rt5650_rt5514_codecs[] = {
113 {
114 .dai_name = "rt5645-aif1",
115 },
116 {
117 .dai_name = "rt5514-aif1",
118 },
119};
120
121enum {
122 DAI_LINK_PLAYBACK,
123 DAI_LINK_CAPTURE,
124 DAI_LINK_CODEC_I2S,
125};
126
127/* Digital audio interface glue - connects codec <---> CPU */
128static struct snd_soc_dai_link mt8173_rt5650_rt5514_dais[] = {
129 /* Front End DAI links */
130 [DAI_LINK_PLAYBACK] = {
131 .name = "rt5650_rt5514 Playback",
132 .stream_name = "rt5650_rt5514 Playback",
133 .cpu_dai_name = "DL1",
134 .codec_name = "snd-soc-dummy",
135 .codec_dai_name = "snd-soc-dummy-dai",
136 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
137 .dynamic = 1,
138 .dpcm_playback = 1,
139 },
140 [DAI_LINK_CAPTURE] = {
141 .name = "rt5650_rt5514 Capture",
142 .stream_name = "rt5650_rt5514 Capture",
143 .cpu_dai_name = "VUL",
144 .codec_name = "snd-soc-dummy",
145 .codec_dai_name = "snd-soc-dummy-dai",
146 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
147 .dynamic = 1,
148 .dpcm_capture = 1,
149 },
150 /* Back End DAI links */
151 [DAI_LINK_CODEC_I2S] = {
152 .name = "Codec",
153 .cpu_dai_name = "I2S",
154 .no_pcm = 1,
155 .codecs = mt8173_rt5650_rt5514_codecs,
156 .num_codecs = 2,
157 .init = mt8173_rt5650_rt5514_init,
158 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
159 SND_SOC_DAIFMT_CBS_CFS,
160 .ops = &mt8173_rt5650_rt5514_ops,
161 .ignore_pmdown_time = 1,
162 .dpcm_playback = 1,
163 .dpcm_capture = 1,
164 },
165};
166
167static struct snd_soc_codec_conf mt8173_rt5650_rt5514_codec_conf[] = {
168 {
169 .name_prefix = "Sub",
170 },
171};
172
173static struct snd_soc_card mt8173_rt5650_rt5514_card = {
174 .name = "mtk-rt5650-rt5514",
175 .owner = THIS_MODULE,
176 .dai_link = mt8173_rt5650_rt5514_dais,
177 .num_links = ARRAY_SIZE(mt8173_rt5650_rt5514_dais),
178 .codec_conf = mt8173_rt5650_rt5514_codec_conf,
179 .num_configs = ARRAY_SIZE(mt8173_rt5650_rt5514_codec_conf),
180 .controls = mt8173_rt5650_rt5514_controls,
181 .num_controls = ARRAY_SIZE(mt8173_rt5650_rt5514_controls),
182 .dapm_widgets = mt8173_rt5650_rt5514_widgets,
183 .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_rt5514_widgets),
184 .dapm_routes = mt8173_rt5650_rt5514_routes,
185 .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_rt5514_routes),
186};
187
188static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
189{
190 struct snd_soc_card *card = &mt8173_rt5650_rt5514_card;
191 struct device_node *platform_node;
192 int i, ret;
193
194 platform_node = of_parse_phandle(pdev->dev.of_node,
195 "mediatek,platform", 0);
196 if (!platform_node) {
197 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
198 return -EINVAL;
199 }
200
201 for (i = 0; i < card->num_links; i++) {
202 if (mt8173_rt5650_rt5514_dais[i].platform_name)
203 continue;
204 mt8173_rt5650_rt5514_dais[i].platform_of_node = platform_node;
205 }
206
207 mt8173_rt5650_rt5514_codecs[0].of_node =
208 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
209 if (!mt8173_rt5650_rt5514_codecs[0].of_node) {
210 dev_err(&pdev->dev,
211 "Property 'audio-codec' missing or invalid\n");
212 return -EINVAL;
213 }
214 mt8173_rt5650_rt5514_codecs[1].of_node =
215 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
216 if (!mt8173_rt5650_rt5514_codecs[1].of_node) {
217 dev_err(&pdev->dev,
218 "Property 'audio-codec' missing or invalid\n");
219 return -EINVAL;
220 }
221 mt8173_rt5650_rt5514_codec_conf[0].of_node =
222 mt8173_rt5650_rt5514_codecs[1].of_node;
223
224 card->dev = &pdev->dev;
225 platform_set_drvdata(pdev, card);
226
227 ret = devm_snd_soc_register_card(&pdev->dev, card);
228 if (ret)
229 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
230 __func__, ret);
231 return ret;
232}
233
234static const struct of_device_id mt8173_rt5650_rt5514_dt_match[] = {
235 { .compatible = "mediatek,mt8173-rt5650-rt5514", },
236 { }
237};
238MODULE_DEVICE_TABLE(of, mt8173_rt5650_rt5514_dt_match);
239
240static struct platform_driver mt8173_rt5650_rt5514_driver = {
241 .driver = {
242 .name = "mtk-rt5650-rt5514",
243 .of_match_table = mt8173_rt5650_rt5514_dt_match,
244#ifdef CONFIG_PM
245 .pm = &snd_soc_pm_ops,
246#endif
247 },
248 .probe = mt8173_rt5650_rt5514_dev_probe,
249};
250
251module_platform_driver(mt8173_rt5650_rt5514_driver);
252
253/* Module information */
254MODULE_DESCRIPTION("MT8173 RT5650 and RT5514 SoC machine driver");
255MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
256MODULE_LICENSE("GPL v2");
257MODULE_ALIAS("platform:mtk-rt5650-rt5514");
258
sound/soc/mediatek/mt8173-rt5650-rt5676.c+13−5
@@ -131,10 +131,17 @@ static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = { · 130 unmodified lines
131 },131 },
132};132};
133 133
134enum {
135 DAI_LINK_PLAYBACK,
136 DAI_LINK_CAPTURE,
137 DAI_LINK_CODEC_I2S,
138 DAI_LINK_INTERCODEC
139};
140
134/* Digital audio interface glue - connects codec <---> CPU */141/* Digital audio interface glue - connects codec <---> CPU */
135static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {142static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = {
136 /* Front End DAI links */143 /* Front End DAI links */
137 {144 [DAI_LINK_PLAYBACK] = {
138 .name = "rt5650_rt5676 Playback",145 .name = "rt5650_rt5676 Playback",
139 .stream_name = "rt5650_rt5676 Playback",146 .stream_name = "rt5650_rt5676 Playback",
140 .cpu_dai_name = "DL1",147 .cpu_dai_name = "DL1",
@@ -144,7 +151,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { · 3 unmodified lines
144 .dynamic = 1,151 .dynamic = 1,
145 .dpcm_playback = 1,152 .dpcm_playback = 1,
146 },153 },
147 {154 [DAI_LINK_CAPTURE] = {
148 .name = "rt5650_rt5676 Capture",155 .name = "rt5650_rt5676 Capture",
149 .stream_name = "rt5650_rt5676 Capture",156 .stream_name = "rt5650_rt5676 Capture",
150 .cpu_dai_name = "VUL",157 .cpu_dai_name = "VUL",
@@ -156,7 +163,7 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { · 5 unmodified lines
156 },163 },
157 164
158 /* Back End DAI links */165 /* Back End DAI links */
159 {166 [DAI_LINK_CODEC_I2S] = {
160 .name = "Codec",167 .name = "Codec",
161 .cpu_dai_name = "I2S",168 .cpu_dai_name = "I2S",
162 .no_pcm = 1,169 .no_pcm = 1,
@@ -170,7 +177,8 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { · 7 unmodified lines
170 .dpcm_playback = 1,177 .dpcm_playback = 1,
171 .dpcm_capture = 1,178 .dpcm_capture = 1,
172 },179 },
173 { /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */180 /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */
181 [DAI_LINK_INTERCODEC] = {
174 .name = "rt5650_rt5676 intercodec",182 .name = "rt5650_rt5676 intercodec",
175 .stream_name = "rt5650_rt5676 intercodec",183 .stream_name = "rt5650_rt5676 intercodec",
176 .cpu_dai_name = "snd-soc-dummy-dai",184 .cpu_dai_name = "snd-soc-dummy-dai",
@@ -240,7 +248,7 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) · 63 unmodified lines
240 mt8173_rt5650_rt5676_codec_conf[0].of_node =248 mt8173_rt5650_rt5676_codec_conf[0].of_node =
241 mt8173_rt5650_rt5676_codecs[1].of_node;249 mt8173_rt5650_rt5676_codecs[1].of_node;
242 250
243 mt8173_rt5650_rt5676_dais[3].codec_of_node =251 mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node =
244 mt8173_rt5650_rt5676_codecs[1].of_node;252 mt8173_rt5650_rt5676_codecs[1].of_node;
245 253
246 card->dev = &pdev->dev;254 card->dev = &pdev->dev;
sound/soc/mediatek/mt8173-rt5650.c+236−0
@@ -0,0 +1,236 @@
1/*
2 * mt8173-rt5650.c -- MT8173 machine driver with RT5650 codecs
3 *
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Koro Chen <koro.chen@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/gpio.h>
19#include <linux/of_gpio.h>
20#include <sound/soc.h>
21#include <sound/jack.h>
22#include "../codecs/rt5645.h"
23
24#define MCLK_FOR_CODECS 12288000
25
26static const struct snd_soc_dapm_widget mt8173_rt5650_widgets[] = {
27 SND_SOC_DAPM_SPK("Speaker", NULL),
28 SND_SOC_DAPM_MIC("Int Mic", NULL),
29 SND_SOC_DAPM_HP("Headphone", NULL),
30 SND_SOC_DAPM_MIC("Headset Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = {
34 {"Speaker", NULL, "SPOL"},
35 {"Speaker", NULL, "SPOR"},
36 {"DMIC L1", NULL, "Int Mic"},
37 {"DMIC R1", NULL, "Int Mic"},
38 {"Headphone", NULL, "HPOL"},
39 {"Headphone", NULL, "HPOR"},
40 {"Headset Mic", NULL, "micbias1"},
41 {"Headset Mic", NULL, "micbias2"},
42 {"IN1P", NULL, "Headset Mic"},
43 {"IN1N", NULL, "Headset Mic"},
44};
45
46static const struct snd_kcontrol_new mt8173_rt5650_controls[] = {
47 SOC_DAPM_PIN_SWITCH("Speaker"),
48 SOC_DAPM_PIN_SWITCH("Int Mic"),
49 SOC_DAPM_PIN_SWITCH("Headphone"),
50 SOC_DAPM_PIN_SWITCH("Headset Mic"),
51};
52
53static int mt8173_rt5650_hw_params(struct snd_pcm_substream *substream,
54 struct snd_pcm_hw_params *params)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 int i, ret;
58
59 for (i = 0; i < rtd->num_codecs; i++) {
60 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
61
62 /* pll from mclk 12.288M */
63 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, MCLK_FOR_CODECS,
64 params_rate(params) * 512);
65 if (ret)
66 return ret;
67
68 /* sysclk from pll */
69 ret = snd_soc_dai_set_sysclk(codec_dai, 1,
70 params_rate(params) * 512,
71 SND_SOC_CLOCK_IN);
72 if (ret)
73 return ret;
74 }
75 return 0;
76}
77
78static struct snd_soc_ops mt8173_rt5650_ops = {
79 .hw_params = mt8173_rt5650_hw_params,
80};
81
82static struct snd_soc_jack mt8173_rt5650_jack;
83
84static int mt8173_rt5650_init(struct snd_soc_pcm_runtime *runtime)
85{
86 struct snd_soc_card *card = runtime->card;
87 struct snd_soc_codec *codec = runtime->codec_dais[0]->codec;
88 int ret;
89
90 rt5645_sel_asrc_clk_src(codec,
91 RT5645_DA_STEREO_FILTER |
92 RT5645_AD_STEREO_FILTER,
93 RT5645_CLK_SEL_I2S1_ASRC);
94 /* enable jack detection */
95 ret = snd_soc_card_jack_new(card, "Headset Jack",
96 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
97 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
98 SND_JACK_BTN_2 | SND_JACK_BTN_3,
99 &mt8173_rt5650_jack, NULL, 0);
100 if (ret) {
101 dev_err(card->dev, "Can't new Headset Jack %d\n", ret);
102 return ret;
103 }
104
105 return rt5645_set_jack_detect(codec,
106 &mt8173_rt5650_jack,
107 &mt8173_rt5650_jack,
108 &mt8173_rt5650_jack);
109}
110
111static struct snd_soc_dai_link_component mt8173_rt5650_codecs[] = {
112 {
113 .dai_name = "rt5645-aif1",
114 },
115};
116
117enum {
118 DAI_LINK_PLAYBACK,
119 DAI_LINK_CAPTURE,
120 DAI_LINK_CODEC_I2S,
121};
122
123/* Digital audio interface glue - connects codec <---> CPU */
124static struct snd_soc_dai_link mt8173_rt5650_dais[] = {
125 /* Front End DAI links */
126 [DAI_LINK_PLAYBACK] = {
127 .name = "rt5650 Playback",
128 .stream_name = "rt5650 Playback",
129 .cpu_dai_name = "DL1",
130 .codec_name = "snd-soc-dummy",
131 .codec_dai_name = "snd-soc-dummy-dai",
132 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
133 .dynamic = 1,
134 .dpcm_playback = 1,
135 },
136 [DAI_LINK_CAPTURE] = {
137 .name = "rt5650 Capture",
138 .stream_name = "rt5650 Capture",
139 .cpu_dai_name = "VUL",
140 .codec_name = "snd-soc-dummy",
141 .codec_dai_name = "snd-soc-dummy-dai",
142 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
143 .dynamic = 1,
144 .dpcm_capture = 1,
145 },
146 /* Back End DAI links */
147 [DAI_LINK_CODEC_I2S] = {
148 .name = "Codec",
149 .cpu_dai_name = "I2S",
150 .no_pcm = 1,
151 .codecs = mt8173_rt5650_codecs,
152 .num_codecs = 1,
153 .init = mt8173_rt5650_init,
154 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
155 SND_SOC_DAIFMT_CBS_CFS,
156 .ops = &mt8173_rt5650_ops,
157 .ignore_pmdown_time = 1,
158 .dpcm_playback = 1,
159 .dpcm_capture = 1,
160 },
161};
162
163static struct snd_soc_card mt8173_rt5650_card = {
164 .name = "mtk-rt5650",
165 .owner = THIS_MODULE,
166 .dai_link = mt8173_rt5650_dais,
167 .num_links = ARRAY_SIZE(mt8173_rt5650_dais),
168 .controls = mt8173_rt5650_controls,
169 .num_controls = ARRAY_SIZE(mt8173_rt5650_controls),
170 .dapm_widgets = mt8173_rt5650_widgets,
171 .num_dapm_widgets = ARRAY_SIZE(mt8173_rt5650_widgets),
172 .dapm_routes = mt8173_rt5650_routes,
173 .num_dapm_routes = ARRAY_SIZE(mt8173_rt5650_routes),
174};
175
176static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
177{
178 struct snd_soc_card *card = &mt8173_rt5650_card;
179 struct device_node *platform_node;
180 int i, ret;
181
182 platform_node = of_parse_phandle(pdev->dev.of_node,
183 "mediatek,platform", 0);
184 if (!platform_node) {
185 dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
186 return -EINVAL;
187 }
188
189 for (i = 0; i < card->num_links; i++) {
190 if (mt8173_rt5650_dais[i].platform_name)
191 continue;
192 mt8173_rt5650_dais[i].platform_of_node = platform_node;
193 }
194
195 mt8173_rt5650_codecs[0].of_node =
196 of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0);
197 if (!mt8173_rt5650_codecs[0].of_node) {
198 dev_err(&pdev->dev,
199 "Property 'audio-codec' missing or invalid\n");
200 return -EINVAL;
201 }
202 card->dev = &pdev->dev;
203 platform_set_drvdata(pdev, card);
204
205 ret = devm_snd_soc_register_card(&pdev->dev, card);
206 if (ret)
207 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
208 __func__, ret);
209 return ret;
210}
211
212static const struct of_device_id mt8173_rt5650_dt_match[] = {
213 { .compatible = "mediatek,mt8173-rt5650", },
214 { }
215};
216MODULE_DEVICE_TABLE(of, mt8173_rt5650_dt_match);
217
218static struct platform_driver mt8173_rt5650_driver = {
219 .driver = {
220 .name = "mtk-rt5650",
221 .of_match_table = mt8173_rt5650_dt_match,
222#ifdef CONFIG_PM
223 .pm = &snd_soc_pm_ops,
224#endif
225 },
226 .probe = mt8173_rt5650_dev_probe,
227};
228
229module_platform_driver(mt8173_rt5650_driver);
230
231/* Module information */
232MODULE_DESCRIPTION("MT8173 RT5650 SoC machine driver");
233MODULE_AUTHOR("Koro Chen <koro.chen@mediatek.com>");
234MODULE_LICENSE("GPL v2");
235MODULE_ALIAS("platform:mtk-rt5650");
236
sound/soc/mediatek/mtk-afe-common.h+1−0
@@ -87,6 +87,7 @@ struct mtk_afe_memif_data { · 86 unmodified lines
87 int irq_en_shift;87 int irq_en_shift;
88 int irq_fs_shift;88 int irq_fs_shift;
89 int irq_clr_shift;89 int irq_clr_shift;
90 int msb_shift;
90};91};
91 92
92struct mtk_afe_memif {93struct mtk_afe_memif {
sound/soc/mediatek/mtk-afe-pcm.c+38−9
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <linux/module.h>21#include <linux/module.h>
22#include <linux/of.h>22#include <linux/of.h>
23#include <linux/of_address.h>23#include <linux/of_address.h>
24#include <linux/dma-mapping.h>
24#include <linux/pm_runtime.h>25#include <linux/pm_runtime.h>
25#include <sound/soc.h>26#include <sound/soc.h>
26#include "mtk-afe-common.h"27#include "mtk-afe-common.h"
@@ -35,9 +36,11 @@ · 8 unmodified lines
35#define AFE_I2S_CON1 0x003436#define AFE_I2S_CON1 0x0034
36#define AFE_I2S_CON2 0x003837#define AFE_I2S_CON2 0x0038
37#define AFE_CONN_24BIT 0x006c38#define AFE_CONN_24BIT 0x006c
39#define AFE_MEMIF_MSB 0x00cc
38 40
39#define AFE_CONN1 0x002441#define AFE_CONN1 0x0024
40#define AFE_CONN2 0x002842#define AFE_CONN2 0x0028
43#define AFE_CONN3 0x002c
41#define AFE_CONN7 0x046044#define AFE_CONN7 0x0460
42#define AFE_CONN8 0x046445#define AFE_CONN8 0x0464
43#define AFE_HDMI_CONN0 0x039046#define AFE_HDMI_CONN0 0x0390
@@ -61,6 +64,7 @@ · 17 unmodified lines
61#define AFE_HDMI_OUT_CUR 0x037864#define AFE_HDMI_OUT_CUR 0x0378
62#define AFE_HDMI_OUT_END 0x037c65#define AFE_HDMI_OUT_END 0x037c
63 66
67#define AFE_ADDA_TOP_CON0 0x0120
64#define AFE_ADDA2_TOP_CON0 0x060068#define AFE_ADDA2_TOP_CON0 0x0600
65 69
66#define AFE_HDMI_OUT_CON0 0x037070#define AFE_HDMI_OUT_CON0 0x0370
@@ -257,6 +261,7 @@ static int mtk_afe_set_i2s(struct mtk_afe *afe, unsigned int rate) · 190 unmodified lines
257 return -EINVAL;261 return -EINVAL;
258 262
259 /* from external ADC */263 /* from external ADC */
264 regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, 0x1, 0x1);
260 regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1);265 regmap_update_bits(afe->regmap, AFE_ADDA2_TOP_CON0, 0x1, 0x1);
261 266
262 /* set input */267 /* set input */
@@ -281,20 +286,13 @@ static void mtk_afe_set_i2s_enable(struct mtk_afe *afe, bool enable) · 18 unmodified lines
281 286
282 regmap_read(afe->regmap, AFE_I2S_CON2, &val);287 regmap_read(afe->regmap, AFE_I2S_CON2, &val);
283 if (!!(val & AFE_I2S_CON2_EN) == enable)288 if (!!(val & AFE_I2S_CON2_EN) == enable)
284 return; /* must skip soft reset */289 return;
285
286 /* I2S soft reset begin */
287 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0x4);
288 290
289 /* input */291 /* input */
290 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable);292 regmap_update_bits(afe->regmap, AFE_I2S_CON2, 0x1, enable);
291 293
292 /* output */294 /* output */
293 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable);295 regmap_update_bits(afe->regmap, AFE_I2S_CON1, 0x1, enable);
294
295 /* I2S soft reset end */
296 udelay(1);
297 regmap_update_bits(afe->regmap, AUDIO_TOP_CON1, 0x4, 0);
298}296}
299 297
300static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,298static int mtk_afe_dais_enable_clks(struct mtk_afe *afe,
@@ -363,6 +361,7 @@ static int mtk_afe_i2s_startup(struct snd_pcm_substream *substream, · 62 unmodified lines
363 return 0;361 return 0;
364 362
365 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);363 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
364 mtk_afe_dais_enable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
366 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,365 regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
367 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);366 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M, 0);
368 return 0;367 return 0;
@@ -382,6 +381,7 @@ static void mtk_afe_i2s_shutdown(struct snd_pcm_substream *substream, · 13 unmodified lines
382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,381 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M,
383 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);382 AUD_TCON0_PDN_22M | AUD_TCON0_PDN_24M);
384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);383 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S1_M], NULL);
384 mtk_afe_dais_disable_clks(afe, afe->clocks[MTK_CLK_I2S2_M], NULL);
385}385}
386 386
387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,387static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream,
@@ -395,6 +395,9 @@ static int mtk_afe_i2s_prepare(struct snd_pcm_substream *substream, · 7 unmodified lines
395 mtk_afe_dais_set_clks(afe,395 mtk_afe_dais_set_clks(afe,
396 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256,396 afe->clocks[MTK_CLK_I2S1_M], runtime->rate * 256,
397 NULL, 0);397 NULL, 0);
398 mtk_afe_dais_set_clks(afe,
399 afe->clocks[MTK_CLK_I2S2_M], runtime->rate * 256,
400 NULL, 0);
398 /* config I2S */401 /* config I2S */
399 ret = mtk_afe_set_i2s(afe, substream->runtime->rate);402 ret = mtk_afe_set_i2s(afe, substream->runtime->rate);
400 if (ret)403 if (ret)
@@ -592,6 +595,7 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, · 191 unmodified lines
592 struct snd_soc_pcm_runtime *rtd = substream->private_data;595 struct snd_soc_pcm_runtime *rtd = substream->private_data;
593 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);596 struct mtk_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
594 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];597 struct mtk_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
598 int msb_at_bit33 = 0;
595 int ret;599 int ret;
596 600
597 dev_dbg(afe->dev,601 dev_dbg(afe->dev,
@@ -603,7 +607,8 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, · 5 unmodified lines
603 if (ret < 0)607 if (ret < 0)
604 return ret;608 return ret;
605 609
606 memif->phys_buf_addr = substream->runtime->dma_addr;610 msb_at_bit33 = upper_32_bits(substream->runtime->dma_addr) ? 1 : 0;
611 memif->phys_buf_addr = lower_32_bits(substream->runtime->dma_addr);
607 memif->buffer_size = substream->runtime->dma_bytes;612 memif->buffer_size = substream->runtime->dma_bytes;
608 613
609 /* start */614 /* start */
@@ -614,6 +619,11 @@ static int mtk_afe_dais_hw_params(struct snd_pcm_substream *substream, · 4 unmodified lines
614 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,619 memif->data->reg_ofs_base + AFE_BASE_END_OFFSET,
615 memif->phys_buf_addr + memif->buffer_size - 1);620 memif->phys_buf_addr + memif->buffer_size - 1);
616 621
622 /* set MSB to 33-bit */
623 regmap_update_bits(afe->regmap, AFE_MEMIF_MSB,
624 1 << memif->data->msb_shift,
625 msb_at_bit33 << memif->data->msb_shift);
626
617 /* set channel */627 /* set channel */
618 if (memif->data->mono_shift >= 0) {628 if (memif->data->mono_shift >= 0) {
619 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;629 unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
@@ -894,15 +904,19 @@ static const struct snd_kcontrol_new mtk_afe_o04_mix[] = { · 274 unmodified lines
894};904};
895 905
896static const struct snd_kcontrol_new mtk_afe_o09_mix[] = {906static const struct snd_kcontrol_new mtk_afe_o09_mix[] = {
907 SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 0, 1, 0),
897 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0),908 SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN7, 30, 1, 0),
898};909};
899 910
900static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {911static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {
912 SOC_DAPM_SINGLE_AUTODISABLE("I04 Switch", AFE_CONN3, 3, 1, 0),
901 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0),913 SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN8, 0, 1, 0),
902};914};
903 915
904static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {916static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
905 /* inter-connections */917 /* inter-connections */
918 SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
919 SND_SOC_DAPM_MIXER("I04", SND_SOC_NOPM, 0, 0, NULL, 0),
906 SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),920 SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),
907 SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),921 SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),
908 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),922 SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -925,12 +939,16 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = { · 16 unmodified lines
925 {"I2S Playback", NULL, "O04"},939 {"I2S Playback", NULL, "O04"},
926 {"VUL", NULL, "O09"},940 {"VUL", NULL, "O09"},
927 {"VUL", NULL, "O10"},941 {"VUL", NULL, "O10"},
942 {"I03", NULL, "I2S Capture"},
943 {"I04", NULL, "I2S Capture"},
928 {"I17", NULL, "I2S Capture"},944 {"I17", NULL, "I2S Capture"},
929 {"I18", NULL, "I2S Capture"},945 {"I18", NULL, "I2S Capture"},
930 { "O03", "I05 Switch", "I05" },946 { "O03", "I05 Switch", "I05" },
931 { "O04", "I06 Switch", "I06" },947 { "O04", "I06 Switch", "I06" },
932 { "O09", "I17 Switch", "I17" },948 { "O09", "I17 Switch", "I17" },
949 { "O09", "I03 Switch", "I03" },
933 { "O10", "I18 Switch", "I18" },950 { "O10", "I18 Switch", "I18" },
951 { "O10", "I04 Switch", "I04" },
934};952};
935 953
936static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {954static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {
@@ -978,6 +996,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 41 unmodified lines
978 .irq_en_shift = 0,996 .irq_en_shift = 0,
979 .irq_fs_shift = 4,997 .irq_fs_shift = 4,
980 .irq_clr_shift = 0,998 .irq_clr_shift = 0,
999 .msb_shift = 0,
981 }, {1000 }, {
982 .name = "DL2",1001 .name = "DL2",
983 .id = MTK_AFE_MEMIF_DL2,1002 .id = MTK_AFE_MEMIF_DL2,
@@ -991,6 +1010,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
991 .irq_en_shift = 2,1010 .irq_en_shift = 2,
992 .irq_fs_shift = 16,1011 .irq_fs_shift = 16,
993 .irq_clr_shift = 2,1012 .irq_clr_shift = 2,
1013 .msb_shift = 1,
994 }, {1014 }, {
995 .name = "VUL",1015 .name = "VUL",
996 .id = MTK_AFE_MEMIF_VUL,1016 .id = MTK_AFE_MEMIF_VUL,
@@ -1004,6 +1024,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
1004 .irq_en_shift = 1,1024 .irq_en_shift = 1,
1005 .irq_fs_shift = 8,1025 .irq_fs_shift = 8,
1006 .irq_clr_shift = 1,1026 .irq_clr_shift = 1,
1027 .msb_shift = 6,
1007 }, {1028 }, {
1008 .name = "DAI",1029 .name = "DAI",
1009 .id = MTK_AFE_MEMIF_DAI,1030 .id = MTK_AFE_MEMIF_DAI,
@@ -1017,6 +1038,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
1017 .irq_en_shift = 3,1038 .irq_en_shift = 3,
1018 .irq_fs_shift = 20,1039 .irq_fs_shift = 20,
1019 .irq_clr_shift = 3,1040 .irq_clr_shift = 3,
1041 .msb_shift = 5,
1020 }, {1042 }, {
1021 .name = "AWB",1043 .name = "AWB",
1022 .id = MTK_AFE_MEMIF_AWB,1044 .id = MTK_AFE_MEMIF_AWB,
@@ -1030,6 +1052,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
1030 .irq_en_shift = 14,1052 .irq_en_shift = 14,
1031 .irq_fs_shift = 24,1053 .irq_fs_shift = 24,
1032 .irq_clr_shift = 6,1054 .irq_clr_shift = 6,
1055 .msb_shift = 3,
1033 }, {1056 }, {
1034 .name = "MOD_DAI",1057 .name = "MOD_DAI",
1035 .id = MTK_AFE_MEMIF_MOD_DAI,1058 .id = MTK_AFE_MEMIF_MOD_DAI,
@@ -1043,6 +1066,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
1043 .irq_en_shift = 3,1066 .irq_en_shift = 3,
1044 .irq_fs_shift = 20,1067 .irq_fs_shift = 20,
1045 .irq_clr_shift = 3,1068 .irq_clr_shift = 3,
1069 .msb_shift = 4,
1046 }, {1070 }, {
1047 .name = "HDMI",1071 .name = "HDMI",
1048 .id = MTK_AFE_MEMIF_HDMI,1072 .id = MTK_AFE_MEMIF_HDMI,
@@ -1056,6 +1080,7 @@ static const struct mtk_afe_memif_data memif_data[MTK_AFE_MEMIF_NUM] = { · 7 unmodified lines
1056 .irq_en_shift = 12,1080 .irq_en_shift = 12,
1057 .irq_fs_shift = -1,1081 .irq_fs_shift = -1,
1058 .irq_clr_shift = 4,1082 .irq_clr_shift = 4,
1083 .msb_shift = 8,
1059 },1084 },
1060};1085};
1061 1086
@@ -1189,6 +1214,10 @@ static int mtk_afe_pcm_dev_probe(struct platform_device *pdev) · 127 unmodified lines
1189 struct mtk_afe *afe;1214 struct mtk_afe *afe;
1190 struct resource *res;1215 struct resource *res;
1191 1216
1217 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
1218 if (ret)
1219 return ret;
1220
1192 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);1221 afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
1193 if (!afe)1222 if (!afe)
1194 return -ENOMEM;1223 return -ENOMEM;
sound/soc/mxs/mxs-saif.c+1−1
@@ -418,7 +418,7 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, · 417 unmodified lines
418 }418 }
419 419
420 stat = __raw_readl(saif->base + SAIF_STAT);420 stat = __raw_readl(saif->base + SAIF_STAT);
421 if (stat & BM_SAIF_STAT_BUSY) {421 if (!saif->mclk_in_use && (stat & BM_SAIF_STAT_BUSY)) {
422 dev_err(cpu_dai->dev, "error: busy\n");422 dev_err(cpu_dai->dev, "error: busy\n");
423 return -EBUSY;423 return -EBUSY;
424 }424 }
sound/soc/omap/omap-hdmi-audio.c+1−0
@@ -345,6 +345,7 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) · 344 unmodified lines
345 dai_drv = &omap4_hdmi_dai;345 dai_drv = &omap4_hdmi_dai;
346 break;346 break;
347 case OMAPDSS_VER_OMAP5:347 case OMAPDSS_VER_OMAP5:
348 case OMAPDSS_VER_DRA7xx:
348 dai_drv = &omap5_hdmi_dai;349 dai_drv = &omap5_hdmi_dai;
349 break;350 break;
350 default:351 default:
sound/soc/pxa/brownstone.c+0−2
@@ -52,7 +52,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, · 51 unmodified lines
52 struct snd_soc_dai *codec_dai = rtd->codec_dai;52 struct snd_soc_dai *codec_dai = rtd->codec_dai;
53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;53 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
54 int freq_out, sspa_mclk, sysclk;54 int freq_out, sspa_mclk, sysclk;
55 int sspa_div;
56 55
57 if (params_rate(params) > 11025) {56 if (params_rate(params) > 11025) {
58 freq_out = params_rate(params) * 512;57 freq_out = params_rate(params) * 512;
@@ -63,7 +62,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, · 4 unmodified lines
63 sysclk = params_rate(params) * 512;62 sysclk = params_rate(params) * 512;
64 sspa_mclk = params_rate(params) * 64;63 sspa_mclk = params_rate(params) * 64;
65 }64 }
66 sspa_div = freq_out / sspa_mclk;
67 65
68 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);66 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
69 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);67 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
sound/soc/qcom/Kconfig+5−2
@@ -11,21 +11,24 @@ config SND_SOC_LPASS_CPU · 10 unmodified lines
11 11
12config SND_SOC_LPASS_PLATFORM12config SND_SOC_LPASS_PLATFORM
13 tristate13 tristate
14 depends on HAS_DMA
14 select REGMAP_MMIO15 select REGMAP_MMIO
15 16
16config SND_SOC_LPASS_IPQ806X17config SND_SOC_LPASS_IPQ806X
17 tristate18 tristate
19 depends on HAS_DMA
18 select SND_SOC_LPASS_CPU20 select SND_SOC_LPASS_CPU
19 select SND_SOC_LPASS_PLATFORM21 select SND_SOC_LPASS_PLATFORM
20 22
21config SND_SOC_LPASS_APQ801623config SND_SOC_LPASS_APQ8016
22 tristate24 tristate
25 depends on HAS_DMA
23 select SND_SOC_LPASS_CPU26 select SND_SOC_LPASS_CPU
24 select SND_SOC_LPASS_PLATFORM27 select SND_SOC_LPASS_PLATFORM
25 28
26config SND_SOC_STORM29config SND_SOC_STORM
27 tristate "ASoC I2S support for Storm boards"30 tristate "ASoC I2S support for Storm boards"
28 depends on SND_SOC_QCOM31 depends on SND_SOC_QCOM && HAS_DMA
29 select SND_SOC_LPASS_IPQ806X32 select SND_SOC_LPASS_IPQ806X
30 select SND_SOC_MAX98357A33 select SND_SOC_MAX98357A
31 help34 help
@@ -34,7 +37,7 @@ config SND_SOC_STORM · 2 unmodified lines
34 37
35config SND_SOC_APQ8016_SBC38config SND_SOC_APQ8016_SBC
36 tristate "SoC Audio support for APQ8016 SBC platforms"39 tristate "SoC Audio support for APQ8016 SBC platforms"
37 depends on SND_SOC_QCOM40 depends on SND_SOC_QCOM && HAS_DMA
38 select SND_SOC_LPASS_APQ801641 select SND_SOC_LPASS_APQ8016
39 help42 help
40 Support for Qualcomm Technologies LPASS audio block in43 Support for Qualcomm Technologies LPASS audio block in
sound/soc/qcom/apq8016_sbc.c+7−3
@@ -30,6 +30,7 @@ struct apq8016_sbc_data { · 29 unmodified lines
30 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */30 struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
31};31};
32 32
33#define MIC_CTRL_TER_WS_SLAVE_SEL BIT(21)
33#define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17)34#define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17)
34#define MIC_CTRL_TLMM_SCLK_EN BIT(1)35#define MIC_CTRL_TLMM_SCLK_EN BIT(1)
35#define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16))36#define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16))
@@ -53,6 +54,12 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) · 17 unmodified lines
53 MIC_CTRL_TLMM_SCLK_EN,54 MIC_CTRL_TLMM_SCLK_EN,
54 pdata->mic_iomux);55 pdata->mic_iomux);
55 break;56 break;
57 case MI2S_TERTIARY:
58 writel(readl(pdata->mic_iomux) | MIC_CTRL_TER_WS_SLAVE_SEL |
59 MIC_CTRL_TLMM_SCLK_EN,
60 pdata->mic_iomux);
61
62 break;
56 63
57 default:64 default:
58 dev_err(card->dev, "unsupported cpu dai configuration\n");65 dev_err(card->dev, "unsupported cpu dai configuration\n");
@@ -126,9 +133,6 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) · 67 unmodified lines
126 }133 }
127 134
128 link->platform_of_node = link->cpu_of_node;135 link->platform_of_node = link->cpu_of_node;
129 /* For now we only support playback */
130 link->playback_only = true;
131
132 ret = of_property_read_string(np, "link-name", &link->name);136 ret = of_property_read_string(np, "link-name", &link->name);
133 if (ret) {137 if (ret) {
134 dev_err(card->dev, "error getting codec dai_link name\n");138 dev_err(card->dev, "error getting codec dai_link name\n");
sound/soc/qcom/lpass-apq8016.c+24−7
@@ -133,23 +133,36 @@ static struct snd_soc_dai_driver apq8016_lpass_cpu_dai_driver[] = { · 132 unmodified lines
133 },133 },
134};134};
135 135
136static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata)136static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata,
137 int direction)
137{138{
138 struct lpass_variant *v = drvdata->variant;139 struct lpass_variant *v = drvdata->variant;
139 int chan = find_first_zero_bit(&drvdata->rdma_ch_bit_map,140 int chan = 0;
141
142 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
143 chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
140 v->rdma_channels);144 v->rdma_channels);
141 145
142 if (chan >= v->rdma_channels)146 if (chan >= v->rdma_channels)
143 return -EBUSY;147 return -EBUSY;
148 } else {
149 chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
150 v->wrdma_channel_start +
151 v->wrdma_channels,
152 v->wrdma_channel_start);
153
154 if (chan >= v->wrdma_channel_start + v->wrdma_channels)
155 return -EBUSY;
156 }
144 157
145 set_bit(chan, &drvdata->rdma_ch_bit_map);158 set_bit(chan, &drvdata->dma_ch_bit_map);
146 159
147 return chan;160 return chan;
148}161}
149 162
150static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)163static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
151{164{
152 clear_bit(chan, &drvdata->rdma_ch_bit_map);165 clear_bit(chan, &drvdata->dma_ch_bit_map);
153 166
154 return 0;167 return 0;
155}168}
@@ -212,7 +225,11 @@ static struct lpass_variant apq8016_data = { · 56 unmodified lines
212 .rdma_reg_base = 0x8400,225 .rdma_reg_base = 0x8400,
213 .rdma_reg_stride = 0x1000,226 .rdma_reg_stride = 0x1000,
214 .rdma_channels = 2,227 .rdma_channels = 2,
215 .rdmactl_audif_start = 1,228 .dmactl_audif_start = 1,
229 .wrdma_reg_base = 0xB000,
230 .wrdma_reg_stride = 0x1000,
231 .wrdma_channel_start = 5,
232 .wrdma_channels = 2,
216 .dai_driver = apq8016_lpass_cpu_dai_driver,233 .dai_driver = apq8016_lpass_cpu_dai_driver,
217 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),234 .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
218 .init = apq8016_lpass_init,235 .init = apq8016_lpass_init,
sound/soc/qcom/lpass-cpu.c+114−32
@@ -120,31 +120,60 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, · 119 unmodified lines
120 return -EINVAL;120 return -EINVAL;
121 }121 }
122 122
123 switch (channels) {123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
124 case 1:124 switch (channels) {
125 regval |= LPAIF_I2SCTL_SPKMODE_SD0;125 case 1:
126 regval |= LPAIF_I2SCTL_SPKMONO_MONO;126 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
127 break;127 regval |= LPAIF_I2SCTL_SPKMONO_MONO;
128 case 2:128 break;
129 regval |= LPAIF_I2SCTL_SPKMODE_SD0;129 case 2:
130 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;130 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
131 break;131 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
132 case 4:132 break;
133 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;133 case 4:
134 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;134 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
135 break;135 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
136 case 6:136 break;
137 regval |= LPAIF_I2SCTL_SPKMODE_6CH;
138 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
139 break;
140 case 8:
141 regval |= LPAIF_I2SCTL_SPKMODE_8CH;
142 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
143 break;
144 default:
145 dev_err(dai->dev, "%s() invalid channels given: %u\n",
146 __func__, channels);
147 return -EINVAL;

173 more lines aren’t shown here.

sound/soc/qcom/lpass-ipq806x.c+9−2

This diff is large: its 26 lines aren’t shown here.

sound/soc/qcom/lpass-lpaif-reg.h+83−33

This diff is large: its 128 lines aren’t shown here.

sound/soc/qcom/lpass-platform.c+147−97

This diff is large: its 413 lines aren’t shown here.

sound/soc/qcom/lpass.h+7−3

This diff is large: its 32 lines aren’t shown here.

sound/soc/rockchip/rockchip_i2s.c+13−0

This diff is large: its 32 lines aren’t shown here.

sound/soc/rockchip/rockchip_spdif.c+12−5

This diff is large: its 44 lines aren’t shown here.

sound/soc/samsung/s3c-i2s-v2.c+1−1

This diff is large: its 9 lines aren’t shown here.

sound/soc/samsung/s3c-i2s-v2.h+1−1

This diff is large: its 9 lines aren’t shown here.

sound/soc/sh/rcar/adg.c+119−99

This diff is large: its 266 lines aren’t shown here.

sound/soc/sh/rcar/cmd.c+12−6

This diff is large: its 52 lines aren’t shown here.

sound/soc/sh/rcar/core.c+119−41

This diff is large: its 278 lines aren’t shown here.

sound/soc/sh/rcar/ctu.c+272−9

This diff is large: its 337 lines aren’t shown here.

sound/soc/sh/rcar/dma.c+29−27

This diff is large: its 91 lines aren’t shown here.

sound/soc/sh/rcar/dvc.c+28−5

This diff is large: its 67 lines aren’t shown here.

sound/soc/sh/rcar/gen.c+37−19

This diff is large: its 79 lines aren’t shown here.

sound/soc/sh/rcar/mix.c+2−2

This diff is large: its 18 lines aren’t shown here.

sound/soc/sh/rcar/rsnd.h+86−29

This diff is large: its 259 lines aren’t shown here.

sound/soc/sh/rcar/rsrc-card.c+18−9

This diff is large: its 69 lines aren’t shown here.

sound/soc/sh/rcar/src.c+70−101

This diff is large: its 406 lines aren’t shown here.

sound/soc/sh/rcar/ssi.c+174−160

This diff is large: its 601 lines aren’t shown here.

sound/soc/sh/rcar/ssiu.c+11−9

This diff is large: its 65 lines aren’t shown here.

sound/soc/soc-core.c+4−4

This diff is large: its 21 lines aren’t shown here.

sound/soc/soc-dapm.c+2−2

This diff is large: its 18 lines aren’t shown here.

sound/soc/soc-pcm.c+12−12

This diff is large: its 38 lines aren’t shown here.

sound/soc/soc-topology.c+154−86

This diff is large: its 309 lines aren’t shown here.

sound/soc/sunxi/Kconfig+8−0

This diff is large: its 13 lines aren’t shown here.

sound/soc/sunxi/Makefile+1−0

This diff is large: its 4 lines aren’t shown here.

sound/soc/sunxi/sun4i-spdif.c+550−0

This diff is large: its 551 lines aren’t shown here.

sound/usb/card.c+53−3

This diff is large: its 108 lines aren’t shown here.

sound/usb/clock.c+2−0

This diff is large: its 9 lines aren’t shown here.

sound/usb/endpoint.c+3−0

This diff is large: its 10 lines aren’t shown here.

sound/usb/midi.c+9−6

This diff is large: its 34 lines aren’t shown here.

sound/usb/midi.h+12−2

This diff is large: its 23 lines aren’t shown here.

sound/usb/mixer_quirks.c+4−0

This diff is large: its 12 lines aren’t shown here.

sound/usb/pcm.c+2−0

This diff is large: its 9 lines aren’t shown here.

sound/usb/quirks.c+35−23

This diff is large: its 151 lines aren’t shown here.

sound/usb/quirks.h+2−1

This diff is large: its 10 lines aren’t shown here.