History

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

Pull sound updates from Takashi Iwai: "At this time, it's an interesting mixture of changes for both old and new stuff. Majority of changes are about ASoC (lots of systematic changes for converting remove callbacks to void, and cleanups), while we got the fixes and the enhancements of very old PCI cards, too. Here are some highlights: ALSA/ASoC Core: - Continued effort of more ASoC core cleanups - Minor improvements for XRUN handling in indirect PCM helpers - Code refactoring of PCM core code ASoC: - Continued feature and simplification work on SOF, including addition of a no-DSP mode for bringup, HDA MLink and extensions to the IPC4 protocol - Hibernation support for CS35L45 - More DT binding conversions - Support for Cirrus Logic CS35L56, Freescale QMC, Maxim MAX98363, nVidia systems with MAX9809x and RT5631, Realtek RT712, Renesas R-Car Gen4, Rockchip RK3588 and TI TAS5733 ALSA: - Lots of works for legacy emu10k1 and ymfpci PCI drivers - PCM kselftest fixes and enhancements" * tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (586 commits) ALSA: emu10k1: use high-level I/O in set_filterQ() ALSA: emu10k1: use high-level I/O functions also during init ALSA: emu10k1: fix error handling in snd_audigy_i2c_volume_put() ALSA: emu10k1: don't stop DSP in _snd_emu10k1_{,audigy_}init_efx() ALSA: emu10k1: fix SNDRV_EMU10K1_IOCTL_SINGLE_STEP ALSA: emu10k1: skip Sound Blaster-specific hacks for E-MU cards ALSA: emu10k1: fixup DSP defines ALSA: emu10k1: pull in some register definitions from kX-project ALSA: emu10k1: remove some bogus defines ALSA: emu10k1: eliminate some unused defines ALSA: emu10k1: fix lineup of EMU_HANA_* defines ALSA: emu10k1: comment updates ALSA: emu10k1: fix snd_emu1010_fpga_read() input masking for rev2 cards ALSA: emu10k1: remove unused emu->pcm_playback_efx_substream field ALSA: emu10k1: remove unused `resume` parameter from snd_emu10k1_init() ALSA: emu10k1: minor optimizations ALSA: emu10k1: remove remaining cruft from snd_emu10k1_emu1010_init() ALSA: emu10k1: remove apparently pointless EMU_HANA_OPTION_CARDS reads ALSA: emu10k1: remove apparently pointless FPGA reads ALSA: emu10k1: stop doing weird things with HCFG in snd_emu10k1_emu1010_init() ...

Linus Torvalds committed 3 years ago

Commit 1c15ca42 parents 34b62f1 baa6584520 files · +19877 −6275Browse files

Unified · Split

520 files
  1. Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml +162 −0
  2. Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml +205 −0
  3. Documentation/devicetree/bindings/sound/adi,adau1372.yaml +1 −1
  4. Documentation/devicetree/bindings/sound/adi,adau17x1.txt +0 −32
  5. Documentation/devicetree/bindings/sound/adi,adau17x1.yaml +52 −0
  6. Documentation/devicetree/bindings/sound/adi,max98363.yaml +60 −0
  7. Documentation/devicetree/bindings/sound/adi,max98396.yaml +4 −4
  8. Documentation/devicetree/bindings/sound/ak4458.txt +0 −28
  9. Documentation/devicetree/bindings/sound/ak5558.txt +0 −24
  10. Documentation/devicetree/bindings/sound/alc5632.txt +0 −43
  11. Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml +73 −0
  12. Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml +48 −0
  13. Documentation/devicetree/bindings/sound/audio-graph-port.yaml +11 −11
  14. Documentation/devicetree/bindings/sound/audio-graph.yaml +4 −4
  15. Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml +9 −1
  16. Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml +79 −1
  17. Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml +6 −6
  18. Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml +66 −0
  19. Documentation/devicetree/bindings/sound/everest,es8316.yaml +4 −0
  20. Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml +117 −0
  21. Documentation/devicetree/bindings/sound/max98371.txt +0 −17
  22. Documentation/devicetree/bindings/sound/max9867.txt +0 −17
  23. Documentation/devicetree/bindings/sound/maxim,max9759.txt +0 −18
  24. Documentation/devicetree/bindings/sound/maxim,max9759.yaml +45 −0
  25. Documentation/devicetree/bindings/sound/maxim,max98371.yaml +42 −0
  26. Documentation/devicetree/bindings/sound/maxim,max9867.yaml +60 −0
  27. Documentation/devicetree/bindings/sound/mt8186-afe-pcm.yaml +3 −3
  28. Documentation/devicetree/bindings/sound/mt8186-mt6366-da7219-max98357.yaml +1 −1
  29. Documentation/devicetree/bindings/sound/mt8186-mt6366-rt1019-rt5682s.yaml +1 −1
  30. Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml +3 −3
  31. Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml +2 −2
  32. Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml +1 −1
  33. Documentation/devicetree/bindings/sound/mt8195-mt6359.yaml +4 −4
  34. Documentation/devicetree/bindings/sound/nau8825.txt +3 −0
  35. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.yaml +4 −4
  36. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-common.yaml +4 −0
  37. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max9808x.yaml +90 −0
  38. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.yaml +4 −4
  39. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5631.yaml +85 −0
  40. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.yaml +3 −3
  41. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5677.yaml +13 −13
  42. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.yaml +3 −3
  43. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.yaml +3 −3
  44. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.yaml +4 −4
  45. Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.yaml +4 −4
  46. Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml +63 −14
  47. Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml +64 −17
  48. Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml +75 −11
  49. Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml +21 −2
  50. Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml +1 −1
  51. Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +0 −123
  52. Documentation/devicetree/bindings/sound/qcom,wcd9335.yaml +156 −0
  53. Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml +1 −0
  54. Documentation/devicetree/bindings/sound/realtek,alc5632.yaml +63 −0
  55. Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +97 −32
  56. Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml +12 −9
  57. Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml +7 −0
  58. Documentation/devicetree/bindings/sound/rockchip-i2s.yaml +5 −0
  59. Documentation/devicetree/bindings/sound/sgtl5000.yaml +3 −3
  60. Documentation/devicetree/bindings/sound/simple-card.yaml +1 −1
  61. Documentation/devicetree/bindings/sound/socionext,uniphier-aio.yaml +1 −1
  62. Documentation/devicetree/bindings/sound/tas571x.txt +1 −0
  63. Documentation/devicetree/bindings/sound/wlf,wm8510.yaml +41 −0
  64. Documentation/devicetree/bindings/sound/wlf,wm8523.yaml +40 −0
  65. Documentation/devicetree/bindings/sound/wlf,wm8524.yaml +40 −0
  66. Documentation/devicetree/bindings/sound/wlf,wm8580.yaml +42 −0
  67. Documentation/devicetree/bindings/sound/wlf,wm8711.yaml +40 −0
  68. Documentation/devicetree/bindings/sound/wlf,wm8728.yaml +40 −0
  69. Documentation/devicetree/bindings/sound/wlf,wm8737.yaml +40 −0
  70. Documentation/devicetree/bindings/sound/wlf,wm8753.yaml +62 −0
  71. Documentation/devicetree/bindings/sound/wlf,wm8960.yaml +88 −0
  72. Documentation/devicetree/bindings/sound/wlf,wm8994.yaml +194 −0
  73. Documentation/devicetree/bindings/sound/wm8510.txt +0 −18
  74. Documentation/devicetree/bindings/sound/wm8523.txt +0 −16
  75. Documentation/devicetree/bindings/sound/wm8524.txt +0 −16
  76. Documentation/devicetree/bindings/sound/wm8580.txt +0 −16
  77. Documentation/devicetree/bindings/sound/wm8711.txt +0 −18
  78. Documentation/devicetree/bindings/sound/wm8728.txt +0 −18
  79. Documentation/devicetree/bindings/sound/wm8737.txt +0 −18
  80. Documentation/devicetree/bindings/sound/wm8753.txt +0 −40
  81. Documentation/devicetree/bindings/sound/wm8960.txt +0 −42
  82. Documentation/devicetree/bindings/sound/wm8994.txt +0 −112
  83. Documentation/sound/alsa-configuration.rst +3 −2
  84. Documentation/sound/cards/audigy-mixer.rst +15 −12
  85. Documentation/sound/cards/sb-live-mixer.rst +10 −7
  86. Documentation/sound/hd-audio/index.rst +1 −0
  87. Documentation/sound/hd-audio/intel-multi-link.rst +312 −0
  88. Documentation/sound/kernel-api/writing-an-alsa-driver.rst +428 −660
  89. MAINTAINERS +34 −2
  90. arch/powerpc/platforms/8xx/cpm1.c +1 −1
  91. drivers/firmware/cirrus/cs_dsp.c +47 −1
  92. drivers/soc/fsl/qe/Kconfig +23 −0
  93. drivers/soc/fsl/qe/Makefile +2 −0
  94. drivers/soc/fsl/qe/qmc.c +1537 −0
  95. drivers/soc/fsl/qe/tsa.c +846 −0
  96. drivers/soc/fsl/qe/tsa.h +42 −0
  97. include/dt-bindings/soc/cpm1-fsl,tsa.h +13 −0
  98. include/dt-bindings/sound/cs35l45.h +57 −0
  99. include/linux/firmware/cirrus/cs_dsp.h +1 −0
  100. include/soc/fsl/qe/qmc.h +71 −0
  101. include/sound/ac97_codec.h +3 −0
  102. include/sound/cs35l41.h +12 −1
  103. include/sound/cs35l56.h +266 −0
  104. include/sound/emu10k1.h +344 −389
  105. include/sound/hda-mlink.h +166 −0
  106. include/sound/hda_register.h +38 −2
  107. include/sound/pcm-indirect.h +16 −6
  108. include/sound/pcm.h +7 −7
  109. include/sound/soc-card.h +16 −1
  110. include/sound/soc-dapm.h +0 −5
  111. include/sound/soc-dpcm.h +0 −1
  112. include/sound/soc.h +109 −10
  113. include/sound/sof.h +5 −0
  114. include/sound/sof/ipc4/header.h +33 −0
  115. include/uapi/sound/asound.h +10 −4
  116. include/uapi/sound/emu10k1.h +96 −54
  117. include/uapi/sound/sof/abi.h +2 −0
  118. include/uapi/sound/sof/header.h +19 −8
  119. include/uapi/sound/sof/tokens.h +13 −8
  120. sound/ac97_bus.c +0 −11
  121. sound/arm/pxa2xx-ac97.c +2 −4
  122. sound/atmel/ac97c.c +2 −4
  123. sound/core/pcm_lib.c +41 −56
  124. sound/core/pcm_local.h +1 −2
  125. sound/core/pcm_native.c +7 −7
  126. sound/drivers/mts64.c +2 −4
  127. sound/drivers/portman2x4.c +2 −14
  128. sound/mips/hal2.c +2 −3
  129. sound/mips/sgio2audio.c +2 −3
  130. sound/pci/Kconfig +2 −2
  131. sound/pci/asihpi/hpi6000.c +0 −2
  132. sound/pci/emu10k1/emu10k1.c +0 −11
  133. sound/pci/emu10k1/emu10k1_callback.c +1 −4
  134. sound/pci/emu10k1/emu10k1_main.c +97 −159
  135. sound/pci/emu10k1/emufx.c +32 −37
  136. sound/pci/emu10k1/emumixer.c +23 −22
  137. sound/pci/emu10k1/emupcm.c +13 −67
  138. sound/pci/emu10k1/emuproc.c +1 −4
  139. sound/pci/emu10k1/io.c +27 −34
  140. sound/pci/emu10k1/irq.c +5 −27
  141. sound/pci/emu10k1/p16v.c +44 −69
  142. sound/pci/emu10k1/p16v.h +1 −1
  143. sound/pci/emu10k1/p17v.h +2 −2
  144. sound/pci/hda/cs35l41_hda.c +3 −3
  145. sound/pci/hda/hda_intel.c +3 −0
  146. sound/pci/hda/hda_tegra.c +2 −4
  147. sound/pci/hda/patch_hdmi.c +4 −8
  148. sound/pci/rme9652/hdspm.c +0 −6
  149. sound/pci/ymfpci/ymfpci.c +26 −13
  150. sound/pci/ymfpci/ymfpci.h +47 −7
  151. sound/pci/ymfpci/ymfpci_main.c +22 −57
  152. sound/ppc/powermac.c +2 −3
  153. sound/ppc/tumbler.c +2 −2
  154. sound/sh/aica.c +2 −5
  155. sound/sh/sh_dac_audio.c +2 −3
  156. sound/soc/adi/axi-i2s.c +2 −4
  157. sound/soc/adi/axi-spdif.c +2 −4
  158. sound/soc/amd/Kconfig +2 −0
  159. sound/soc/amd/acp-pcm-dma.c +2 −4
  160. sound/soc/amd/acp/acp-rembrandt.c +3 −10
  161. sound/soc/amd/acp/acp-renoir.c +2 −3
  162. sound/soc/amd/ps/acp63.h +2 −0
  163. sound/soc/amd/ps/pci-ps.c +7 −3
  164. sound/soc/amd/ps/ps-pdm-dma.c +2 −3
  165. sound/soc/amd/raven/acp3x-pcm-dma.c +2 −3
  166. sound/soc/amd/renoir/acp3x-pdm-dma.c +2 −3
  167. sound/soc/amd/vangogh/acp5x-mach.c +144 −153
  168. sound/soc/amd/vangogh/acp5x-pcm-dma.c +2 −3
  169. sound/soc/amd/yc/acp6x-mach.c +21 −0
  170. sound/soc/amd/yc/acp6x-pdm-dma.c +2 −3
  171. sound/soc/amd/yc/acp6x.h +3 −0
  172. sound/soc/amd/yc/pci-acp6x.c +7 −1
  173. sound/soc/apple/mca.c +2 −3
  174. sound/soc/atmel/atmel-classd.c +1 −4
  175. sound/soc/atmel/atmel-i2s.c +2 −4
  176. sound/soc/atmel/atmel-pdmic.c +1 −4
  177. sound/soc/atmel/atmel_wm8904.c +2 −4
  178. sound/soc/atmel/mchp-i2s-mcc.c +2 −4
  179. sound/soc/atmel/mchp-pdmc.c +9 −16
  180. sound/soc/atmel/mchp-spdifrx.c +2 −4
  181. sound/soc/atmel/mchp-spdiftx.c +17 −34
  182. sound/soc/atmel/mikroe-proto.c +2 −4
  183. sound/soc/atmel/sam9g20_wm8731.c +2 −4
  184. sound/soc/atmel/sam9x5_wm8731.c +2 −4
  185. sound/soc/atmel/tse850-pcm5142.c +2 −4
  186. sound/soc/au1x/ac97c.c +2 −4
  187. sound/soc/au1x/i2sc.c +2 −4
  188. sound/soc/au1x/psc-ac97.c +2 −4
  189. sound/soc/au1x/psc-i2s.c +2 −4
  190. sound/soc/bcm/bcm63xx-i2s-whistler.c +2 −3
  191. sound/soc/bcm/cygnus-ssp.c +2 −4
  192. sound/soc/cirrus/Kconfig +5 −1
  193. sound/soc/cirrus/edb93xx.c +2 −4
  194. sound/soc/cirrus/ep93xx-i2s.c +21 −4
  195. sound/soc/codecs/Kconfig +62 −0
  196. sound/soc/codecs/Makefile +14 −0
  197. sound/soc/codecs/adau1977-spi.c +1 −1
  198. sound/soc/codecs/cs35l41-lib.c +72 −1
  199. sound/soc/codecs/cs35l41.c +76 −68
  200. sound/soc/codecs/cs35l41.h +1 −0
  201. sound/soc/codecs/cs35l45-i2c.c +3 −0
  202. sound/soc/codecs/cs35l45-spi.c +5 −0
  203. sound/soc/codecs/cs35l45-tables.c +133 −2
  204. sound/soc/codecs/cs35l45.c +620 −10
  205. sound/soc/codecs/cs35l45.h +266 −1
  206. sound/soc/codecs/cs35l56-i2c.c +82 −0
  207. sound/soc/codecs/cs35l56-sdw.c +566 −0
  208. sound/soc/codecs/cs35l56-shared.c +362 −0
  209. sound/soc/codecs/cs35l56-spi.c +79 −0
  210. sound/soc/codecs/cs35l56.c +1601 −0
  211. sound/soc/codecs/cs35l56.h +81 −0
  212. sound/soc/codecs/cs4271-i2c.c +0 −1
  213. sound/soc/codecs/cs4271-spi.c +0 −1
  214. sound/soc/codecs/cs4271.c +2 −2
  215. sound/soc/codecs/cs42l42-sdw.c +0 −3
  216. sound/soc/codecs/cs47l15.c +2 −4
  217. sound/soc/codecs/cs47l24.c +2 −4
  218. sound/soc/codecs/cs47l35.c +2 −4
  219. sound/soc/codecs/cs47l85.c +2 −4
  220. sound/soc/codecs/cs47l90.c +2 −4
  221. sound/soc/codecs/cs47l92.c +2 −4
  222. sound/soc/codecs/da7218.c +3 −7
  223. sound/soc/codecs/da7219-aad.c +29 −31
  224. sound/soc/codecs/da7219-aad.h +2 −3
  225. sound/soc/codecs/es8316.c +18 −15
  226. sound/soc/codecs/inno_rk3036.c +2 −4
  227. sound/soc/codecs/lpass-macro-common.c +1 −1
  228. sound/soc/codecs/lpass-macro-common.h +3 −0
  229. sound/soc/codecs/lpass-rx-macro.c +30 −12
  230. sound/soc/codecs/lpass-tx-macro.c +29 −12
  231. sound/soc/codecs/lpass-va-macro.c +2 −4
  232. sound/soc/codecs/lpass-wsa-macro.c +31 −12
  233. sound/soc/codecs/max98363.c +464 −0
  234. sound/soc/codecs/max98363.h +36 −0
  235. sound/soc/codecs/max98373-sdw.c +7 −27
  236. sound/soc/codecs/max9867.c +17 −2
  237. sound/soc/codecs/msm8916-wcd-analog.c +2 −4
  238. sound/soc/codecs/msm8916-wcd-digital.c +2 −4
  239. sound/soc/codecs/mt6358.c +1 −1
  240. sound/soc/codecs/mt6359.c +1 −1
  241. sound/soc/codecs/nau8821.c +96 −0
  242. sound/soc/codecs/nau8821.h +23 −0
  243. sound/soc/codecs/nau8825.c +7 −1
  244. sound/soc/codecs/nau8825.h +1 −0
  245. sound/soc/codecs/pcm179x-spi.c +1 −1
  246. sound/soc/codecs/rk817_codec.c +2 −4
  247. sound/soc/codecs/rt1019.c +1 −1
  248. sound/soc/codecs/rt1308-sdw.c +7 −23
  249. sound/soc/codecs/rt1308-sdw.h +0 −4
  250. sound/soc/codecs/rt1316-sdw.c +7 −23
  251. sound/soc/codecs/rt1316-sdw.h +0 −4
  252. sound/soc/codecs/rt1318-sdw.c +7 −23
  253. sound/soc/codecs/rt1318-sdw.h +0 −4
  254. sound/soc/codecs/rt5682-sdw.c +7 −27
  255. sound/soc/codecs/rt700.c +7 −23
  256. sound/soc/codecs/rt700.h +0 −4
  257. sound/soc/codecs/rt711-sdca.c +7 −23
  258. sound/soc/codecs/rt711-sdca.h +0 −4
  259. sound/soc/codecs/rt711.c +7 −23
  260. sound/soc/codecs/rt711.h +0 −4
  261. sound/soc/codecs/rt712-sdca-dmic.c +983 −0
  262. sound/soc/codecs/rt712-sdca-dmic.h +108 −0
  263. sound/soc/codecs/rt712-sdca.c +7 −23
  264. sound/soc/codecs/rt712-sdca.h +0 −4
  265. sound/soc/codecs/rt715-sdca.c +7 −23
  266. sound/soc/codecs/rt715-sdca.h +0 −4
  267. sound/soc/codecs/rt715.c +7 −23
  268. sound/soc/codecs/rt715.h +0 −4
  269. sound/soc/codecs/sdw-mockup.c +6 −28
  270. sound/soc/codecs/sma1303.c +1 −1
  271. sound/soc/codecs/src4xxx-i2c.c +1 −1
  272. sound/soc/codecs/ssm2602.c +12 −3
  273. sound/soc/codecs/sta32x.c +18 −21
  274. sound/soc/codecs/sta350.c +28 −35
  275. sound/soc/codecs/tas5086.c +1 −1
  276. sound/soc/codecs/tas571x.c +59 −0
  277. sound/soc/codecs/tas5720.c +2 −1
  278. sound/soc/codecs/wcd9335.c +11 −16
  279. sound/soc/codecs/wcd934x.c +10 −15
  280. sound/soc/codecs/wcd938x.c +12 −21
  281. sound/soc/codecs/wm5102.c +2 −4
  282. sound/soc/codecs/wm5110.c +2 −4
  283. sound/soc/codecs/wm8903.c +0 −1
  284. sound/soc/codecs/wm8994.c +2 −4
  285. sound/soc/codecs/wm8997.c +2 −4
  286. sound/soc/codecs/wm8998.c +2 −4
  287. sound/soc/codecs/wm_adsp.c +48 −15
  288. sound/soc/codecs/wm_adsp.h +3 −0
  289. sound/soc/codecs/zl38060.c +1 −1
  290. sound/soc/dwc/dwc-i2s.c +2 −3
  291. sound/soc/fsl/Kconfig +9 −0
  292. sound/soc/fsl/Makefile +2 −0
  293. sound/soc/fsl/eukrea-tlv320.c +2 −4
  294. sound/soc/fsl/fsl-asoc-card.c +6 −3
  295. sound/soc/fsl/fsl_asrc.c +2 −4
  296. sound/soc/fsl/fsl_aud2htx.c +2 −4
  297. sound/soc/fsl/fsl_audmix.c +2 −4
  298. sound/soc/fsl/fsl_dma.c +2 −4
  299. sound/soc/fsl/fsl_easrc.c +2 −4
  300. sound/soc/fsl/fsl_esai.c +2 −4
  301. sound/soc/fsl/fsl_mqs.c +7 −13
  302. sound/soc/fsl/fsl_qmc_audio.c +735 −0
  303. sound/soc/fsl/fsl_rpmsg.c +2 −4
  304. sound/soc/fsl/fsl_sai.c +8 −10
  305. sound/soc/fsl/fsl_spdif.c +2 −4
  306. sound/soc/fsl/fsl_ssi.c +3 −5
  307. sound/soc/fsl/fsl_xcvr.c +2 −3
  308. sound/soc/fsl/imx-audmix.c +11 −11
  309. sound/soc/fsl/imx-audmux.c +2 −4
  310. sound/soc/fsl/imx-card.c +1 −1
  311. sound/soc/fsl/imx-es8328.c +7 −4
  312. sound/soc/fsl/imx-pcm-rpmsg.c +2 −4
  313. sound/soc/fsl/imx-sgtl5000.c +2 −4
  314. sound/soc/fsl/imx-spdif.c +7 −4
  315. sound/soc/fsl/mpc5200_psc_ac97.c +2 −3
  316. sound/soc/fsl/mpc5200_psc_i2s.c +2 −3
  317. sound/soc/fsl/mpc8610_hpcd.c +2 −4
  318. sound/soc/fsl/p1022_ds.c +2 −4
  319. sound/soc/fsl/p1022_rdk.c +2 −4
  320. sound/soc/fsl/pcm030-audio-fabric.c +2 −4
  321. sound/soc/generic/audio-graph-card.c +13 −2
  322. sound/soc/generic/audio-graph-card2-custom-sample.c +3 −0
  323. sound/soc/generic/audio-graph-card2.c +20 −3
  324. sound/soc/generic/simple-card-utils.c +22 −13
  325. sound/soc/generic/simple-card.c +22 −1
  326. sound/soc/generic/test-component.c +2 −4
  327. sound/soc/img/img-i2s-in.c +2 −4
  328. sound/soc/img/img-i2s-out.c +2 −4
  329. sound/soc/img/img-parallel-out.c +2 −4
  330. sound/soc/img/img-spdif-in.c +2 −4
  331. sound/soc/img/img-spdif-out.c +2 −4
  332. sound/soc/img/pistachio-internal-dac.c +2 −4
  333. sound/soc/intel/atom/sst-mfld-platform-pcm.c +2 −3
  334. sound/soc/intel/atom/sst/sst_acpi.c +2 −3
  335. sound/soc/intel/avs/boards/hdaudio.c +4 −6
  336. sound/soc/intel/avs/path.c +1 −1
  337. sound/soc/intel/boards/bytcht_es8316.c +2 −3
  338. sound/soc/intel/boards/bytcr_rt5640.c +2 −3
  339. sound/soc/intel/boards/bytcr_rt5651.c +2 −3
  340. sound/soc/intel/boards/bytcr_wm5102.c +2 −3
  341. sound/soc/intel/boards/cht_bsw_max98090_ti.c +2 −4
  342. sound/soc/intel/boards/sof_cirrus_common.c +6 −1
  343. sound/soc/intel/boards/sof_es8336.c +2 −4
  344. sound/soc/intel/boards/sof_pcm512x.c +2 −4
  345. sound/soc/intel/boards/sof_rt5682.c +23 −5
  346. sound/soc/intel/boards/sof_sdw.c +121 −66
  347. sound/soc/intel/boards/sof_sdw_common.h +0 −3
  348. sound/soc/intel/boards/sof_sdw_max98373.c +11 −11
  349. sound/soc/intel/boards/sof_wm8804.c +2 −3
  350. sound/soc/intel/catpt/device.c +2 −4
  351. sound/soc/intel/common/soc-acpi-intel-rpl-match.c +33 −1
  352. sound/soc/intel/skylake/skl-ssp-clk.c +2 −4
  353. sound/soc/kirkwood/kirkwood-i2s.c +2 −4
  354. sound/soc/mediatek/common/mtk-btcvsd.c +2 −3
  355. sound/soc/mediatek/common/mtk-soundcard-driver.c +9 −3
  356. sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +2 −4
  357. sound/soc/mediatek/mt6797/mt6797-afe-pcm.c +2 −4
  358. sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +2 −3
  359. sound/soc/mediatek/mt8183/mt8183-afe-pcm.c +2 −4
  360. sound/soc/mediatek/mt8186/mt8186-afe-gpio.c +14 −14
  361. sound/soc/mediatek/mt8186/mt8186-dai-adda.c +2 −2
  362. sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c +1 −1
  363. sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c +3 −3
  364. sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +2 −4
  365. sound/soc/mediatek/mt8192/mt8192-afe-clk.c +0 −4
  366. sound/soc/mediatek/mt8192/mt8192-afe-pcm.c +3 −8
  367. sound/soc/mediatek/mt8192/mt8192-dai-tdm.c +13 −15
  368. sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c +5 −7
  369. sound/soc/mediatek/mt8195/mt8195-afe-pcm.c +2 −3
  370. sound/soc/mediatek/mt8195/mt8195-dai-adda.c +11 −6
  371. sound/soc/mediatek/mt8195/mt8195-dai-etdm.c +154 −23
  372. sound/soc/mediatek/mt8195/mt8195-dai-pcm.c +20 −6
  373. sound/soc/mediatek/mt8195/mt8195-mt6359.c +1 −1
  374. sound/soc/meson/aiu.c +2 −4
  375. sound/soc/meson/axg-card.c +2 −1
  376. sound/soc/meson/axg-tdm-interface.c +4 −9
  377. sound/soc/meson/gx-card.c +2 −1
  378. sound/soc/meson/meson-codec-glue.c +3 −2
  379. sound/soc/mxs/mxs-sgtl5000.c +3 −5
  380. sound/soc/pxa/mmp-sspa.c +3 −4
  381. sound/soc/pxa/pxa2xx-ac97.c +2 −3
  382. sound/soc/qcom/common.c +15 −2
  383. sound/soc/qcom/qdsp6/q6apm-lpass-dais.c +3 −0
  384. sound/soc/qcom/qdsp6/q6apm.c +1 −1
  385. sound/soc/qcom/qdsp6/q6routing.c +2 −4
  386. sound/soc/qcom/sdw.c +2 −5
  387. sound/soc/rockchip/rockchip_i2s.c +3 −4
  388. sound/soc/rockchip/rockchip_pdm.c +2 −4
  389. sound/soc/rockchip/rockchip_rt5645.c +2 −4
  390. sound/soc/rockchip/rockchip_spdif.c +2 −4
  391. sound/soc/samsung/aries_wm8994.c +4 −2
  392. sound/soc/samsung/arndale.c +2 −3
  393. sound/soc/samsung/bells.c +14 −7
  394. sound/soc/samsung/i2s.c +4 −6
  395. sound/soc/samsung/littlemill.c +2 −1
  396. sound/soc/samsung/lowland.c +2 −1
  397. sound/soc/samsung/odroid.c +2 −4
  398. sound/soc/samsung/pcm.c +2 −4
  399. sound/soc/samsung/snow.c +2 −4
  400. sound/soc/samsung/spdif.c +2 −4
  401. sound/soc/samsung/speyside.c +2 −1
  402. sound/soc/sh/fsi.c +3 −5
  403. sound/soc/sh/hac.c +2 −3
  404. sound/soc/sh/rcar/core.c +2 −4
  405. sound/soc/sh/rcar/ssi.c +2 −2
  406. sound/soc/sh/rz-ssi.c +46 −23
  407. sound/soc/sh/siu_dai.c +2 −3
  408. sound/soc/soc-component.c +6 −6
  409. sound/soc/soc-compress.c +33 −37
  410. sound/soc/soc-core.c +25 −27
  411. sound/soc/soc-dai.c +3 −0
  412. sound/soc/soc-dapm.c +171 −153
  413. sound/soc/soc-jack.c +1 −0
  414. sound/soc/soc-pcm.c +11 −26
  415. sound/soc/soc-topology.c +7 −3
  416. sound/soc/sof/amd/acp-common.c +1 −16
  417. sound/soc/sof/amd/acp-pcm.c +34 −0
  418. sound/soc/sof/amd/acp.c +29 −16
  419. sound/soc/sof/amd/acp.h +4 −3
  420. sound/soc/sof/amd/pci-rmb.c +2 −89
  421. sound/soc/sof/amd/pci-rn.c +2 −89
  422. sound/soc/sof/amd/rembrandt.c +0 −4
  423. sound/soc/sof/amd/renoir.c +0 −3
  424. sound/soc/sof/compress.c +2 −6
  425. sound/soc/sof/core.c +26 −5
  426. sound/soc/sof/debug.c +1 −0
  427. sound/soc/sof/intel/Kconfig +7 −0
  428. sound/soc/sof/intel/Makefile +4 −1
  429. sound/soc/sof/intel/apl.c +4 −0
  430. sound/soc/sof/intel/cnl.c +4 −0
  431. sound/soc/sof/intel/hda-common-ops.c +0 −1
  432. sound/soc/sof/intel/hda-ctrl.c +6 −3
  433. sound/soc/sof/intel/hda-dai-ops.c +390 −0
  434. sound/soc/sof/intel/hda-dai.c +180 −518
  435. sound/soc/sof/intel/hda-dsp.c +66 −35
  436. sound/soc/sof/intel/hda-ipc.c +3 −0
  437. sound/soc/sof/intel/hda-loader.c +5 −4
  438. sound/soc/sof/intel/hda-mlink.c +799 −23
  439. sound/soc/sof/intel/hda-pcm.c +17 −7
  440. sound/soc/sof/intel/hda-stream.c +59 −34
  441. sound/soc/sof/intel/hda.c +118 −115
  442. sound/soc/sof/intel/hda.h +42 −27
  443. sound/soc/sof/intel/icl.c +4 −0
  444. sound/soc/sof/intel/mtl.c +23 −3
  445. sound/soc/sof/intel/pci-apl.c +2 −0
  446. sound/soc/sof/intel/pci-cnl.c +3 −0
  447. sound/soc/sof/intel/pci-icl.c +2 −0
  448. sound/soc/sof/intel/pci-mtl.c +1 −0
  449. sound/soc/sof/intel/pci-skl.c +2 −0
  450. sound/soc/sof/intel/pci-tgl.c +8 −0
  451. sound/soc/sof/intel/tgl.c +4 −0
  452. sound/soc/sof/ipc3-control.c +28 −62
  453. sound/soc/sof/ipc3-dtrace.c +4 −8
  454. sound/soc/sof/ipc3-pcm.c +3 −4
  455. sound/soc/sof/ipc3-topology.c +10 −23
  456. sound/soc/sof/ipc3.c +3 −9
  457. sound/soc/sof/ipc4-control.c +252 −5
  458. sound/soc/sof/ipc4-mtrace.c +21 −0
  459. sound/soc/sof/ipc4-pcm.c +176 −10
  460. sound/soc/sof/ipc4-topology.c +890 −324
  461. sound/soc/sof/ipc4-topology.h +77 −12
  462. sound/soc/sof/loader.c +2 −2
  463. sound/soc/sof/pcm.c +48 −15
  464. sound/soc/sof/pm.c +5 −0
  465. sound/soc/sof/sof-audio.c +75 −10
  466. sound/soc/sof/sof-audio.h +31 −18
  467. sound/soc/sof/sof-client-ipc-flood-test.c +1 −2
  468. sound/soc/sof/sof-client-probes-ipc3.c +4 −8
  469. sound/soc/sof/sof-client-probes-ipc4.c +2 −2
  470. sound/soc/sof/sof-client.c +3 −0
  471. sound/soc/sof/sof-client.h +4 −0
  472. sound/soc/sof/sof-priv.h +21 −0
  473. sound/soc/sof/topology.c +218 −84
  474. sound/soc/sprd/sprd-mcdt.c +2 −4
  475. sound/soc/stm/stm32_adfsdm.c +2 −4
  476. sound/soc/stm/stm32_i2s.c +3 −5
  477. sound/soc/stm/stm32_sai_sub.c +4 −6
  478. sound/soc/stm/stm32_spdifrx.c +2 −4
  479. sound/soc/sunxi/sun4i-codec.c +2 −4
  480. sound/soc/sunxi/sun4i-i2s.c +2 −4
  481. sound/soc/sunxi/sun4i-spdif.c +2 −4
  482. sound/soc/sunxi/sun50i-dmic.c +2 −4
  483. sound/soc/sunxi/sun8i-codec.c +2 −4
  484. sound/soc/tegra/Kconfig +18 −0
  485. sound/soc/tegra/tegra186_asrc.c +2 −4
  486. sound/soc/tegra/tegra186_dspk.c +2 −4
  487. sound/soc/tegra/tegra20_ac97.c +4 −5
  488. sound/soc/tegra/tegra20_i2s.c +2 −4
  489. sound/soc/tegra/tegra210_admaif.c +2 −4
  490. sound/soc/tegra/tegra210_adx.c +2 −4
  491. sound/soc/tegra/tegra210_ahub.c +2 −4
  492. sound/soc/tegra/tegra210_amx.c +2 −4
  493. sound/soc/tegra/tegra210_dmic.c +2 −4
  494. sound/soc/tegra/tegra210_i2s.c +2 −4
  495. sound/soc/tegra/tegra210_mixer.c +2 −4
  496. sound/soc/tegra/tegra210_mvc.c +2 −4
  497. sound/soc/tegra/tegra210_ope.c +2 −4
  498. sound/soc/tegra/tegra210_sfc.c +2 −4
  499. sound/soc/tegra/tegra30_ahub.c +2 −4
  500. sound/soc/tegra/tegra30_i2s.c +2 −4
  501. sound/soc/tegra/tegra_asoc_machine.c +122 −5
  502. sound/soc/ti/ams-delta.c +2 −3
  503. sound/soc/ti/davinci-i2s.c +2 −4
  504. sound/soc/ti/davinci-mcasp.c +2 −4
  505. sound/soc/ti/omap-hdmi.c +3 −7
  506. sound/soc/ti/omap-mcbsp.c +2 −4
  507. sound/soc/uniphier/evea.c +2 −4
  508. sound/soc/ux500/mop500.c +2 −4
  509. sound/soc/ux500/ux500_msp_dai.c +2 −4
  510. sound/soc/xilinx/xlnx_formatter_pcm.c +2 −3
  511. sound/soc/xilinx/xlnx_spdif.c +2 −3
  512. sound/soc/xtensa/xtfpga-i2s.c +2 −3
  513. sound/sparc/cs4231.c +2 −4
  514. sound/sparc/dbri.c +2 −4
  515. sound/usb/card.c +0 −1
  516. sound/usb/endpoint.c +4 −17
  517. sound/usb/helper.c +0 −1
  518. sound/usb/usbaudio.h +2 −0
  519. tools/testing/selftests/alsa/mixer-test.c +59 −7
  520. tools/testing/selftests/alsa/pcm-test.c +17 −6
Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml+162−0
@@ -0,0 +1,162 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: PowerQUICC CPM QUICC Multichannel Controller (QMC)
8+
9+maintainers:
10+ - Herve Codina <herve.codina@bootlin.com>
11+
12+description:
13+ The QMC (QUICC Multichannel Controller) emulates up to 64 channels within one
14+ serial controller using the same TDM physical interface routed from TSA.
15+
16+properties:
17+ compatible:
18+ items:
19+ - enum:
20+ - fsl,mpc885-scc-qmc
21+ - fsl,mpc866-scc-qmc
22+ - const: fsl,cpm1-scc-qmc
23+
24+ reg:
25+ items:
26+ - description: SCC (Serial communication controller) register base
27+ - description: SCC parameter ram base
28+ - description: Dual port ram base
29+
30+ reg-names:
31+ items:
32+ - const: scc_regs
33+ - const: scc_pram
34+ - const: dpram
35+
36+ interrupts:
37+ maxItems: 1
38+ description: SCC interrupt line in the CPM interrupt controller
39+
40+ fsl,tsa-serial:
41+ $ref: /schemas/types.yaml#/definitions/phandle-array
42+ items:
43+ - items:
44+ - description: phandle to TSA node
45+ - enum: [1, 2, 3]
46+ description: |
47+ TSA serial interface (dt-bindings/soc/cpm1-fsl,tsa.h defines these
48+ values)
49+ - 1: SCC2
50+ - 2: SCC3
51+ - 3: SCC4
52+ description:
53+ Should be a phandle/number pair. The phandle to TSA node and the TSA
54+ serial interface to use.
55+
56+ '#address-cells':
57+ const: 1
58+
59+ '#size-cells':
60+ const: 0
61+
62+patternProperties:
63+ '^channel@([0-9]|[1-5][0-9]|6[0-3])$':
64+ description:
65+ A channel managed by this controller
66+ type: object
67+
68+ properties:
69+ reg:
70+ minimum: 0
71+ maximum: 63
72+ description:
73+ The channel number
74+
75+ fsl,operational-mode:
76+ $ref: /schemas/types.yaml#/definitions/string
77+ enum: [transparent, hdlc]
78+ default: transparent
79+ description: |
80+ The channel operational mode
81+ - hdlc: The channel handles HDLC frames
82+ - transparent: The channel handles raw data without any processing
83+
84+ fsl,reverse-data:
85+ $ref: /schemas/types.yaml#/definitions/flag
86+ description:
87+ The bit order as seen on the channels is reversed,
88+ transmitting/receiving the MSB of each octet first.
89+ This flag is used only in 'transparent' mode.
90+
91+ fsl,tx-ts-mask:
92+ $ref: /schemas/types.yaml#/definitions/uint64
93+ description:
94+ Channel assigned Tx time-slots within the Tx time-slots routed by the
95+ TSA to this cell.
96+
97+ fsl,rx-ts-mask:
98+ $ref: /schemas/types.yaml#/definitions/uint64
99+ description:
100+ Channel assigned Rx time-slots within the Rx time-slots routed by the
101+ TSA to this cell.
102+
103+ required:
104+ - reg
105+ - fsl,tx-ts-mask
106+ - fsl,rx-ts-mask
107+
108+required:
109+ - compatible
110+ - reg
111+ - reg-names
112+ - interrupts
113+ - fsl,tsa-serial
114+ - '#address-cells'
115+ - '#size-cells'
116+
117+additionalProperties: false
118+
119+examples:
120+ - |
121+ #include <dt-bindings/soc/cpm1-fsl,tsa.h>
122+
123+ qmc@a60 {
124+ compatible = "fsl,mpc885-scc-qmc", "fsl,cpm1-scc-qmc";
125+ reg = <0xa60 0x20>,
126+ <0x3f00 0xc0>,
127+ <0x2000 0x1000>;
128+ reg-names = "scc_regs", "scc_pram", "dpram";
129+ interrupts = <27>;
130+ interrupt-parent = <&CPM_PIC>;
131+
132+ #address-cells = <1>;
133+ #size-cells = <0>;
134+
135+ fsl,tsa-serial = <&tsa FSL_CPM_TSA_SCC4>;
136+
137+ channel@16 {
138+ /* Ch16 : First 4 even TS from all routed from TSA */
139+ reg = <16>;
140+ fsl,mode = "transparent";
141+ fsl,reverse-data;
142+ fsl,tx-ts-mask = <0x00000000 0x000000aa>;
143+ fsl,rx-ts-mask = <0x00000000 0x000000aa>;
144+ };
145+
146+ channel@17 {
147+ /* Ch17 : First 4 odd TS from all routed from TSA */
148+ reg = <17>;
149+ fsl,mode = "transparent";
150+ fsl,reverse-data;
151+ fsl,tx-ts-mask = <0x00000000 0x00000055>;
152+ fsl,rx-ts-mask = <0x00000000 0x00000055>;
153+ };
154+
155+ channel@19 {
156+ /* Ch19 : 8 TS (TS 8..15) from all routed from TSA */
157+ reg = <19>;
158+ fsl,mode = "hdlc";
159+ fsl,tx-ts-mask = <0x00000000 0x0000ff00>;
160+ fsl,rx-ts-mask = <0x00000000 0x0000ff00>;
161+ };
162+ };
Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml+205−0
@@ -0,0 +1,205 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: PowerQUICC CPM Time-slot assigner (TSA) controller
8+
9+maintainers:
10+ - Herve Codina <herve.codina@bootlin.com>
11+
12+description:
13+ The TSA is the time-slot assigner that can be found on some PowerQUICC SoC.
14+ Its purpose is to route some TDM time-slots to other internal serial
15+ controllers.
16+
17+properties:
18+ compatible:
19+ items:
20+ - enum:
21+ - fsl,mpc885-tsa
22+ - fsl,mpc866-tsa
23+ - const: fsl,cpm1-tsa
24+
25+ reg:
26+ items:
27+ - description: SI (Serial Interface) register base
28+ - description: SI RAM base
29+
30+ reg-names:
31+ items:
32+ - const: si_regs
33+ - const: si_ram
34+
35+ '#address-cells':
36+ const: 1
37+
38+ '#size-cells':
39+ const: 0
40+
41+patternProperties:
42+ '^tdm@[0-1]$':
43+ description:
44+ The TDM managed by this controller
45+ type: object
46+
47+ additionalProperties: false
48+
49+ properties:
50+ reg:
51+ minimum: 0
52+ maximum: 1
53+ description:
54+ The TDM number for this TDM, 0 for TDMa and 1 for TDMb
55+
56+ fsl,common-rxtx-pins:
57+ $ref: /schemas/types.yaml#/definitions/flag
58+ description:
59+ The hardware can use four dedicated pins for Tx clock, Tx sync, Rx
60+ clock and Rx sync or use only two pins, Tx/Rx clock and Tx/Rx sync.
61+ Without the 'fsl,common-rxtx-pins' property, the four pins are used.
62+ With the 'fsl,common-rxtx-pins' property, two pins are used.
63+
64+ clocks:
65+ minItems: 2
66+ items:
67+ - description: External clock connected to L1RSYNC pin
68+ - description: External clock connected to L1RCLK pin
69+ - description: External clock connected to L1TSYNC pin
70+ - description: External clock connected to L1TCLK pin
71+
72+ clock-names:
73+ minItems: 2
74+ items:
75+ - const: l1rsync
76+ - const: l1rclk
77+ - const: l1tsync
78+ - const: l1tclk
79+
80+ fsl,rx-frame-sync-delay-bits:
81+ enum: [0, 1, 2, 3]
82+ default: 0
83+ description: |
84+ Receive frame sync delay in number of bits.
85+ Indicates the delay between the Rx sync and the first bit of the Rx
86+ frame. 0 for no bit delay. 1, 2 or 3 for 1, 2 or 3 bits delay.
87+
88+ fsl,tx-frame-sync-delay-bits:
89+ enum: [0, 1, 2, 3]
90+ default: 0
91+ description: |
92+ Transmit frame sync delay in number of bits.
93+ Indicates the delay between the Tx sync and the first bit of the Tx
94+ frame. 0 for no bit delay. 1, 2 or 3 for 1, 2 or 3 bits delay.
95+
96+ fsl,clock-falling-edge:
97+ $ref: /schemas/types.yaml#/definitions/flag
98+ description:
99+ Data is sent on falling edge of the clock (and received on the rising
100+ edge). If 'clock-falling-edge' is not present, data is sent on the
101+ rising edge (and received on the falling edge).
102+
103+ fsl,fsync-rising-edge:
104+ $ref: /schemas/types.yaml#/definitions/flag
105+ description:
106+ Frame sync pulses are sampled with the rising edge of the channel
107+ clock. If 'fsync-rising-edge' is not present, pulses are sampled with
108+ the falling edge.
109+
110+ fsl,double-speed-clock:
111+ $ref: /schemas/types.yaml#/definitions/flag
112+ description:
113+ The channel clock is twice the data rate.
114+
115+ patternProperties:
116+ '^fsl,[rt]x-ts-routes$':
117+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
118+ description: |
119+ A list of tuple that indicates the Tx or Rx time-slots routes.
120+ items:
121+ items:
122+ - description:
123+ The number of time-slots
124+ minimum: 1
125+ maximum: 64
126+ - description: |
127+ The source (Tx) or destination (Rx) serial interface
128+ (dt-bindings/soc/cpm1-fsl,tsa.h defines these values)
129+ - 0: No destination
130+ - 1: SCC2
131+ - 2: SCC3
132+ - 3: SCC4
133+ - 4: SMC1
134+ - 5: SMC2
135+ enum: [0, 1, 2, 3, 4, 5]
136+ minItems: 1
137+ maxItems: 64
138+
139+ allOf:
140+ # If fsl,common-rxtx-pins is present, only 2 clocks are needed.
141+ # Else, the 4 clocks must be present.
142+ - if:
143+ required:
144+ - fsl,common-rxtx-pins
145+ then:
146+ properties:
147+ clocks:
148+ maxItems: 2
149+ clock-names:
150+ maxItems: 2
151+ else:
152+ properties:
153+ clocks:
154+ minItems: 4
155+ clock-names:
156+ minItems: 4
157+
158+ required:
159+ - reg
160+ - clocks
161+ - clock-names
162+
163+required:
164+ - compatible
165+ - reg
166+ - reg-names
167+ - '#address-cells'
168+ - '#size-cells'
169+
170+additionalProperties: false
171+
172+examples:
173+ - |
174+ #include <dt-bindings/soc/cpm1-fsl,tsa.h>
175+
176+ tsa@ae0 {
177+ compatible = "fsl,mpc885-tsa", "fsl,cpm1-tsa";
178+ reg = <0xae0 0x10>,
179+ <0xc00 0x200>;
180+ reg-names = "si_regs", "si_ram";
181+
182+ #address-cells = <1>;
183+ #size-cells = <0>;
184+
185+ tdm@0 {
186+ /* TDMa */
187+ reg = <0>;
188+
189+ clocks = <&clk_l1rsynca>, <&clk_l1rclka>;
190+ clock-names = "l1rsync", "l1rclk";
191+
192+ fsl,common-rxtx-pins;
193+ fsl,fsync-rising-edge;
194+
195+ fsl,tx-ts-routes = <2 0>, /* TS 0..1 */
196+ <24 FSL_CPM_TSA_SCC4>, /* TS 2..25 */
197+ <1 0>, /* TS 26 */
198+ <5 FSL_CPM_TSA_SCC3>; /* TS 27..31 */
199+
200+ fsl,rx-ts-routes = <2 0>, /* TS 0..1 */
201+ <24 FSL_CPM_TSA_SCC4>, /* 2..25 */
202+ <1 0>, /* TS 26 */
203+ <5 FSL_CPM_TSA_SCC3>; /* TS 27..31 */
204+ };
205+ };
Documentation/devicetree/bindings/sound/adi,adau1372.yaml+1−1
@@ -32,7 +32,7 @@ properties: · 31 unmodified lines
3232 maxItems: 1
3333
3434 clock-names:
35− const: "mclk"
35+ const: mclk
3636
3737 powerdown-gpios:
3838 description: GPIO used for hardware power-down.
Documentation/devicetree/bindings/sound/adi,adau17x1.txt+0−32
@@ -1,32 +0,0 @@
1−Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781
2−
3−Required 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−
16−Optional properties:
17− - clock-names: If provided must be "mclk".
18− - clocks: phandle + clock-specifiers for the clock that provides
19− the audio master clock for the device.
20−
21−Examples:
22−#include <dt-bindings/sound/adau17x1.h>
23−
24− i2c_bus {
25− adau1361@38 {
26− compatible = "adi,adau1761";
27− reg = <0x38>;
28−
29− clock-names = "mclk";
30− clocks = <&audio_clock>;
31− };
32− };
Documentation/devicetree/bindings/sound/adi,adau17x1.yaml+52−0
@@ -0,0 +1,52 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/adi,adau17x1.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781 Codec
8+
9+maintainers:
10+ - Lars-Peter Clausen <lars@metafoo.de>
11+
12+properties:
13+ compatible:
14+ enum:
15+ - adi,adau1361
16+ - adi,adau1381
17+ - adi,adau1461
18+ - adi,adau1761
19+ - adi,adau1781
20+ - adi,adau1961
21+
22+ reg:
23+ maxItems: 1
24+ description:
25+ The i2c address. Value depends on the state of ADDR0 and ADDR1,
26+ as wired in hardware.
27+
28+ clock-names:
29+ const: mclk
30+
31+ clocks:
32+ items:
33+ - description: provides the audio master clock for the device.
34+
35+required:
36+ - compatible
37+ - reg
38+
39+additionalProperties: false
40+
41+examples:
42+ - |
43+ i2c {
44+ #address-cells = <1>;
45+ #size-cells = <0>;
46+ audio-codec@38 {
47+ compatible = "adi,adau1761";
48+ reg = <0x38>;
49+ clock-names = "mclk";
50+ clocks = <&audio_clock>;
51+ };
52+ };
Documentation/devicetree/bindings/sound/adi,max98363.yaml+60−0
@@ -0,0 +1,60 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/adi,max98363.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Analog Devices MAX98363 SoundWire Amplifier
8+
9+maintainers:
10+ - Ryan Lee <ryans.lee@analog.com>
11+
12+description:
13+ The MAX98363 is a SoundWire input Class D mono amplifier that
14+ supports MIPI SoundWire v1.2-compatible digital interface for
15+ audio and control data.
16+ SoundWire peripheral device ID of MAX98363 is 0x3*019f836300
17+ where * is the peripheral device unique ID decoded from pin.
18+ It supports up to 10 peripheral devices(0x0 to 0x9).
19+
20+allOf:
21+ - $ref: dai-common.yaml#
22+
23+properties:
24+ compatible:
25+ const: sdw3019f836300
26+
27+ reg:
28+ maxItems: 1
29+
30+ '#sound-dai-cells':
31+ const: 0
32+
33+required:
34+ - compatible
35+ - reg
36+ - "#sound-dai-cells"
37+
38+unevaluatedProperties: false
39+
40+examples:
41+ - |
42+ soundwire-controller@3250000 {
43+ #address-cells = <2>;
44+ #size-cells = <0>;
45+ reg = <0x3250000 0x2000>;
46+
47+ speaker@0,0 {
48+ compatible = "sdw3019f836300";
49+ reg = <0 0>;
50+ #sound-dai-cells = <0>;
51+ sound-name-prefix = "Speaker Left";
52+ };
53+
54+ speaker@0,1 {
55+ compatible = "sdw3019f836300";
56+ reg = <0 1>;
57+ #sound-dai-cells = <0>;
58+ sound-name-prefix = "Speaker Right";
59+ };
60+ };
Documentation/devicetree/bindings/sound/adi,max98396.yaml+4−4
@@ -41,21 +41,21 @@ properties: · 40 unmodified lines
4141
4242 adi,vmon-slot-no:
4343 description: slot number of the voltage sense monitor
44− $ref: "/schemas/types.yaml#/definitions/uint32"
44+ $ref: /schemas/types.yaml#/definitions/uint32
4545 minimum: 0
4646 maximum: 15
4747 default: 0
4848
4949 adi,imon-slot-no:
5050 description: slot number of the current sense monitor
51− $ref: "/schemas/types.yaml#/definitions/uint32"
51+ $ref: /schemas/types.yaml#/definitions/uint32
5252 minimum: 0
5353 maximum: 15
5454 default: 1
5555
5656 adi,spkfb-slot-no:
5757 description: slot number of speaker DSP monitor
58− $ref: "/schemas/types.yaml#/definitions/uint32"
58+ $ref: /schemas/types.yaml#/definitions/uint32
5959 minimum: 0
6060 maximum: 15
6161 default: 2
@@ -64,7 +64,7 @@ properties: · 2 unmodified lines
6464 description:
6565 Selects the PCM data input channel that is routed to the speaker
6666 audio processing bypass path.
67− $ref: "/schemas/types.yaml#/definitions/uint32"
67+ $ref: /schemas/types.yaml#/definitions/uint32
6868 minimum: 0
6969 maximum: 15
7070 default: 0
Documentation/devicetree/bindings/sound/ak4458.txt+0−28
@@ -1,28 +0,0 @@
1−AK4458 audio DAC
2−
3−This device supports I2C mode.
4−
5−Required properties:
6−
7−- compatible : "asahi-kasei,ak4458" or "asahi-kasei,ak4497"
8−- reg : The I2C address of the device for I2C
9−
10−Optional properties:
11−- reset-gpios: A GPIO specifier for the power down & reset pin
12−- mute-gpios: A GPIO specifier for the soft mute pin
13−- AVDD-supply: Analog power supply
14−- DVDD-supply: Digital power supply
15−- dsd-path: Select DSD input pins for ak4497
16− 0: select #16, #17, #19 pins
17− 1: select #3, #4, #5 pins
18−
19−Example:
20−
21−&i2c {
22− ak4458: dac@10 {
23− compatible = "asahi-kasei,ak4458";
24− reg = <0x10>;
25− reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>
26− mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>
27− };
28−};
Documentation/devicetree/bindings/sound/ak5558.txt+0−24
@@ -1,24 +0,0 @@
1−AK5558 8 channel differential 32-bit delta-sigma ADC
2−
3−This device supports I2C mode only.
4−
5−Required properties:
6−
7−- compatible : "asahi-kasei,ak5558" or "asahi-kasei,ak5552".
8−- reg : The I2C address of the device.
9−
10−Optional properties:
11−
12−- reset-gpios: A GPIO specifier for the power down & reset pin.
13−- AVDD-supply: Analog power supply
14−- DVDD-supply: Digital power supply
15−
16−Example:
17−
18−&i2c {
19− ak5558: adc@10 {
20− compatible = "asahi-kasei,ak5558";
21− reg = <0x10>;
22− reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
23− };
24−};
Documentation/devicetree/bindings/sound/alc5632.txt+0−43
@@ -1,43 +0,0 @@
1−ALC5632 audio CODEC
2−
3−This device supports I2C only.
4−
5−Required properties:
6−
7− - compatible : "realtek,alc5632"
8−
9− - reg : the I2C address of the device.
10−
11− - gpio-controller : Indicates this device is a GPIO controller.
12−
13− - #gpio-cells : Should be two. The first cell is the pin number and the
14− second cell is used to specify optional parameters (currently unused).
15−
16−Pins on the device (for linking into audio routes):
17−
18− * SPK_OUTP
19− * SPK_OUTN
20− * HP_OUT_L
21− * HP_OUT_R
22− * AUX_OUT_P
23− * AUX_OUT_N
24− * LINE_IN_L
25− * LINE_IN_R
26− * PHONE_P
27− * PHONE_N
28− * MIC1_P
29− * MIC1_N
30− * MIC2_P
31− * MIC2_N
32− * MICBIAS1
33− * DMICDAT
34−
35−Example:
36−
37−alc5632: alc5632@1e {
38− compatible = "realtek,alc5632";
39− reg = <0x1a>;
40−
41− gpio-controller;
42− #gpio-cells = <2>;
43−};
Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml+73−0
@@ -0,0 +1,73 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/asahi-kasei,ak4458.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: AK4458 audio DAC
8+
9+maintainers:
10+ - Shengjiu Wang <shengjiu.wang@nxp.com>
11+
12+properties:
13+ compatible:
14+ enum:
15+ - asahi-kasei,ak4458
16+ - asahi-kasei,ak4497
17+
18+ reg:
19+ maxItems: 1
20+
21+ avdd-supply:
22+ description: Analog power supply
23+
24+ dvdd-supply:
25+ description: Digital power supply
26+
27+ reset-gpios:
28+ maxItems: 1
29+
30+ mute-gpios:
31+ maxItems: 1
32+ description:
33+ GPIO used to mute all the outputs
34+
35+ dsd-path:
36+ description: Select DSD input pins for ak4497
37+ $ref: /schemas/types.yaml#/definitions/uint32
38+ oneOf:
39+ - const: 0
40+ description: "select #16, #17, #19 pins"
41+ - const: 1
42+ description: "select #3, #4, #5 pins"
43+
44+required:
45+ - compatible
46+ - reg
47+
48+allOf:
49+ - if:
50+ properties:
51+ compatible:
52+ contains:
53+ const: asahi-kasei,ak4458
54+
55+ then:
56+ properties:
57+ dsd-path: false
58+
59+additionalProperties: false
60+
61+examples:
62+ - |
63+ #include <dt-bindings/gpio/gpio.h>
64+ i2c {
65+ #address-cells = <1>;
66+ #size-cells = <0>;
67+ codec@10 {
68+ compatible = "asahi-kasei,ak4458";
69+ reg = <0x10>;
70+ reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
71+ mute-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
72+ };
73+ };
Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml+48−0
@@ -0,0 +1,48 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/asahi-kasei,ak5558.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: AK5558 8 channel differential 32-bit delta-sigma ADC
8+
9+maintainers:
10+ - Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>
11+ - Mihai Serban <mihai.serban@nxp.com>
12+
13+properties:
14+ compatible:
15+ enum:
16+ - asahi-kasei,ak5552
17+ - asahi-kasei,ak5558
18+
19+ reg:
20+ maxItems: 1
21+
22+ avdd-supply:
23+ description: A 1.8V supply that powers up the AVDD pin.
24+
25+ dvdd-supply:
26+ description: A 1.2V supply that powers up the DVDD pin.
27+
28+ reset-gpios:
29+ maxItems: 1
30+
31+required:
32+ - compatible
33+ - reg
34+
35+additionalProperties: false
36+
37+examples:
38+ - |
39+ #include <dt-bindings/gpio/gpio.h>
40+ i2c {
41+ #address-cells = <1>;
42+ #size-cells = <0>;
43+ ak5558: codec@10 {
44+ compatible = "asahi-kasei,ak5558";
45+ reg = <0x10>;
46+ reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
47+ };
48+ };
Documentation/devicetree/bindings/sound/audio-graph-port.yaml+11−11
@@ -16,19 +16,19 @@ definitions: · 15 unmodified lines
1616 $ref: /schemas/graph.yaml#/$defs/port-base
1717 properties:
1818 convert-rate:
19− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"
19+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
2020 convert-channels:
21− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"
21+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
2222 convert-sample-format:
23− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-format"
23+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-format
2424 mclk-fs:
25− $ref: "simple-card.yaml#/definitions/mclk-fs"
25+ $ref: simple-card.yaml#/definitions/mclk-fs
2626
2727 endpoint-base:
2828 $ref: /schemas/graph.yaml#/$defs/endpoint-base
2929 properties:
3030 mclk-fs:
31− $ref: "simple-card.yaml#/definitions/mclk-fs"
31+ $ref: simple-card.yaml#/definitions/mclk-fs
3232 frame-inversion:
3333 description: dai-link uses frame clock inversion
3434 $ref: /schemas/types.yaml#/definitions/flag
@@ -49,11 +49,11 @@ definitions: · 14 unmodified lines
4949 description: Indicates system clock
5050 $ref: /schemas/types.yaml#/definitions/phandle
5151 system-clock-frequency:
52− $ref: "simple-card.yaml#/definitions/system-clock-frequency"
52+ $ref: simple-card.yaml#/definitions/system-clock-frequency
5353 system-clock-direction-out:
54− $ref: "simple-card.yaml#/definitions/system-clock-direction-out"
54+ $ref: simple-card.yaml#/definitions/system-clock-direction-out
5555 system-clock-fixed:
56− $ref: "simple-card.yaml#/definitions/system-clock-fixed"
56+ $ref: simple-card.yaml#/definitions/system-clock-fixed
5757
5858 dai-format:
5959 description: audio format.
@@ -69,11 +69,11 @@ definitions: · 9 unmodified lines
6969 - msb
7070 - lsb
7171 convert-rate:
72− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"
72+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
7373 convert-channels:
74− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"
74+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
7575 convert-sample-format:
76− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-format"
76+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-format
7777
7878 dai-tdm-slot-num:
7979 description: Number of slots in use.
Documentation/devicetree/bindings/sound/audio-graph.yaml+4−4
@@ -15,7 +15,7 @@ properties: · 14 unmodified lines
1515 label:
1616 maxItems: 1
1717 prefix:
18− description: "device name prefix"
18+ description: device name prefix
1919 $ref: /schemas/types.yaml#/definitions/string
2020 routing:
2121 description: |
@@ -27,11 +27,11 @@ properties: · 5 unmodified lines
2727 description: User specified audio sound widgets.
2828 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
2929 convert-rate:
30− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"
30+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
3131 convert-channels:
32− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"
32+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
3333 convert-sample-format:
34− $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-format"
34+ $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-format
3535
3636 pa-gpios:
3737 maxItems: 1
Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml+9−1
@@ -85,11 +85,19 @@ properties: · 84 unmodified lines
8585 boost-cap-microfarad.
8686 External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to
8787 enable boost voltage.
88+ Shared boost allows two amplifiers to share a single boost circuit by
89+ communicating on the MDSYNC bus. The active amplifier controls the boost
90+ circuit using combined data from both amplifiers. GPIO1 should be
91+ configured for Sync when shared boost is used. Shared boost is not
92+ compatible with External boost. Active amplifier requires
93+ boost-peak-milliamp, boost-ind-nanohenry and boost-cap-microfarad.
8894 0 = Internal Boost
8995 1 = External Boost
96+ 2 = Shared Boost Active
97+ 3 = Shared Boost Passive
9098 $ref: /schemas/types.yaml#/definitions/uint32
9199 minimum: 0
92− maximum: 1
100+ maximum: 3
93101
94102 cirrus,gpio1-polarity-invert:
95103 description:
Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml+79−1
@@ -45,11 +45,79 @@ properties: · 44 unmodified lines
4545 Audio serial port SDOUT Hi-Z control. Sets the Hi-Z
4646 configuration for SDOUT pin of amplifier. Logical OR of
4747 CS35L45_ASP_TX_HIZ_xxx values.
48− $ref: "/schemas/types.yaml#/definitions/uint32"
48+ $ref: /schemas/types.yaml#/definitions/uint32
4949 minimum: 0
5050 maximum: 3
5151 default: 2
5252
53+patternProperties:
54+ "^cirrus,gpio-ctrl[1-3]$":
55+ description:
56+ GPIO pins configuration.
57+ type: object
58+ additionalProperties: false
59+ properties:
60+ gpio-dir:
61+ description:
62+ GPIO pin direction. Valid only when 'gpio-ctrl' is 1
63+ 0 = Output
64+ 1 = Input
65+ $ref: "/schemas/types.yaml#/definitions/uint32"
66+ minimum: 0
67+ maximum: 1
68+ default: 1
69+ gpio-lvl:
70+ description:
71+ GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0
72+ 0 = Low
73+ 1 = High
74+ $ref: "/schemas/types.yaml#/definitions/uint32"
75+ minimum: 0
76+ maximum: 1
77+ default: 0
78+ gpio-op-cfg:
79+ description:
80+ GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0
81+ 0 = CMOS
82+ 1 = Open Drain
83+ $ref: "/schemas/types.yaml#/definitions/uint32"
84+ minimum: 0
85+ maximum: 1
86+ default: 0
87+ gpio-pol:
88+ description:
89+ GPIO output polarity select. Valid only when 'gpio-ctrl' is 1
90+ and 'gpio-dir' is 0
91+ 0 = Non-inverted, Active High
92+ 1 = Inverted, Active Low
93+ $ref: "/schemas/types.yaml#/definitions/uint32"
94+ minimum: 0
95+ maximum: 1
96+ default: 0
97+ gpio-ctrl:
98+ description:
99+ Defines the function of the GPIO pin.
100+ GPIO1
101+ 0 = High impedance input
102+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
103+ 2 = Pin acts as MDSYNC, direction controlled by MDSYNC
104+ 3-7 = Reserved
105+ GPIO2
106+ 0 = High impedance input
107+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
108+ 2 = Pin acts as open drain INT
109+ 3 = Reserved
110+ 4 = Pin acts as push-pull output INT. Active low.
111+ 5 = Pin acts as push-pull output INT. Active high.
112+ 6,7 = Reserved
113+ GPIO3
114+ 0 = High impedance input
115+ 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
116+ 2-7 = Reserved
117+ $ref: "/schemas/types.yaml#/definitions/uint32"
118+ minimum: 0
119+ maximum: 7
120+ default: 0
53121 required:
54122 - compatible
55123 - reg
@@ -74,5 +142,15 @@ examples: · 18 unmodified lines
74142 reset-gpios = <&gpio 110 0>;
75143 cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
76144 CS35L45_ASP_TX_HIZ_DISABLED)>;
145+ cirrus,gpio-ctrl1 {
146+ gpio-ctrl = <0x2>;
147+ };
148+ cirrus,gpio-ctrl2 {
149+ gpio-ctrl = <0x2>;
150+ };
151+ cirrus,gpio-ctrl3 {
152+ gpio-ctrl = <0x1>;
153+ gpio-dir = <0x1>;
154+ };
77155 };
78156 };
Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml+6−6
@@ -68,7 +68,7 @@ properties: · 67 unmodified lines
6868 This is "normal tip sense (TS)" in the datasheet.
6969
7070 The CS42L42_TS_INV_* defines are available for this.
71− $ref: "/schemas/types.yaml#/definitions/uint32"
71+ $ref: /schemas/types.yaml#/definitions/uint32
7272 minimum: 0
7373 maximum: 1
7474
@@ -87,7 +87,7 @@ properties: · 12 unmodified lines
8787 7 - 1.5s
8888
8989 The CS42L42_TS_DBNCE_* defines are available for this.
90− $ref: "/schemas/types.yaml#/definitions/uint32"
90+ $ref: /schemas/types.yaml#/definitions/uint32
9191 minimum: 0
9292 maximum: 7
9393
@@ -106,7 +106,7 @@ properties: · 12 unmodified lines
106106 7 - 1.5s
107107
108108 The CS42L42_TS_DBNCE_* defines are available for this.
109− $ref: "/schemas/types.yaml#/definitions/uint32"
109+ $ref: /schemas/types.yaml#/definitions/uint32
110110 minimum: 0
111111 maximum: 7
112112
@@ -120,7 +120,7 @@ properties: · 7 unmodified lines
120120
121121 0ms - 200ms,
122122 Default = 100ms
123− $ref: "/schemas/types.yaml#/definitions/uint32"
123+ $ref: /schemas/types.yaml#/definitions/uint32
124124 minimum: 0
125125 maximum: 200
126126
@@ -133,7 +133,7 @@ properties: · 6 unmodified lines
133133
134134 0ms - 20ms,
135135 Default = 10ms
136− $ref: "/schemas/types.yaml#/definitions/uint32"
136+ $ref: /schemas/types.yaml#/definitions/uint32
137137 minimum: 0
138138 maximum: 20
139139
@@ -169,7 +169,7 @@ properties: · 29 unmodified lines
169169 3 - Slowest
170170
171171 The CS42L42_HSBIAS_RAMP_* defines are available for this.
172− $ref: "/schemas/types.yaml#/definitions/uint32"
172+ $ref: /schemas/types.yaml#/definitions/uint32
173173 minimum: 0
174174 maximum: 3
175175
Documentation/devicetree/bindings/sound/cirrus,ep9301-i2s.yaml+66−0
@@ -0,0 +1,66 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/cirrus,ep9301-i2s.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Cirrus EP93xx I2S Controller
8+
9+description: |
10+ The I2S controller is used to stream serial audio data between the external
11+ I2S CODECs’, ADCs/DACs, and the ARM Core. The controller supports I2S, Left-
12+ and Right-Justified DSP formats.
13+
14+maintainers:
15+ - Alexander Sverdlin <alexander.sverdlin@gmail.com>
16+
17+allOf:
18+ - $ref: dai-common.yaml#
19+
20+properties:
21+ compatible:
22+ const: cirrus,ep9301-i2s
23+
24+ '#sound-dai-cells':
25+ const: 0
26+
27+ reg:
28+ maxItems: 1
29+
30+ interrupts:
31+ maxItems: 1
32+
33+ clocks:
34+ minItems: 3
35+ maxItems: 3
36+
37+ clock-names:
38+ items:
39+ - const: mclk
40+ - const: sclk
41+ - const: lrclk
42+
43+required:
44+ - compatible
45+ - '#sound-dai-cells'
46+ - reg
47+ - clocks
48+ - clock-names
49+
50+additionalProperties: false
51+
52+examples:
53+ - |
54+ i2s: i2s@80820000 {
55+ compatible = "cirrus,ep9301-i2s";
56+ #sound-dai-cells = <0>;
57+ reg = <0x80820000 0x100>;
58+ interrupt-parent = <&vic1>;
59+ interrupts = <28>;
60+ clocks = <&syscon 29>,
61+ <&syscon 30>,
62+ <&syscon 31>;
63+ clock-names = "mclk", "sclk", "lrclk";
64+ };
65+
66+...
Documentation/devicetree/bindings/sound/everest,es8316.yaml+4−0
@@ -28,6 +28,10 @@ properties: · 27 unmodified lines
2828 items:
2929 - const: mclk
3030
31+ port:
32+ $ref: audio-graph-port.yaml#
33+ unevaluatedProperties: false
34+
3135 "#sound-dai-cells":
3236 const: 0
3337
Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml+117−0
@@ -0,0 +1,117 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/fsl,qmc-audio.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: QMC audio
8+
9+maintainers:
10+ - Herve Codina <herve.codina@bootlin.com>
11+
12+description: |
13+ The QMC audio is an ASoC component which uses QMC (QUICC Multichannel
14+ Controller) channels to transfer the audio data.
15+ It provides as many DAI as the number of QMC channel used.
16+
17+allOf:
18+ - $ref: dai-common.yaml#
19+
20+properties:
21+ compatible:
22+ const: fsl,qmc-audio
23+
24+ '#address-cells':
25+ const: 1
26+ '#size-cells':
27+ const: 0
28+ '#sound-dai-cells':
29+ const: 1
30+
31+patternProperties:
32+ '^dai@([0-9]|[1-5][0-9]|6[0-3])$':
33+ description:
34+ A DAI managed by this controller
35+ type: object
36+
37+ properties:
38+ reg:
39+ minimum: 0
40+ maximum: 63
41+ description:
42+ The DAI number
43+
44+ fsl,qmc-chan:
45+ $ref: /schemas/types.yaml#/definitions/phandle-array
46+ items:
47+ - items:
48+ - description: phandle to QMC node
49+ - description: Channel number
50+ description:
51+ Should be a phandle/number pair. The phandle to QMC node and the QMC
52+ channel to use for this DAI.
53+
54+ required:
55+ - reg
56+ - fsl,qmc-chan
57+
58+required:
59+ - compatible
60+ - '#address-cells'
61+ - '#size-cells'
62+ - '#sound-dai-cells'
63+
64+additionalProperties: false
65+
66+examples:
67+ - |
68+ audio_controller: audio-controller {
69+ compatible = "fsl,qmc-audio";
70+ #address-cells = <1>;
71+ #size-cells = <0>;
72+ #sound-dai-cells = <1>;
73+ dai@16 {
74+ reg = <16>;
75+ fsl,qmc-chan = <&qmc 16>;
76+ };
77+ dai@17 {
78+ reg = <17>;
79+ fsl,qmc-chan = <&qmc 17>;
80+ };
81+ };
82+
83+ sound {
84+ compatible = "simple-audio-card";
85+ #address-cells = <1>;
86+ #size-cells = <0>;
87+ simple-audio-card,dai-link@0 {
88+ reg = <0>;
89+ format = "dsp_b";
90+ cpu {
91+ sound-dai = <&audio_controller 16>;
92+ };
93+ codec {
94+ sound-dai = <&codec1>;
95+ dai-tdm-slot-num = <4>;
96+ dai-tdm-slot-width = <8>;
97+ /* TS 3, 5, 7, 9 */
98+ dai-tdm-slot-tx-mask = <0 0 0 1 0 1 0 1 0 1>;
99+ dai-tdm-slot-rx-mask = <0 0 0 1 0 1 0 1 0 1>;
100+ };
101+ };
102+ simple-audio-card,dai-link@1 {
103+ reg = <1>;
104+ format = "dsp_b";
105+ cpu {
106+ sound-dai = <&audio_controller 17>;
107+ };
108+ codec {
109+ sound-dai = <&codec2>;
110+ dai-tdm-slot-num = <4>;
111+ dai-tdm-slot-width = <8>;
112+ /* TS 2, 4, 6, 8 */
113+ dai-tdm-slot-tx-mask = <0 0 1 0 1 0 1 0 1>;
114+ dai-tdm-slot-rx-mask = <0 0 1 0 1 0 1 0 1>;
115+ };
116+ };
117+ };
Documentation/devicetree/bindings/sound/max98371.txt+0−17
@@ -1,17 +0,0 @@
1−max98371 codec
2−
3−This device supports I2C mode only.
4−
5−Required properties:
6−
7−- compatible : "maxim,max98371"
8−- reg : The chip select number on the I2C bus
9−
10−Example:
11−
12−&i2c {
13− max98371: max98371@31 {
14− compatible = "maxim,max98371";
15− reg = <0x31>;
16− };
17−};
Documentation/devicetree/bindings/sound/max9867.txt+0−17
@@ -1,17 +0,0 @@
1−max9867 codec
2−
3−This device supports I2C mode only.
4−
5−Required properties:
6−
7−- compatible : "maxim,max9867"
8−- reg : The chip select number on the I2C bus
9−
10−Example:
11−
12−&i2c {
13− max9867: max9867@18 {
14− compatible = "maxim,max9867";
15− reg = <0x18>;
16− };
17−};
Documentation/devicetree/bindings/sound/maxim,max9759.txt+0−18
@@ -1,18 +0,0 @@
1−Maxim MAX9759 Speaker Amplifier
2−===============================
3−
4−Required properties:
5−- compatible : "maxim,max9759"
6−- shutdown-gpios : the gpio connected to the shutdown pin
7−- mute-gpios : the gpio connected to the mute pin
8−- gain-gpios : the 2 gpios connected to the g1 and g2 pins
9−
10−Example:
11−
12−max9759: analog-amplifier {
13− compatible = "maxim,max9759";
14− shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
15− mute-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
16− gain-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>,
17− <&gpio3 25 GPIO_ACTIVE_LOW>;
18−};
Documentation/devicetree/bindings/sound/maxim,max9759.yaml+45−0
@@ -0,0 +1,45 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/maxim,max9759.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Maxim MAX9759 Speaker Amplifier
8+
9+maintainers:
10+ - Otabek Nazrullaev <otabeknazrullaev1998@gmail.com>
11+
12+properties:
13+ compatible:
14+ const: maxim,max9759
15+
16+ shutdown-gpios:
17+ maxItems: 1
18+ description: the gpio connected to the shutdown pin
19+
20+ mute-gpios:
21+ maxItems: 1
22+ description: the gpio connected to the mute pin
23+
24+ gain-gpios:
25+ maxItems: 2
26+ description: the 2 gpios connected to the g1 and g2 pins
27+
28+required:
29+ - compatible
30+ - shutdown-gpios
31+ - mute-gpios
32+ - gain-gpios
33+
34+additionalProperties: false
35+
36+examples:
37+ - |
38+ #include <dt-bindings/gpio/gpio.h>
39+ amplifier {
40+ compatible = "maxim,max9759";
41+ shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
42+ mute-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
43+ gain-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>,
44+ <&gpio3 25 GPIO_ACTIVE_LOW>;
45+ };
Documentation/devicetree/bindings/sound/maxim,max98371.yaml+42−0
@@ -0,0 +1,42 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/maxim,max98371.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Maxim MAX98371 audio codec
8+
9+maintainers:
10+ - anish kumar <yesanishhere@gmail.com>
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: maxim,max98371
18+
19+ '#sound-dai-cells':
20+ const: 0
21+
22+ reg:
23+ maxItems: 1
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+
37+ codec@31 {
38+ compatible = "maxim,max98371";
39+ reg = <0x31>;
40+ #sound-dai-cells = <0>;
41+ };
42+ };
Documentation/devicetree/bindings/sound/maxim,max9867.yaml+60−0
@@ -0,0 +1,60 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/maxim,max9867.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Maxim Integrated MAX9867 CODEC
8+
9+description: |
10+ This device supports I2C only.
11+ Pins on the device (for linking into audio routes):
12+ * LOUT
13+ * ROUT
14+ * LINL
15+ * LINR
16+ * MICL
17+ * MICR
18+ * DMICL
19+ * DMICR
20+
21+maintainers:
22+ - Ladislav Michl <ladis@linux-mips.org>
23+
24+allOf:
25+ - $ref: dai-common.yaml#
26+
27+properties:
28+ compatible:
29+ enum:
30+ - maxim,max9867
31+
32+ '#sound-dai-cells':
33+ const: 0
34+
35+ reg:
36+ maxItems: 1
37+
38+ clocks:
39+ maxItems: 1
40+
41+required:
42+ - compatible
43+ - reg
44+ - clocks
45+
46+additionalProperties: false
47+
48+examples:
49+ - |
50+ i2c {
51+ #address-cells = <1>;
52+ #size-cells = <0>;
53+ codec@18 {
54+ compatible = "maxim,max9867";
55+ #sound-dai-cells = <0>;
56+ reg = <0x18>;
57+ clocks = <&codec_clk>;
58+ };
59+ };
60+...
Documentation/devicetree/bindings/sound/mt8186-afe-pcm.yaml+3−3
@@ -26,15 +26,15 @@ properties: · 25 unmodified lines
2626 const: audiosys
2727
2828 mediatek,apmixedsys:
29− $ref: "/schemas/types.yaml#/definitions/phandle"
29+ $ref: /schemas/types.yaml#/definitions/phandle
3030 description: The phandle of the mediatek apmixedsys controller
3131
3232 mediatek,infracfg:
33− $ref: "/schemas/types.yaml#/definitions/phandle"
33+ $ref: /schemas/types.yaml#/definitions/phandle
3434 description: The phandle of the mediatek infracfg controller
3535
3636 mediatek,topckgen:
37− $ref: "/schemas/types.yaml#/definitions/phandle"
37+ $ref: /schemas/types.yaml#/definitions/phandle
3838 description: The phandle of the mediatek topckgen controller
3939
4040 clocks:
Documentation/devicetree/bindings/sound/mt8186-mt6366-da7219-max98357.yaml+1−1
@@ -18,7 +18,7 @@ properties: · 17 unmodified lines
1818 - mediatek,mt8186-mt6366-da7219-max98357-sound
1919
2020 mediatek,platform:
21− $ref: "/schemas/types.yaml#/definitions/phandle"
21+ $ref: /schemas/types.yaml#/definitions/phandle
2222 description: The phandle of MT8186 ASoC platform.
2323
2424 headset-codec:
Documentation/devicetree/bindings/sound/mt8186-mt6366-rt1019-rt5682s.yaml+1−1
@@ -19,7 +19,7 @@ properties: · 18 unmodified lines
1919 - mediatek,mt8186-mt6366-rt5682s-max98360-sound
2020
2121 mediatek,platform:
22− $ref: "/schemas/types.yaml#/definitions/phandle"
22+ $ref: /schemas/types.yaml#/definitions/phandle
2323 description: The phandle of MT8186 ASoC platform.
2424
2525 dmic-gpios:
Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml+3−3
@@ -24,15 +24,15 @@ properties: · 23 unmodified lines
2424 const: audiosys
2525
2626 mediatek,apmixedsys:
27− $ref: "/schemas/types.yaml#/definitions/phandle"
27+ $ref: /schemas/types.yaml#/definitions/phandle
2828 description: The phandle of the mediatek apmixedsys controller
2929
3030 mediatek,infracfg:
31− $ref: "/schemas/types.yaml#/definitions/phandle"
31+ $ref: /schemas/types.yaml#/definitions/phandle
3232 description: The phandle of the mediatek infracfg controller
3333
3434 mediatek,topckgen:
35− $ref: "/schemas/types.yaml#/definitions/phandle"
35+ $ref: /schemas/types.yaml#/definitions/phandle
3636 description: The phandle of the mediatek topckgen controller
3737
3838 power-domains:
Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml+2−2
@@ -21,11 +21,11 @@ properties: · 20 unmodified lines
2121 - mediatek,mt8192_mt6359_rt1015p_rt5682s
2222
2323 mediatek,platform:
24− $ref: "/schemas/types.yaml#/definitions/phandle"
24+ $ref: /schemas/types.yaml#/definitions/phandle
2525 description: The phandle of MT8192 ASoC platform.
2626
2727 mediatek,hdmi-codec:
28− $ref: "/schemas/types.yaml#/definitions/phandle"
28+ $ref: /schemas/types.yaml#/definitions/phandle
2929 description: The phandle of HDMI codec.
3030
3131 headset-codec:
Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml+1−1
@@ -32,7 +32,7 @@ properties: · 31 unmodified lines
3232 See ../reserved-memory/reserved-memory.txt for details.
3333
3434 mediatek,topckgen:
35− $ref: "/schemas/types.yaml#/definitions/phandle"
35+ $ref: /schemas/types.yaml#/definitions/phandle
3636 description: The phandle of the mediatek topckgen controller
3737
3838 power-domains:
Documentation/devicetree/bindings/sound/mt8195-mt6359.yaml+4−4
@@ -24,19 +24,19 @@ properties: · 23 unmodified lines
2424 description: User specified audio sound card name
2525
2626 mediatek,platform:
27− $ref: "/schemas/types.yaml#/definitions/phandle"
27+ $ref: /schemas/types.yaml#/definitions/phandle
2828 description: The phandle of MT8195 ASoC platform.
2929
3030 mediatek,dptx-codec:
31− $ref: "/schemas/types.yaml#/definitions/phandle"
31+ $ref: /schemas/types.yaml#/definitions/phandle
3232 description: The phandle of MT8195 Display Port Tx codec node.
3333
3434 mediatek,hdmi-codec:
35− $ref: "/schemas/types.yaml#/definitions/phandle"
35+ $ref: /schemas/types.yaml#/definitions/phandle
3636 description: The phandle of MT8195 HDMI codec node.
3737
3838 mediatek,adsp:
39− $ref: "/schemas/types.yaml#/definitions/phandle"
39+ $ref: /schemas/types.yaml#/definitions/phandle
4040 description: The phandle of MT8195 ADSP platform.
4141
4242 mediatek,dai-link:
Documentation/devicetree/bindings/sound/nau8825.txt+3−0
@@ -74,6 +74,9 @@ Optional properties: · 73 unmodified lines
7474 - nuvoton,adcout-drive-strong: make the drive strength of ADCOUT IO PIN strong if set.
7575 Otherwise, the drive keeps normal strength.
7676
77+ - nuvoton,adc-delay-ms: Delay (in ms) to make input path stable and avoid pop noise. The
78+ default value is 125 and range between 125 to 500 ms.
79+
7780 - clocks: list of phandle and clock specifier pairs according to common clock bindings for the
7881 clocks described in clock-names
7982 - clock-names: should include "mclk" for the MCLK master clock
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.yaml+4−4
@@ -31,10 +31,10 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headset Stereophone"
35− - "Int Spk"
36− - "Headset Mic"
37− - "Digital Mic"
34+ - Headset Stereophone
35+ - Int Spk
36+ - Headset Mic
37+ - Digital Mic
3838
3939 # CODEC Pins
4040 - SPKOUT
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-common.yaml+4−0
@@ -80,4 +80,8 @@ properties: · 79 unmodified lines
8080 type: boolean
8181 description: The Mic Jack represents state of the headset microphone pin
8282
83+ nvidia,coupled-mic-hp-det:
84+ type: boolean
85+ description: The Mic detect GPIO is viable only if HP detect GPIO is active
86+
8387 additionalProperties: true
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max9808x.yaml+90−0
@@ -0,0 +1,90 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-max9808x.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: NVIDIA Tegra audio complex with MAX9808x CODEC
8+
9+maintainers:
10+ - Jon Hunter <jonathanh@nvidia.com>
11+ - Thierry Reding <thierry.reding@gmail.com>
12+
13+allOf:
14+ - $ref: nvidia,tegra-audio-common.yaml#
15+
16+properties:
17+ compatible:
18+ oneOf:
19+ - items:
20+ - pattern: '^[a-z0-9]+,tegra-audio-max98088(-[a-z0-9]+)+$'
21+ - const: nvidia,tegra-audio-max98088
22+ - items:
23+ - pattern: '^[a-z0-9]+,tegra-audio-max98089(-[a-z0-9]+)+$'
24+ - const: nvidia,tegra-audio-max98089
25+
26+ nvidia,audio-routing:
27+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
28+ description: |
29+ A list of the connections between audio components.
30+ Each entry is a pair of strings, the first being the connection's sink,
31+ the second being the connection's source. Valid names for sources and
32+ sinks are the pins (documented in the binding document),
33+ and the jacks on the board.
34+ minItems: 2
35+ items:
36+ enum:
37+ # Board Connectors
38+ - "Int Spk"
39+ - "Headphone Jack"
40+ - "Earpiece"
41+ - "Headset Mic"
42+ - "Internal Mic 1"
43+ - "Internal Mic 2"
44+
45+ # CODEC Pins
46+ - HPL
47+ - HPR
48+ - SPKL
49+ - SPKR
50+ - RECL
51+ - RECR
52+ - INA1
53+ - INA2
54+ - INB1
55+ - INB2
56+ - MIC1
57+ - MIC2
58+ - MICBIAS
59+
60+unevaluatedProperties: false
61+
62+examples:
63+ - |
64+ #include <dt-bindings/clock/tegra30-car.h>
65+ #include <dt-bindings/soc/tegra-pmc.h>
66+ sound {
67+ compatible = "lge,tegra-audio-max98089-p895",
68+ "nvidia,tegra-audio-max98089";
69+ nvidia,model = "LG Optimus Vu MAX98089";
70+
71+ nvidia,audio-routing =
72+ "Headphone Jack", "HPL",
73+ "Headphone Jack", "HPR",
74+ "Int Spk", "SPKL",
75+ "Int Spk", "SPKR",
76+ "Earpiece", "RECL",
77+ "Earpiece", "RECR",
78+ "INA1", "Headset Mic",
79+ "MIC1", "MICBIAS",
80+ "MICBIAS", "Internal Mic 1",
81+ "MIC2", "Internal Mic 2";
82+
83+ nvidia,i2s-controller = <&tegra_i2s0>;
84+ nvidia,audio-codec = <&codec>;
85+
86+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
87+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
88+ <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
89+ clock-names = "pll_a", "pll_a_out0", "mclk";
90+ };
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.yaml+4−4
@@ -38,10 +38,10 @@ properties: · 37 unmodified lines
3838 items:
3939 enum:
4040 # Board Connectors
41− - "Headphones"
42− - "Speakers"
43− - "Mic Jack"
44− - "Int Mic"
41+ - Headphones
42+ - Speakers
43+ - Mic Jack
44+ - Int Mic
4545
4646 # CODEC Pins
4747 - MIC1
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5631.yaml+85−0
@@ -0,0 +1,85 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-rt5631.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: NVIDIA Tegra audio complex with RT5631 CODEC
8+
9+maintainers:
10+ - Jon Hunter <jonathanh@nvidia.com>
11+ - Thierry Reding <thierry.reding@gmail.com>
12+
13+allOf:
14+ - $ref: nvidia,tegra-audio-common.yaml#
15+
16+properties:
17+ compatible:
18+ items:
19+ - pattern: '^[a-z0-9]+,tegra-audio-rt5631(-[a-z0-9]+)+$'
20+ - const: nvidia,tegra-audio-rt5631
21+
22+ nvidia,audio-routing:
23+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
24+ description: |
25+ A list of the connections between audio components.
26+ Each entry is a pair of strings, the first being the connection's sink,
27+ the second being the connection's source. Valid names for sources and
28+ sinks are the pins (documented in the binding document),
29+ and the jacks on the board.
30+ minItems: 2
31+ items:
32+ enum:
33+ # Board Connectors
34+ - "Int Spk"
35+ - "Headphone Jack"
36+ - "Mic Jack"
37+ - "Int Mic"
38+
39+ # CODEC Pins
40+ - MIC1
41+ - MIC2
42+ - AXIL
43+ - AXIR
44+ - MONOIN_RXN
45+ - MONOIN_RXP
46+ - DMIC
47+ - MIC Bias1
48+ - MIC Bias2
49+ - MONO_IN
50+ - AUXO1
51+ - AUXO2
52+ - SPOL
53+ - SPOR
54+ - HPOL
55+ - HPOR
56+ - MONO
57+
58+unevaluatedProperties: false
59+
60+examples:
61+ - |
62+ #include <dt-bindings/clock/tegra30-car.h>
63+ #include <dt-bindings/soc/tegra-pmc.h>
64+ sound {
65+ compatible = "asus,tegra-audio-rt5631-tf700t",
66+ "nvidia,tegra-audio-rt5631";
67+ nvidia,model = "Asus Transformer Infinity TF700T RT5631";
68+
69+ nvidia,audio-routing =
70+ "Headphone Jack", "HPOL",
71+ "Headphone Jack", "HPOR",
72+ "Int Spk", "SPOL",
73+ "Int Spk", "SPOR",
74+ "MIC1", "MIC Bias1",
75+ "MIC Bias1", "Mic Jack",
76+ "DMIC", "Int Mic";
77+
78+ nvidia,i2s-controller = <&tegra_i2s1>;
79+ nvidia,audio-codec = <&rt5631>;
80+
81+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
82+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
83+ <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
84+ clock-names = "pll_a", "pll_a_out0", "mclk";
85+ };
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.yaml+3−3
@@ -31,9 +31,9 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headphones"
35− - "Speakers"
36− - "Mic Jack"
34+ - Headphones
35+ - Speakers
36+ - Mic Jack
3737
3838 # CODEC Pins
3939 - DMIC1
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5677.yaml+13−13
@@ -31,11 +31,11 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headphone"
35− - "Speaker"
36− - "Headset Mic"
37− - "Internal Mic 1"
38− - "Internal Mic 2"
34+ - Headphone
35+ - Speaker
36+ - Headset Mic
37+ - Internal Mic 1
38+ - Internal Mic 2
3939
4040 # CODEC Pins
4141 - IN1P
@@ -47,14 +47,14 @@ properties: · 5 unmodified lines
4747 - DMIC2
4848 - DMIC3
4949 - DMIC4
50− - "DMIC L1"
51− - "DMIC L2"
52− - "DMIC L3"
53− - "DMIC L4"
54− - "DMIC R1"
55− - "DMIC R2"
56− - "DMIC R3"
57− - "DMIC R4"
50+ - DMIC L1
51+ - DMIC L2
52+ - DMIC L3
53+ - DMIC L4
54+ - DMIC R1
55+ - DMIC R2
56+ - DMIC R3
57+ - DMIC R4
5858 - LOUT1
5959 - LOUT2
6060 - LOUT3
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.yaml+3−3
@@ -31,9 +31,9 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headphone Jack"
35− - "Line In Jack"
36− - "Mic Jack"
34+ - Headphone Jack
35+ - Line In Jack
36+ - Mic Jack
3737
3838 # CODEC Pins
3939 - HP_OUT
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.yaml+3−3
@@ -31,8 +31,8 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headphone Jack"
35− - "Mic Jack"
34+ - Headphone Jack
35+ - Mic Jack
3636
3737 # CODEC Pins
3838 - LOUT1
@@ -53,7 +53,7 @@ properties: · 14 unmodified lines
5353 - MIC1
5454 - MIC2N
5555 - MIC2
56− - "Mic Bias"
56+ - Mic Bias
5757
5858 required:
5959 - nvidia,i2s-controller
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.yaml+4−4
@@ -35,10 +35,10 @@ properties: · 34 unmodified lines
3535 items:
3636 enum:
3737 # Board Connectors
38− - "Headphone Jack"
39− - "Int Spk"
40− - "Mic Jack"
41− - "Int Mic"
38+ - Headphone Jack
39+ - Int Spk
40+ - Mic Jack
41+ - Int Mic
4242
4343 # CODEC Pins
4444 - IN1L
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.yaml+4−4
@@ -31,9 +31,9 @@ properties: · 30 unmodified lines
3131 items:
3232 enum:
3333 # Board Connectors
34− - "Headphone"
35− - "LineIn"
36− - "Mic"
34+ - Headphone
35+ - LineIn
36+ - Mic
3737
3838 # CODEC Pins
3939 - MONOOUT
@@ -48,7 +48,7 @@ properties: · 8 unmodified lines
4848 - PCBEEP
4949 - MIC1
5050 - MIC2
51− - "Mic Bias"
51+ - Mic Bias
5252
5353 required:
5454 - nvidia,ac97-controller
Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml+63−14
@@ -9,15 +9,13 @@ title: LPASS(Low Power Audio Subsystem) RX Macro audio codec · 8 unmodified lines
99 maintainers:
1010 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
1111
12−allOf:
13− - $ref: dai-common.yaml#
14−
1512 properties:
1613 compatible:
1714 enum:
1815 - qcom,sc7280-lpass-rx-macro
1916 - qcom,sm8250-lpass-rx-macro
2017 - qcom,sm8450-lpass-rx-macro
18+ - qcom,sm8550-lpass-rx-macro
2119 - qcom,sc8280xp-lpass-rx-macro
2220
2321 reg:
@@ -30,20 +28,12 @@ properties: · 6 unmodified lines
3028 const: 0
3129
3230 clocks:
31+ minItems: 3
3332 maxItems: 5
3433
3534 clock-names:
36− oneOf:
37− - items: # for ADSP based platforms
38− - const: mclk
39− - const: npl
40− - const: macro
41− - const: dcodec
42− - const: fsgen
43− - items: # for ADSP bypass based platforms
44− - const: mclk
45− - const: npl
46− - const: fsgen
35+ minItems: 3
36+ maxItems: 5
4737
4838 clock-output-names:
4939 maxItems: 1
@@ -61,6 +51,65 @@ required: · 11 unmodified lines
6151 - reg
6252 - "#sound-dai-cells"
6353
54+allOf:
55+ - $ref: dai-common.yaml#
56+ - if:
57+ properties:
58+ compatible:
59+ enum:
60+ - qcom,sc7280-lpass-rx-macro
61+ then:
62+ properties:
63+ clock-names:
64+ oneOf:
65+ - items: # for ADSP based platforms
66+ - const: mclk
67+ - const: npl
68+ - const: macro
69+ - const: dcodec
70+ - const: fsgen
71+ - items: # for ADSP bypass based platforms
72+ - const: mclk
73+ - const: npl
74+ - const: fsgen
75+
76+ - if:
77+ properties:
78+ compatible:
79+ enum:
80+ - qcom,sc8280xp-lpass-rx-macro
81+ - qcom,sm8250-lpass-rx-macro
82+ - qcom,sm8450-lpass-rx-macro
83+ then:
84+ properties:
85+ clocks:
86+ minItems: 5
87+ maxItems: 5
88+ clock-names:
89+ items:
90+ - const: mclk
91+ - const: npl
92+ - const: macro
93+ - const: dcodec
94+ - const: fsgen
95+
96+ - if:
97+ properties:
98+ compatible:
99+ enum:
100+ - qcom,sm8550-lpass-rx-macro
101+ then:
102+ properties:
103+ clocks:
104+ minItems: 4
105+ maxItems: 4
106+ clock-names:
107+ items:
108+ - const: mclk
109+ - const: macro
110+ - const: dcodec
111+ - const: fsgen
112+
64113 unevaluatedProperties: false
65114
66115 examples:
Documentation/devicetree/bindings/sound/qcom,lpass-tx-macro.yaml+64−17
@@ -9,15 +9,13 @@ title: LPASS(Low Power Audio Subsystem) TX Macro audio codec · 8 unmodified lines
99 maintainers:
1010 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
1111
12−allOf:
13− - $ref: dai-common.yaml#
14−
1512 properties:
1613 compatible:
1714 enum:
1815 - qcom,sc7280-lpass-tx-macro
1916 - qcom,sm8250-lpass-tx-macro
2017 - qcom,sm8450-lpass-tx-macro
18+ - qcom,sm8550-lpass-tx-macro
2119 - qcom,sc8280xp-lpass-tx-macro
2220
2321 reg:
@@ -30,22 +28,12 @@ properties: · 6 unmodified lines
3028 const: 0
3129
3230 clocks:
33− oneOf:
34− - maxItems: 3
35− - maxItems: 5
31+ minItems: 3
32+ maxItems: 5
3633
3734 clock-names:
38− oneOf:
39− - items: # for ADSP based platforms
40− - const: mclk
41− - const: npl
42− - const: macro
43− - const: dcodec
44− - const: fsgen
45− - items: # for ADSP bypass based platforms
46− - const: mclk
47− - const: npl
48− - const: fsgen
35+ minItems: 3
36+ maxItems: 5
4937
5038 clock-output-names:
5139 maxItems: 1
@@ -67,6 +55,65 @@ required: · 15 unmodified lines
6755 - reg
6856 - "#sound-dai-cells"
6957
58+allOf:
59+ - $ref: dai-common.yaml#
60+ - if:
61+ properties:
62+ compatible:
63+ enum:
64+ - qcom,sc7280-lpass-tx-macro
65+ then:
66+ properties:
67+ clock-names:
68+ oneOf:
69+ - items: # for ADSP based platforms
70+ - const: mclk
71+ - const: npl
72+ - const: macro
73+ - const: dcodec
74+ - const: fsgen
75+ - items: # for ADSP bypass based platforms
76+ - const: mclk
77+ - const: npl
78+ - const: fsgen
79+
80+ - if:
81+ properties:
82+ compatible:
83+ enum:
84+ - qcom,sc8280xp-lpass-tx-macro
85+ - qcom,sm8250-lpass-tx-macro
86+ - qcom,sm8450-lpass-tx-macro
87+ then:
88+ properties:
89+ clocks:
90+ minItems: 5
91+ maxItems: 5
92+ clock-names:
93+ items:
94+ - const: mclk
95+ - const: npl
96+ - const: macro
97+ - const: dcodec
98+ - const: fsgen
99+
100+ - if:
101+ properties:
102+ compatible:
103+ enum:
104+ - qcom,sm8550-lpass-tx-macro
105+ then:
106+ properties:
107+ clocks:
108+ minItems: 4
109+ maxItems: 4
110+ clock-names:
111+ items:
112+ - const: mclk
113+ - const: macro
114+ - const: dcodec
115+ - const: fsgen
116+
70117 unevaluatedProperties: false
71118
72119 examples:
Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml+75−11
@@ -9,15 +9,13 @@ title: LPASS(Low Power Audio Subsystem) VA Macro audio codec · 8 unmodified lines
99 maintainers:
1010 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
1111
12−allOf:
13− - $ref: dai-common.yaml#
14−
1512 properties:
1613 compatible:
1714 enum:
1815 - qcom,sc7280-lpass-va-macro
1916 - qcom,sm8250-lpass-va-macro
2017 - qcom,sm8450-lpass-va-macro
18+ - qcom,sm8550-lpass-va-macro
2119 - qcom,sc8280xp-lpass-va-macro
2220
2321 reg:
@@ -30,16 +28,12 @@ properties: · 6 unmodified lines
3028 const: 0
3129
3230 clocks:
33− maxItems: 3
31+ minItems: 1
32+ maxItems: 4
3433
3534 clock-names:
36− oneOf:
37− - items: # for ADSP based platforms
38− - const: mclk
39− - const: macro
40− - const: dcodec
41− - items: # for ADSP bypass based platforms
42− - const: mclk
35+ minItems: 1
36+ maxItems: 4
4337
4438 clock-output-names:
4539 maxItems: 1
@@ -63,6 +57,76 @@ required: · 17 unmodified lines
6357 - compatible
6458 - reg
6559 - "#sound-dai-cells"
60+ - clock-names
61+ - clocks
62+
63+allOf:
64+ - $ref: dai-common.yaml#
65+
66+ - if:
67+ properties:
68+ compatible:
69+ contains:
70+ const: qcom,sc7280-lpass-va-macro
71+ then:
72+ properties:
73+ clocks:
74+ maxItems: 1
75+ clock-names:
76+ items:
77+ - const: mclk
78+
79+ - if:
80+ properties:
81+ compatible:
82+ contains:
83+ const: qcom,sm8250-lpass-va-macro
84+ then:
85+ properties:
86+ clocks:
87+ minItems: 3
88+ maxItems: 3
89+ clock-names:
90+ items:
91+ - const: mclk
92+ - const: macro
93+ - const: dcodec
94+
95+ - if:
96+ properties:
97+ compatible:
98+ contains:
99+ enum:
100+ - qcom,sc8280xp-lpass-va-macro
101+ - qcom,sm8450-lpass-va-macro
102+ then:
103+ properties:
104+ clocks:
105+ minItems: 4
106+ maxItems: 4
107+ clock-names:
108+ items:
109+ - const: mclk
110+ - const: macro
111+ - const: dcodec
112+ - const: npl
113+
114+ - if:
115+ properties:
116+ compatible:
117+ contains:
118+ enum:
119+ - qcom,sm8550-lpass-va-macro
120+ then:
121+ properties:
122+ clocks:
123+ minItems: 3
124+ maxItems: 3
125+ clock-names:
126+ items:
127+ - const: mclk
128+ - const: macro
129+ - const: dcodec
66130
67131 unevaluatedProperties: false
68132
Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml+21−2
@@ -15,6 +15,7 @@ properties: · 14 unmodified lines
1515 - qcom,sc7280-lpass-wsa-macro
1616 - qcom,sm8250-lpass-wsa-macro
1717 - qcom,sm8450-lpass-wsa-macro
18+ - qcom,sm8550-lpass-wsa-macro
1819 - qcom,sc8280xp-lpass-wsa-macro
1920
2021 reg:
@@ -27,11 +28,11 @@ properties: · 6 unmodified lines
2728 const: 0
2829
2930 clocks:
30− minItems: 5
31+ minItems: 4
3132 maxItems: 6
3233
3334 clock-names:
34− minItems: 5
35+ minItems: 4
3536 maxItems: 6
3637
3738 clock-output-names:
@@ -62,6 +63,7 @@ allOf: · 24 unmodified lines
6263 then:
6364 properties:
6465 clocks:
66+ minItems: 5
6567 maxItems: 5
6668 clock-names:
6769 items:
@@ -89,6 +91,23 @@ allOf: · 21 unmodified lines
8991 - const: va
9092 - const: fsgen
9193
94+ - if:
95+ properties:
96+ compatible:
97+ enum:
98+ - qcom,sm8550-lpass-wsa-macro
99+ then:
100+ properties:
101+ clocks:
102+ minItems: 4
103+ maxItems: 4
104+ clock-names:
105+ items:
106+ - const: mclk
107+ - const: macro
108+ - const: dcodec
109+ - const: fsgen
110+
92111 unevaluatedProperties: false
93112
94113 examples:
Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml+1−1
@@ -56,7 +56,7 @@ patternProperties: · 55 unmodified lines
5656 Compress offload dai.
5757
5858 dependencies:
59− is-compress-dai: ["direction"]
59+ is-compress-dai: [ direction ]
6060
6161 required:
6262 - reg
Documentation/devicetree/bindings/sound/qcom,wcd9335.txt+0−123
@@ -1,123 +0,0 @@
1−QCOM WCD9335 Codec
2−
3−Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC, supports
4−Qualcomm Technologies, Inc. (QTI) multimedia solutions, including
5−the MSM8996, MSM8976, and MSM8956 chipsets. It has in-built
6−Soundwire controller, interrupt mux. It supports both I2S/I2C and
7−SLIMbus audio interfaces.
8−
9−Required properties with SLIMbus Interface:
10−
11−- compatible:
12− Usage: required
13− Value type: <stringlist>
14− Definition: For SLIMbus interface it should be "slimMID,PID",
15− textual representation of Manufacturer ID, Product Code,
16− shall be in lower case hexadecimal with leading zeroes
17− suppressed. Refer to slimbus/bus.txt for details.
18− Should be:
19− "slim217,1a0" for MSM8996 and APQ8096 SoCs with SLIMbus.
20−
21−- reg
22− Usage: required
23− Value type: <u32 u32>
24− Definition: Should be ('Device index', 'Instance ID')
25−
26−- interrupts
27− Usage: required
28− Value type: <prop-encoded-array>
29− Definition: Interrupts via WCD INTR1 and INTR2 pins
30−
31−- interrupt-names:
32− Usage: required
33− Value type: <String array>
34− Definition: Interrupt names of WCD INTR1 and INTR2
35− Should be: "intr1", "intr2"
36−
37−- reset-gpios:
38− Usage: required
39− Value type: <String Array>
40− Definition: Reset gpio line
41−
42−- slim-ifc-dev:
43− Usage: required
44− Value type: <phandle>
45− Definition: SLIM interface device
46−
47−- clocks:
48− Usage: required
49− Value type: <prop-encoded-array>
50− Definition: See clock-bindings.txt section "consumers". List of
51− three clock specifiers for mclk, mclk2 and slimbus clock.
52−
53−- clock-names:
54− Usage: required
55− Value type: <string>
56− Definition: Must contain "mclk", "mclk2" and "slimbus" strings.
57−
58−- vdd-buck-supply:
59− Usage: required
60− Value type: <phandle>
61− Definition: Should contain a reference to the 1.8V buck supply
62−
63−- vdd-buck-sido-supply:
64− Usage: required
65− Value type: <phandle>
66− Definition: Should contain a reference to the 1.8V SIDO buck supply
67−
68−- vdd-rx-supply:
69− Usage: required
70− Value type: <phandle>
71− Definition: Should contain a reference to the 1.8V rx supply
72−
73−- vdd-tx-supply:
74− Usage: required
75− Value type: <phandle>
76− Definition: Should contain a reference to the 1.8V tx supply
77−
78−- vdd-vbat-supply:
79− Usage: Optional
80− Value type: <phandle>
81− Definition: Should contain a reference to the vbat supply
82−
83−- vdd-micbias-supply:
84− Usage: required
85− Value type: <phandle>
86− Definition: Should contain a reference to the micbias supply
87−
88−- vdd-io-supply:
89− Usage: required
90− Value type: <phandle>
91− Definition: Should contain a reference to the 1.8V io supply
92−
93−- interrupt-controller:
94− Usage: required
95− Definition: Indicating that this is a interrupt controller
96−
97−- #interrupt-cells:
98− Usage: required
99− Value type: <int>
100− Definition: should be 1
101−
102−#sound-dai-cells
103− Usage: required
104− Value type: <u32>
105− Definition: Must be 1
106−
107−audio-codec@1{
108− compatible = "slim217,1a0";
109− reg = <1 0>;
110− interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
111− interrupt-names = "intr2"
112− reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>;
113− slim-ifc-dev = <&wc9335_ifd>;
114− clock-names = "mclk", "native";
115− clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
116− <&rpmcc RPM_SMD_BB_CLK1>;
117− vdd-buck-supply = <&pm8994_s4>;
118− vdd-rx-supply = <&pm8994_s4>;
119− vdd-buck-sido-supply = <&pm8994_s4>;
120− vdd-tx-supply = <&pm8994_s4>;
121− vdd-io-supply = <&pm8994_s4>;
122− #sound-dai-cells = <1>;
123−}
Documentation/devicetree/bindings/sound/qcom,wcd9335.yaml+156−0
@@ -0,0 +1,156 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/qcom,wcd9335.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Qualcomm WCD9335 Audio Codec
8+
9+maintainers:
10+ - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
11+
12+description:
13+ Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC with in-built
14+ Soundwire controller and interrupt mux. It supports both I2S/I2C and SLIMbus
15+ audio interfaces.
16+
17+properties:
18+ compatible:
19+ const: slim217,1a0
20+
21+ reg:
22+ maxItems: 1
23+
24+ clocks:
25+ maxItems: 2
26+
27+ clock-names:
28+ items:
29+ - const: mclk
30+ - const: slimbus
31+
32+ interrupts:
33+ maxItems: 2
34+
35+ interrupt-names:
36+ items:
37+ - const: intr1
38+ - const: intr2
39+
40+ interrupt-controller: true
41+
42+ '#interrupt-cells':
43+ const: 1
44+
45+ reset-gpios:
46+ maxItems: 1
47+
48+ slim-ifc-dev:
49+ description: SLIM IFC device interface
50+ $ref: /schemas/types.yaml#/definitions/phandle
51+
52+ '#sound-dai-cells':
53+ const: 1
54+
55+ vdd-buck-supply:
56+ description: 1.8V buck supply
57+
58+ vdd-buck-sido-supply:
59+ description: 1.8V SIDO buck supply
60+
61+ vdd-io-supply:
62+ description: 1.8V I/O supply
63+
64+ vdd-micbias-supply:
65+ description: micbias supply
66+
67+ vdd-rx-supply:
68+ description: 1.8V rx supply
69+
70+ vdd-tx-supply:
71+ description: 1.8V tx supply
72+
73+ vdd-vbat-supply:
74+ description: vbat supply
75+
76+required:
77+ - compatible
78+ - reg
79+
80+allOf:
81+ - $ref: dai-common.yaml#
82+ - if:
83+ required:
84+ - slim-ifc-dev
85+ then:
86+ required:
87+ - clocks
88+ - clock-names
89+ - interrupts
90+ - interrupt-names
91+ - interrupt-controller
92+ - '#interrupt-cells'
93+ - reset-gpios
94+ - slim-ifc-dev
95+ - '#sound-dai-cells'
96+ - vdd-buck-supply
97+ - vdd-buck-sido-supply
98+ - vdd-io-supply
99+ - vdd-rx-supply
100+ - vdd-tx-supply
101+ else:
102+ properties:
103+ clocks: false
104+ clock-names: false
105+ interrupts: false
106+ interrupt-names: false
107+ interrupt-controller: false
108+ '#interrupt-cells': false
109+ reset-gpios: false
110+ slim-ifc-dev: false
111+ '#sound-dai-cells': false
112+ vdd-buck-supply: false
113+ vdd-buck-sido-supply: false
114+ vdd-io-supply: false
115+ vdd-micbias-supply: false
116+ vdd-rx-supply: false
117+ vdd-tx-supply: false
118+ vdd-vbat-supply: false
119+
120+additionalProperties: false
121+
122+examples:
123+ - |
124+ #include <dt-bindings/clock/qcom,rpmcc.h>
125+ #include <dt-bindings/gpio/gpio.h>
126+ #include <dt-bindings/interrupt-controller/irq.h>
127+
128+ tasha_ifd: codec@0,0 {
129+ compatible = "slim217,1a0";
130+ reg = <0 0>;
131+ };
132+
133+ codec@1,0 {
134+ compatible = "slim217,1a0";
135+ reg = <1 0>;
136+
137+ clock-names = "mclk", "slimbus";
138+ clocks = <&div1_mclk>, <&rpmcc RPM_SMD_BB_CLK1>;
139+
140+ interrupt-parent = <&tlmm>;
141+ interrupts = <54 IRQ_TYPE_LEVEL_HIGH>,
142+ <53 IRQ_TYPE_LEVEL_HIGH>;
143+ interrupt-names = "intr1", "intr2";
144+ interrupt-controller;
145+ #interrupt-cells = <1>;
146+
147+ reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
148+ slim-ifc-dev = <&tasha_ifd>;
149+ #sound-dai-cells = <1>;
150+
151+ vdd-buck-supply = <&vreg_s4a_1p8>;
152+ vdd-buck-sido-supply = <&vreg_s4a_1p8>;
153+ vdd-tx-supply = <&vreg_s4a_1p8>;
154+ vdd-rx-supply = <&vreg_s4a_1p8>;
155+ vdd-io-supply = <&vreg_s4a_1p8>;
156+ };
Documentation/devicetree/bindings/sound/qcom,wcd934x.yaml+1−0
@@ -152,6 +152,7 @@ required: · 151 unmodified lines
152152 - reg
153153
154154 allOf:
155+ - $ref: dai-common.yaml#
155156 - if:
156157 required:
157158 - slim-ifc-dev
Documentation/devicetree/bindings/sound/realtek,alc5632.yaml+63−0
@@ -0,0 +1,63 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/realtek,alc5632.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: ALC5632 audio CODEC
8+
9+description: |
10+ Pins on the device (for linking into audio routes):
11+ * SPK_OUTP
12+ * SPK_OUTN
13+ * HP_OUT_L
14+ * HP_OUT_R
15+ * AUX_OUT_P
16+ * AUX_OUT_N
17+ * LINE_IN_L
18+ * LINE_IN_R
19+ * PHONE_P
20+ * PHONE_N
21+ * MIC1_P
22+ * MIC1_N
23+ * MIC2_P
24+ * MIC2_N
25+ * MICBIAS1
26+ * DMICDAT
27+
28+maintainers:
29+ - Leon Romanovsky <leon@leon.nu>
30+
31+properties:
32+ compatible:
33+ const: realtek,alc5632
34+
35+ reg:
36+ maxItems: 1
37+
38+ '#gpio-cells':
39+ const: 2
40+
41+ gpio-controller: true
42+
43+required:
44+ - compatible
45+ - reg
46+ - '#gpio-cells'
47+ - gpio-controller
48+
49+additionalProperties: false
50+
51+examples:
52+ - |
53+ #include <dt-bindings/gpio/gpio.h>
54+ i2c {
55+ #address-cells = <1>;
56+ #size-cells = <0>;
57+ codec@1a {
58+ compatible = "realtek,alc5632";
59+ reg = <0x1a>;
60+ gpio-controller;
61+ #gpio-cells = <2>;
62+ };
63+ };
Documentation/devicetree/bindings/sound/renesas,rsnd.yaml+97−32
@@ -101,17 +101,7 @@ properties: · 100 unmodified lines
101101
102102 clock-names:
103103 description: List of necessary clock names.
104− minItems: 1
105− maxItems: 31
106− items:
107− oneOf:
108− - const: ssi-all
109− - pattern: '^ssi\.[0-9]$'
110− - pattern: '^src\.[0-9]$'
111− - pattern: '^mix\.[0-1]$'
112− - pattern: '^ctu\.[0-1]$'
113− - pattern: '^dvc\.[0-1]$'
114− - pattern: '^clk_(a|b|c|i)$'
104+ # details are defined below
115105
116106 ports:
117107 $ref: audio-graph-port.yaml#/definitions/port-base
@@ -155,7 +145,7 @@ properties: · 37 unmodified lines
155145 dmas:
156146 maxItems: 1
157147 dma-names:
158− const: "tx"
148+ const: tx
159149 required:
160150 - dmas
161151 - dma-names
@@ -288,6 +278,11 @@ required: · 126 unmodified lines
288278
289279 allOf:
290280 - $ref: dai-common.yaml#
281+
282+ # --------------------
283+ # reg/reg-names
284+ # --------------------
285+ # for Gen1
291286 - if:
292287 properties:
293288 compatible:
@@ -303,7 +298,15 @@ allOf: · 9 unmodified lines
303298 - scu
304299 - ssi
305300 - adg
306− else:
301+ # for Gen2/Gen3
302+ - if:
303+ properties:
304+ compatible:
305+ contains:
306+ enum:
307+ - renesas,rcar_sound-gen2
308+ - renesas,rcar_sound-gen3
309+ then:
307310 properties:
308311 reg:
309312 minItems: 5
@@ -315,35 +318,87 @@ allOf: · 5 unmodified lines
315318 - ssiu
316319 - ssi
317320 - audmapp
321+ # for Gen4
322+ - if:
323+ properties:
324+ compatible:
325+ contains:
326+ const: renesas,rcar_sound-gen4
327+ then:
328+ properties:
329+ reg:
330+ maxItems: 4
331+ reg-names:
332+ items:
333+ enum:
334+ - adg
335+ - ssiu
336+ - ssi
337+ - sdmc
338+
339+ # --------------------
340+ # clock-names
341+ # --------------------
342+ - if:
343+ properties:
344+ compatible:
345+ contains:
346+ const: renesas,rcar_sound-gen4
347+ then:
348+ properties:
349+ clock-names:
350+ maxItems: 3
351+ items:
352+ enum:
353+ - ssi.0
354+ - ssiu.0
355+ - clkin
356+ else:
357+ properties:
358+ clock-names:
359+ minItems: 1
360+ maxItems: 31
361+ items:
362+ oneOf:
363+ - const: ssi-all
364+ - pattern: '^ssi\.[0-9]$'
365+ - pattern: '^src\.[0-9]$'
366+ - pattern: '^mix\.[0-1]$'
367+ - pattern: '^ctu\.[0-1]$'
368+ - pattern: '^dvc\.[0-1]$'
369+ - pattern: '^clk_(a|b|c|i)$'
318370
319371 unevaluatedProperties: false
320372
321373 examples:
322374 - |
375+ #include <dt-bindings/clock/r8a7790-cpg-mssr.h>
376+ #include <dt-bindings/interrupt-controller/arm-gic.h>
377+ #include <dt-bindings/power/r8a7790-sysc.h>
323378 rcar_sound: sound@ec500000 {
324379 #sound-dai-cells = <1>;
325380 compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";
326381 reg = <0xec500000 0x1000>, /* SCU */
327382 <0xec5a0000 0x100>, /* ADG */
328383 <0xec540000 0x1000>, /* SSIU */
329− <0xec541000 0x1280>, /* SSI */
384+ <0xec541000 0x280>, /* SSI */
330385 <0xec740000 0x200>; /* Audio DMAC peri peri*/
331386 reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
332387
333− clocks = <&mstp10_clks 1005>, /* SSI-ALL */
334− <&mstp10_clks 1006>, <&mstp10_clks 1007>, /* SSI9, SSI8 */
335− <&mstp10_clks 1008>, <&mstp10_clks 1009>, /* SSI7, SSI6 */
336− <&mstp10_clks 1010>, <&mstp10_clks 1011>, /* SSI5, SSI4 */
337− <&mstp10_clks 1012>, <&mstp10_clks 1013>, /* SSI3, SSI2 */
338− <&mstp10_clks 1014>, <&mstp10_clks 1015>, /* SSI1, SSI0 */
339− <&mstp10_clks 1022>, <&mstp10_clks 1023>, /* SRC9, SRC8 */
340− <&mstp10_clks 1024>, <&mstp10_clks 1025>, /* SRC7, SRC6 */
341− <&mstp10_clks 1026>, <&mstp10_clks 1027>, /* SRC5, SRC4 */
342− <&mstp10_clks 1028>, <&mstp10_clks 1029>, /* SRC3, SRC2 */
343− <&mstp10_clks 1030>, <&mstp10_clks 1031>, /* SRC1, SRC0 */
344− <&mstp10_clks 1020>, <&mstp10_clks 1021>, /* MIX1, MIX0 */
345− <&mstp10_clks 1020>, <&mstp10_clks 1021>, /* CTU1, CTU0 */
346− <&mstp10_clks 1019>, <&mstp10_clks 1018>, /* DVC0, DVC1 */
388+ clocks = <&cpg CPG_MOD 1005>, /* SSI-ALL */
389+ <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, /* SSI9, SSI8 */
390+ <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, /* SSI7, SSI6 */
391+ <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, /* SSI5, SSI4 */
392+ <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, /* SSI3, SSI2 */
393+ <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, /* SSI1, SSI0 */
394+ <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, /* SRC9, SRC8 */
395+ <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, /* SRC7, SRC6 */
396+ <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, /* SRC5, SRC4 */
397+ <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, /* SRC3, SRC2 */
398+ <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, /* SRC1, SRC0 */
399+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, /* MIX1, MIX0 */
400+ <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, /* CTU1, CTU0 */
401+ <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, /* DVC0, DVC1 */
347402 <&audio_clk_a>, <&audio_clk_b>, /* CLKA, CLKB */
348403 <&audio_clk_c>, <&audio_clk_i>; /* CLKC, CLKI */
349404
@@ -364,6 +419,17 @@ examples: · 14 unmodified lines
364419 "clk_a", "clk_b",
365420 "clk_c", "clk_i";
366421
422+ power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
423+
424+ resets = <&cpg 1005>,
425+ <&cpg 1006>, <&cpg 1007>, <&cpg 1008>, <&cpg 1009>,
426+ <&cpg 1010>, <&cpg 1011>, <&cpg 1012>, <&cpg 1013>,
427+ <&cpg 1014>, <&cpg 1015>;
428+ reset-names = "ssi-all",
429+ "ssi.9", "ssi.8", "ssi.7", "ssi.6",
430+ "ssi.5", "ssi.4", "ssi.3", "ssi.2",
431+ "ssi.1", "ssi.0";
432+
367433 rcar_sound,dvc {
368434 dvc0: dvc-0 {
369435 dmas = <&audma0 0xbc>;
@@ -396,7 +462,7 @@ examples: · 26 unmodified lines
396462 status = "disabled";
397463 };
398464 src1: src-1 {
399− interrupts = <0 353 0>;
465+ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
400466 dmas = <&audma0 0x87>, <&audma1 0x9c>;
401467 dma-names = "rx", "tx";
402468 };
@@ -417,12 +483,12 @@ examples: · 14 unmodified lines
417483
418484 rcar_sound,ssi {
419485 ssi0: ssi-0 {
420− interrupts = <0 370 1>;
486+ interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
421487 dmas = <&audma0 0x01>, <&audma1 0x02>;
422488 dma-names = "rx", "tx";
423489 };
424490 ssi1: ssi-1 {
425− interrupts = <0 371 1>;
491+ interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
426492 dmas = <&audma0 0x03>, <&audma1 0x04>;
427493 dma-names = "rx", "tx";
428494 };
@@ -464,7 +530,6 @@ examples: · 35 unmodified lines
464530 };
465531 };
466532
467−
468533 /* assume audio-graph */
469534 codec {
470535 port {
Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml+12−9
@@ -25,14 +25,18 @@ properties: · 24 unmodified lines
2525 maxItems: 1
2626
2727 interrupts:
28− maxItems: 4
28+ minItems: 2
29+ maxItems: 3
2930
3031 interrupt-names:
31− items:
32− - const: int_req
33− - const: dma_rx
34− - const: dma_tx
35− - const: dma_rt
32+ oneOf:
33+ - items:
34+ - const: int_req
35+ - const: dma_rx
36+ - const: dma_tx
37+ - items:
38+ - const: int_req
39+ - const: dma_rt
3640
3741 clocks:
3842 maxItems: 4
@@ -106,9 +110,8 @@ examples: · 67 unmodified lines
106110 reg = <0x10049c00 0x400>;
107111 interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
108112 <GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
109− <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
110− <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;
111− interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
113+ <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
114+ interrupt-names = "int_req", "dma_rx", "dma_tx";
112115 clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
113116 <&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
114117 <&audio_clk1>,
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml+7−0
@@ -86,6 +86,13 @@ properties: · 85 unmodified lines
8686 - tx-m
8787 - rx-m
8888
89+ port:
90+ $ref: audio-graph-port.yaml#
91+ unevaluatedProperties: false
92+
93+ power-domains:
94+ maxItems: 1
95+
8996 rockchip,grf:
9097 $ref: /schemas/types.yaml#/definitions/phandle
9198 description:
Documentation/devicetree/bindings/sound/rockchip-i2s.yaml+5−0
@@ -34,6 +34,7 @@ properties: · 33 unmodified lines
3434 - rockchip,rk3366-i2s
3535 - rockchip,rk3368-i2s
3636 - rockchip,rk3399-i2s
37+ - rockchip,rk3588-i2s
3738 - rockchip,rv1126-i2s
3839 - const: rockchip,rk3066-i2s
3940
@@ -82,6 +83,10 @@ properties: · 42 unmodified lines
8283 resets:
8384 maxItems: 2
8485
86+ port:
87+ $ref: audio-graph-port.yaml#
88+ unevaluatedProperties: false
89+
8590 rockchip,capture-channels:
8691 $ref: /schemas/types.yaml#/definitions/uint32
8792 default: 2
Documentation/devicetree/bindings/sound/sgtl5000.yaml+3−3
@@ -50,7 +50,7 @@ properties: · 49 unmodified lines
5050 description: The bias voltage to be used in mVolts. The voltage can take
5151 values from 1.25V to 3V by 250mV steps. If this node is not mentioned
5252 or the value is unknown, then the value is set to 1.25V.
53− $ref: "/schemas/types.yaml#/definitions/uint32"
53+ $ref: /schemas/types.yaml#/definitions/uint32
5454 enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ]
5555
5656 lrclk-strength:
@@ -63,7 +63,7 @@ properties: · 6 unmodified lines
6363 1 = 1.66 mA 2.87 mA 4.02 mA
6464 2 = 3.33 mA 5.74 mA 8.03 mA
6565 3 = 4.99 mA 8.61 mA 12.05 mA
66− $ref: "/schemas/types.yaml#/definitions/uint32"
66+ $ref: /schemas/types.yaml#/definitions/uint32
6767 enum: [ 0, 1, 2, 3 ]
6868
6969 sclk-strength:
@@ -76,7 +76,7 @@ properties: · 6 unmodified lines
7676 1 = 1.66 mA 2.87 mA 4.02 mA
7777 2 = 3.33 mA 5.74 mA 8.03 mA
7878 3 = 4.99 mA 8.61 mA 12.05 mA
79− $ref: "/schemas/types.yaml#/definitions/uint32"
79+ $ref: /schemas/types.yaml#/definitions/uint32
8080 enum: [ 0, 1, 2, 3 ]
8181
8282 port:
Documentation/devicetree/bindings/sound/simple-card.yaml+1−1
@@ -78,7 +78,7 @@ definitions: · 77 unmodified lines
7878 $ref: /schemas/types.yaml#/definitions/uint32
7979
8080 prefix:
81− description: "device name prefix"
81+ description: device name prefix
8282 $ref: /schemas/types.yaml#/definitions/string
8383
8484 label:
Documentation/devicetree/bindings/sound/socionext,uniphier-aio.yaml+1−1
@@ -42,7 +42,7 @@ properties: · 41 unmodified lines
4242 Specifies a phandle to soc-glue, which is used for changing mode of S/PDIF
4343 signal pin to output from Hi-Z. This property is optional if you use I2S
4444 signal pins only.
45− $ref: "/schemas/types.yaml#/definitions/phandle"
45+ $ref: /schemas/types.yaml#/definitions/phandle
4646
4747 "#sound-dai-cells":
4848 const: 1
Documentation/devicetree/bindings/sound/tas571x.txt+1−0
@@ -12,6 +12,7 @@ Required properties: · 11 unmodified lines
1212 - "ti,tas5717",
1313 - "ti,tas5719",
1414 - "ti,tas5721"
15+ - "ti,tas5733"
1516 - reg: The I2C address of the device
1617 - #sound-dai-cells: must be equal to 0
1718
Documentation/devicetree/bindings/sound/wlf,wm8510.yaml+41−0
@@ -0,0 +1,41 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8510.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8510 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8510
18+
19+ reg:
20+ maxItems: 1
21+
22+ "#sound-dai-cells":
23+ const: 0
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+
37+ codec@1a {
38+ compatible = "wlf,wm8510";
39+ reg = <0x1a>;
40+ };
41+ };
Documentation/devicetree/bindings/sound/wlf,wm8523.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8523.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8523 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8523
18+
19+ reg:
20+ maxItems: 1
21+
22+ "#sound-dai-cells":
23+ const: 0
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+ codec@1a {
37+ compatible = "wlf,wm8523";
38+ reg = <0x1a>;
39+ };
40+ };
Documentation/devicetree/bindings/sound/wlf,wm8524.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8524.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Wolfson WM8524 24-bit 192KHz Stereo DAC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8524
18+
19+ "#sound-dai-cells":
20+ const: 0
21+
22+ wlf,mute-gpios:
23+ maxItems: 1
24+ description:
25+ a GPIO spec for the MUTE pin.
26+
27+required:
28+ - compatible
29+ - wlf,mute-gpios
30+
31+unevaluatedProperties: false
32+
33+examples:
34+ - |
35+ #include <dt-bindings/gpio/gpio.h>
36+
37+ wm8524: codec {
38+ compatible = "wlf,wm8524";
39+ wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
40+ };
Documentation/devicetree/bindings/sound/wlf,wm8580.yaml+42−0
@@ -0,0 +1,42 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8580.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8580 and WM8581 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ enum:
18+ - wlf,wm8580
19+ - wlf,wm8581
20+
21+ reg:
22+ maxItems: 1
23+
24+ "#sound-dai-cells":
25+ const: 0
26+
27+required:
28+ - compatible
29+ - reg
30+
31+unevaluatedProperties: false
32+
33+examples:
34+ - |
35+ i2c {
36+ #address-cells = <1>;
37+ #size-cells = <0>;
38+ codec@1a {
39+ compatible = "wlf,wm8580";
40+ reg = <0x1a>;
41+ };
42+ };
Documentation/devicetree/bindings/sound/wlf,wm8711.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8711.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8711 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8711
18+
19+ reg:
20+ maxItems: 1
21+
22+ "#sound-dai-cells":
23+ const: 0
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+ codec@1a {
37+ compatible = "wlf,wm8711";
38+ reg = <0x1a>;
39+ };
40+ };
Documentation/devicetree/bindings/sound/wlf,wm8728.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8728.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8728 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8728
18+
19+ reg:
20+ maxItems: 1
21+
22+ "#sound-dai-cells":
23+ const: 0
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+ codec@1a {
37+ compatible = "wlf,wm8728";
38+ reg = <0x1a>;
39+ };
40+ };
Documentation/devicetree/bindings/sound/wlf,wm8737.yaml+40−0
@@ -0,0 +1,40 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8737.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8737 audio CODEC
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+allOf:
13+ - $ref: dai-common.yaml#
14+
15+properties:
16+ compatible:
17+ const: wlf,wm8737
18+
19+ reg:
20+ maxItems: 1
21+
22+ "#sound-dai-cells":
23+ const: 0
24+
25+required:
26+ - compatible
27+ - reg
28+
29+unevaluatedProperties: false
30+
31+examples:
32+ - |
33+ i2c {
34+ #address-cells = <1>;
35+ #size-cells = <0>;
36+ codec@1a {
37+ compatible = "wlf,wm8737";
38+ reg = <0x1a>;
39+ };
40+ };
Documentation/devicetree/bindings/sound/wlf,wm8753.yaml+62−0
@@ -0,0 +1,62 @@
1+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8753.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: WM8753 audio CODEC
8+
9+description: |
10+ Pins on the device (for linking into audio routes):
11+ * LOUT1
12+ * LOUT2
13+ * ROUT1
14+ * ROUT2
15+ * MONO1
16+ * MONO2
17+ * OUT3
18+ * OUT4
19+ * LINE1
20+ * LINE2
21+ * RXP
22+ * RXN
23+ * ACIN
24+ * ACOP
25+ * MIC1N
26+ * MIC1
27+ * MIC2N
28+ * MIC2
29+ * Mic Bias
30+
31+maintainers:
32+ - patches@opensource.cirrus.com
33+
34+allOf:
35+ - $ref: dai-common.yaml#
36+
37+properties:
38+ compatible:
39+ const: wlf,wm8753
40+
41+ reg:
42+ maxItems: 1
43+
44+ "#sound-dai-cells":
45+ const: 0
46+
47+required:
48+ - compatible
49+ - reg
50+
51+unevaluatedProperties: false
52+
53+examples:
54+ - |
55+ i2c {
56+ #address-cells = <1>;
57+ #size-cells = <0>;
58+ codec@1a {
59+ compatible = "wlf,wm8753";
60+ reg = <0x1a>;
61+ };
62+ };
Documentation/devicetree/bindings/sound/wlf,wm8960.yaml+88−0
@@ -0,0 +1,88 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8960.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Wolfson WM8960 audio codec
8+
9+maintainers:
10+ - patches@opensource.cirrus.com
11+
12+properties:
13+ compatible:
14+ const: wlf,wm8960
15+
16+ reg:
17+ maxItems: 1
18+
19+ clocks:
20+ maxItems: 1
21+
22+ clock-names:
23+ items:
24+ - const: mclk
25+
26+ '#sound-dai-cells':
27+ const: 0
28+
29+ wlf,capless:
30+ type: boolean
31+ description:
32+ If present, OUT3 pin will be enabled and disabled together with HP_L and
33+ HP_R pins in response to jack detect events.
34+
35+ wlf,gpio-cfg:
36+ $ref: /schemas/types.yaml#/definitions/uint32-array
37+ maxItems: 2
38+ description: |
39+ A list of GPIO configuration register values.
40+ - gpio-cfg[0]: ALRCGPIO of R9 (Audio interface)
41+ - gpio-cfg[1]: {GPIOPOL:GPIOSEL[2:0]} of R48 (Additional Control 4).
42+
43+ wlf,hp-cfg:
44+ $ref: /schemas/types.yaml#/definitions/uint32-array
45+ maxItems: 3
46+ description: |
47+ A list of headphone jack detect configuration register values:
48+ - hp-cfg[0]: HPSEL[1:0] of R48 (Additional Control 4).
49+ - hp-cfg[1]: {HPSWEN:HPSWPOL} of R24 (Additional Control 2).
50+ - hp-cfg[2]: {TOCLKSEL:TOEN} of R23 (Additional Control 1).
51+
52+ wlf,shared-lrclk:
53+ type: boolean
54+ description:
55+ If present, the LRCM bit of R24 (Additional control 2) gets set,
56+ indicating that ADCLRC and DACLRC pins will be disabled only when ADC
57+ (Left and Right) and DAC (Left and Right) are disabled.
58+ When WM8960 works on synchronize mode and DACLRC pin is used to supply
59+ frame clock, it will no frame clock for captrue unless enable DAC to
60+ enable DACLRC pin. If shared-lrclk is present, no need to enable DAC for
61+ captrue.
62+
63+required:
64+ - compatible
65+ - reg
66+
67+allOf:
68+ - $ref: dai-common.yaml#
69+
70+unevaluatedProperties: false
71+
72+examples:
73+ - |
74+ i2c {
75+ #address-cells = <1>;
76+ #size-cells = <0>;
77+
78+ audio-codec@1a {
79+ compatible = "wlf,wm8960";
80+ reg = <0x1a>;
81+ clocks = <&clks 0>;
82+ clock-names = "mclk";
83+ #sound-dai-cells = <0>;
84+ wlf,hp-cfg = <3 2 3>;
85+ wlf,gpio-cfg = <1 3>;
86+ wlf,shared-lrclk;
87+ };
88+ };
Documentation/devicetree/bindings/sound/wlf,wm8994.yaml+194−0
@@ -0,0 +1,194 @@
1+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/wlf,wm8994.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Wolfson WM1811/WM8994/WM8958 audio codecs
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11+ - patches@opensource.cirrus.com
12+
13+description: |
14+ These devices support both I2C and SPI (configured with pin strapping on the
15+ board).
16+
17+ Pins on the device (for linking into audio routes):
18+ IN1LN, IN1LP, IN2LN, IN2LP:VXRN, IN1RN, IN1RP, IN2RN, IN2RP:VXRP, SPKOUTLP,
19+ SPKOUTLN, SPKOUTRP, SPKOUTRN, HPOUT1L, HPOUT1R, HPOUT2P, HPOUT2N, LINEOUT1P,
20+ LINEOUT1N, LINEOUT2P, LINEOUT2N.
21+
22+properties:
23+ compatible:
24+ enum:
25+ - wlf,wm1811
26+ - wlf,wm8994
27+ - wlf,wm8958
28+
29+ reg:
30+ maxItems: 1
31+
32+ clocks:
33+ minItems: 1
34+ maxItems: 2
35+
36+ clock-names:
37+ minItems: 1
38+ items:
39+ - const: MCLK1
40+ - const: MCLK2
41+
42+ gpio-controller: true
43+
44+ '#gpio-cells':
45+ const: 2
46+
47+ interrupts:
48+ maxItems: 1
49+
50+ interrupt-controller: true
51+
52+ '#interrupt-cells':
53+ const: 2
54+ description:
55+ The first cell is the IRQ number. The second cell is the flags, encoded
56+ as the trigger masks.
57+
58+ AVDD1-supply: true
59+ AVDD2-supply: true
60+ CPVDD-supply: true
61+ DBVDD-supply: true
62+ DBVDD1-supply: true
63+ DBVDD2-supply: true
64+ DBVDD3-supply: true
65+ DCVDD-supply: true
66+ LDO1VDD-supply: true
67+ LDO2VDD-supply: true
68+ SPKVDD1-supply: true
69+ SPKVDD2-supply: true
70+
71+ '#sound-dai-cells':
72+ const: 0
73+
74+ wlf,gpio-cfg:
75+ $ref: /schemas/types.yaml#/definitions/uint32-array
76+ maxItems: 11
77+ description:
78+ A list of GPIO configuration register values. If absent, no configuration
79+ of these registers is performed. If any value is over 0xffff then the
80+ register will be left as default. If present 11 values must be supplied.
81+
82+ wlf,micbias-cfg:
83+ $ref: /schemas/types.yaml#/definitions/uint32-array
84+ maxItems: 2
85+ description:
86+ Two MICBIAS register values for WM1811 or WM8958. If absent the register
87+ defaults will be used.
88+
89+ wlf,ldo1ena-gpios:
90+ maxItems: 1
91+ description:
92+ Control of LDO1ENA input to device.
93+
94+ wlf,ldo2ena-gpios:
95+ maxItems: 1
96+ description:
97+ Control of LDO2ENA input to device.
98+
99+ wlf,lineout1-se:
100+ type: boolean
101+ description:
102+ LINEOUT1 is in single ended mode.
103+
104+ wlf,lineout2-se:
105+ type: boolean
106+ description:
107+ INEOUT2 is in single ended mode.
108+
109+ wlf,lineout1-feedback:
110+ type: boolean
111+ description:
112+ LINEOUT1 has common mode feedback connected.
113+
114+ wlf,lineout2-feedback:
115+ type: boolean
116+ description:
117+ LINEOUT2 has common mode feedback connected.
118+
119+ wlf,ldoena-always-driven:
120+ type: boolean
121+ description:
122+ LDOENA is always driven.
123+
124+ wlf,spkmode-pu:
125+ type: boolean
126+ description:
127+ Enable the internal pull-up resistor on the SPKMODE pin.
128+
129+ wlf,csnaddr-pd:
130+ type: boolean
131+ description:
132+ Enable the internal pull-down resistor on the CS/ADDR pin.
133+
134+required:
135+ - compatible
136+ - reg
137+ - AVDD2-supply
138+ - CPVDD-supply
139+ - SPKVDD1-supply
140+ - SPKVDD2-supply
141+
142+allOf:
143+ - $ref: dai-common.yaml#
144+ - if:
145+ properties:
146+ compatible:
147+ enum:
148+ - wlf,wm1811
149+ - wlf,wm8958
150+ then:
151+ properties:
152+ DBVDD-supply: false
153+ LDO2VDD-supply: false
154+ required:
155+ - DBVDD1-supply
156+ - DBVDD2-supply
157+ - DBVDD3-supply
158+ else:
159+ properties:
160+ DBVDD1-supply: false
161+ DBVDD2-supply: false
162+ DBVDD3-supply: false
163+ required:
164+ - DBVDD-supply
165+
166+unevaluatedProperties: false
167+
168+examples:
169+ - |
170+ #include <dt-bindings/gpio/gpio.h>
171+
172+ i2c {
173+ #address-cells = <1>;
174+ #size-cells = <0>;
175+
176+ audio-codec@1a {
177+ compatible = "wlf,wm1811";
178+ reg = <0x1a>;
179+ clocks = <&i2s0 0>;
180+ clock-names = "MCLK1";
181+
182+ AVDD2-supply = <&main_dc_reg>;
183+ CPVDD-supply = <&main_dc_reg>;
184+ DBVDD1-supply = <&main_dc_reg>;
185+ DBVDD2-supply = <&main_dc_reg>;
186+ DBVDD3-supply = <&main_dc_reg>;
187+ LDO1VDD-supply = <&main_dc_reg>;
188+ SPKVDD1-supply = <&main_dc_reg>;
189+ SPKVDD2-supply = <&main_dc_reg>;
190+
191+ wlf,ldo1ena-gpios = <&gpb0 0 GPIO_ACTIVE_HIGH>;
192+ wlf,ldo2ena-gpios = <&gpb0 1 GPIO_ACTIVE_HIGH>;
193+ };
194+ };
Documentation/devicetree/bindings/sound/wm8510.txt+0−18
@@ -1,18 +0,0 @@
1−WM8510 audio CODEC
2−
3−This device supports both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : "wlf,wm8510"
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13−Example:
14−
15−wm8510: codec@1a {
16− compatible = "wlf,wm8510";
17− reg = <0x1a>;
18−};
Documentation/devicetree/bindings/sound/wm8523.txt+0−16
@@ -1,16 +0,0 @@
1−WM8523 audio CODEC
2−
3−This device supports I2C only.
4−
5−Required properties:
6−
7− - compatible : "wlf,wm8523"
8−
9− - reg : the I2C address of the device.
10−
11−Example:
12−
13−wm8523: codec@1a {
14− compatible = "wlf,wm8523";
15− reg = <0x1a>;
16−};
Documentation/devicetree/bindings/sound/wm8524.txt+0−16
@@ -1,16 +0,0 @@
1−WM8524 audio CODEC
2−
3−This device does not use I2C or SPI but a simple Hardware Control Interface.
4−
5−Required properties:
6−
7− - compatible : "wlf,wm8524"
8−
9− - wlf,mute-gpios: a GPIO spec for the MUTE pin.
10−
11−Example:
12−
13−wm8524: codec {
14− compatible = "wlf,wm8524";
15− wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
16−};
Documentation/devicetree/bindings/sound/wm8580.txt+0−16
@@ -1,16 +0,0 @@
1−WM8580 and WM8581 audio CODEC
2−
3−This device supports I2C only.
4−
5−Required properties:
6−
7− - compatible : "wlf,wm8580", "wlf,wm8581"
8−
9− - reg : the I2C address of the device.
10−
11−Example:
12−
13−wm8580: codec@1a {
14− compatible = "wlf,wm8580";
15− reg = <0x1a>;
16−};
Documentation/devicetree/bindings/sound/wm8711.txt+0−18
@@ -1,18 +0,0 @@
1−WM8711 audio CODEC
2−
3−This device supports both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : "wlf,wm8711"
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13−Example:
14−
15−wm8711: codec@1a {
16− compatible = "wlf,wm8711";
17− reg = <0x1a>;
18−};
Documentation/devicetree/bindings/sound/wm8728.txt+0−18
@@ -1,18 +0,0 @@
1−WM8728 audio CODEC
2−
3−This device supports both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : "wlf,wm8728"
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13−Example:
14−
15−wm8728: codec@1a {
16− compatible = "wlf,wm8728";
17− reg = <0x1a>;
18−};
Documentation/devicetree/bindings/sound/wm8737.txt+0−18
@@ -1,18 +0,0 @@
1−WM8737 audio CODEC
2−
3−This device supports both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : "wlf,wm8737"
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13−Example:
14−
15−wm8737: codec@1a {
16− compatible = "wlf,wm8737";
17− reg = <0x1a>;
18−};
Documentation/devicetree/bindings/sound/wm8753.txt+0−40
@@ -1,40 +0,0 @@
1−WM8753 audio CODEC
2−
3−This device supports both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : "wlf,wm8753"
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13−Pins on the device (for linking into audio routes):
14−
15− * LOUT1
16− * LOUT2
17− * ROUT1
18− * ROUT2
19− * MONO1
20− * MONO2
21− * OUT3
22− * OUT4
23− * LINE1
24− * LINE2
25− * RXP
26− * RXN
27− * ACIN
28− * ACOP
29− * MIC1N
30− * MIC1
31− * MIC2N
32− * MIC2
33− * Mic Bias
34−
35−Example:
36−
37−wm8753: codec@1a {
38− compatible = "wlf,wm8753";
39− reg = <0x1a>;
40−};
Documentation/devicetree/bindings/sound/wm8960.txt+0−42
@@ -1,42 +0,0 @@
1−WM8960 audio CODEC
2−
3−This device supports I2C only.
4−
5−Required properties:
6−
7− - compatible : "wlf,wm8960"
8−
9− - reg : the I2C address of the device.
10−
11−Optional properties:
12− - wlf,shared-lrclk: This is a boolean property. If present, the LRCM bit of
13− R24 (Additional control 2) gets set, indicating that ADCLRC and DACLRC pins
14− will be disabled only when ADC (Left and Right) and DAC (Left and Right)
15− are disabled.
16− When wm8960 works on synchronize mode and DACLRC pin is used to supply
17− frame clock, it will no frame clock for captrue unless enable DAC to enable
18− DACLRC pin. If shared-lrclk is present, no need to enable DAC for captrue.
19−
20− - wlf,capless: This is a boolean property. If present, OUT3 pin will be
21− enabled and disabled together with HP_L and HP_R pins in response to jack
22− detect events.
23−
24− - wlf,hp-cfg: A list of headphone jack detect configuration register values.
25− The list must be 3 entries long.
26− hp-cfg[0]: HPSEL[1:0] of R48 (Additional Control 4).
27− hp-cfg[1]: {HPSWEN:HPSWPOL} of R24 (Additional Control 2).
28− hp-cfg[2]: {TOCLKSEL:TOEN} of R23 (Additional Control 1).
29−
30− - wlf,gpio-cfg: A list of GPIO configuration register values.
31− The list must be 2 entries long.
32− gpio-cfg[0]: ALRCGPIO of R9 (Audio interface)
33− gpio-cfg[1]: {GPIOPOL:GPIOSEL[2:0]} of R48 (Additional Control 4).
34−
35−Example:
36−
37−wm8960: codec@1a {
38− compatible = "wlf,wm8960";
39− reg = <0x1a>;
40−
41− wlf,shared-lrclk;
42−};
Documentation/devicetree/bindings/sound/wm8994.txt+0−112
@@ -1,112 +0,0 @@
1−WM1811/WM8994/WM8958 audio CODEC
2−
3−These devices support both I2C and SPI (configured with pin strapping
4−on the board).
5−
6−Required properties:
7−
8− - compatible : One of "wlf,wm1811", "wlf,wm8994" or "wlf,wm8958".
9−
10− - reg : the I2C address of the device for I2C, the chip select
11− number for SPI.
12−
13− - gpio-controller : Indicates this device is a GPIO controller.
14− - #gpio-cells : Must be 2. The first cell is the pin number and the
15− second cell is used to specify optional parameters (currently unused).
16−
17− - power supplies for the device, as covered in
18− Documentation/devicetree/bindings/regulator/regulator.txt, depending
19− on compatible:
20− - for wlf,wm1811 and wlf,wm8958:
21− AVDD1-supply, AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply,
22− DCVDD-supply, CPVDD-supply, SPKVDD1-supply, SPKVDD2-supply
23− - for wlf,wm8994:
24− AVDD1-supply, AVDD2-supply, DBVDD-supply, DCVDD-supply, CPVDD-supply,
25− SPKVDD1-supply, SPKVDD2-supply
26−
27−Optional properties:
28−
29− - interrupts : The interrupt line the IRQ signal for the device is
30− connected to. This is optional, if it is not connected then none
31− of the interrupt related properties should be specified.
32− - interrupt-controller : These devices contain interrupt controllers
33− and may provide interrupt services to other devices if they have an
34− interrupt line connected.
35− - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
36− The first cell is the IRQ number.
37− The second cell is the flags, encoded as the trigger masks from
38− Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
39−
40− - clocks : A list of up to two phandle and clock specifier pairs
41− - clock-names : A list of clock names sorted in the same order as clocks.
42− Valid clock names are "MCLK1" and "MCLK2".
43−
44− - wlf,gpio-cfg : A list of GPIO configuration register values. If absent,
45− no configuration of these registers is performed. If any value is
46− over 0xffff then the register will be left as default. If present 11
47− values must be supplied.
48−
49− - wlf,micbias-cfg : Two MICBIAS register values for WM1811 or
50− WM8958. If absent the register defaults will be used.
51−
52− - wlf,ldo1ena : GPIO specifier for control of LDO1ENA input to device.
53− - wlf,ldo2ena : GPIO specifier for control of LDO2ENA input to device.
54−
55− - wlf,lineout1-se : If present LINEOUT1 is in single ended mode.
56− - wlf,lineout2-se : If present LINEOUT2 is in single ended mode.
57−
58− - wlf,lineout1-feedback : If present LINEOUT1 has common mode feedback
59− connected.
60− - wlf,lineout2-feedback : If present LINEOUT2 has common mode feedback
61− connected.
62−
63− - wlf,ldoena-always-driven : If present LDOENA is always driven.
64−
65− - wlf,spkmode-pu : If present enable the internal pull-up resistor on
66− the SPKMODE pin.
67−
68− - wlf,csnaddr-pd : If present enable the internal pull-down resistor on
69− the CS/ADDR pin.
70−
71−Pins on the device (for linking into audio routes):
72−
73− * IN1LN
74− * IN1LP
75− * IN2LN
76− * IN2LP:VXRN
77− * IN1RN
78− * IN1RP
79− * IN2RN
80− * IN2RP:VXRP
81− * SPKOUTLP
82− * SPKOUTLN
83− * SPKOUTRP
84− * SPKOUTRN
85− * HPOUT1L
86− * HPOUT1R
87− * HPOUT2P
88− * HPOUT2N
89− * LINEOUT1P
90− * LINEOUT1N
91− * LINEOUT2P
92− * LINEOUT2N
93−
94−Example:
95−
96−wm8994: codec@1a {
97− compatible = "wlf,wm8994";
98− reg = <0x1a>;
99−
100− gpio-controller;
101− #gpio-cells = <2>;
102−
103− lineout1-se;
104−
105− AVDD1-supply = <&regulator>;
106− AVDD2-supply = <&regulator>;
107− CPVDD-supply = <&regulator>;
108− DBVDD-supply = <&regulator>;
109− DCVDD-supply = <&regulator>;
110− SPKVDD1-supply = <&regulator>;
111− SPKVDD2-supply = <&regulator>;
112−};
Documentation/sound/alsa-configuration.rst+3−2
@@ -723,9 +723,10 @@ Module for EMU10K1/EMU10k2 based PCI sound cards. · 722 unmodified lines
723723
724724 * Sound Blaster Live!
725725 * Sound Blaster PCI 512
726−* Emu APS (partially supported)
727726 * Sound Blaster Audigy
728−
727+* E-MU APS (partially supported)
728+* E-MU DAS
729+
729730 extin
730731 bitmap of available external inputs for FX8010 (see below)
731732 extout
Documentation/sound/cards/audigy-mixer.rst+15−12
@@ -19,9 +19,9 @@ Digital mixer controls · 18 unmodified lines
1919 These controls are built using the DSP instructions. They offer extended
2020 functionality. Only the default built-in code in the ALSA driver is described
2121 here. Note that the controls work as attenuators: the maximum value is the
22−neutral position leaving the signal unchanged. Note that if the same destination
23−is mentioned in multiple controls, the signal is accumulated and can be wrapped
24−(set to maximal or minimal value without checking of overflow).
22+neutral position leaving the signal unchanged. Note that if the same destination
23+is mentioned in multiple controls, the signal is accumulated and can be clipped
24+(set to maximal or minimal value without checking for overflow).
2525
2626
2727 Explanation of used abbreviations:
@@ -32,17 +32,17 @@ ADC · 4 unmodified lines
3232 analog to digital converter
3333 I2S
3434 one-way three wire serial bus for digital sound by Philips Semiconductors
35− (this standard is used for connecting standalone DAC and ADC converters)
35+ (this standard is used for connecting standalone D/A and A/D converters)
3636 LFE
37− low frequency effects (subwoofer signal)
37+ low frequency effects (used as subwoofer signal)
3838 AC97
39− a chip containing an analog mixer, DAC and ADC converters
39+ a chip containing an analog mixer, D/A and A/D converters
4040 IEC958
4141 S/PDIF
4242 FX-bus
4343 the EMU10K2 chip has an effect bus containing 64 accumulators.
44− Each of the synthesizer voices can feed its output to these accumulators
45− and the DSP microcontroller can operate with the resulting sum.
44+ Each of the synthesizer voices can feed its output to these accumulators
45+ and the DSP microcontroller can operate with the resulting sum.
4646
4747 name='PCM Front Playback Volume',index=0
4848 ----------------------------------------
@@ -218,8 +218,8 @@ LFE outputs. · 169 unmodified lines
218218 name='IEC958 Optical Raw Playback Switch',index=0
219219 -------------------------------------------------
220220 If this switch is on, then the samples for the IEC958 (S/PDIF) digital
221−output are taken only from the raw FX8010 PCM, otherwise standard front
222−PCM samples are taken.
221+output are taken only from the raw iec958 ALSA PCM device (which uses
222+accumulators 20 and 21 for left and right PCM by default).
223223
224224
225225 PCM stream related controls
@@ -237,8 +237,8 @@ as follows: · 11 unmodified lines
237237
238238 name='EMU10K1 PCM Send Routing',index 0-31
239239 ------------------------------------------
240−This control specifies the destination - FX-bus accumulators. There 24
241−values with this mapping:
240+This control specifies the destination - FX-bus accumulators. There are 24
241+values in this mapping:
242242
243243 * 0 - mono, A destination (FX-bus 0-63), default 0
244244 * 1 - mono, B destination (FX-bus 0-63), default 1
@@ -306,6 +306,9 @@ MANUALS/PATENTS · 61 unmodified lines
306306 ftp://opensource.creative.com/pub/doc
307307 -------------------------------------
308308
309+Note that the site is defunct, but the documents are available
310+from various other locations.
311+
309312 LM4545.pdf
310313 AC97 Codec
311314
Documentation/sound/cards/sb-live-mixer.rst+10−7
@@ -15,7 +15,7 @@ The ALSA driver programs this portion of chip by default code · 14 unmodified lines
1515 IEC958 (S/PDIF) raw PCM
1616 =======================
1717
18−This PCM device (it's the 4th PCM device (index 3!) and first subdevice
18+This PCM device (it's the 3rd PCM device (index 2!) and first subdevice
1919 (index 0) for a given card) allows to forward 48kHz, stereo, 16-bit
2020 little endian streams without any modifications to the digital output
2121 (coaxial or optical). The universal interface allows the creation of up
@@ -33,9 +33,9 @@ Digital mixer controls · 11 unmodified lines
3333 These controls are built using the DSP instructions. They offer extended
3434 functionality. Only the default built-in code in the ALSA driver is described
3535 here. Note that the controls work as attenuators: the maximum value is the
36−neutral position leaving the signal unchanged. Note that if the same destination
37−is mentioned in multiple controls, the signal is accumulated and can be wrapped
38−(set to maximal or minimal value without checking of overflow).
36+neutral position leaving the signal unchanged. Note that if the same destination
37+is mentioned in multiple controls, the signal is accumulated and can be clipped
38+(set to maximal or minimal value without checking for overflow).
3939
4040
4141 Explanation of used abbreviations:
@@ -46,11 +46,11 @@ ADC · 4 unmodified lines
4646 analog to digital converter
4747 I2S
4848 one-way three wire serial bus for digital sound by Philips Semiconductors
49− (this standard is used for connecting standalone DAC and ADC converters)
49+ (this standard is used for connecting standalone D/A and A/D converters)
5050 LFE
51− low frequency effects (subwoofer signal)
51+ low frequency effects (used as subwoofer signal)
5252 AC97
53− a chip containing an analog mixer, DAC and ADC converters
53+ a chip containing an analog mixer, D/A and A/D converters
5454 IEC958
5555 S/PDIF
5656 FX-bus
@@ -313,6 +313,9 @@ MANUALS/PATENTS · 256 unmodified lines
313313 ftp://opensource.creative.com/pub/doc
314314 -------------------------------------
315315
316+Note that the site is defunct, but the documents are available
317+from various other locations.
318+
316319 LM4545.pdf
317320 AC97 Codec
318321 m2049.pdf
Documentation/sound/hd-audio/index.rst+1−0
@@ -9,3 +9,4 @@ HD-Audio · 8 unmodified lines
99 controls
1010 dp-mst
1111 realtek-pc-beep
12+ intel-multi-link
Documentation/sound/hd-audio/intel-multi-link.rst+312−0
@@ -0,0 +1,312 @@
1+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2+.. include:: <isonum.txt>
3+
4+================================================
5+HDAudio multi-link extensions on Intel platforms
6+================================================
7+
8+:Copyright: |copy| 2023 Intel Corporation
9+
10+This file documents the 'multi-link structure' introduced in 2015 with
11+the Skylake processor and recently extended in newer Intel platforms
12+
13+HDaudio existing link mapping (2015 addition in SkyLake)
14+========================================================
15+
16+External HDAudio codecs are handled with link #0, while iDISP codec
17+for HDMI/DisplayPort is handled with link #1.
18+
19+The only change to the 2015 definitions is the declaration of the
20+LCAP.ALT=0x0 - since the ALT bit was previously reserved, this is a
21+backwards-compatible change.
22+
23+LCTL.SPA and LCTL.CPA are automatically set when exiting reset. They
24+are only used in existing drivers when the SCF value needs to be
25+corrected.
26+
27+Basic structure for HDaudio codecs
28+----------------------------------
29+
30+::
31+
32+ +-----------+
33+ | ML cap #0 |
34+ +-----------+
35+ | ML cap #1 |---+
36+ +-----------+ |
37+ |
38+ +--> 0x0 +---------------+ LCAP
39+ | ALT=0 |
40+ +---------------+
41+ | S192 |
42+ +---------------+
43+ | S96 |
44+ +---------------+
45+ | S48 |
46+ +---------------+
47+ | S24 |
48+ +---------------+
49+ | S12 |
50+ +---------------+
51+ | S6 |
52+ +---------------+
53+
54+ 0x4 +---------------+ LCTL
55+ | INTSTS |
56+ +---------------+
57+ | CPA |
58+ +---------------+
59+ | SPA |
60+ +---------------+
61+ | SCF |
62+ +---------------+
63+
64+ 0x8 +---------------+ LOSIDV
65+ | L1OSIVD15 |
66+ +---------------+
67+ | L1OSIDV.. |
68+ +---------------+
69+ | L1OSIDV1 |
70+ +---------------+
71+
72+ 0xC +---------------+ LSDIID
73+ | SDIID14 |
74+ +---------------+
75+ | SDIID... |
76+ +---------------+
77+ | SDIID0 |
78+ +---------------+
79+
80+SoundWire HDaudio extended link mapping
81+=======================================
82+
83+A SoundWire extended link is identified when LCAP.ALT=1 and
84+LEPTR.ID=0.
85+
86+DMA control uses the existing LOSIDV register.
87+
88+Changes include additional descriptions for enumeration that were not
89+present in earlier generations.
90+
91+- multi-link synchronization: capabilities in LCAP.LSS and control in LSYNC
92+- number of sublinks (manager IP) in LCAP.LSCOUNT
93+- power management moved from SHIM to LCTL.SPA bits
94+- hand-over to the DSP for access to multi-link registers, SHIM/IP with LCTL.OFLEN
95+- mapping of SoundWire codecs to SDI ID bits
96+- move of SHIM and Cadence registers to different offsets, with no
97+ change in functionality. The LEPTR.PTR value is an offset from the
98+ ML address, with a default value of 0x30000.
99+
100+Extended structure for SoundWire (assuming 4 Manager IP)
101+--------------------------------------------------------
102+
103+::
104+
105+ +-----------+
106+ | ML cap #0 |
107+ +-----------+
108+ | ML cap #1 |
109+ +-----------+
110+ | ML cap #2 |---+
111+ +-----------+ |
112+ |
113+ +--> 0x0 +---------------+ LCAP
114+ | ALT=1 |
115+ +---------------+
116+ | INTC |
117+ +---------------+
118+ | OFLS |
119+ +---------------+
120+ | LSS |
121+ +---------------+
122+ | SLCOUNT=4 |-----------+
123+ +---------------+ |
124+ |
125+ 0x4 +---------------+ LCTL |
126+ | INTSTS | |
127+ +---------------+ |
128+ | CPA (x bits) | |
129+ +---------------+ |
130+ | SPA (x bits) | |
131+ +---------------+ for each sublink x
132+ | INTEN | |
133+ +---------------+ |
134+ | OFLEN | |
135+ +---------------+ |
136+ |
137+ 0x8 +---------------+ LOSIDV |
138+ | L1OSIVD15 | |
139+ +---------------+ |
140+ | L1OSIDV.. | |
141+ +---------------+ |
142+ | L1OSIDV1 | +---+----------------------------------------------------------+
143+ +---------------+ | |
144+ v |
145+ 0xC + 0x2 * x +---------------+ LSDIIDx +---> 0x30000 +-----------------+ 0x00030000 |
146+ | SDIID14 | | | SoundWire SHIM | |
147+ +---------------+ | | generic | |
148+ | SDIID... | | +-----------------+ 0x00030100 |
149+ +---------------+ | | SoundWire IP | |
150+ | SDIID0 | | +-----------------+ 0x00036000 |
151+ +---------------+ | | SoundWire SHIM | |
152+ | | vendor-specific | |
153+ 0x1C +---------------+ LSYNC | +-----------------+ |
154+ | CMDSYNC | | v
155+ +---------------+ | +-----------------+ 0x00030000 + 0x8000 * x
156+ | SYNCGO | | | SoundWire SHIM |
157+ +---------------+ | | generic |
158+ | SYNCPU | | +-----------------+ 0x00030100 + 0x8000 * x
159+ +---------------+ | | SoundWire IP |
160+ | SYNPRD | | +-----------------+ 0x00036000 + 0x8000 * x
161+ +---------------+ | | SoundWire SHIM |
162+ | | vendor-specific |
163+ 0x20 +---------------+ LEPTR | +-----------------+
164+ | ID = 0 | |
165+ +---------------+ |
166+ | VER | |
167+ +---------------+ |
168+ | PTR |------------+
169+ +---------------+
170+
171+
172+DMIC HDaudio extended link mapping
173+==================================
174+
175+A DMIC extended link is identified when LCAP.ALT=1 and
176+LEPTR.ID=0xC1 are set.
177+
178+DMA control uses the existing LOSIDV register
179+
180+Changes include additional descriptions for enumeration that were not
181+present in earlier generations.
182+
183+- multi-link synchronization: capabilities in LCAP.LSS and control in LSYNC
184+- power management with LCTL.SPA bits
185+- hand-over to the DSP for access to multi-link registers, SHIM/IP with LCTL.OFLEN
186+
187+- move of DMIC registers to different offsets, with no change in
188+ functionality. The LEPTR.PTR value is an offset from the ML
189+ address, with a default value of 0x10000.
190+
191+Extended structure for DMIC
192+---------------------------
193+
194+::
195+
196+ +-----------+
197+ | ML cap #0 |
198+ +-----------+
199+ | ML cap #1 |
200+ +-----------+
201+ | ML cap #2 |---+
202+ +-----------+ |
203+ |
204+ +--> 0x0 +---------------+ LCAP
205+ | ALT=1 |
206+ +---------------+
207+ | INTC |
208+ +---------------+
209+ | OFLS |
210+ +---------------+
211+ | SLCOUNT=1 |
212+ +---------------+
213+
214+ 0x4 +---------------+ LCTL
215+ | INTSTS |
216+ +---------------+
217+ | CPA |
218+ +---------------+
219+ | SPA |
220+ +---------------+
221+ | INTEN |
222+ +---------------+
223+ | OFLEN |
224+ +---------------+ +---> 0x10000 +-----------------+ 0x00010000
225+ | | DMIC SHIM |
226+ 0x8 +---------------+ LOSIDV | | generic |
227+ | L1OSIVD15 | | +-----------------+ 0x00010100
228+ +---------------+ | | DMIC IP |
229+ | L1OSIDV.. | | +-----------------+ 0x00016000
230+ +---------------+ | | DMIC SHIM |
231+ | L1OSIDV1 | | | vendor-specific |
232+ +---------------+ | +-----------------+
233+ |
234+ 0x20 +---------------+ LEPTR |
235+ | ID = 0xC1 | |
236+ +---------------+ |
237+ | VER | |
238+ +---------------+ |
239+ | PTR |-----------+
240+ +---------------+
241+
242+
243+SSP HDaudio extended link mapping
244+=================================
245+
246+A DMIC extended link is identified when LCAP.ALT=1 and
247+LEPTR.ID=0xC0 are set.
248+
249+DMA control uses the existing LOSIDV register
250+
251+Changes include additional descriptions for enumeration and control that were not
252+present in earlier generations:
253+- number of sublinks (SSP IP instances) in LCAP.LSCOUNT
254+- power management moved from SHIM to LCTL.SPA bits
255+- hand-over to the DSP for access to multi-link registers, SHIM/IP
256+with LCTL.OFLEN
257+- move of SHIM and SSP IP registers to different offsets, with no
258+change in functionality. The LEPTR.PTR value is an offset from the ML
259+address, with a default value of 0x28000.
260+
261+Extended structure for SSP (assuming 3 instances of the IP)
262+-----------------------------------------------------------
263+
264+::
265+
266+ +-----------+
267+ | ML cap #0 |
268+ +-----------+
269+ | ML cap #1 |
270+ +-----------+
271+ | ML cap #2 |---+
272+ +-----------+ |
273+ |
274+ +--> 0x0 +---------------+ LCAP
275+ | ALT=1 |
276+ +---------------+
277+ | INTC |
278+ +---------------+
279+ | OFLS |
280+ +---------------+
281+ | SLCOUNT=3 |-------------------------for each sublink x -------------------------+
282+ +---------------+ |
283+ |
284+ 0x4 +---------------+ LCTL |
285+ | INTSTS | |
286+ +---------------+ |
287+ | CPA (x bits) | |
288+ +---------------+ |
289+ | SPA (x bits) | |
290+ +---------------+ |
291+ | INTEN | |
292+ +---------------+ |
293+ | OFLEN | |
294+ +---------------+ +---> 0x28000 +-----------------+ 0x00028000 |
295+ | | SSP SHIM | |
296+ 0x8 +---------------+ LOSIDV | | generic | |
297+ | L1OSIVD15 | | +-----------------+ 0x00028100 |
298+ +---------------+ | | SSP IP | |
299+ | L1OSIDV.. | | +-----------------+ 0x00028C00 |
300+ +---------------+ | | SSP SHIM | |
301+ | L1OSIDV1 | | | vendor-specific | |
302+ +---------------+ | +-----------------+ |
303+ | v
304+ 0x20 +---------------+ LEPTR | +-----------------+ 0x00028000 + 0x1000 * x
305+ | ID = 0xC0 | | | SSP SHIM |
306+ +---------------+ | | generic |
307+ | VER | | +-----------------+ 0x00028100 + 0x1000 * x
308+ +---------------+ | | SSP IP |
309+ | PTR |-----------+ +-----------------+ 0x00028C00 + 0x1000 * x
310+ +---------------+ | SSP SHIM |
311+ | vendor-specific |
312+ +-----------------+
Documentation/sound/kernel-api/writing-an-alsa-driver.rst+428−660
@@ -19,18 +19,13 @@ explain the general topic of linux kernel coding and doesn't cover · 18 unmodified lines
1919 low-level driver implementation details. It only describes the standard
2020 way to write a PCI sound driver on ALSA.
2121
22−This document is still a draft version. Any feedback and corrections,
23−please!!
24−
2522 File Tree Structure
2623 ===================
2724
2825 General
2926 -------
3027
31−The file tree structure of ALSA driver is depicted below.
32−
33−::
28+The file tree structure of ALSA driver is depicted below::
3429
3530 sound
3631 /core
@@ -68,8 +63,8 @@ kernel config. · 31 unmodified lines
6863 core/oss
6964 ~~~~~~~~
7065
71−The codes for PCM and mixer OSS emulation modules are stored in this
72−directory. The rawmidi OSS emulation is included in the ALSA rawmidi
66+The code for OSS PCM and mixer emulation modules is stored in this
67+directory. The OSS rawmidi emulation is included in the ALSA rawmidi
7368 code since it's quite small. The sequencer code is stored in
7469 ``core/seq/oss`` directory (see `below <core/seq/oss_>`__).
7570
@@ -78,19 +73,19 @@ core/seq · 2 unmodified lines
7873
7974 This directory and its sub-directories are for the ALSA sequencer. This
8075 directory contains the sequencer core and primary sequencer modules such
81−like snd-seq-midi, snd-seq-virmidi, etc. They are compiled only when
76+as snd-seq-midi, snd-seq-virmidi, etc. They are compiled only when
8277 ``CONFIG_SND_SEQUENCER`` is set in the kernel config.
8378
8479 core/seq/oss
8580 ~~~~~~~~~~~~
8681
87−This contains the OSS sequencer emulation codes.
82+This contains the OSS sequencer emulation code.
8883
8984 include directory
9085 -----------------
9186
9287 This is the place for the public header files of ALSA drivers, which are
93−to be exported to user-space, or included by several files at different
88+to be exported to user-space, or included by several files in different
9489 directories. Basically, the private header files should not be placed in
9590 this directory, but you may still find files there, due to historical
9691 reasons :)
@@ -100,7 +95,7 @@ drivers directory · 3 unmodified lines
10095
10196 This directory contains code shared among different drivers on different
10297 architectures. They are hence supposed not to be architecture-specific.
103−For example, the dummy pcm driver and the serial MIDI driver are found
98+For example, the dummy PCM driver and the serial MIDI driver are found
10499 in this directory. In the sub-directories, there is code for components
105100 which are independent from bus and cpu architectures.
106101
@@ -156,8 +151,8 @@ these architectures. · 49 unmodified lines
156151 usb directory
157152 -------------
158153
159−This directory contains the USB-audio driver. In the latest version, the
160−USB MIDI driver is integrated in the usb-audio driver.
154+This directory contains the USB-audio driver.
155+The USB MIDI driver is integrated in the usb-audio driver.
161156
162157 pcmcia directory
163158 ----------------
@@ -175,9 +170,9 @@ layer including ASoC core, codec and machine drivers. · 11 unmodified lines
175170 oss directory
176171 -------------
177172
178−Here contains OSS/Lite codes.
179−All codes have been deprecated except for dmasound on m68k as of
180−writing this.
173+This contains OSS/Lite code.
174+At the time of writing, all code has been removed except for dmasound
175+on m68k.
181176
182177
183178 Basic Flow for PCI Drivers
@@ -341,7 +336,7 @@ to details explained in the following section. · 157 unmodified lines
341336
342337 error:
343338 snd_card_free(card);
344− return err;
339+ return err;
345340 }
346341
347342 /* destructor -- see the "Destructor" sub-section */
@@ -381,7 +376,7 @@ where ``enable[dev]`` is the module option. · 33 unmodified lines
381376
382377 Each time the ``probe`` callback is called, check the availability of
383378 the device. If not available, simply increment the device index and
384−returns. dev will be incremented also later (`step 7
379+return. dev will be incremented also later (`step 7
385380 <7) Set the PCI driver data and return zero._>`__).
386381
387382 2) Create a card instance
@@ -402,9 +397,7 @@ Components`_. · 14 unmodified lines
402397 3) Create a main component
403398 ~~~~~~~~~~~~~~~~~~~~~~~~~~
404399
405−In this part, the PCI resources are allocated.
406−
407−::
400+In this part, the PCI resources are allocated::
408401
409402 struct mychip *chip;
410403 ....
@@ -417,13 +410,11 @@ Management`_. · 6 unmodified lines
417410
418411 When something goes wrong, the probe function needs to deal with the
419412 error. In this example, we have a single error handling path placed
420−at the end of the function.
421−
422−::
413+at the end of the function::
423414
424415 error:
425416 snd_card_free(card);
426− return err;
417+ return err;
427418
428419 Since each component can be properly freed, the single
429420 :c:func:`snd_card_free()` call should suffice in most cases.
@@ -483,13 +474,11 @@ remove callback and power-management callbacks, too. · 53 unmodified lines
483474 Destructor
484475 ----------
485476
486−The destructor, remove callback, simply releases the card instance. Then
487−the ALSA middle layer will release all the attached components
477+The destructor, the remove callback, simply releases the card instance.
478+Then the ALSA middle layer will release all the attached components
488479 automatically.
489480
490−It would be typically just calling :c:func:`snd_card_free()`:
491−
492−::
481+It would be typically just calling :c:func:`snd_card_free()`::
493482
494483 static void snd_mychip_remove(struct pci_dev *pci)
495484 {
@@ -504,9 +493,7 @@ Header Files · 8 unmodified lines
504493 ------------
505494
506495 For the above example, at least the following include files are
507−necessary.
508−
509−::
496+necessary::
510497
511498 #include <linux/init.h>
512499 #include <linux/pci.h>
@@ -544,9 +531,7 @@ list on the card record is used to manage the correct release of · 31 unmodified lines
544531 resources at destruction.
545532
546533 As mentioned above, to create a card instance, call
547−:c:func:`snd_card_new()`.
548−
549−::
534+:c:func:`snd_card_new()`::
550535
551536 struct snd_card *card;
552537 int err;
@@ -572,10 +557,8 @@ struct snd_device object. A component · 19 unmodified lines
572557 can be a PCM instance, a control interface, a raw MIDI interface, etc.
573558 Each such instance has one component entry.
574559
575−A component can be created via :c:func:`snd_device_new()`
576−function.
577−
578−::
560+A component can be created via the :c:func:`snd_device_new()`
561+function::
579562
580563 snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
581564
@@ -591,7 +574,7 @@ allocated manually beforehand, and its pointer is passed as the · 9 unmodified lines
591574 argument. This pointer (``chip`` in the above example) is used as the
592575 identifier for the instance.
593576
594−Each pre-defined ALSA component such as ac97 and pcm calls
577+Each pre-defined ALSA component such as AC97 and PCM calls
595578 :c:func:`snd_device_new()` inside its constructor. The destructor
596579 for each component is defined in the callback pointers. Hence, you don't
597580 need to take care of calling a destructor for such a component.
@@ -605,9 +588,7 @@ Chip-Specific Data · 7 unmodified lines
605588 ------------------
606589
607590 Chip-specific information, e.g. the I/O port address, its resource
608−pointer, or the irq number, is stored in the chip-specific record.
609−
610−::
591+pointer, or the irq number, is stored in the chip-specific record::
611592
612593 struct mychip {
613594 ....
@@ -620,9 +601,7 @@ In general, there are two ways of allocating the chip record. · 6 unmodified lines
620601 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
621602
622603 As mentioned above, you can pass the extra-data-length to the 5th
623−argument of :c:func:`snd_card_new()`, i.e.
624−
625−::
604+argument of :c:func:`snd_card_new()`, e.g.::
626605
627606 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
628607 sizeof(struct mychip), &card);
@@ -642,9 +621,7 @@ released together with the card instance. · 13 unmodified lines
642621 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
643622
644623 After allocating a card instance via :c:func:`snd_card_new()`
645−(with ``0`` on the 4th arg), call :c:func:`kzalloc()`.
646−
647−::
624+(with ``0`` on the 4th arg), call :c:func:`kzalloc()`::
648625
649626 struct snd_card *card;
650627 struct mychip *chip;
@@ -663,16 +640,12 @@ The chip record should have the field to hold the card pointer at least, · 12 unmodified lines
663640 };
664641
665642
666−Then, set the card pointer in the returned chip instance.
667−
668−::
643+Then, set the card pointer in the returned chip instance::
669644
670645 chip->card = card;
671646
672647 Next, initialize the fields, and register this chip record as a
673−low-level device with a specified ``ops``,
674−
675−::
648+low-level device with a specified ``ops``::
676649
677650 static const struct snd_device_ops ops = {
678651 .dev_free = snd_mychip_dev_free,
@@ -681,9 +654,7 @@ low-level device with a specified ``ops``, · 2 unmodified lines
681654 snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
682655
683656 :c:func:`snd_mychip_dev_free()` is the device-destructor
684−function, which will call the real destructor.
685−
686−::
657+function, which will call the real destructor::
687658
688659 static int snd_mychip_dev_free(struct snd_device *device)
689660 {
@@ -692,10 +663,10 @@ function, which will call the real destructor. · 2 unmodified lines
692663
693664 where :c:func:`snd_mychip_free()` is the real destructor.
694665
695−The demerit of this method is the obviously more amount of codes.
696−The merit is, however, you can trigger the own callback at registering
697−and disconnecting the card via setting in snd_device_ops.
698−About the registering and disconnecting the card, see the subsections
666+The demerit of this method is the obviously larger amount of code.
667+The merit is, however, that you can trigger your own callback at
668+registering and disconnecting the card via a setting in snd_device_ops.
669+About registering and disconnecting the card, see the subsections
699670 below.
700671
701672
@@ -724,9 +695,7 @@ Full Code Example · 22 unmodified lines
724695 -----------------
725696
726697 In this section, we'll complete the chip-specific constructor,
727−destructor and PCI entries. Example code is shown first, below.
728−
729−::
698+destructor and PCI entries. Example code is shown first, below::
730699
731700 struct mychip {
732701 struct snd_card *card;
@@ -866,9 +835,7 @@ resources. Also, you need to set the proper PCI DMA mask to limit the · 133 unmodified lines
866835 accessed I/O range. In some cases, you might need to call
867836 :c:func:`pci_set_master()` function, too.
868837
869−Suppose the 28bit mask, and the code to be added would be like:
870−
871−::
838+Suppose a 28bit mask, the code to be added would look like::
872839
873840 err = pci_enable_device(pci);
874841 if (err < 0)
@@ -890,9 +857,7 @@ function (see below). · 15 unmodified lines
890857
891858 Now assume that the PCI device has an I/O port with 8 bytes and an
892859 interrupt. Then struct mychip will have the
893−following fields:
894−
895−::
860+following fields::
896861
897862 struct mychip {
898863 struct snd_card *card;
@@ -905,14 +870,12 @@ following fields: · 6 unmodified lines
905870 For an I/O port (and also a memory region), you need to have the
906871 resource pointer for the standard resource management. For an irq, you
907872 have to keep only the irq number (integer). But you need to initialize
908−this number as -1 before actual allocation, since irq 0 is valid. The
873+this number to -1 before actual allocation, since irq 0 is valid. The
909874 port address and its resource pointer can be initialized as null by
910875 :c:func:`kzalloc()` automatically, so you don't have to take care of
911876 resetting them.
912877
913−The allocation of an I/O port is done like this:
914−
915−::
878+The allocation of an I/O port is done like this::
916879
917880 err = pci_request_regions(pci, "My Chip");
918881 if (err < 0) {
@@ -928,9 +891,7 @@ The returned value, ``chip->res_port``, is allocated via · 9 unmodified lines
928891 must be released via :c:func:`kfree()`, but there is a problem with
929892 this. This issue will be explained later.
930893
931−The allocation of an interrupt source is done like this:
932−
933−::
894+The allocation of an interrupt source is done like this::
934895
935896 if (request_irq(pci->irq, snd_mychip_interrupt,
936897 IRQF_SHARED, KBUILD_MODNAME, chip)) {
@@ -954,9 +915,7 @@ used for that, but you can use what you like, too. · 17 unmodified lines
954915
955916 I won't give details about the interrupt handler at this point, but at
956917 least its appearance can be explained now. The interrupt handler looks
957−usually like the following:
958−
959−::
918+usually as follows::
960919
961920 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
962921 {
@@ -966,13 +925,12 @@ usually like the following: · 3 unmodified lines
966925 }
967926
968927 After requesting the IRQ, you can passed it to ``card->sync_irq``
969−field:
970−::
928+field::
971929
972930 card->irq = chip->irq;
973931
974−This allows PCM core automatically performing
975−:c:func:`synchronize_irq()` at the necessary timing like ``hw_free``.
932+This allows the PCM core to automatically call
933+:c:func:`synchronize_irq()` at the right time, like before ``hw_free``.
976934 See the later section `sync_stop callback`_ for details.
977935
978936 Now let's write the corresponding destructor for the resources above.
@@ -981,9 +939,7 @@ activated) and release the resources. So far, we have no hardware part, · 2 unmodified lines
981939 so the disabling code is not written here.
982940
983941 To release the resources, the “check-and-release” method is a safer way.
984−For the interrupt, do like this:
985−
986−::
942+For the interrupt, do like this::
987943
988944 if (chip->irq >= 0)
989945 free_irq(chip->irq, chip);
@@ -997,9 +953,7 @@ When you requested I/O ports or memory regions via · 7 unmodified lines
997953 :c:func:`pci_request_regions()` like in this example, release the
998954 resource(s) using the corresponding function,
999955 :c:func:`pci_release_region()` or
1000−:c:func:`pci_release_regions()`.
1001−
1002−::
956+:c:func:`pci_release_regions()`::
1003957
1004958 pci_release_regions(chip->pci);
1005959
@@ -1007,39 +961,32 @@ When you requested manually via :c:func:`request_region()` or · 1 unmodified line
1007961 :c:func:`request_mem_region()`, you can release it via
1008962 :c:func:`release_resource()`. Suppose that you keep the resource
1009963 pointer returned from :c:func:`request_region()` in
1010−chip->res_port, the release procedure looks like:
1011−
1012−::
964+chip->res_port, the release procedure looks like::
1013965
1014966 release_and_free_resource(chip->res_port);
1015967
1016968 Don't forget to call :c:func:`pci_disable_device()` before the
1017969 end.
1018970
1019−And finally, release the chip-specific record.
1020−
1021−::
971+And finally, release the chip-specific record::
1022972
1023973 kfree(chip);
1024974
1025−We didn't implement the hardware disabling part in the above. If you
975+We didn't implement the hardware disabling part above. If you
1026976 need to do this, please note that the destructor may be called even
1027977 before the initialization of the chip is completed. It would be better
1028978 to have a flag to skip hardware disabling if the hardware was not
1029979 initialized yet.
1030980
1031981 When the chip-data is assigned to the card using
1032−:c:func:`snd_device_new()` with ``SNDRV_DEV_LOWLELVEL`` , its
1033−destructor is called at the last. That is, it is assured that all other
982+:c:func:`snd_device_new()` with ``SNDRV_DEV_LOWLELVEL``, its
983+destructor is called last. That is, it is assured that all other
1034984 components like PCMs and controls have already been released. You don't
1035985 have to stop PCMs, etc. explicitly, but just call low-level hardware
1036986 stopping.
1037987
1038988 The management of a memory-mapped region is almost as same as the
1039−management of an I/O port. You'll need three fields like the
1040−following:
1041−
1042−::
989+management of an I/O port. You'll need two fields as follows::
1043990
1044991 struct mychip {
1045992 ....
@@ -1047,9 +994,7 @@ following: · 1 unmodified line
1047994 void __iomem *iobase_virt;
1048995 };
1049996
1050−and the allocation would be like below:
1051−
1052−::
997+and the allocation would look like below::
1053998
1054999 err = pci_request_regions(pci, "My Chip");
10551000 if (err < 0) {
@@ -1060,9 +1005,7 @@ and the allocation would be like below: · 4 unmodified lines
10601005 chip->iobase_virt = ioremap(chip->iobase_phys,
10611006 pci_resource_len(pci, 0));
10621007
1063−and the corresponding destructor would be:
1064−
1065−::
1008+and the corresponding destructor would be::
10661009
10671010 static int snd_mychip_free(struct mychip *chip)
10681011 {
@@ -1075,9 +1018,7 @@ and the corresponding destructor would be: · 6 unmodified lines
10751018 }
10761019
10771020 Of course, a modern way with :c:func:`pci_iomap()` will make things a
1078−bit easier, too.
1079−
1080−::
1021+bit easier, too::
10811022
10821023 err = pci_request_regions(pci, "My Chip");
10831024 if (err < 0) {
@@ -1097,9 +1038,7 @@ struct pci_device_id table for · 13 unmodified lines
10971038 this chipset. It's a table of PCI vendor/device ID number, and some
10981039 masks.
10991040
1100−For example,
1101−
1102−::
1041+For example::
11031042
11041043 static struct pci_device_id snd_mychip_ids[] = {
11051044 { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
@@ -1120,9 +1059,7 @@ The last entry of this list is the terminator. You must specify this · 14 unmodified lines
11201059 all-zero entry.
11211060
11221061 Then, prepare the struct pci_driver
1123−record:
1124−
1125−::
1062+record::
11261063
11271064 static struct pci_driver driver = {
11281065 .name = KBUILD_MODNAME,
@@ -1133,11 +1070,9 @@ record: · 4 unmodified lines
11331070
11341071 The ``probe`` and ``remove`` functions have already been defined in
11351072 the previous sections. The ``name`` field is the name string of this
1136−device. Note that you must not use a slash “/” in this string.
1137−
1138−And at last, the module entries:
1073+device. Note that you must not use slashes (“/”) in this string.
11391074
1140−::
1075+And at last, the module entries::
11411076
11421077 static int __init alsa_card_mychip_init(void)
11431078 {
@@ -1167,22 +1102,22 @@ The PCM middle layer of ALSA is quite powerful and it is only necessary · 23 unmodified lines
11671102 for each driver to implement the low-level functions to access its
11681103 hardware.
11691104
1170−For accessing to the PCM layer, you need to include ``<sound/pcm.h>``
1105+To access the PCM layer, you need to include ``<sound/pcm.h>``
11711106 first. In addition, ``<sound/pcm_params.h>`` might be needed if you
1172−access to some functions related with hw_param.
1107+access some functions related with hw_param.
11731108
1174−Each card device can have up to four pcm instances. A pcm instance
1175−corresponds to a pcm device file. The limitation of number of instances
1176−comes only from the available bit size of the Linux's device numbers.
1177−Once when 64bit device number is used, we'll have more pcm instances
1109+Each card device can have up to four PCM instances. A PCM instance
1110+corresponds to a PCM device file. The limitation of number of instances
1111+comes only from the available bit size of Linux' device numbers.
1112+Once 64bit device numbers are used, we'll have more PCM instances
11781113 available.
11791114
1180−A pcm instance consists of pcm playback and capture streams, and each
1181−pcm stream consists of one or more pcm substreams. Some soundcards
1115+A PCM instance consists of PCM playback and capture streams, and each
1116+PCM stream consists of one or more PCM substreams. Some soundcards
11821117 support multiple playback functions. For example, emu10k1 has a PCM
11831118 playback of 32 stereo substreams. In this case, at each open, a free
11841119 substream is (usually) automatically chosen and opened. Meanwhile, when
1185−only one substream exists and it was already opened, the successful open
1120+only one substream exists and it was already opened, a subsequent open
11861121 will either block or error with ``EAGAIN`` according to the file open
11871122 mode. But you don't have to care about such details in your driver. The
11881123 PCM middle layer will take care of such work.
@@ -1191,9 +1126,7 @@ Full Code Example · 2 unmodified lines
11911126 -----------------
11921127
11931128 The example code below does not include any hardware access routines but
1194−shows only the skeleton, how to build up the PCM interfaces.
1195−
1196−::
1129+shows only the skeleton, how to build up the PCM interfaces::
11971130
11981131 #include <sound/pcm.h>
11991132 ....
@@ -1399,10 +1332,8 @@ shows only the skeleton, how to build up the PCM interfaces. · 199 unmodified lines
13991332 PCM Constructor
14001333 ---------------
14011334
1402−A pcm instance is allocated by the :c:func:`snd_pcm_new()`
1403−function. It would be better to create a constructor for pcm, namely,
1404−
1405−::
1335+A PCM instance is allocated by the :c:func:`snd_pcm_new()`
1336+function. It would be better to create a constructor for the PCM, namely::
14061337
14071338 static int snd_mychip_new_pcm(struct mychip *chip)
14081339 {
@@ -1415,16 +1346,16 @@ function. It would be better to create a constructor for pcm, namely, · 6 unmodified lines
14151346 pcm->private_data = chip;
14161347 strcpy(pcm->name, "My Chip");
14171348 chip->pcm = pcm;
1418− ....
1349+ ...
14191350 return 0;
14201351 }
14211352
1422−The :c:func:`snd_pcm_new()` function takes four arguments. The
1423−first argument is the card pointer to which this pcm is assigned, and
1353+The :c:func:`snd_pcm_new()` function takes six arguments. The
1354+first argument is the card pointer to which this PCM is assigned, and
14241355 the second is the ID string.
14251356
14261357 The third argument (``index``, 0 in the above) is the index of this new
1427−pcm. It begins from zero. If you create more than one pcm instances,
1358+PCM. It begins from zero. If you create more than one PCM instances,
14281359 specify the different numbers in this argument. For example, ``index =
14291360 1`` for the second PCM device.
14301361
@@ -1437,26 +1368,20 @@ If a chip supports multiple playbacks or captures, you can specify more · 6 unmodified lines
14371368 numbers, but they must be handled properly in open/close, etc.
14381369 callbacks. When you need to know which substream you are referring to,
14391370 then it can be obtained from struct snd_pcm_substream data passed to each
1440−callback as follows:
1441−
1442−::
1371+callback as follows::
14431372
14441373 struct snd_pcm_substream *substream;
14451374 int index = substream->number;
14461375
14471376
1448−After the pcm is created, you need to set operators for each pcm stream.
1449−
1450−::
1377+After the PCM is created, you need to set operators for each PCM stream::
14511378
14521379 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
14531380 &snd_mychip_playback_ops);
14541381 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
14551382 &snd_mychip_capture_ops);
14561383
1457−The operators are defined typically like this:
1458−
1459−::
1384+The operators are defined typically like this::
14601385
14611386 static struct snd_pcm_ops snd_mychip_playback_ops = {
14621387 .open = snd_mychip_pcm_open,
@@ -1472,25 +1397,21 @@ All the callbacks are described in the Operators_ subsection. · 9 unmodified lines
14721397
14731398 After setting the operators, you probably will want to pre-allocate the
14741399 buffer and set up the managed allocation mode.
1475−For that, simply call the following:
1476−
1477−::
1400+For that, simply call the following::
14781401
14791402 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
14801403 &chip->pci->dev,
14811404 64*1024, 64*1024);
14821405
1483−It will allocate a buffer up to 64kB as default. Buffer management
1406+It will allocate a buffer up to 64kB by default. Buffer management
14841407 details will be described in the later section `Buffer and Memory
14851408 Management`_.
14861409
1487−Additionally, you can set some extra information for this pcm in
1410+Additionally, you can set some extra information for this PCM in
14881411 ``pcm->info_flags``. The available values are defined as
14891412 ``SNDRV_PCM_INFO_XXX`` in ``<sound/asound.h>``, which is used for the
14901413 hardware definition (described later). When your soundchip supports only
1491−half-duplex, specify like this:
1492−
1493−::
1414+half-duplex, specify it like this::
14941415
14951416 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
14961417
@@ -1498,15 +1419,13 @@ half-duplex, specify like this: · 1 unmodified line
14981419 ... And the Destructor?
14991420 -----------------------
15001421
1501−The destructor for a pcm instance is not always necessary. Since the pcm
1422+The destructor for a PCM instance is not always necessary. Since the PCM
15021423 device will be released by the middle layer code automatically, you
15031424 don't have to call the destructor explicitly.
15041425
15051426 The destructor would be necessary if you created special records
15061427 internally and needed to release them. In such a case, set the
1507−destructor function to ``pcm->private_free``:
1508−
1509−::
1428+destructor function to ``pcm->private_free``::
15101429
15111430 static void mychip_pcm_free(struct snd_pcm *pcm)
15121431 {
@@ -1537,13 +1456,11 @@ Runtime Pointer - The Chest of PCM Information · 24 unmodified lines
15371456 When the PCM substream is opened, a PCM runtime instance is allocated
15381457 and assigned to the substream. This pointer is accessible via
15391458 ``substream->runtime``. This runtime pointer holds most information you
1540−need to control the PCM: the copy of hw_params and sw_params
1459+need to control the PCM: a copy of hw_params and sw_params
15411460 configurations, the buffer pointers, mmap records, spinlocks, etc.
15421461
15431462 The definition of runtime instance is found in ``<sound/pcm.h>``. Here
1544−are the contents of this file:
1545−
1546−::
1463+is the relevant part of this file::
15471464
15481465 struct _snd_pcm_runtime {
15491466 /* -- Status -- */
@@ -1577,14 +1494,19 @@ are the contents of this file: · 27 unmodified lines
15771494 unsigned int period_step;
15781495 unsigned int sleep_min; /* min ticks to sleep */
15791496 snd_pcm_uframes_t start_threshold;
1580− snd_pcm_uframes_t stop_threshold;
1581− snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
1582− noise is nearest than this */
1583− snd_pcm_uframes_t silence_size; /* Silence filling size */
1497+ /*
1498+ * The following two thresholds alleviate playback buffer underruns; when
1499+ * hw_avail drops below the threshold, the respective action is triggered:
1500+ */
1501+ snd_pcm_uframes_t stop_threshold; /* - stop playback */
1502+ snd_pcm_uframes_t silence_threshold; /* - pre-fill buffer with silence */
1503+ snd_pcm_uframes_t silence_size; /* max size of silence pre-fill; when >= boundary,
1504+ * fill played area with silence immediately */
15841505 snd_pcm_uframes_t boundary; /* pointers wrap point */
15851506
1586− snd_pcm_uframes_t silenced_start;
1587− snd_pcm_uframes_t silenced_size;
1507+ /* internal data of auto-silencer */
1508+ snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
1509+ snd_pcm_uframes_t silence_filled; /* size filled with silence */
15881510
15891511 snd_pcm_sync_id_t sync; /* hardware synchronization ID */
15901512
@@ -1638,14 +1560,12 @@ Hardware Description · 47 unmodified lines
16381560
16391561 The hardware descriptor (struct snd_pcm_hardware) contains the definitions of
16401562 the fundamental hardware configuration. Above all, you'll need to define this
1641−in the `PCM open callback`_. Note that the runtime instance holds the copy of
1642−the descriptor, not the pointer to the existing descriptor. That is,
1563+in the `PCM open callback`_. Note that the runtime instance holds a copy of
1564+the descriptor, not a pointer to the existing descriptor. That is,
16431565 in the open callback, you can modify the copied descriptor
16441566 (``runtime->hw``) as you need. For example, if the maximum number of
16451567 channels is 1 only on some chip models, you can still use the same
1646−hardware descriptor and change the channels_max later:
1647−
1648−::
1568+hardware descriptor and change the channels_max later::
16491569
16501570 struct snd_pcm_runtime *runtime = substream->runtime;
16511571 ...
@@ -1653,9 +1573,7 @@ hardware descriptor and change the channels_max later: · 1 unmodified line
16531573 if (chip->model == VERY_OLD_ONE)
16541574 runtime->hw.channels_max = 1;
16551575
1656−Typically, you'll have a hardware descriptor as below:
1657−
1658−::
1576+Typically, you'll have a hardware descriptor as below::
16591577
16601578 static struct snd_pcm_hardware snd_mychip_playback_hw = {
16611579 .info = (SNDRV_PCM_INFO_MMAP |
@@ -1676,51 +1594,51 @@ Typically, you'll have a hardware descriptor as below: · 14 unmodified lines
16761594 };
16771595
16781596 - The ``info`` field contains the type and capabilities of this
1679− pcm. The bit flags are defined in ``<sound/asound.h>`` as
1597+ PCM. The bit flags are defined in ``<sound/asound.h>`` as
16801598 ``SNDRV_PCM_INFO_XXX``. Here, at least, you have to specify whether
1681− the mmap is supported and which interleaved format is
1599+ mmap is supported and which interleaving formats are
16821600 supported. When the hardware supports mmap, add the
16831601 ``SNDRV_PCM_INFO_MMAP`` flag here. When the hardware supports the
1684− interleaved or the non-interleaved formats,
1602+ interleaved or the non-interleaved formats, the
16851603 ``SNDRV_PCM_INFO_INTERLEAVED`` or ``SNDRV_PCM_INFO_NONINTERLEAVED``
16861604 flag must be set, respectively. If both are supported, you can set
16871605 both, too.
16881606
16891607 In the above example, ``MMAP_VALID`` and ``BLOCK_TRANSFER`` are
16901608 specified for the OSS mmap mode. Usually both are set. Of course,
1691− ``MMAP_VALID`` is set only if the mmap is really supported.
1609+ ``MMAP_VALID`` is set only if mmap is really supported.
16921610
16931611 The other possible flags are ``SNDRV_PCM_INFO_PAUSE`` and
1694− ``SNDRV_PCM_INFO_RESUME``. The ``PAUSE`` bit means that the pcm
1612+ ``SNDRV_PCM_INFO_RESUME``. The ``PAUSE`` bit means that the PCM
16951613 supports the “pause” operation, while the ``RESUME`` bit means that
1696− the pcm supports the full “suspend/resume” operation. If the
1614+ the PCM supports the full “suspend/resume” operation. If the
16971615 ``PAUSE`` flag is set, the ``trigger`` callback below must handle
16981616 the corresponding (pause push/release) commands. The suspend/resume
16991617 trigger commands can be defined even without the ``RESUME``
1700− flag. See `Power Management`_ section for details.
1618+ flag. See the `Power Management`_ section for details.
17011619
17021620 When the PCM substreams can be synchronized (typically,
1703− synchronized start/stop of a playback and a capture streams), you
1621+ synchronized start/stop of a playback and a capture stream), you
17041622 can give ``SNDRV_PCM_INFO_SYNC_START``, too. In this case, you'll
17051623 need to check the linked-list of PCM substreams in the trigger
1706− callback. This will be described in the later section.
1624+ callback. This will be described in a later section.
17071625
1708−- ``formats`` field contains the bit-flags of supported formats
1626+- The ``formats`` field contains the bit-flags of supported formats
17091627 (``SNDRV_PCM_FMTBIT_XXX``). If the hardware supports more than one
17101628 format, give all or'ed bits. In the example above, the signed 16bit
17111629 little-endian format is specified.
17121630
1713−- ``rates`` field contains the bit-flags of supported rates
1631+- The ``rates`` field contains the bit-flags of supported rates
17141632 (``SNDRV_PCM_RATE_XXX``). When the chip supports continuous rates,
1715− pass ``CONTINUOUS`` bit additionally. The pre-defined rate bits are
1716− provided only for typical rates. If your chip supports
1633+ pass the ``CONTINUOUS`` bit additionally. The pre-defined rate bits
1634+ are provided only for typical rates. If your chip supports
17171635 unconventional rates, you need to add the ``KNOT`` bit and set up
17181636 the hardware constraint manually (explained later).
17191637
17201638 - ``rate_min`` and ``rate_max`` define the minimum and maximum sample
17211639 rate. This should correspond somehow to ``rates`` bits.
17221640
1723−- ``channels_min`` and ``channels_max`` define, as you might already
1641+- ``channels_min`` and ``channels_max`` define, as you might have already
17241642 expected, the minimum and maximum number of channels.
17251643
17261644 - ``buffer_bytes_max`` defines the maximum buffer size in
@@ -1732,15 +1650,16 @@ Typically, you'll have a hardware descriptor as below: · 5 unmodified lines
17321650 number of periods in the buffer.
17331651
17341652 The “period” is a term that corresponds to a fragment in the OSS
1735− world. The period defines the size at which a PCM interrupt is
1736− generated. This size strongly depends on the hardware. Generally,
1737− the smaller period size will give you more interrupts, that is,
1738− more controls. In the case of capture, this size defines the input
1739− latency. On the other hand, the whole buffer size defines the
1740− output latency for the playback direction.
1653+ world. The period defines the point at which a PCM interrupt is
1654+ generated. This point strongly depends on the hardware. Generally,
1655+ a smaller period size will give you more interrupts, which results
1656+ in being able to fill/drain the buffer more timely. In the case of
1657+ capture, this size defines the input latency. On the other hand,
1658+ the whole buffer size defines the output latency for the playback
1659+ direction.
17411660
17421661 - There is also a field ``fifo_size``. This specifies the size of the
1743− hardware FIFO, but currently it is neither used in the driver nor
1662+ hardware FIFO, but currently it is neither used by the drivers nor
17441663 in the alsa-lib. So, you can ignore this field.
17451664
17461665 PCM Configurations
@@ -1759,34 +1678,32 @@ One thing to be noted is that the configured buffer and period sizes · 12 unmodified lines
17591678 are stored in “frames” in the runtime. In the ALSA world, ``1 frame =
17601679 channels \* samples-size``. For conversion between frames and bytes,
17611680 you can use the :c:func:`frames_to_bytes()` and
1762−:c:func:`bytes_to_frames()` helper functions.
1763−
1764−::
1681+:c:func:`bytes_to_frames()` helper functions::
17651682
17661683 period_bytes = frames_to_bytes(runtime, runtime->period_size);
17671684
17681685 Also, many software parameters (sw_params) are stored in frames, too.
1769−Please check the type of the field. ``snd_pcm_uframes_t`` is for the
1770−frames as unsigned integer while ``snd_pcm_sframes_t`` is for the
1686+Please check the type of the field. ``snd_pcm_uframes_t`` is for
1687+frames as unsigned integer while ``snd_pcm_sframes_t`` is for
17711688 frames as signed integer.
17721689
17731690 DMA Buffer Information
17741691 ~~~~~~~~~~~~~~~~~~~~~~
17751692
1776−The DMA buffer is defined by the following four fields, ``dma_area``,
1777−``dma_addr``, ``dma_bytes`` and ``dma_private``. The ``dma_area``
1693+The DMA buffer is defined by the following four fields: ``dma_area``,
1694+``dma_addr``, ``dma_bytes`` and ``dma_private``. ``dma_area``
17781695 holds the buffer pointer (the logical address). You can call
17791696 :c:func:`memcpy()` from/to this pointer. Meanwhile, ``dma_addr`` holds
17801697 the physical address of the buffer. This field is specified only when
1781−the buffer is a linear buffer. ``dma_bytes`` holds the size of buffer
1782−in bytes. ``dma_private`` is used for the ALSA DMA allocator.
1698+the buffer is a linear buffer. ``dma_bytes`` holds the size of the
1699+buffer in bytes. ``dma_private`` is used for the ALSA DMA allocator.
17831700
17841701 If you use either the managed buffer allocation mode or the standard
17851702 API function :c:func:`snd_pcm_lib_malloc_pages()` for allocating the buffer,
17861703 these fields are set by the ALSA middle layer, and you should *not*
17871704 change them by yourself. You can read them but not write them. On the
17881705 other hand, if you want to allocate the buffer by yourself, you'll
1789−need to manage it in hw_params callback. At least, ``dma_bytes`` is
1706+need to manage it in the hw_params callback. At least, ``dma_bytes`` is
17901707 mandatory. ``dma_area`` is necessary when the buffer is mmapped. If
17911708 your driver doesn't support mmap, this field is not
17921709 necessary. ``dma_addr`` is also optional. You can use dma_private as
@@ -1796,13 +1713,13 @@ Running Status · 3 unmodified lines
17961713 ~~~~~~~~~~~~~~
17971714
17981715 The running status can be referred via ``runtime->status``. This is
1799−the pointer to the struct snd_pcm_mmap_status record.
1716+a pointer to a struct snd_pcm_mmap_status record.
18001717 For example, you can get the current
18011718 DMA hardware pointer via ``runtime->status->hw_ptr``.
18021719
18031720 The DMA application pointer can be referred via ``runtime->control``,
1804−which points to the struct snd_pcm_mmap_control record.
1805−However, accessing directly to this value is not recommended.
1721+which points to a struct snd_pcm_mmap_control record.
1722+However, accessing this value directly is not recommended.
18061723
18071724 Private Data
18081725 ~~~~~~~~~~~~
@@ -1811,11 +1728,10 @@ You can allocate a record for the substream and store it in · 2 unmodified lines
18111728 ``runtime->private_data``. Usually, this is done in the `PCM open
18121729 callback`_. Don't mix this with ``pcm->private_data``. The
18131730 ``pcm->private_data`` usually points to the chip instance assigned
1814−statically at the creation of PCM, while the ``runtime->private_data``
1815−points to a dynamic data structure created at the PCM open
1816−callback.
1817−
1818−::
1731+statically at creation time of the PCM device, while
1732+``runtime->private_data``
1733+points to a dynamic data structure created in the PCM open
1734+callback::
18191735
18201736 static int snd_xxx_open(struct snd_pcm_substream *substream)
18211737 {
@@ -1832,20 +1748,18 @@ The allocated object must be released in the `close callback`_. · 10 unmodified lines
18321748 Operators
18331749 ---------
18341750
1835−OK, now let me give details about each pcm callback (``ops``). In
1751+OK, now let me give details about each PCM callback (``ops``). In
18361752 general, every callback must return 0 if successful, or a negative
18371753 error number such as ``-EINVAL``. To choose an appropriate error
18381754 number, it is advised to check what value other parts of the kernel
18391755 return when the same kind of request fails.
18401756
1841−The callback function takes at least the argument with
1757+Each callback function takes at least one argument containing a
18421758 struct snd_pcm_substream pointer. To retrieve the chip
18431759 record from the given substream instance, you can use the following
1844−macro.
1845−
1846−::
1760+macro::
18471761
1848− int xxx() {
1762+ int xxx(...) {
18491763 struct mychip *chip = snd_pcm_substream_chip(substream);
18501764 ....
18511765 }
@@ -1864,12 +1778,10 @@ PCM open callback · 12 unmodified lines
18641778
18651779 static int snd_xxx_open(struct snd_pcm_substream *substream);
18661780
1867−This is called when a pcm substream is opened.
1781+This is called when a PCM substream is opened.
18681782
18691783 At least, here you have to initialize the ``runtime->hw``
1870−record. Typically, this is done by like this:
1871−
1872−::
1784+record. Typically, this is done like this::
18731785
18741786 static int snd_xxx_open(struct snd_pcm_substream *substream)
18751787 {
@@ -1883,7 +1795,7 @@ record. Typically, this is done by like this: · 7 unmodified lines
18831795 where ``snd_mychip_playback_hw`` is the pre-defined hardware
18841796 description.
18851797
1886−You can allocate a private data in this callback, as described in
1798+You can allocate private data in this callback, as described in the
18871799 `Private Data`_ section.
18881800
18891801 If the hardware configuration needs more constraints, set the hardware
@@ -1897,12 +1809,10 @@ close callback · 7 unmodified lines
18971809 static int snd_xxx_close(struct snd_pcm_substream *substream);
18981810
18991811
1900−Obviously, this is called when a pcm substream is closed.
1901−
1902−Any private instance for a pcm substream allocated in the ``open``
1903−callback will be released here.
1812+Obviously, this is called when a PCM substream is closed.
19041813
1905−::
1814+Any private instance for a PCM substream allocated in the ``open``
1815+callback will be released here::
19061816
19071817 static int snd_xxx_close(struct snd_pcm_substream *substream)
19081818 {
@@ -1914,9 +1824,9 @@ callback will be released here. · 5 unmodified lines
19141824 ioctl callback
19151825 ~~~~~~~~~~~~~~
19161826
1917−This is used for any special call to pcm ioctls. But usually you can
1918−leave it as NULL, then PCM core calls the generic ioctl callback
1919−function :c:func:`snd_pcm_lib_ioctl()`. If you need to deal with the
1827+This is used for any special call to PCM ioctls. But usually you can
1828+leave it NULL, then the PCM core calls the generic ioctl callback
1829+function :c:func:`snd_pcm_lib_ioctl()`. If you need to deal with a
19201830 unique setup of channel info or reset procedure, you can pass your own
19211831 callback function here.
19221832
@@ -1928,22 +1838,20 @@ hw_params callback · 5 unmodified lines
19281838 static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
19291839 struct snd_pcm_hw_params *hw_params);
19301840
1931−This is called when the hardware parameter (``hw_params``) is set up
1841+This is called when the hardware parameters (``hw_params``) are set up
19321842 by the application, that is, once when the buffer size, the period
1933−size, the format, etc. are defined for the pcm substream.
1843+size, the format, etc. are defined for the PCM substream.
19341844
19351845 Many hardware setups should be done in this callback, including the
19361846 allocation of buffers.
19371847
1938−Parameters to be initialized are retrieved by
1848+Parameters to be initialized are retrieved by the
19391849 :c:func:`params_xxx()` macros.
19401850
1941−When you set up the managed buffer allocation mode for the substream,
1851+When you choose managed buffer allocation mode for the substream,
19421852 a buffer is already allocated before this callback gets
19431853 called. Alternatively, you can call a helper function below for
1944−allocating the buffer, too.
1945−
1946−::
1854+allocating the buffer::
19471855
19481856 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
19491857
@@ -1951,8 +1859,8 @@ allocating the buffer, too. · 1 unmodified line
19511859 DMA buffers have been pre-allocated. See the section `Buffer Types`_
19521860 for more details.
19531861
1954−Note that this and ``prepare`` callbacks may be called multiple times
1955−per initialization. For example, the OSS emulation may call these
1862+Note that this one and the ``prepare`` callback may be called multiple
1863+times per initialization. For example, the OSS emulation may call these
19561864 callbacks at each change via its ioctl.
19571865
19581866 Thus, you need to be careful not to allocate the same buffers many
@@ -1960,10 +1868,10 @@ times, which will lead to memory leaks! Calling the helper function · 1 unmodified line
19601868 above many times is OK. It will release the previous buffer
19611869 automatically when it was already allocated.
19621870
1963−Another note is that this callback is non-atomic (schedulable) as
1871+Another note is that this callback is non-atomic (schedulable) by
19641872 default, i.e. when no ``nonatomic`` flag set. This is important,
19651873 because the ``trigger`` callback is atomic (non-schedulable). That is,
1966−mutexes or any schedule-related functions are not available in
1874+mutexes or any schedule-related functions are not available in the
19671875 ``trigger`` callback. Please see the subsection Atomicity_ for
19681876 details.
19691877
@@ -1979,16 +1887,14 @@ This is called to release the resources allocated via · 9 unmodified lines
19791887
19801888 This function is always called before the close callback is called.
19811889 Also, the callback may be called multiple times, too. Keep track
1982−whether the resource was already released.
1890+whether each resource was already released.
19831891
1984−When you have set up the managed buffer allocation mode for the PCM
1892+When you have chosen managed buffer allocation mode for the PCM
19851893 substream, the allocated PCM buffer will be automatically released
19861894 after this callback gets called. Otherwise you'll have to release the
19871895 buffer manually. Typically, when the buffer was allocated from the
19881896 pre-allocated pool, you can use the standard API function
1989−:c:func:`snd_pcm_lib_malloc_pages()` like:
1990−
1991−::
1897+:c:func:`snd_pcm_lib_malloc_pages()` like::
19921898
19931899 snd_pcm_lib_free_pages(substream);
19941900
@@ -1999,13 +1905,13 @@ prepare callback · 4 unmodified lines
19991905
20001906 static int snd_xxx_prepare(struct snd_pcm_substream *substream);
20011907
2002−This callback is called when the pcm is “prepared”. You can set the
1908+This callback is called when the PCM is “prepared”. You can set the
20031909 format type, sample rate, etc. here. The difference from ``hw_params``
20041910 is that the ``prepare`` callback will be called each time
20051911 :c:func:`snd_pcm_prepare()` is called, i.e. when recovering after
20061912 underruns, etc.
20071913
2008−Note that this callback is now non-atomic. You can use
1914+Note that this callback is non-atomic. You can use
20091915 schedule-related functions safely in this callback.
20101916
20111917 In this and the following callbacks, you can refer to the values via
@@ -2026,13 +1932,11 @@ trigger callback · 14 unmodified lines
20261932
20271933 static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
20281934
2029−This is called when the pcm is started, stopped or paused.
2030−
2031−Which action is specified in the second argument,
2032−``SNDRV_PCM_TRIGGER_XXX`` in ``<sound/pcm.h>``. At least, the ``START``
2033−and ``STOP`` commands must be defined in this callback.
1935+This is called when the PCM is started, stopped or paused.
20341936
2035−::
1937+The action is specified in the second argument, ``SNDRV_PCM_TRIGGER_XXX``
1938+defined in ``<sound/pcm.h>``. At least, the ``START``
1939+and ``STOP`` commands must be defined in this callback::
20361940
20371941 switch (cmd) {
20381942 case SNDRV_PCM_TRIGGER_START:
@@ -2045,23 +1949,23 @@ and ``STOP`` commands must be defined in this callback. · 6 unmodified lines
20451949 return -EINVAL;
20461950 }
20471951
2048−When the pcm supports the pause operation (given in the info field of
1952+When the PCM supports the pause operation (given in the info field of
20491953 the hardware table), the ``PAUSE_PUSH`` and ``PAUSE_RELEASE`` commands
2050−must be handled here, too. The former is the command to pause the pcm,
2051−and the latter to restart the pcm again.
1954+must be handled here, too. The former is the command to pause the PCM,
1955+and the latter to restart the PCM again.
20521956
2053−When the pcm supports the suspend/resume operation, regardless of full
1957+When the PCM supports the suspend/resume operation, regardless of full
20541958 or partial suspend/resume support, the ``SUSPEND`` and ``RESUME``
20551959 commands must be handled, too. These commands are issued when the
20561960 power-management status is changed. Obviously, the ``SUSPEND`` and
2057−``RESUME`` commands suspend and resume the pcm substream, and usually,
1961+``RESUME`` commands suspend and resume the PCM substream, and usually,
20581962 they are identical to the ``STOP`` and ``START`` commands, respectively.
20591963 See the `Power Management`_ section for details.
20601964
2061−As mentioned, this callback is atomic as default unless ``nonatomic``
1965+As mentioned, this callback is atomic by default unless the ``nonatomic``
20621966 flag set, and you cannot call functions which may sleep. The
20631967 ``trigger`` callback should be as minimal as possible, just really
2064−triggering the DMA. The other stuff should be initialized
1968+triggering the DMA. The other stuff should be initialized in
20651969 ``hw_params`` and ``prepare`` callbacks properly beforehand.
20661970
20671971 sync_stop callback
@@ -2072,22 +1976,22 @@ sync_stop callback · 4 unmodified lines
20721976 static int snd_xxx_sync_stop(struct snd_pcm_substream *substream);
20731977
20741978 This callback is optional, and NULL can be passed. It's called after
2075−the PCM core stops the stream and changes the stream state
1979+the PCM core stops the stream, before it changes the stream state via
20761980 ``prepare``, ``hw_params`` or ``hw_free``.
20771981 Since the IRQ handler might be still pending, we need to wait until
20781982 the pending task finishes before moving to the next step; otherwise it
2079−might lead to a crash due to resource conflicts or access to the freed
1983+might lead to a crash due to resource conflicts or access to freed
20801984 resources. A typical behavior is to call a synchronization function
20811985 like :c:func:`synchronize_irq()` here.
20821986
2083−For majority of drivers that need only a call of
1987+For the majority of drivers that need only a call of
20841988 :c:func:`synchronize_irq()`, there is a simpler setup, too.
2085−While keeping NULL to ``sync_stop`` PCM callback, the driver can set
2086−``card->sync_irq`` field to store the valid interrupt number after
2087−requesting an IRQ, instead. Then PCM core will look call
1989+While keeping the ``sync_stop`` PCM callback NULL, the driver can set
1990+the ``card->sync_irq`` field to the returned interrupt number after
1991+requesting an IRQ, instead. Then PCM core will call
20881992 :c:func:`synchronize_irq()` with the given IRQ appropriately.
20891993
2090−If the IRQ handler is released at the card destructor, you don't need
1994+If the IRQ handler is released by the card destructor, you don't need
20911995 to clear ``card->sync_irq``, as the card itself is being released.
20921996 So, usually you'll need to add just a single line for assigning
20931997 ``card->sync_irq`` in the driver code unless the driver re-acquires
@@ -2103,30 +2007,30 @@ pointer callback · 9 unmodified lines
21032007 static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
21042008
21052009 This callback is called when the PCM middle layer inquires the current
2106−hardware position on the buffer. The position must be returned in
2010+hardware position in the buffer. The position must be returned in
21072011 frames, ranging from 0 to ``buffer_size - 1``.
21082012
2109−This is called usually from the buffer-update routine in the pcm
2013+This is usually called from the buffer-update routine in the PCM
21102014 middle layer, which is invoked when :c:func:`snd_pcm_period_elapsed()`
2111−is called in the interrupt routine. Then the pcm middle layer updates
2015+is called by the interrupt routine. Then the PCM middle layer updates
21122016 the position and calculates the available space, and wakes up the
21132017 sleeping poll threads, etc.
21142018
2115−This callback is also atomic as default.
2019+This callback is also atomic by default.
21162020
21172021 copy_user, copy_kernel and fill_silence ops
21182022 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21192023
21202024 These callbacks are not mandatory, and can be omitted in most cases.
21212025 These callbacks are used when the hardware buffer cannot be in the
2122−normal memory space. Some chips have their own buffer on the hardware
2026+normal memory space. Some chips have their own buffer in the hardware
21232027 which is not mappable. In such a case, you have to transfer the data
21242028 manually from the memory buffer to the hardware buffer. Or, if the
21252029 buffer is non-contiguous on both physical and virtual memory spaces,
21262030 these callbacks must be defined, too.
21272031
21282032 If these two callbacks are defined, copy and set-silence operations
2129−are done by them. The detailed will be described in the later section
2033+are done by them. The details will be described in the later section
21302034 `Buffer and Memory Management`_.
21312035
21322036 ack callback
@@ -2137,7 +2041,11 @@ This callback is also not mandatory. This callback is called when the · 4 unmodified lines
21372041 emu10k1-fx and cs46xx need to track the current ``appl_ptr`` for the
21382042 internal buffer, and this callback is useful only for such a purpose.
21392043
2140−This callback is atomic as default.
2044+The callback function may return 0 or a negative error. When the
2045+return value is ``-EPIPE``, PCM core treats that as a buffer XRUN,
2046+and changes the state to ``SNDRV_PCM_STATE_XRUN`` automatically.
2047+
2048+This callback is atomic by default.
21412049
21422050 page callback
21432051 ~~~~~~~~~~~~~
@@ -2145,16 +2053,15 @@ page callback · 1 unmodified line
21452053 This callback is optional too. The mmap calls this callback to get the
21462054 page fault address.
21472055
2148−Since the recent changes, you need no special callback any longer for
2149−the standard SG-buffer or vmalloc-buffer. Hence this callback should
2150−be rarely used.
2056+You need no special callback for the standard SG-buffer or vmalloc-
2057+buffer. Hence this callback should be rarely used.
21512058
2152−mmap calllback
2153−~~~~~~~~~~~~~~
2059+mmap callback
2060+~~~~~~~~~~~~~
21542061
21552062 This is another optional callback for controlling mmap behavior.
2156−Once when defined, PCM core calls this callback when a page is
2157−memory-mapped instead of dealing via the standard helper.
2063+When defined, the PCM core calls this callback when a page is
2064+memory-mapped, instead of using the standard helper.
21582065 If you need special handling (due to some architecture or
21592066 device-specific issues), implement everything here as you like.
21602067
@@ -2162,13 +2069,14 @@ device-specific issues), implement everything here as you like. · 1 unmodified line
21622069 PCM Interrupt Handler
21632070 ---------------------
21642071
2165−The rest of pcm stuff is the PCM interrupt handler. The role of PCM
2072+The remainder of the PCM stuff is the PCM interrupt handler. The role
2073+of the PCM
21662074 interrupt handler in the sound driver is to update the buffer position
21672075 and to tell the PCM middle layer when the buffer position goes across
2168−the prescribed period size. To inform this, call the
2076+the specified period boundary. To inform about this, call the
21692077 :c:func:`snd_pcm_period_elapsed()` function.
21702078
2171−There are several types of sound chips to generate the interrupts.
2079+There are several ways sound chips can generate interrupts.
21722080
21732081 Interrupts at the period (fragment) boundary
21742082 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2184,14 +2092,12 @@ chip record to hold the current running substream pointer, and set the · 9 unmodified lines
21842092 pointer value at ``open`` callback (and reset at ``close`` callback).
21852093
21862094 If you acquire a spinlock in the interrupt handler, and the lock is used
2187−in other pcm callbacks, too, then you have to release the lock before
2095+in other PCM callbacks, too, then you have to release the lock before
21882096 calling :c:func:`snd_pcm_period_elapsed()`, because
2189−:c:func:`snd_pcm_period_elapsed()` calls other pcm callbacks
2097+:c:func:`snd_pcm_period_elapsed()` calls other PCM callbacks
21902098 inside.
21912099
2192−Typical code would be like:
2193−
2194−::
2100+Typical code would look like::
21952101
21962102
21972103 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
@@ -2211,6 +2117,12 @@ Typical code would be like: · 13 unmodified lines
22112117 return IRQ_HANDLED;
22122118 }
22132119
2120+Also, when the device can detect a buffer underrun/overrun, the driver
2121+can notify the XRUN status to the PCM core by calling
2122+:c:func:`snd_pcm_stop_xrun()`. This function stops the stream and sets
2123+the PCM state to ``SNDRV_PCM_STATE_XRUN``. Note that it must be called
2124+outside the PCM stream lock, hence it can't be called from the atomic
2125+callback.
22142126
22152127
22162128 High frequency timer interrupts
@@ -2223,9 +2135,7 @@ position and accumulate the processed sample length at each interrupt. · 6 unmodified lines
22232135 When the accumulated size exceeds the period size, call
22242136 :c:func:`snd_pcm_period_elapsed()` and reset the accumulator.
22252137
2226−Typical code would be like the following.
2227−
2228−::
2138+Typical code would look as follows::
22292139
22302140
22312141 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
@@ -2270,9 +2180,9 @@ Typical code would be like the following. · 38 unmodified lines
22702180 On calling :c:func:`snd_pcm_period_elapsed()`
22712181 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22722182
2273−In both cases, even if more than one period are elapsed, you don't have
2183+In both cases, even if more than one period has elapsed, you don't have
22742184 to call :c:func:`snd_pcm_period_elapsed()` many times. Call only
2275−once. And the pcm layer will check the current hardware pointer and
2185+once. And the PCM layer will check the current hardware pointer and
22762186 update to the latest status.
22772187
22782188 Atomicity
@@ -2283,15 +2193,16 @@ kernel programming are race conditions. In the Linux kernel, they are · 4 unmodified lines
22832193 usually avoided via spin-locks, mutexes or semaphores. In general, if a
22842194 race condition can happen in an interrupt handler, it has to be managed
22852195 atomically, and you have to use a spinlock to protect the critical
2286−session. If the critical section is not in interrupt handler code and if
2196+section. If the critical section is not in interrupt handler code and if
22872197 taking a relatively long time to execute is acceptable, you should use
22882198 mutexes or semaphores instead.
22892199
2290−As already seen, some pcm callbacks are atomic and some are not. For
2291−example, the ``hw_params`` callback is non-atomic, while ``trigger``
2200+As already seen, some PCM callbacks are atomic and some are not. For
2201+example, the ``hw_params`` callback is non-atomic, while the ``trigger``
22922202 callback is atomic. This means, the latter is called already in a
2293−spinlock held by the PCM middle layer. Please take this atomicity into
2294−account when you choose a locking scheme in the callbacks.
2203+spinlock held by the PCM middle layer, the PCM stream lock. Please
2204+take this atomicity into account when you choose a locking scheme in
2205+the callbacks.
22952206
22962207 In the atomic callbacks, you cannot use functions which may call
22972208 :c:func:`schedule()` or go to :c:func:`sleep()`. Semaphores and
@@ -2302,29 +2213,34 @@ callback, please use :c:func:`udelay()` or :c:func:`mdelay()`. · 4 unmodified lines
23022213 All three atomic callbacks (trigger, pointer, and ack) are called with
23032214 local interrupts disabled.
23042215
2305−The recent changes in PCM core code, however, allow all PCM operations
2306−to be non-atomic. This assumes that the all caller sides are in
2216+However, it is possible to request all PCM operations to be non-atomic.
2217+This assumes that all call sites are in
23072218 non-atomic contexts. For example, the function
23082219 :c:func:`snd_pcm_period_elapsed()` is called typically from the
23092220 interrupt handler. But, if you set up the driver to use a threaded
23102221 interrupt handler, this call can be in non-atomic context, too. In such
2311−a case, you can set ``nonatomic`` filed of struct snd_pcm object
2222+a case, you can set the ``nonatomic`` field of the struct snd_pcm object
23122223 after creating it. When this flag is set, mutex and rwsem are used internally
23132224 in the PCM core instead of spin and rwlocks, so that you can call all PCM
23142225 functions safely in a non-atomic
23152226 context.
23162227
2228+Also, in some cases, you might need to call
2229+:c:func:`snd_pcm_period_elapsed()` in the atomic context (e.g. the
2230+period gets elapsed during ``ack`` or other callback). There is a
2231+variant that can be called inside the PCM stream lock
2232+:c:func:`snd_pcm_period_elapsed_under_stream_lock()` for that purpose,
2233+too.
2234+
23172235 Constraints
23182236 -----------
23192237
2320−If your chip supports unconventional sample rates, or only the limited
2321−samples, you need to set a constraint for the condition.
2238+Due to physical limitations, hardware is not infinitely configurable.
2239+These limitations are expressed by setting constraints.
23222240
2323−For example, in order to restrict the sample rates in the some supported
2241+For example, in order to restrict the sample rates to some supported
23242242 values, use :c:func:`snd_pcm_hw_constraint_list()`. You need to
2325−call this function in the open callback.
2326−
2327−::
2243+call this function in the open callback::
23282244
23292245 static unsigned int rates[] =
23302246 {4000, 10000, 22050, 44100};
@@ -2346,16 +2262,12 @@ call this function in the open callback. · 15 unmodified lines
23462262 ....
23472263 }
23482264
2349−
2350−
23512265 There are many different constraints. Look at ``sound/pcm.h`` for a
23522266 complete list. You can even define your own constraint rules. For
23532267 example, let's suppose my_chip can manage a substream of 1 channel if
23542268 and only if the format is ``S16_LE``, otherwise it supports any format
2355−specified in struct snd_pcm_hardware> (or in any other
2356−constraint_list). You can build a rule like this:
2357−
2358−::
2269+specified in struct snd_pcm_hardware (or in any other
2270+constraint_list). You can build a rule like this::
23592271
23602272 static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
23612273 struct snd_pcm_hw_rule *rule)
@@ -2375,9 +2287,7 @@ constraint_list). You can build a rule like this: · 13 unmodified lines
23752287 }
23762288
23772289
2378−Then you need to call this function to add your rule:
2379−
2380−::
2290+Then you need to call this function to add your rule::
23812291
23822292 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
23832293 hw_rule_channels_by_format, NULL,
@@ -2386,9 +2296,7 @@ Then you need to call this function to add your rule: · 2 unmodified lines
23862296 The rule function is called when an application sets the PCM format, and
23872297 it refines the number of channels accordingly. But an application may
23882298 set the number of channels before setting the format. Thus you also need
2389−to define the inverse rule:
2390−
2391−::
2299+to define the inverse rule::
23922300
23932301 static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
23942302 struct snd_pcm_hw_rule *rule)
@@ -2407,16 +2315,14 @@ to define the inverse rule: · 12 unmodified lines
24072315 }
24082316
24092317
2410−... and in the open callback:
2411−
2412−::
2318+... and in the open callback::
24132319
24142320 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
24152321 hw_rule_format_by_channels, NULL,
24162322 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
24172323
24182324 One typical usage of the hw constraints is to align the buffer size
2419−with the period size. As default, ALSA PCM core doesn't enforce the
2325+with the period size. By default, ALSA PCM core doesn't enforce the
24202326 buffer size to be aligned with the period size. For example, it'd be
24212327 possible to have a combination like 256 period bytes with 999 buffer
24222328 bytes.
@@ -2424,9 +2330,7 @@ bytes. · 1 unmodified line
24242330 Many device chips, however, require the buffer to be a multiple of
24252331 periods. In such a case, call
24262332 :c:func:`snd_pcm_hw_constraint_integer()` for
2427−``SNDRV_PCM_HW_PARAM_PERIODS``.
2428−
2429−::
2333+``SNDRV_PCM_HW_PARAM_PERIODS``::
24302334
24312335 snd_pcm_hw_constraint_integer(substream->runtime,
24322336 SNDRV_PCM_HW_PARAM_PERIODS);
@@ -2434,7 +2338,7 @@ periods. In such a case, call · 1 unmodified line
24342338 This assures that the number of periods is integer, hence the buffer
24352339 size is aligned with the period size.
24362340
2437−The hw constraint is a very much powerful mechanism to define the
2341+The hw constraint is a very powerful mechanism to define the
24382342 preferred PCM configuration, and there are relevant helpers.
24392343 I won't give more details here, rather I would like to say, “Luke, use
24402344 the source.”
@@ -2461,9 +2365,7 @@ Definition of Controls · 20 unmodified lines
24612365
24622366 To create a new control, you need to define the following three
24632367 callbacks: ``info``, ``get`` and ``put``. Then, define a
2464−struct snd_kcontrol_new record, such as:
2465−
2466−::
2368+struct snd_kcontrol_new record, such as::
24672369
24682370
24692371 static struct snd_kcontrol_new my_control = {
@@ -2506,7 +2408,7 @@ The ``private_value`` field contains an arbitrary long integer value · 36 unmodified lines
25062408 for this record. When using the generic ``info``, ``get`` and ``put``
25072409 callbacks, you can pass a value through this field. If several small
25082410 numbers are necessary, you can combine them in bitwise. Or, it's
2509−possible to give a pointer (casted to unsigned long) of some record to
2411+possible to store a pointer (casted to unsigned long) of some record in
25102412 this field, too.
25112413
25122414 The ``tlv`` field can be used to provide metadata about the control;
@@ -2573,7 +2475,7 @@ The access flag is the bitmask which specifies the access type of the · 60 unmodified lines
25732475 given control. The default access type is
25742476 ``SNDRV_CTL_ELEM_ACCESS_READWRITE``, which means both read and write are
25752477 allowed to this control. When the access flag is omitted (i.e. = 0), it
2576−is considered as ``READWRITE`` access as default.
2478+is considered as ``READWRITE`` access by default.
25772479
25782480 When the control is read-only, pass ``SNDRV_CTL_ELEM_ACCESS_READ``
25792481 instead. In this case, you don't have to define the ``put`` callback.
@@ -2586,8 +2488,11 @@ If the control value changes frequently (e.g. the VU meter), · 6 unmodified lines
25862488 changed without `Change notification`_. Applications should poll such
25872489 a control constantly.
25882490
2589−When the control is inactive, set the ``INACTIVE`` flag, too. There are
2590−``LOCK`` and ``OWNER`` flags to change the write permissions.
2491+When the control may be updated, but currently has no effect on anything,
2492+setting the ``INACTIVE`` flag may be appropriate. For example, PCM
2493+controls should be inactive while no PCM device is open.
2494+
2495+There are ``LOCK`` and ``OWNER`` flags to change the write permissions.
25912496
25922497 Control Callbacks
25932498 -----------------
@@ -2598,9 +2503,7 @@ info callback · 4 unmodified lines
25982503 The ``info`` callback is used to get detailed information on this
25992504 control. This must store the values of the given
26002505 struct snd_ctl_elem_info object. For example,
2601−for a boolean control with a single element:
2602−
2603−::
2506+for a boolean control with a single element::
26042507
26052508
26062509 static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,
@@ -2619,13 +2522,11 @@ The ``type`` field specifies the type of the control. There are · 12 unmodified lines
26192522 ``BOOLEAN``, ``INTEGER``, ``ENUMERATED``, ``BYTES``, ``IEC958`` and
26202523 ``INTEGER64``. The ``count`` field specifies the number of elements in
26212524 this control. For example, a stereo volume would have count = 2. The
2622−``value`` field is a union, and the values stored are depending on the
2525+``value`` field is a union, and the values stored depend on the
26232526 type. The boolean and integer types are identical.
26242527
2625−The enumerated type is a bit different from others. You'll need to set
2626−the string for the currently given item index.
2627−
2628−::
2528+The enumerated type is a bit different from the others. You'll need to
2529+set the string for the selectec item index::
26292530
26302531 static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
26312532 struct snd_ctl_elem_info *uinfo)
@@ -2670,13 +2571,10 @@ stereo channel boolean item. · 38 unmodified lines
26702571 get callback
26712572 ~~~~~~~~~~~~
26722573
2673−This callback is used to read the current value of the control and to
2674−return to user-space.
2675−
2676−For example,
2677−
2678−::
2574+This callback is used to read the current value of the control, so it
2575+can be returned to user-space.
26792576
2577+For example::
26802578
26812579 static int snd_myctl_get(struct snd_kcontrol *kcontrol,
26822580 struct snd_ctl_elem_value *ucontrol)
@@ -2691,15 +2589,11 @@ For example, · 8 unmodified lines
26912589 The ``value`` field depends on the type of control as well as on the
26922590 info callback. For example, the sb driver uses this field to store the
26932591 register offset, the bit-shift and the bit-mask. The ``private_value``
2694−field is set as follows:
2695−
2696−::
2592+field is set as follows::
26972593
26982594 .private_value = reg | (shift << 16) | (mask << 24)
26992595
2700−and is retrieved in callbacks like
2701−
2702−::
2596+and is retrieved in callbacks like::
27032597
27042598 static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
27052599 struct snd_ctl_elem_value *ucontrol)
@@ -2711,19 +2605,16 @@ and is retrieved in callbacks like · 5 unmodified lines
27112605 }
27122606
27132607 In the ``get`` callback, you have to fill all the elements if the
2714−control has more than one elements, i.e. ``count > 1``. In the example
2608+control has more than one element, i.e. ``count > 1``. In the example
27152609 above, we filled only one element (``value.integer.value[0]``) since
2716−it's assumed as ``count = 1``.
2610+``count = 1`` is assumed.
27172611
27182612 put callback
27192613 ~~~~~~~~~~~~
27202614
2721−This callback is used to write a value from user-space.
2722−
2723−For example,
2724−
2725−::
2615+This callback is used to write a value coming from user-space.
27262616
2617+For example::
27272618
27282619 static int snd_myctl_put(struct snd_kcontrol *kcontrol,
27292620 struct snd_ctl_elem_value *ucontrol)
@@ -2746,12 +2637,12 @@ value is not changed, return 0 instead. If any fatal error happens, · 16 unmodified lines
27462637 return a negative error code as usual.
27472638
27482639 As in the ``get`` callback, when the control has more than one
2749−elements, all elements must be evaluated in this callback, too.
2640+element, all elements must be evaluated in this callback, too.
27502641
27512642 Callbacks are not atomic
27522643 ~~~~~~~~~~~~~~~~~~~~~~~~
27532644
2754−All these three callbacks are basically not atomic.
2645+All these three callbacks are not-atomic.
27552646
27562647 Control Constructor
27572648 -------------------
@@ -2760,9 +2651,7 @@ When everything is ready, finally we can create a new control. To create · 2 unmodified lines
27602651 a control, there are two functions to be called,
27612652 :c:func:`snd_ctl_new1()` and :c:func:`snd_ctl_add()`.
27622653
2763−In the simplest way, you can do like this:
2764−
2765−::
2654+In the simplest way, you can do it like this::
27662655
27672656 err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
27682657 if (err < 0)
@@ -2780,9 +2669,7 @@ Change Notification · 11 unmodified lines
27802669 -------------------
27812670
27822671 If you need to change and update a control in the interrupt routine, you
2783−can call :c:func:`snd_ctl_notify()`. For example,
2784−
2785−::
2672+can call :c:func:`snd_ctl_notify()`. For example::
27862673
27872674 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
27882675
@@ -2796,13 +2683,11 @@ for hardware volume interrupts. · 7 unmodified lines
27962683 Metadata
27972684 --------
27982685
2799−To provide information about the dB values of a mixer control, use on of
2686+To provide information about the dB values of a mixer control, use one of
28002687 the ``DECLARE_TLV_xxx`` macros from ``<sound/tlv.h>`` to define a
28012688 variable containing this information, set the ``tlv.p`` field to point to
28022689 this variable, and include the ``SNDRV_CTL_ELEM_ACCESS_TLV_READ`` flag
2803−in the ``access`` field; like this:
2804−
2805−::
2690+in the ``access`` field; like this::
28062691
28072692 static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
28082693
@@ -2892,9 +2777,7 @@ AC97 Constructor · 83 unmodified lines
28922777 ----------------
28932778
28942779 To create an ac97 instance, first call :c:func:`snd_ac97_bus()`
2895−with an ``ac97_bus_ops_t`` record with callback functions.
2896−
2897−::
2780+with an ``ac97_bus_ops_t`` record with callback functions::
28982781
28992782 struct snd_ac97_bus *bus;
29002783 static struct snd_ac97_bus_ops ops = {
@@ -2906,10 +2789,8 @@ with an ``ac97_bus_ops_t`` record with callback functions. · 5 unmodified lines
29062789
29072790 The bus record is shared among all belonging ac97 instances.
29082791
2909−And then call :c:func:`snd_ac97_mixer()` with an struct snd_ac97_template
2910−record together with the bus pointer created above.
2911−
2912−::
2792+And then call :c:func:`snd_ac97_mixer()` with a struct snd_ac97_template
2793+record together with the bus pointer created above::
29132794
29142795 struct snd_ac97_template ac97;
29152796 int err;
@@ -2934,9 +2815,7 @@ correspond to the functions for read and write accesses to the · 18 unmodified lines
29342815 hardware low-level codes.
29352816
29362817 The ``read`` callback returns the register value specified in the
2937−argument.
2938−
2939−::
2818+argument::
29402819
29412820 static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
29422821 unsigned short reg)
@@ -2949,9 +2828,7 @@ argument. · 6 unmodified lines
29492828 Here, the chip can be cast from ``ac97->private_data``.
29502829
29512830 Meanwhile, the ``write`` callback is used to set the register
2952−value
2953−
2954−::
2831+value::
29552832
29562833 static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
29572834 unsigned short reg, unsigned short val)
@@ -2984,32 +2861,24 @@ Both :c:func:`snd_ac97_write()` and · 26 unmodified lines
29842861 the given register (``AC97_XXX``). The difference between them is that
29852862 :c:func:`snd_ac97_update()` doesn't write a value if the given
29862863 value has been already set, while :c:func:`snd_ac97_write()`
2987−always rewrites the value.
2988−
2989−::
2864+always rewrites the value::
29902865
29912866 snd_ac97_write(ac97, AC97_MASTER, 0x8080);
29922867 snd_ac97_update(ac97, AC97_MASTER, 0x8080);
29932868
29942869 :c:func:`snd_ac97_read()` is used to read the value of the given
2995−register. For example,
2996−
2997−::
2870+register. For example::
29982871
29992872 value = snd_ac97_read(ac97, AC97_MASTER);
30002873
30012874 :c:func:`snd_ac97_update_bits()` is used to update some bits in
3002−the given register.
3003−
3004−::
2875+the given register::
30052876
30062877 snd_ac97_update_bits(ac97, reg, mask, value);
30072878
30082879 Also, there is a function to change the sample rate (of a given register
30092880 such as ``AC97_PCM_FRONT_DAC_RATE``) when VRA or DRA is supported by the
3010−codec: :c:func:`snd_ac97_set_rate()`.
3011−
3012−::
2881+codec: :c:func:`snd_ac97_set_rate()`::
30132882
30142883 snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
30152884
@@ -3064,9 +2933,7 @@ mpu401 stuff. For example, emu10k1 has its own mpu401 routines. · 48 unmodified lines
30642933 MIDI Constructor
30652934 ----------------
30662935
3067−To create a rawmidi object, call :c:func:`snd_mpu401_uart_new()`.
3068−
3069−::
2936+To create a rawmidi object, call :c:func:`snd_mpu401_uart_new()`::
30702937
30712938 struct snd_rawmidi *rmidi;
30722939 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
@@ -3111,16 +2978,12 @@ corresponds to the data port. If not, you may change the ``cport`` · 38 unmodified lines
31112978 field of struct snd_mpu401 manually afterward.
31122979 However, struct snd_mpu401 pointer is
31132980 not returned explicitly by :c:func:`snd_mpu401_uart_new()`. You
3114−need to cast ``rmidi->private_data`` to struct snd_mpu401 explicitly,
3115−
3116−::
2981+need to cast ``rmidi->private_data`` to struct snd_mpu401 explicitly::
31172982
31182983 struct snd_mpu401 *mpu;
31192984 mpu = rmidi->private_data;
31202985
3121−and reset the ``cport`` as you like:
3122−
3123−::
2986+and reset the ``cport`` as you like::
31242987
31252988 mpu->cport = my_own_control_port;
31262989
@@ -3144,9 +3007,7 @@ occurred. · 17 unmodified lines
31443007
31453008 In this case, you need to pass the private_data of the returned rawmidi
31463009 object from :c:func:`snd_mpu401_uart_new()` as the second
3147−argument of :c:func:`snd_mpu401_uart_interrupt()`.
3148−
3149−::
3010+argument of :c:func:`snd_mpu401_uart_interrupt()`::
31503011
31513012 snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
31523013
@@ -3170,9 +3031,7 @@ RawMIDI Constructor · 17 unmodified lines
31703031 -------------------
31713032
31723033 To create a rawmidi device, call the :c:func:`snd_rawmidi_new()`
3173−function:
3174−
3175−::
3034+function::
31763035
31773036 struct snd_rawmidi *rmidi;
31783037 err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
@@ -3202,16 +3061,12 @@ output and input at the same time. · 23 unmodified lines
32023061
32033062 After the rawmidi device is created, you need to set the operators
32043063 (callbacks) for each substream. There are helper functions to set the
3205−operators for all the substreams of a device:
3206−
3207−::
3064+operators for all the substreams of a device::
32083065
32093066 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
32103067 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
32113068
3212−The operators are usually defined like this:
3213−
3214−::
3069+The operators are usually defined like this::
32153070
32163071 static struct snd_rawmidi_ops snd_mymidi_output_ops = {
32173072 .open = snd_mymidi_output_open,
@@ -3222,9 +3077,7 @@ The operators are usually defined like this: · 4 unmodified lines
32223077 These callbacks are explained in the `RawMIDI Callbacks`_ section.
32233078
32243079 If there are more than one substream, you should give a unique name to
3225−each of them:
3226−
3227−::
3080+each of them::
32283081
32293082 struct snd_rawmidi_substream *substream;
32303083 list_for_each_entry(substream,
@@ -3242,9 +3095,7 @@ device can be accessed as ``substream->rmidi->private_data``. · 11 unmodified lines
32423095
32433096 If there is more than one port, your callbacks can determine the port
32443097 index from the struct snd_rawmidi_substream data passed to each
3245−callback:
3246−
3247−::
3098+callback::
32483099
32493100 struct snd_rawmidi_substream *substream;
32503101 int index = substream->number;
@@ -3289,9 +3140,7 @@ of bytes that have been read; this will be less than the number of bytes · 38 unmodified lines
32893140 requested when there are no more data in the buffer. After the data have
32903141 been transmitted successfully, call
32913142 :c:func:`snd_rawmidi_transmit_ack()` to remove the data from the
3292−substream buffer:
3293−
3294−::
3143+substream buffer::
32953144
32963145 unsigned char data;
32973146 while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
@@ -3303,9 +3152,7 @@ substream buffer: · 5 unmodified lines
33033152
33043153 If you know beforehand that the hardware will accept data, you can use
33053154 the :c:func:`snd_rawmidi_transmit()` function which reads some
3306−data and removes them from the buffer at once:
3307−
3308−::
3155+data and removes them from the buffer at once::
33093156
33103157 while (snd_mychip_transmit_possible()) {
33113158 unsigned char data;
@@ -3340,9 +3187,7 @@ The ``trigger`` callback must not sleep; the actual reading of data · 28 unmodified lines
33403187 from the device is usually done in an interrupt handler.
33413188
33423189 When data reception is enabled, your interrupt handler should call
3343−:c:func:`snd_rawmidi_receive()` for all received data:
3344−
3345−::
3190+:c:func:`snd_rawmidi_receive()` for all received data::
33463191
33473192 void snd_mychip_midi_interrupt(...)
33483193 {
@@ -3388,9 +3233,7 @@ whereas in OSS compatible mode, FM registers can be accessed with the · 39 unmodified lines
33883233 OSS direct-FM compatible API in ``/dev/dmfmX`` device.
33893234
33903235 To create the OPL3 component, you have two functions to call. The first
3391−one is a constructor for the ``opl3_t`` instance.
3392−
3393−::
3236+one is a constructor for the ``opl3_t`` instance::
33943237
33953238 struct snd_opl3 *opl3;
33963239 snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
@@ -3408,9 +3251,7 @@ the opl3 module will allocate the specified ports by itself. · 11 unmodified lines
34083251
34093252 When the accessing the hardware requires special method instead of the
34103253 standard I/O access, you can create opl3 instance separately with
3411−:c:func:`snd_opl3_new()`.
3412−
3413−::
3254+:c:func:`snd_opl3_new()`::
34143255
34153256 struct snd_opl3 *opl3;
34163257 snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
@@ -3427,9 +3268,7 @@ proper state. Note that :c:func:`snd_opl3_create()` always calls · 10 unmodified lines
34273268 it internally.
34283269
34293270 If the opl3 instance is created successfully, then create a hwdep device
3430−for this opl3.
3431−
3432−::
3271+for this opl3::
34333272
34343273 struct snd_hwdep *opl3hwdep;
34353274 snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
@@ -3451,9 +3290,7 @@ the micro code. In such a case, you can create a hwdep · 15 unmodified lines
34513290 ``isa/sb/sb16_csp.c``.
34523291
34533292 The creation of the ``hwdep`` instance is done via
3454−:c:func:`snd_hwdep_new()`.
3455−
3456−::
3293+:c:func:`snd_hwdep_new()`::
34573294
34583295 struct snd_hwdep *hw;
34593296 snd_hwdep_new(card, "My HWDEP", 0, &hw);
@@ -3461,18 +3298,14 @@ The creation of the ``hwdep`` instance is done via · 1 unmodified line
34613298 where the third argument is the index number.
34623299
34633300 You can then pass any pointer value to the ``private_data``. If you
3464−assign a private data, you should define the destructor, too. The
3465−destructor function is set in the ``private_free`` field.
3466−
3467−::
3301+assign private data, you should define a destructor, too. The
3302+destructor function is set in the ``private_free`` field::
34683303
34693304 struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
34703305 hw->private_data = p;
34713306 hw->private_free = mydata_free;
34723307
3473−and the implementation of the destructor would be:
3474−
3475−::
3308+and the implementation of the destructor would be::
34763309
34773310 static void mydata_free(struct snd_hwdep *hw)
34783311 {
@@ -3482,9 +3315,7 @@ and the implementation of the destructor would be: · 3 unmodified lines
34823315
34833316 The arbitrary file operations can be defined for this instance. The file
34843317 operators are defined in the ``ops`` table. For example, assume that
3485−this chip needs an ioctl.
3486−
3487−::
3318+this chip needs an ioctl::
34883319
34893320 hw->ops.open = mydata_open;
34903321 hw->ops.ioctl = mydata_ioctl;
@@ -3534,31 +3365,30 @@ Buffer Types · 43 unmodified lines
35343365
35353366 ALSA provides several different buffer allocation functions depending on
35363367 the bus and the architecture. All these have a consistent API. The
3537−allocation of physically-contiguous pages is done via
3368+allocation of physically-contiguous pages is done via the
35383369 :c:func:`snd_malloc_xxx_pages()` function, where xxx is the bus
35393370 type.
35403371
3541−The allocation of pages with fallback is
3542−:c:func:`snd_malloc_xxx_pages_fallback()`. This function tries
3543−to allocate the specified pages but if the pages are not available, it
3544−tries to reduce the page sizes until enough space is found.
3372+The allocation of pages with fallback is done via
3373+:c:func:`snd_dma_alloc_pages_fallback()`. This function tries
3374+to allocate the specified number of pages, but if not enough pages are
3375+available, it tries to reduce the request size until enough space
3376+is found, down to one page.
35453377
3546−The release the pages, call :c:func:`snd_free_xxx_pages()`
3378+To release the pages, call the :c:func:`snd_dma_free_pages()`
35473379 function.
35483380
35493381 Usually, ALSA drivers try to allocate and reserve a large contiguous
3550−physical space at the time the module is loaded for the later use. This
3382+physical space at the time the module is loaded for later use. This
35513383 is called “pre-allocation”. As already written, you can call the
3552−following function at pcm instance construction time (in the case of PCI
3553−bus).
3554−
3555−::
3384+following function at PCM instance construction time (in the case of PCI
3385+bus)::
35563386
35573387 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
35583388 &pci->dev, size, max);
35593389
3560−where ``size`` is the byte size to be pre-allocated and the ``max`` is
3561−the maximum size to be changed via the ``prealloc`` proc file. The
3390+where ``size`` is the byte size to be pre-allocated and ``max`` is
3391+the maximum size settable via the ``prealloc`` proc file. The
35623392 allocator will try to get an area as large as possible within the
35633393 given size.
35643394
@@ -3567,10 +3397,10 @@ dependent on the bus. For normal devices, pass the device pointer · 2 unmodified lines
35673397 (typically identical as ``card->dev``) to the third argument with
35683398 ``SNDRV_DMA_TYPE_DEV`` type.
35693399
3570−For the continuous buffer unrelated to the
3400+A continuous buffer unrelated to the
35713401 bus can be pre-allocated with ``SNDRV_DMA_TYPE_CONTINUOUS`` type.
35723402 You can pass NULL to the device pointer in that case, which is the
3573−default mode implying to allocate with ``GFP_KERNEL`` flag.
3403+default mode implying to allocate with the ``GFP_KERNEL`` flag.
35743404 If you need a restricted (lower) address, set up the coherent DMA mask
35753405 bits for the device, and pass the device pointer, like the normal
35763406 device memory allocations. For this type, it's still allowed to pass
@@ -3580,37 +3410,33 @@ For the scatter-gather buffers, use ``SNDRV_DMA_TYPE_DEV_SG`` with the · 3 unmodified lines
35803410 device pointer (see the `Non-Contiguous Buffers`_ section).
35813411
35823412 Once the buffer is pre-allocated, you can use the allocator in the
3583−``hw_params`` callback:
3584−
3585−::
3413+``hw_params`` callback::
35863414
35873415 snd_pcm_lib_malloc_pages(substream, size);
35883416
35893417 Note that you have to pre-allocate to use this function.
35903418
3591−Most of drivers use, though, rather the newly introduced "managed
3592−buffer allocation mode" instead of the manual allocation or release.
3419+But most drivers use the "managed buffer allocation mode" instead
3420+of manual allocation and release.
35933421 This is done by calling :c:func:`snd_pcm_set_managed_buffer_all()`
3594−instead of :c:func:`snd_pcm_lib_preallocate_pages_for_all()`.
3595−
3596−::
3422+instead of :c:func:`snd_pcm_lib_preallocate_pages_for_all()`::
35973423
35983424 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
35993425 &pci->dev, size, max);
36003426
3601−where passed arguments are identical in both functions.
3427+where the passed arguments are identical for both functions.
36023428 The difference in the managed mode is that PCM core will call
36033429 :c:func:`snd_pcm_lib_malloc_pages()` internally already before calling
36043430 the PCM ``hw_params`` callback, and call :c:func:`snd_pcm_lib_free_pages()`
36053431 after the PCM ``hw_free`` callback automatically. So the driver
36063432 doesn't have to call these functions explicitly in its callback any
3607−longer. This made many driver code having NULL ``hw_params`` and
3433+longer. This allows many drivers to have NULL ``hw_params`` and
36083434 ``hw_free`` entries.
36093435
36103436 External Hardware Buffers
36113437 -------------------------
36123438
3613−Some chips have their own hardware buffers and the DMA transfer from the
3439+Some chips have their own hardware buffers and DMA transfer from the
36143440 host memory is not available. In such a case, you need to either 1)
36153441 copy/set the audio data directly to the external hardware buffer, or 2)
36163442 make an intermediate buffer and copy/set the data from it to the
@@ -3618,8 +3444,8 @@ external hardware buffer in interrupts (or in tasklets, preferably). · 1 unmodified line
36183444
36193445 The first case works fine if the external hardware buffer is large
36203446 enough. This method doesn't need any extra buffers and thus is more
3621−effective. You need to define the ``copy_user`` and ``copy_kernel``
3622−callbacks for the data transfer, in addition to ``fill_silence``
3447+efficient. You need to define the ``copy_user`` and ``copy_kernel``
3448+callbacks for the data transfer, in addition to the ``fill_silence``
36233449 callback for playback. However, there is a drawback: it cannot be
36243450 mmapped. The examples are GUS's GF1 PCM or emu8000's wavetable PCM.
36253451
@@ -3633,16 +3459,14 @@ buffer instead of the host memory. In this case, mmap is available only · 7 unmodified lines
36333459 on certain architectures like the Intel one. In non-mmap mode, the data
36343460 cannot be transferred as in the normal way. Thus you need to define the
36353461 ``copy_user``, ``copy_kernel`` and ``fill_silence`` callbacks as well,
3636−as in the cases above. The examples are found in ``rme32.c`` and
3462+as in the cases above. Examples are found in ``rme32.c`` and
36373463 ``rme96.c``.
36383464
36393465 The implementation of the ``copy_user``, ``copy_kernel`` and
36403466 ``silence`` callbacks depends upon whether the hardware supports
36413467 interleaved or non-interleaved samples. The ``copy_user`` callback is
3642−defined like below, a bit differently depending whether the direction
3643−is playback or capture:
3644−
3645−::
3468+defined like below, a bit differently depending on whether the direction
3469+is playback or capture::
36463470
36473471 static int playback_copy_user(struct snd_pcm_substream *substream,
36483472 int channel, unsigned long pos,
@@ -3652,8 +3476,7 @@ is playback or capture: · 3 unmodified lines
36523476 void __user *dst, unsigned long count);
36533477
36543478 In the case of interleaved samples, the second argument (``channel``) is
3655−not used. The third argument (``pos``) points the current position
3656−offset in bytes.
3479+not used. The third argument (``pos``) specifies the position in bytes.
36573480
36583481 The meaning of the fourth argument is different between playback and
36593482 capture. For playback, it holds the source data pointer, and for
@@ -3664,49 +3487,42 @@ The last argument is the number of bytes to be copied. · 4 unmodified lines
36643487 What you have to do in this callback is again different between playback
36653488 and capture directions. In the playback case, you copy the given amount
36663489 of data (``count``) at the specified pointer (``src``) to the specified
3667−offset (``pos``) on the hardware buffer. When coded like memcpy-like
3668−way, the copy would be like:
3669−
3670−::
3490+offset (``pos``) in the hardware buffer. When coded like memcpy-like
3491+way, the copy would look like::
36713492
36723493 my_memcpy_from_user(my_buffer + pos, src, count);
36733494
36743495 For the capture direction, you copy the given amount of data (``count``)
3675−at the specified offset (``pos``) on the hardware buffer to the
3676−specified pointer (``dst``).
3677−
3678−::
3496+at the specified offset (``pos``) in the hardware buffer to the
3497+specified pointer (``dst``)::
36793498
36803499 my_memcpy_to_user(dst, my_buffer + pos, count);
36813500
3682−Here the functions are named as ``from_user`` and ``to_user`` because
3501+Here the functions are named ``from_user`` and ``to_user`` because
36833502 it's the user-space buffer that is passed to these callbacks. That
3684−is, the callback is supposed to copy from/to the user-space data
3503+is, the callback is supposed to copy data from/to the user-space
36853504 directly to/from the hardware buffer.
36863505
36873506 Careful readers might notice that these callbacks receive the
36883507 arguments in bytes, not in frames like other callbacks. It's because
3689−it would make coding easier like the examples above, and also it makes
3690−easier to unify both the interleaved and non-interleaved cases, as
3691−explained in the following.
3508+this makes coding easier like in the examples above, and also it makes
3509+it easier to unify both the interleaved and non-interleaved cases, as
3510+explained below.
36923511
36933512 In the case of non-interleaved samples, the implementation will be a bit
3694−more complicated. The callback is called for each channel, passed by
3695−the second argument, so totally it's called for N-channels times per
3696−transfer.
3697−
3698−The meaning of other arguments are almost same as the interleaved
3699−case. The callback is supposed to copy the data from/to the given
3700−user-space buffer, but only for the given channel. For the detailed
3701−implementations, please check ``isa/gus/gus_pcm.c`` or
3702−"pci/rme9652/rme9652.c" as examples.
3513+more complicated. The callback is called for each channel, passed in
3514+the second argument, so in total it's called N times per transfer.
37033515
3704−The above callbacks are the copy from/to the user-space buffer. There
3705−are some cases where we want copy from/to the kernel-space buffer
3706−instead. In such a case, ``copy_kernel`` callback is called. It'd
3707−look like:
3516+The meaning of the other arguments are almost the same as in the
3517+interleaved case. The callback is supposed to copy the data from/to
3518+the given user-space buffer, but only for the given channel. For
3519+details, please check ``isa/gus/gus_pcm.c`` or ``pci/rme9652/rme9652.c``
3520+as examples.
37083521
3709−::
3522+The above callbacks are the copies from/to the user-space buffer. There
3523+are some cases where we want to copy from/to the kernel-space buffer
3524+instead. In such a case, the ``copy_kernel`` callback is called. It'd
3525+look like::
37103526
37113527 static int playback_copy_kernel(struct snd_pcm_substream *substream,
37123528 int channel, unsigned long pos,
@@ -3716,19 +3532,15 @@ look like: · 3 unmodified lines
37163532 void *dst, unsigned long count);
37173533
37183534 As found easily, the only difference is that the buffer pointer is
3719−without ``__user`` prefix; that is, a kernel-buffer pointer is passed
3535+without a ``__user`` prefix; that is, a kernel-buffer pointer is passed
37203536 in the fourth argument. Correspondingly, the implementation would be
3721−a version without the user-copy, such as:
3722−
3723−::
3537+a version without the user-copy, such as::
37243538
37253539 my_memcpy(my_buffer + pos, src, count);
37263540
37273541 Usually for the playback, another callback ``fill_silence`` is
37283542 defined. It's implemented in a similar way as the copy callbacks
3729−above:
3730−
3731−::
3543+above::
37323544
37333545 static int silence(struct snd_pcm_substream *substream, int channel,
37343546 unsigned long pos, unsigned long count);
@@ -3736,54 +3548,47 @@ above: · 1 unmodified line
37363548 The meanings of arguments are the same as in the ``copy_user`` and
37373549 ``copy_kernel`` callbacks, although there is no buffer pointer
37383550 argument. In the case of interleaved samples, the channel argument has
3739−no meaning, as well as on ``copy_*`` callbacks.
3551+no meaning, as for the ``copy_*`` callbacks.
37403552
3741−The role of ``fill_silence`` callback is to set the given amount
3742−(``count``) of silence data at the specified offset (``pos``) on the
3553+The role of the ``fill_silence`` callback is to set the given amount
3554+(``count``) of silence data at the specified offset (``pos``) in the
37433555 hardware buffer. Suppose that the data format is signed (that is, the
37443556 silent-data is 0), and the implementation using a memset-like function
3745−would be like:
3746−
3747−::
3557+would look like::
37483558
37493559 my_memset(my_buffer + pos, 0, count);
37503560
37513561 In the case of non-interleaved samples, again, the implementation
3752−becomes a bit more complicated, as it's called N-times per transfer
3562+becomes a bit more complicated, as it's called N times per transfer
37533563 for each channel. See, for example, ``isa/gus/gus_pcm.c``.
37543564
37553565 Non-Contiguous Buffers
37563566 ----------------------
37573567
3758−If your hardware supports the page table as in emu10k1 or the buffer
3759−descriptors as in via82xx, you can use the scatter-gather (SG) DMA. ALSA
3568+If your hardware supports a page table as in emu10k1 or buffer
3569+descriptors as in via82xx, you can use scatter-gather (SG) DMA. ALSA
37603570 provides an interface for handling SG-buffers. The API is provided in
37613571 ``<sound/pcm.h>``.
37623572
37633573 For creating the SG-buffer handler, call
37643574 :c:func:`snd_pcm_set_managed_buffer()` or
37653575 :c:func:`snd_pcm_set_managed_buffer_all()` with
3766−``SNDRV_DMA_TYPE_DEV_SG`` in the PCM constructor like other PCI
3767−pre-allocator. You need to pass ``&pci->dev``, where pci is
3768−the struct pci_dev pointer of the chip as
3769−well.
3770−
3771−::
3576+``SNDRV_DMA_TYPE_DEV_SG`` in the PCM constructor like for other PCI
3577+pre-allocations. You need to pass ``&pci->dev``, where pci is
3578+the struct pci_dev pointer of the chip as well::
37723579
37733580 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
37743581 &pci->dev, size, max);
37753582
37763583 The ``struct snd_sg_buf`` instance is created as
3777−``substream->dma_private`` in turn. You can cast the pointer like:
3778−
3779−::
3584+``substream->dma_private`` in turn. You can cast the pointer like::
37803585
37813586 struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
37823587
3783−Then in :c:func:`snd_pcm_lib_malloc_pages()` call, the common SG-buffer
3588+Then in the :c:func:`snd_pcm_lib_malloc_pages()` call, the common SG-buffer
37843589 handler will allocate the non-contiguous kernel pages of the given size
3785−and map them onto the virtually contiguous memory. The virtual pointer
3786−is addressed in runtime->dma_area. The physical address
3590+and map them as virtually contiguous memory. The virtual pointer
3591+is addressed via runtime->dma_area. The physical address
37873592 (``runtime->dma_addr``) is set to zero, because the buffer is
37883593 physically non-contiguous. The physical address table is set up in
37893594 ``sgbuf->table``. You can get the physical address at a certain offset
@@ -3796,22 +3601,20 @@ Vmalloc'ed Buffers · 6 unmodified lines
37963601 ------------------
37973602
37983603 It's possible to use a buffer allocated via :c:func:`vmalloc()`, for
3799−example, for an intermediate buffer. In the recent version of kernel,
3800−you can simply allocate it via standard
3801−:c:func:`snd_pcm_lib_malloc_pages()` and co after setting up the
3802−buffer preallocation with ``SNDRV_DMA_TYPE_VMALLOC`` type.
3803−
3804−::
3604+example, for an intermediate buffer.
3605+You can simply allocate it via the standard
3606+:c:func:`snd_pcm_lib_malloc_pages()` and co. after setting up the
3607+buffer preallocation with ``SNDRV_DMA_TYPE_VMALLOC`` type::
38053608
38063609 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
38073610 NULL, 0, 0);
38083611
3809−The NULL is passed to the device pointer argument, which indicates
3810−that the default pages (GFP_KERNEL and GFP_HIGHMEM) will be
3612+NULL is passed as the device pointer argument, which indicates
3613+that default pages (GFP_KERNEL and GFP_HIGHMEM) will be
38113614 allocated.
38123615
3813−Also, note that zero is passed to both the size and the max size
3814−arguments here. Since each vmalloc call should succeed at any time,
3616+Also, note that zero is passed as both the size and the max size
3617+argument here. Since each vmalloc call should succeed at any time,
38153618 we don't need to pre-allocate the buffers like other continuous
38163619 pages.
38173620
@@ -3823,9 +3626,7 @@ useful for debugging. I recommend you set up proc files if you write a · 5 unmodified lines
38233626 driver and want to get a running status or register dumps. The API is
38243627 found in ``<sound/info.h>``.
38253628
3826−To create a proc file, call :c:func:`snd_card_proc_new()`.
3827−
3828−::
3629+To create a proc file, call :c:func:`snd_card_proc_new()`::
38293630
38303631 struct snd_info_entry *entry;
38313632 int err = snd_card_proc_new(card, "my-file", &entry);
@@ -3841,28 +3642,22 @@ automatically in the card registration and release functions. · 9 unmodified lines
38413642 When the creation is successful, the function stores a new instance in
38423643 the pointer given in the third argument. It is initialized as a text
38433644 proc file for read only. To use this proc file as a read-only text file
3844−as it is, set the read callback with a private data via
3845−:c:func:`snd_info_set_text_ops()`.
3846−
3847−::
3645+as-is, set the read callback with private data via
3646+:c:func:`snd_info_set_text_ops()`::
38483647
38493648 snd_info_set_text_ops(entry, chip, my_proc_read);
38503649
38513650 where the second argument (``chip``) is the private data to be used in
3852−the callbacks. The third parameter specifies the read buffer size and
3651+the callback. The third parameter specifies the read buffer size and
38533652 the fourth (``my_proc_read``) is the callback function, which is
3854−defined like
3855−
3856−::
3653+defined like::
38573654
38583655 static void my_proc_read(struct snd_info_entry *entry,
38593656 struct snd_info_buffer *buffer);
38603657
38613658 In the read callback, use :c:func:`snd_iprintf()` for output
38623659 strings, which works just like normal :c:func:`printf()`. For
3863−example,
3864−
3865−::
3660+example::
38663661
38673662 static void my_proc_read(struct snd_info_entry *entry,
38683663 struct snd_info_buffer *buffer)
@@ -3873,28 +3668,22 @@ example, · 4 unmodified lines
38733668 snd_iprintf(buffer, "Port = %ld\n", chip->port);
38743669 }
38753670
3876−The file permissions can be changed afterwards. As default, it's set as
3671+The file permissions can be changed afterwards. By default, they are
38773672 read only for all users. If you want to add write permission for the
3878−user (root as default), do as follows:
3879−
3880−::
3673+user (root by default), do as follows::
38813674
38823675 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
38833676
3884−and set the write buffer size and the callback
3885−
3886−::
3677+and set the write buffer size and the callback::
38873678
38883679 entry->c.text.write = my_proc_write;
38893680
3890−For the write callback, you can use :c:func:`snd_info_get_line()`
3681+In the write callback, you can use :c:func:`snd_info_get_line()`
38913682 to get a text line, and :c:func:`snd_info_get_str()` to retrieve
38923683 a string from the line. Some examples are found in
38933684 ``core/oss/mixer_oss.c``, core/oss/and ``pcm_oss.c``.
38943685
3895−For a raw-data proc-file, set the attributes as follows:
3896−
3897−::
3686+For a raw-data proc-file, set the attributes as follows::
38983687
38993688 static const struct snd_info_entry_ops my_file_io_ops = {
39003689 .read = my_file_io_read,
@@ -3906,14 +3695,13 @@ For a raw-data proc-file, set the attributes as follows: · 5 unmodified lines
39063695 entry->size = 4096;
39073696 entry->mode = S_IFREG | S_IRUGO;
39083697
3909−For the raw data, ``size`` field must be set properly. This specifies
3698+For raw data, ``size`` field must be set properly. This specifies
39103699 the maximum size of the proc file access.
39113700
39123701 The read/write callbacks of raw mode are more direct than the text mode.
39133702 You need to use a low-level I/O functions such as
3914−:c:func:`copy_from_user()` and :c:func:`copy_to_user()` to transfer the data.
3915−
3916−::
3703+:c:func:`copy_from_user()` and :c:func:`copy_to_user()` to transfer the
3704+data::
39173705
39183706 static ssize_t my_file_io_read(struct snd_info_entry *entry,
39193707 void *file_private_data,
@@ -3938,12 +3726,11 @@ Power Management · 18 unmodified lines
39383726 If the chip is supposed to work with suspend/resume functions, you need
39393727 to add power-management code to the driver. The additional code for
39403728 power-management should be ifdef-ed with ``CONFIG_PM``, or annotated
3941−with __maybe_unused attribute; otherwise the compiler will complain
3942−you.
3729+with __maybe_unused attribute; otherwise the compiler will complain.
39433730
39443731 If the driver *fully* supports suspend/resume that is, the device can be
39453732 properly resumed to its state when suspend was called, you can set the
3946−``SNDRV_PCM_INFO_RESUME`` flag in the pcm info field. Usually, this is
3733+``SNDRV_PCM_INFO_RESUME`` flag in the PCM info field. Usually, this is
39473734 possible when the registers of the chip can be safely saved and restored
39483735 to RAM. If this is set, the trigger callback is called with
39493736 ``SNDRV_PCM_TRIGGER_RESUME`` after the resume callback completes.
@@ -3953,7 +3740,7 @@ is still possible, it's still worthy to implement suspend/resume · 3 unmodified lines
39533740 callbacks. In such a case, applications would reset the status by
39543741 calling :c:func:`snd_pcm_prepare()` and restart the stream
39553742 appropriately. Hence, you can define suspend/resume callbacks below but
3956−don't set ``SNDRV_PCM_INFO_RESUME`` info flag to the PCM.
3743+don't set the ``SNDRV_PCM_INFO_RESUME`` info flag to the PCM.
39573744
39583745 Note that the trigger with SUSPEND can always be called when
39593746 :c:func:`snd_pcm_suspend_all()` is called, regardless of the
@@ -3963,12 +3750,9 @@ behavior of :c:func:`snd_pcm_resume()`. (Thus, in theory, · 3 unmodified lines
39633750 callback when no ``SNDRV_PCM_INFO_RESUME`` flag is set. But, it's better
39643751 to keep it for compatibility reasons.)
39653752
3966−In the earlier version of ALSA drivers, a common power-management layer
3967−was provided, but it has been removed. The driver needs to define the
3753+The driver needs to define the
39683754 suspend/resume hooks according to the bus the device is connected to. In
3969−the case of PCI drivers, the callbacks look like below:
3970−
3971−::
3755+the case of PCI drivers, the callbacks look like below::
39723756
39733757 static int __maybe_unused snd_my_suspend(struct device *dev)
39743758 {
@@ -3981,7 +3765,7 @@ the case of PCI drivers, the callbacks look like below: · 6 unmodified lines
39813765 return 0;
39823766 }
39833767
3984−The scheme of the real suspend job is as follows.
3768+The scheme of the real suspend job is as follows:
39853769
39863770 1. Retrieve the card and the chip data.
39873771
@@ -3995,9 +3779,7 @@ The scheme of the real suspend job is as follows. · 7 unmodified lines
39953779
39963780 5. Stop the hardware if necessary.
39973781
3998−A typical code would be like:
3999−
4000−::
3782+Typical code would look like::
40013783
40023784 static int __maybe_unused mychip_suspend(struct device *dev)
40033785 {
@@ -4016,7 +3798,7 @@ A typical code would be like: · 12 unmodified lines
40163798 }
40173799
40183800
4019−The scheme of the real resume job is as follows.
3801+The scheme of the real resume job is as follows:
40203802
40213803 1. Retrieve the card and the chip data.
40223804
@@ -4024,16 +3806,14 @@ The scheme of the real resume job is as follows. · 1 unmodified line
40243806
40253807 3. Restore the saved registers if necessary.
40263808
4027−4. Resume the mixer, e.g. calling :c:func:`snd_ac97_resume()`.
3809+4. Resume the mixer, e.g. by calling :c:func:`snd_ac97_resume()`.
40283810
40293811 5. Restart the hardware (if any).
40303812
40313813 6. Call :c:func:`snd_power_change_state()` with
40323814 ``SNDRV_CTL_POWER_D0`` to notify the processes.
40333815
4034−A typical code would be like:
4035−
4036−::
3816+Typical code would look like::
40373817
40383818 static int __maybe_unused mychip_resume(struct pci_dev *pci)
40393819 {
@@ -4060,9 +3840,7 @@ been already suspended via its own PM ops calling · 20 unmodified lines
40603840 OK, we have all callbacks now. Let's set them up. In the initialization
40613841 of the card, make sure that you can get the chip data from the card
40623842 instance, typically via ``private_data`` field, in case you created the
4063−chip data individually.
4064−
4065−::
3843+chip data individually::
40663844
40673845 static int snd_mychip_probe(struct pci_dev *pci,
40683846 const struct pci_device_id *pci_id)
@@ -4082,9 +3860,7 @@ chip data individually. · 13 unmodified lines
40823860 }
40833861
40843862 When you created the chip data with :c:func:`snd_card_new()`, it's
4085−anyway accessible via ``private_data`` field.
4086−
4087−::
3863+anyway accessible via ``private_data`` field::
40883864
40893865 static int snd_mychip_probe(struct pci_dev *pci,
40903866 const struct pci_device_id *pci_id)
@@ -4101,14 +3877,12 @@ anyway accessible via ``private_data`` field. · 10 unmodified lines
41013877 ....
41023878 }
41033879
4104−If you need a space to save the registers, allocate the buffer for it
3880+If you need space to save the registers, allocate the buffer for it
41053881 here, too, since it would be fatal if you cannot allocate a memory in
41063882 the suspend phase. The allocated buffer should be released in the
41073883 corresponding destructor.
41083884
4109−And next, set suspend/resume callbacks to the pci_driver.
4110−
4111−::
3885+And next, set suspend/resume callbacks to the pci_driver::
41123886
41133887 static SIMPLE_DEV_PM_OPS(snd_my_pm_ops, mychip_suspend, mychip_resume);
41143888
@@ -4128,9 +3902,7 @@ have the ``index``, ``id`` and ``enable`` options. · 13 unmodified lines
41283902
41293903 If the module supports multiple cards (usually up to 8 = ``SNDRV_CARDS``
41303904 cards), they should be arrays. The default initial values are defined
4131−already as constants for easier programming:
4132−
4133−::
3905+already as constants for easier programming::
41343906
41353907 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
41363908 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -4144,9 +3916,7 @@ The module parameters must be declared with the standard · 7 unmodified lines
41443916 ``module_param()``, ``module_param_array()`` and
41453917 :c:func:`MODULE_PARM_DESC()` macros.
41463918
4147−The typical coding would be like below:
4148−
4149−::
3919+Typical code would look as below::
41503920
41513921 #define CARD_NAME "My Chip"
41523922
@@ -4159,9 +3929,7 @@ The typical coding would be like below: · 6 unmodified lines
41593929
41603930 Also, don't forget to define the module description and the license.
41613931 Especially, the recent modprobe requires to define the
4162−module license as GPL, etc., otherwise the system is shown as “tainted”.
4163−
4164−::
3932+module license as GPL, etc., otherwise the system is shown as “tainted”::
41653933
41663934 MODULE_DESCRIPTION("Sound driver for My Chip");
41673935 MODULE_LICENSE("GPL");
@@ -4224,32 +3992,36 @@ Driver with A Single Source File · 56 unmodified lines
42243992
42253993 1. Modify sound/pci/Makefile
42263994
4227− Suppose you have a file xyz.c. Add the following two lines
4228−
4229−::
3995+ Suppose you have a file xyz.c. Add the following two lines::
42303996
42313997 snd-xyz-objs := xyz.o
42323998 obj-$(CONFIG_SND_XYZ) += snd-xyz.o
42333999
42344000 2. Create the Kconfig entry
42354001
4236− Add the new entry of Kconfig for your xyz driver. config SND_XYZ
4237− tristate "Foobar XYZ" depends on SND select SND_PCM help Say Y here
4238− to include support for Foobar XYZ soundcard. To compile this driver
4239− as a module, choose M here: the module will be called snd-xyz. the
4240− line, select SND_PCM, specifies that the driver xyz supports PCM. In
4241− addition to SND_PCM, the following components are supported for
4242− select command: SND_RAWMIDI, SND_TIMER, SND_HWDEP,
4243− SND_MPU401_UART, SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB,
4244− SND_AC97_CODEC. Add the select command for each supported
4245− component.
4002+ Add the new entry of Kconfig for your xyz driver::
4003+
4004+ config SND_XYZ
4005+ tristate "Foobar XYZ"
4006+ depends on SND
4007+ select SND_PCM
4008+ help
4009+ Say Y here to include support for Foobar XYZ soundcard.
4010+ To compile this driver as a module, choose M here:
4011+ the module will be called snd-xyz.
4012+
4013+The line ``select SND_PCM`` specifies that the driver xyz supports PCM.
4014+In addition to SND_PCM, the following components are supported for
4015+select command: SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART,
4016+SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC.
4017+Add the select command for each supported component.
42464018
4247− Note that some selections imply the lowlevel selections. For example,
4248− PCM includes TIMER, MPU401_UART includes RAWMIDI, AC97_CODEC
4249− includes PCM, and OPL3_LIB includes HWDEP. You don't need to give
4250− the lowlevel selections again.
4019+Note that some selections imply the lowlevel selections. For example,
4020+PCM includes TIMER, MPU401_UART includes RAWMIDI, AC97_CODEC
4021+includes PCM, and OPL3_LIB includes HWDEP. You don't need to give
4022+the lowlevel selections again.
42514023
4252− For the details of Kconfig script, refer to the kbuild documentation.
4024+For the details of Kconfig script, refer to the kbuild documentation.
42534025
42544026 Drivers with Several Source Files
42554027 ---------------------------------
@@ -4258,16 +4030,12 @@ Suppose that the driver snd-xyz have several source files. They are · 2 unmodified lines
42584030 located in the new subdirectory, sound/pci/xyz.
42594031
42604032 1. Add a new directory (``sound/pci/xyz``) in ``sound/pci/Makefile``
4261− as below
4262−
4263−::
4033+ as below::
42644034
42654035 obj-$(CONFIG_SND) += sound/pci/xyz/
42664036
42674037
4268−2. Under the directory ``sound/pci/xyz``, create a Makefile
4269−
4270−::
4038+2. Under the directory ``sound/pci/xyz``, create a Makefile::
42714039
42724040 snd-xyz-objs := xyz.o abc.o def.o
42734041 obj-$(CONFIG_SND_XYZ) += snd-xyz.o
MAINTAINERS+34−2
@@ -2075,6 +2075,7 @@ M: Alexander Sverdlin <alexander.sverdlin@gmail.com> · 2074 unmodified lines
20752075 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
20762076 S: Maintained
20772077 F: Documentation/devicetree/bindings/iio/adc/cirrus,ep9301-adc.yaml
2078+F: Documentation/devicetree/bindings/sound/cirrus,ep9301-*
20782079 F: arch/arm/boot/compressed/misc-ep93xx.h
20792080 F: arch/arm/mach-ep93xx/
20802081 F: drivers/iio/adc/ep93xx_adc.c
@@ -4922,6 +4923,7 @@ L: patches@opensource.cirrus.com · 2841 unmodified lines
49224923 S: Maintained
49234924 F: Documentation/devicetree/bindings/sound/cirrus,cs*
49244925 F: include/dt-bindings/sound/cs*
4926+F: include/sound/cs*
49254927 F: sound/pci/hda/cs*
49264928 F: sound/pci/hda/hda_cs_dsp_ctl.*
49274929 F: sound/soc/codecs/cs*
@@ -8282,6 +8284,23 @@ S: Maintained · 3354 unmodified lines
82828284 F: drivers/soc/fsl/qe/
82838285 F: include/soc/fsl/qe/
82848286
8287+FREESCALE QUICC ENGINE QMC DRIVER
8288+M: Herve Codina <herve.codina@bootlin.com>
8289+L: linuxppc-dev@lists.ozlabs.org
8290+S: Maintained
8291+F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
8292+F: drivers/soc/fsl/qe/qmc.c
8293+F: include/soc/fsl/qe/qmc.h
8294+
8295+FREESCALE QUICC ENGINE TSA DRIVER
8296+M: Herve Codina <herve.codina@bootlin.com>
8297+L: linuxppc-dev@lists.ozlabs.org
8298+S: Maintained
8299+F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml
8300+F: drivers/soc/fsl/qe/tsa.c
8301+F: drivers/soc/fsl/qe/tsa.h
8302+F: include/dt-bindings/soc/cpm1-fsl,tsa.h
8303+
82858304 FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
82868305 M: Li Yang <leoyang.li@nxp.com>
82878306 L: netdev@vger.kernel.org
@@ -8333,6 +8352,14 @@ F: sound/soc/fsl/fsl* · 45 unmodified lines
83338352 F: sound/soc/fsl/imx*
83348353 F: sound/soc/fsl/mpc8610_hpcd.c
83358354
8355+FREESCALE SOC SOUND QMC DRIVER
8356+M: Herve Codina <herve.codina@bootlin.com>
8357+L: alsa-devel@alsa-project.org (moderated for non-subscribers)
8358+L: linuxppc-dev@lists.ozlabs.org
8359+S: Maintained
8360+F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
8361+F: sound/soc/fsl/fsl_qmc_audio.c
8362+
83368363 FREESCALE USB PERIPHERAL DRIVERS
83378364 M: Li Yang <leoyang.li@nxp.com>
83388365 L: linux-usb@vger.kernel.org
@@ -13651,9 +13678,13 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml · 5312 unmodified lines
1365113678 F: drivers/spi/spi-at91-usart.c
1365213679
1365313680 MICROCHIP AUDIO ASOC DRIVERS
13654−M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
13681+M: Claudiu Beznea <claudiu.beznea@microchip.com>
1365513682 L: alsa-devel@alsa-project.org (moderated for non-subscribers)
1365613683 S: Supported
13684+F: Documentation/devicetree/bindings/sound/atmel*
13685+F: Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt
13686+F: Documentation/devicetree/bindings/sound/microchip,sama7g5-*
13687+F: Documentation/devicetree/bindings/sound/mikroe,mikroe-proto.txt
1365713688 F: sound/soc/atmel
1365813689
1365913690 MICROCHIP CSI2DC DRIVER
@@ -13826,9 +13857,10 @@ S: Supported · 166 unmodified lines
1382613857 F: drivers/spi/spi-atmel.*
1382713858
1382813859 MICROCHIP SSC DRIVER
13829−M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
13860+M: Claudiu Beznea <claudiu.beznea@microchip.com>
1383013861 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
1383113862 S: Supported
13863+F: Documentation/devicetree/bindings/misc/atmel-ssc.txt
1383213864 F: drivers/misc/atmel-ssc.c
1383313865 F: include/linux/atmel-ssc.h
1383413866
arch/powerpc/platforms/8xx/cpm1.c+1−1
@@ -94,7 +94,7 @@ int cpm_command(u32 command, u8 opcode) · 93 unmodified lines
9494 int i, ret;
9595 unsigned long flags;
9696
97− if (command & 0xffffff0f)
97+ if (command & 0xffffff03)
9898 return -EINVAL;
9999
100100 spin_lock_irqsave(&cmd_lock, flags);
drivers/firmware/cirrus/cs_dsp.c+47−1
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/delay.h>
1515 #include <linux/module.h>
1616 #include <linux/moduleparam.h>
17+#include <linux/seq_file.h>
1718 #include <linux/slab.h>
1819 #include <linux/vmalloc.h>
1920
@@ -301,6 +302,7 @@ struct cs_dsp_ops { · 281 unmodified lines
301302 static const struct cs_dsp_ops cs_dsp_adsp1_ops;
302303 static const struct cs_dsp_ops cs_dsp_adsp2_ops[];
303304 static const struct cs_dsp_ops cs_dsp_halo_ops;
305+static const struct cs_dsp_ops cs_dsp_halo_ao_ops;
304306
305307 struct cs_dsp_buf {
306308 struct list_head list;
@@ -456,6 +458,33 @@ static const struct { · 149 unmodified lines
456458 },
457459 };
458460
461+static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg,
462+ unsigned int off);
463+
464+static int cs_dsp_debugfs_read_controls_show(struct seq_file *s, void *ignored)
465+{
466+ struct cs_dsp *dsp = s->private;
467+ struct cs_dsp_coeff_ctl *ctl;
468+ unsigned int reg;
469+
470+ list_for_each_entry(ctl, &dsp->ctl_list, list) {
471+ cs_dsp_coeff_base_reg(ctl, &reg, 0);
472+ seq_printf(s, "%22.*s: %#8zx %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n",
473+ ctl->subname_len, ctl->subname, ctl->len,
474+ cs_dsp_mem_region_name(ctl->alg_region.type),
475+ ctl->offset, reg, ctl->fw_name, ctl->alg_region.alg, ctl->type,
476+ ctl->flags & WMFW_CTL_FLAG_VOLATILE ? 'V' : '-',
477+ ctl->flags & WMFW_CTL_FLAG_SYS ? 'S' : '-',
478+ ctl->flags & WMFW_CTL_FLAG_READABLE ? 'R' : '-',
479+ ctl->flags & WMFW_CTL_FLAG_WRITEABLE ? 'W' : '-',
480+ ctl->enabled ? "enabled" : "disabled",
481+ ctl->set ? "dirty" : "clean");
482+ }
483+
484+ return 0;
485+}
486+DEFINE_SHOW_ATTRIBUTE(cs_dsp_debugfs_read_controls);
487+
459488 /**
460489 * cs_dsp_init_debugfs() - Create and populate DSP representation in debugfs
461490 * @dsp: pointer to DSP structure
@@ -478,6 +507,9 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) · 16 unmodified lines
478507 debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root,
479508 dsp, &cs_dsp_debugfs_fops[i].fops);
480509
510+ debugfs_create_file("controls", 0444, root, dsp,
511+ &cs_dsp_debugfs_read_controls_fops);
512+
481513 dsp->debugfs_root = root;
482514 }
483515 EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP);
@@ -1300,6 +1332,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, · 816 unmodified lines
13001332 int regions = 0;
13011333 int ret, offset, type;
13021334
1335+ if (!firmware)
1336+ return 0;
1337+
13031338 ret = -EINVAL;
13041339
13051340 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
@@ -2821,7 +2856,10 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_adsp2_init, FW_CS_DSP); · 1515 unmodified lines
28212856 */
28222857 int cs_dsp_halo_init(struct cs_dsp *dsp)
28232858 {
2824− dsp->ops = &cs_dsp_halo_ops;
2859+ if (dsp->no_core_startstop)
2860+ dsp->ops = &cs_dsp_halo_ao_ops;
2861+ else
2862+ dsp->ops = &cs_dsp_halo_ops;
28252863
28262864 return cs_dsp_common_init(dsp);
28272865 }
@@ -3187,6 +3225,14 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { · 359 unmodified lines
31873225 .stop_core = cs_dsp_halo_stop_core,
31883226 };
31893227
3228+static const struct cs_dsp_ops cs_dsp_halo_ao_ops = {
3229+ .parse_sizes = cs_dsp_adsp2_parse_sizes,
3230+ .validate_version = cs_dsp_halo_validate_version,
3231+ .setup_algs = cs_dsp_halo_setup_algs,
3232+ .region_to_reg = cs_dsp_halo_region_to_reg,
3233+ .show_fw_status = cs_dsp_halo_show_fw_status,
3234+};
3235+
31903236 /**
31913237 * cs_dsp_chunk_write() - Format data to a DSP memory chunk
31923238 * @ch: Pointer to the chunk structure
drivers/soc/fsl/qe/Kconfig+23−0
@@ -33,6 +33,29 @@ config UCC · 32 unmodified lines
3333 bool
3434 default y if UCC_FAST || UCC_SLOW
3535
36+config CPM_TSA
37+ tristate "CPM TSA support"
38+ depends on OF && HAS_IOMEM
39+ depends on CPM1 || COMPILE_TEST
40+ help
41+ Freescale CPM Time Slot Assigner (TSA)
42+ controller.
43+
44+ This option enables support for this
45+ controller
46+
47+config CPM_QMC
48+ tristate "CPM QMC support"
49+ depends on OF && HAS_IOMEM
50+ depends on CPM1 || (FSL_SOC && COMPILE_TEST)
51+ depends on CPM_TSA
52+ help
53+ Freescale CPM QUICC Multichannel Controller
54+ (QMC)
55+
56+ This option enables support for this
57+ controller
58+
3659 config QE_TDM
3760 bool
3861 default y if FSL_UCC_HDLC
drivers/soc/fsl/qe/Makefile+2−0
@@ -4,6 +4,8 @@ · 3 unmodified lines
44 #
55 obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o
66 obj-$(CONFIG_CPM) += qe_common.o
7+obj-$(CONFIG_CPM_TSA) += tsa.o
8+obj-$(CONFIG_CPM_QMC) += qmc.o
79 obj-$(CONFIG_UCC) += ucc.o
810 obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
911 obj-$(CONFIG_UCC_FAST) += ucc_fast.o
drivers/soc/fsl/qe/qmc.c+1537−0
@@ -0,0 +1,1537 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * QMC driver
4+ *
5+ * Copyright 2022 CS GROUP France
6+ *
7+ * Author: Herve Codina <herve.codina@bootlin.com>
8+ */
9+
10+#include <soc/fsl/qe/qmc.h>
11+#include <linux/dma-mapping.h>
12+#include <linux/hdlc.h>
13+#include <linux/interrupt.h>
14+#include <linux/io.h>
15+#include <linux/module.h>
16+#include <linux/of.h>
17+#include <linux/of_platform.h>
18+#include <linux/platform_device.h>
19+#include <linux/slab.h>
20+#include <soc/fsl/cpm.h>
21+#include <sysdev/fsl_soc.h>
22+#include "tsa.h"
23+
24+/* SCC general mode register high (32 bits) */
25+#define SCC_GSMRL 0x00
26+#define SCC_GSMRL_ENR (1 << 5)
27+#define SCC_GSMRL_ENT (1 << 4)
28+#define SCC_GSMRL_MODE_QMC (0x0A << 0)
29+
30+/* SCC general mode register low (32 bits) */
31+#define SCC_GSMRH 0x04
32+#define SCC_GSMRH_CTSS (1 << 7)
33+#define SCC_GSMRH_CDS (1 << 8)
34+#define SCC_GSMRH_CTSP (1 << 9)
35+#define SCC_GSMRH_CDP (1 << 10)
36+
37+/* SCC event register (16 bits) */
38+#define SCC_SCCE 0x10
39+#define SCC_SCCE_IQOV (1 << 3)
40+#define SCC_SCCE_GINT (1 << 2)
41+#define SCC_SCCE_GUN (1 << 1)
42+#define SCC_SCCE_GOV (1 << 0)
43+
44+/* SCC mask register (16 bits) */
45+#define SCC_SCCM 0x14
46+/* Multichannel base pointer (32 bits) */
47+#define QMC_GBL_MCBASE 0x00
48+/* Multichannel controller state (16 bits) */
49+#define QMC_GBL_QMCSTATE 0x04
50+/* Maximum receive buffer length (16 bits) */
51+#define QMC_GBL_MRBLR 0x06
52+/* Tx time-slot assignment table pointer (16 bits) */
53+#define QMC_GBL_TX_S_PTR 0x08
54+/* Rx pointer (16 bits) */
55+#define QMC_GBL_RXPTR 0x0A
56+/* Global receive frame threshold (16 bits) */
57+#define QMC_GBL_GRFTHR 0x0C
58+/* Global receive frame count (16 bits) */
59+#define QMC_GBL_GRFCNT 0x0E
60+/* Multichannel interrupt base address (32 bits) */
61+#define QMC_GBL_INTBASE 0x10
62+/* Multichannel interrupt pointer (32 bits) */
63+#define QMC_GBL_INTPTR 0x14
64+/* Rx time-slot assignment table pointer (16 bits) */
65+#define QMC_GBL_RX_S_PTR 0x18
66+/* Tx pointer (16 bits) */
67+#define QMC_GBL_TXPTR 0x1A
68+/* CRC constant (32 bits) */
69+#define QMC_GBL_C_MASK32 0x1C
70+/* Time slot assignment table Rx (32 x 16 bits) */
71+#define QMC_GBL_TSATRX 0x20
72+/* Time slot assignment table Tx (32 x 16 bits) */
73+#define QMC_GBL_TSATTX 0x60
74+/* CRC constant (16 bits) */
75+#define QMC_GBL_C_MASK16 0xA0
76+
77+/* TSA entry (16bit entry in TSATRX and TSATTX) */
78+#define QMC_TSA_VALID (1 << 15)
79+#define QMC_TSA_WRAP (1 << 14)
80+#define QMC_TSA_MASK (0x303F)
81+#define QMC_TSA_CHANNEL(x) ((x) << 6)
82+
83+/* Tx buffer descriptor base address (16 bits, offset from MCBASE) */
84+#define QMC_SPE_TBASE 0x00
85+
86+/* Channel mode register (16 bits) */
87+#define QMC_SPE_CHAMR 0x02
88+#define QMC_SPE_CHAMR_MODE_HDLC (1 << 15)
89+#define QMC_SPE_CHAMR_MODE_TRANSP ((0 << 15) | (1 << 13))
90+#define QMC_SPE_CHAMR_ENT (1 << 12)
91+#define QMC_SPE_CHAMR_POL (1 << 8)
92+#define QMC_SPE_CHAMR_HDLC_IDLM (1 << 13)
93+#define QMC_SPE_CHAMR_HDLC_CRC (1 << 7)
94+#define QMC_SPE_CHAMR_HDLC_NOF (0x0f << 0)
95+#define QMC_SPE_CHAMR_TRANSP_RD (1 << 14)
96+#define QMC_SPE_CHAMR_TRANSP_SYNC (1 << 10)
97+
98+/* Tx internal state (32 bits) */
99+#define QMC_SPE_TSTATE 0x04
100+/* Tx buffer descriptor pointer (16 bits) */
101+#define QMC_SPE_TBPTR 0x0C
102+/* Zero-insertion state (32 bits) */
103+#define QMC_SPE_ZISTATE 0x14
104+/* Channel’s interrupt mask flags (16 bits) */
105+#define QMC_SPE_INTMSK 0x1C
106+/* Rx buffer descriptor base address (16 bits, offset from MCBASE) */
107+#define QMC_SPE_RBASE 0x20
108+/* HDLC: Maximum frame length register (16 bits) */
109+#define QMC_SPE_MFLR 0x22
110+/* TRANSPARENT: Transparent maximum receive length (16 bits) */
111+#define QMC_SPE_TMRBLR 0x22
112+/* Rx internal state (32 bits) */
113+#define QMC_SPE_RSTATE 0x24
114+/* Rx buffer descriptor pointer (16 bits) */
115+#define QMC_SPE_RBPTR 0x2C
116+/* Packs 4 bytes to 1 long word before writing to buffer (32 bits) */
117+#define QMC_SPE_RPACK 0x30
118+/* Zero deletion state (32 bits) */
119+#define QMC_SPE_ZDSTATE 0x34
120+
121+/* Transparent synchronization (16 bits) */
122+#define QMC_SPE_TRNSYNC 0x3C
123+#define QMC_SPE_TRNSYNC_RX(x) ((x) << 8)
124+#define QMC_SPE_TRNSYNC_TX(x) ((x) << 0)
125+
126+/* Interrupt related registers bits */
127+#define QMC_INT_V (1 << 15)
128+#define QMC_INT_W (1 << 14)
129+#define QMC_INT_NID (1 << 13)
130+#define QMC_INT_IDL (1 << 12)
131+#define QMC_INT_GET_CHANNEL(x) (((x) & 0x0FC0) >> 6)
132+#define QMC_INT_MRF (1 << 5)
133+#define QMC_INT_UN (1 << 4)
134+#define QMC_INT_RXF (1 << 3)
135+#define QMC_INT_BSY (1 << 2)
136+#define QMC_INT_TXB (1 << 1)
137+#define QMC_INT_RXB (1 << 0)
138+
139+/* BD related registers bits */
140+#define QMC_BD_RX_E (1 << 15)
141+#define QMC_BD_RX_W (1 << 13)
142+#define QMC_BD_RX_I (1 << 12)
143+#define QMC_BD_RX_L (1 << 11)
144+#define QMC_BD_RX_F (1 << 10)
145+#define QMC_BD_RX_CM (1 << 9)
146+#define QMC_BD_RX_UB (1 << 7)
147+#define QMC_BD_RX_LG (1 << 5)
148+#define QMC_BD_RX_NO (1 << 4)
149+#define QMC_BD_RX_AB (1 << 3)
150+#define QMC_BD_RX_CR (1 << 2)
151+
152+#define QMC_BD_TX_R (1 << 15)
153+#define QMC_BD_TX_W (1 << 13)
154+#define QMC_BD_TX_I (1 << 12)
155+#define QMC_BD_TX_L (1 << 11)
156+#define QMC_BD_TX_TC (1 << 10)
157+#define QMC_BD_TX_CM (1 << 9)
158+#define QMC_BD_TX_UB (1 << 7)
159+#define QMC_BD_TX_PAD (0x0f << 0)
160+
161+/* Numbers of BDs and interrupt items */
162+#define QMC_NB_TXBDS 8
163+#define QMC_NB_RXBDS 8
164+#define QMC_NB_INTS 128
165+
166+struct qmc_xfer_desc {
167+ union {
168+ void (*tx_complete)(void *context);
169+ void (*rx_complete)(void *context, size_t length);
170+ };
171+ void *context;
172+};
173+
174+struct qmc_chan {
175+ struct list_head list;
176+ unsigned int id;
177+ struct qmc *qmc;
178+ void *__iomem s_param;
179+ enum qmc_mode mode;
180+ u64 tx_ts_mask;
181+ u64 rx_ts_mask;
182+ bool is_reverse_data;
183+
184+ spinlock_t tx_lock;
185+ cbd_t __iomem *txbds;
186+ cbd_t __iomem *txbd_free;
187+ cbd_t __iomem *txbd_done;
188+ struct qmc_xfer_desc tx_desc[QMC_NB_TXBDS];
189+ u64 nb_tx_underrun;
190+ bool is_tx_stopped;
191+
192+ spinlock_t rx_lock;
193+ cbd_t __iomem *rxbds;
194+ cbd_t __iomem *rxbd_free;
195+ cbd_t __iomem *rxbd_done;
196+ struct qmc_xfer_desc rx_desc[QMC_NB_RXBDS];
197+ u64 nb_rx_busy;
198+ int rx_pending;
199+ bool is_rx_halted;
200+ bool is_rx_stopped;
201+};
202+
203+struct qmc {
204+ struct device *dev;
205+ struct tsa_serial *tsa_serial;
206+ void *__iomem scc_regs;
207+ void *__iomem scc_pram;
208+ void *__iomem dpram;
209+ u16 scc_pram_offset;
210+ cbd_t __iomem *bd_table;
211+ dma_addr_t bd_dma_addr;
212+ size_t bd_size;
213+ u16 __iomem *int_table;
214+ u16 __iomem *int_curr;
215+ dma_addr_t int_dma_addr;
216+ size_t int_size;
217+ struct list_head chan_head;
218+ struct qmc_chan *chans[64];
219+};
220+
221+static inline void qmc_write16(void *__iomem addr, u16 val)
222+{
223+ iowrite16be(val, addr);
224+}
225+
226+static inline u16 qmc_read16(void *__iomem addr)
227+{
228+ return ioread16be(addr);
229+}
230+
231+static inline void qmc_setbits16(void *__iomem addr, u16 set)
232+{
233+ qmc_write16(addr, qmc_read16(addr) | set);
234+}
235+
236+static inline void qmc_clrbits16(void *__iomem addr, u16 clr)
237+{
238+ qmc_write16(addr, qmc_read16(addr) & ~clr);
239+}
240+
241+static inline void qmc_write32(void *__iomem addr, u32 val)
242+{
243+ iowrite32be(val, addr);
244+}
245+
246+static inline u32 qmc_read32(void *__iomem addr)
247+{
248+ return ioread32be(addr);
249+}
250+
251+static inline void qmc_setbits32(void *__iomem addr, u32 set)
252+{
253+ qmc_write32(addr, qmc_read32(addr) | set);
254+}
255+
256+
257+int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info)
258+{
259+ struct tsa_serial_info tsa_info;
260+ int ret;
261+
262+ /* Retrieve info from the TSA related serial */
263+ ret = tsa_serial_get_info(chan->qmc->tsa_serial, &tsa_info);
264+ if (ret)
265+ return ret;
266+
267+ info->mode = chan->mode;
268+ info->rx_fs_rate = tsa_info.rx_fs_rate;
269+ info->rx_bit_rate = tsa_info.rx_bit_rate;
270+ info->nb_tx_ts = hweight64(chan->tx_ts_mask);
271+ info->tx_fs_rate = tsa_info.tx_fs_rate;
272+ info->tx_bit_rate = tsa_info.tx_bit_rate;
273+ info->nb_rx_ts = hweight64(chan->rx_ts_mask);
274+
275+ return 0;
276+}
277+EXPORT_SYMBOL(qmc_chan_get_info);
278+
279+int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param)
280+{
281+ if (param->mode != chan->mode)
282+ return -EINVAL;
283+
284+ switch (param->mode) {
285+ case QMC_HDLC:
286+ if ((param->hdlc.max_rx_buf_size % 4) ||
287+ (param->hdlc.max_rx_buf_size < 8))
288+ return -EINVAL;
289+
290+ qmc_write16(chan->qmc->scc_pram + QMC_GBL_MRBLR,
291+ param->hdlc.max_rx_buf_size - 8);
292+ qmc_write16(chan->s_param + QMC_SPE_MFLR,
293+ param->hdlc.max_rx_frame_size);
294+ if (param->hdlc.is_crc32) {
295+ qmc_setbits16(chan->s_param + QMC_SPE_CHAMR,
296+ QMC_SPE_CHAMR_HDLC_CRC);
297+ } else {
298+ qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR,
299+ QMC_SPE_CHAMR_HDLC_CRC);
300+ }
301+ break;
302+
303+ case QMC_TRANSPARENT:
304+ qmc_write16(chan->s_param + QMC_SPE_TMRBLR,
305+ param->transp.max_rx_buf_size);
306+ break;
307+
308+ default:
309+ return -EINVAL;
310+ }
311+
312+ return 0;
313+}
314+EXPORT_SYMBOL(qmc_chan_set_param);
315+
316+int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
317+ void (*complete)(void *context), void *context)
318+{
319+ struct qmc_xfer_desc *xfer_desc;
320+ unsigned long flags;
321+ cbd_t *__iomem bd;
322+ u16 ctrl;
323+ int ret;
324+
325+ /*
326+ * R bit UB bit
327+ * 0 0 : The BD is free
328+ * 1 1 : The BD is in used, waiting for transfer
329+ * 0 1 : The BD is in used, waiting for completion
330+ * 1 0 : Should not append
331+ */
332+
333+ spin_lock_irqsave(&chan->tx_lock, flags);
334+ bd = chan->txbd_free;
335+
336+ ctrl = qmc_read16(&bd->cbd_sc);
337+ if (ctrl & (QMC_BD_TX_R | QMC_BD_TX_UB)) {
338+ /* We are full ... */
339+ ret = -EBUSY;
340+ goto end;
341+ }
342+
343+ qmc_write16(&bd->cbd_datlen, length);
344+ qmc_write32(&bd->cbd_bufaddr, addr);
345+
346+ xfer_desc = &chan->tx_desc[bd - chan->txbds];
347+ xfer_desc->tx_complete = complete;
348+ xfer_desc->context = context;
349+
350+ /* Activate the descriptor */
351+ ctrl |= (QMC_BD_TX_R | QMC_BD_TX_UB);
352+ wmb(); /* Be sure to flush the descriptor before control update */
353+ qmc_write16(&bd->cbd_sc, ctrl);
354+
355+ if (!chan->is_tx_stopped)
356+ qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL);
357+
358+ if (ctrl & QMC_BD_TX_W)
359+ chan->txbd_free = chan->txbds;
360+ else
361+ chan->txbd_free++;
362+
363+ ret = 0;
364+
365+end:
366+ spin_unlock_irqrestore(&chan->tx_lock, flags);
367+ return ret;
368+}
369+EXPORT_SYMBOL(qmc_chan_write_submit);
370+
371+static void qmc_chan_write_done(struct qmc_chan *chan)
372+{
373+ struct qmc_xfer_desc *xfer_desc;
374+ void (*complete)(void *context);
375+ unsigned long flags;
376+ void *context;
377+ cbd_t *__iomem bd;
378+ u16 ctrl;
379+
380+ /*
381+ * R bit UB bit
382+ * 0 0 : The BD is free
383+ * 1 1 : The BD is in used, waiting for transfer
384+ * 0 1 : The BD is in used, waiting for completion
385+ * 1 0 : Should not append
386+ */
387+
388+ spin_lock_irqsave(&chan->tx_lock, flags);
389+ bd = chan->txbd_done;
390+
391+ ctrl = qmc_read16(&bd->cbd_sc);
392+ while (!(ctrl & QMC_BD_TX_R)) {
393+ if (!(ctrl & QMC_BD_TX_UB))
394+ goto end;
395+
396+ xfer_desc = &chan->tx_desc[bd - chan->txbds];
397+ complete = xfer_desc->tx_complete;
398+ context = xfer_desc->context;
399+ xfer_desc->tx_complete = NULL;
400+ xfer_desc->context = NULL;
401+
402+ qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_TX_UB);
403+
404+ if (ctrl & QMC_BD_TX_W)
405+ chan->txbd_done = chan->txbds;
406+ else
407+ chan->txbd_done++;
408+
409+ if (complete) {
410+ spin_unlock_irqrestore(&chan->tx_lock, flags);
411+ complete(context);
412+ spin_lock_irqsave(&chan->tx_lock, flags);
413+ }
414+
415+ bd = chan->txbd_done;
416+ ctrl = qmc_read16(&bd->cbd_sc);
417+ }
418+
419+end:
420+ spin_unlock_irqrestore(&chan->tx_lock, flags);
421+}
422+
423+int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
424+ void (*complete)(void *context, size_t length), void *context)
425+{
426+ struct qmc_xfer_desc *xfer_desc;
427+ unsigned long flags;
428+ cbd_t *__iomem bd;
429+ u16 ctrl;
430+ int ret;
431+
432+ /*
433+ * E bit UB bit
434+ * 0 0 : The BD is free
435+ * 1 1 : The BD is in used, waiting for transfer
436+ * 0 1 : The BD is in used, waiting for completion
437+ * 1 0 : Should not append
438+ */
439+
440+ spin_lock_irqsave(&chan->rx_lock, flags);
441+ bd = chan->rxbd_free;
442+
443+ ctrl = qmc_read16(&bd->cbd_sc);
444+ if (ctrl & (QMC_BD_RX_E | QMC_BD_RX_UB)) {
445+ /* We are full ... */
446+ ret = -EBUSY;
447+ goto end;
448+ }
449+
450+ qmc_write16(&bd->cbd_datlen, 0); /* data length is updated by the QMC */
451+ qmc_write32(&bd->cbd_bufaddr, addr);
452+
453+ xfer_desc = &chan->rx_desc[bd - chan->rxbds];
454+ xfer_desc->rx_complete = complete;
455+ xfer_desc->context = context;
456+
457+ /* Activate the descriptor */
458+ ctrl |= (QMC_BD_RX_E | QMC_BD_RX_UB);
459+ wmb(); /* Be sure to flush data before descriptor activation */
460+ qmc_write16(&bd->cbd_sc, ctrl);
461+
462+ /* Restart receiver if needed */
463+ if (chan->is_rx_halted && !chan->is_rx_stopped) {
464+ /* Restart receiver */
465+ if (chan->mode == QMC_TRANSPARENT)
466+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
467+ else
468+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
469+ qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
470+ chan->is_rx_halted = false;
471+ }
472+ chan->rx_pending++;
473+
474+ if (ctrl & QMC_BD_RX_W)
475+ chan->rxbd_free = chan->rxbds;
476+ else
477+ chan->rxbd_free++;
478+
479+ ret = 0;
480+end:
481+ spin_unlock_irqrestore(&chan->rx_lock, flags);
482+ return ret;
483+}
484+EXPORT_SYMBOL(qmc_chan_read_submit);
485+
486+static void qmc_chan_read_done(struct qmc_chan *chan)
487+{
488+ void (*complete)(void *context, size_t size);
489+ struct qmc_xfer_desc *xfer_desc;
490+ unsigned long flags;
491+ cbd_t *__iomem bd;
492+ void *context;
493+ u16 datalen;
494+ u16 ctrl;
495+
496+ /*
497+ * E bit UB bit
498+ * 0 0 : The BD is free
499+ * 1 1 : The BD is in used, waiting for transfer
500+ * 0 1 : The BD is in used, waiting for completion
501+ * 1 0 : Should not append
502+ */
503+
504+ spin_lock_irqsave(&chan->rx_lock, flags);
505+ bd = chan->rxbd_done;
506+
507+ ctrl = qmc_read16(&bd->cbd_sc);
508+ while (!(ctrl & QMC_BD_RX_E)) {
509+ if (!(ctrl & QMC_BD_RX_UB))
510+ goto end;
511+
512+ xfer_desc = &chan->rx_desc[bd - chan->rxbds];
513+ complete = xfer_desc->rx_complete;
514+ context = xfer_desc->context;
515+ xfer_desc->rx_complete = NULL;
516+ xfer_desc->context = NULL;
517+
518+ datalen = qmc_read16(&bd->cbd_datlen);
519+ qmc_write16(&bd->cbd_sc, ctrl & ~QMC_BD_RX_UB);
520+
521+ if (ctrl & QMC_BD_RX_W)
522+ chan->rxbd_done = chan->rxbds;
523+ else
524+ chan->rxbd_done++;
525+
526+ chan->rx_pending--;
527+
528+ if (complete) {
529+ spin_unlock_irqrestore(&chan->rx_lock, flags);
530+ complete(context, datalen);
531+ spin_lock_irqsave(&chan->rx_lock, flags);
532+ }
533+
534+ bd = chan->rxbd_done;
535+ ctrl = qmc_read16(&bd->cbd_sc);
536+ }
537+
538+end:
539+ spin_unlock_irqrestore(&chan->rx_lock, flags);
540+}
541+
542+static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
543+{
544+ return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E);
545+}
546+
547+static int qmc_chan_stop_rx(struct qmc_chan *chan)
548+{
549+ unsigned long flags;
550+ int ret;
551+
552+ spin_lock_irqsave(&chan->rx_lock, flags);
553+
554+ /* Send STOP RECEIVE command */
555+ ret = qmc_chan_command(chan, 0x0);
556+ if (ret) {
557+ dev_err(chan->qmc->dev, "chan %u: Send STOP RECEIVE failed (%d)\n",
558+ chan->id, ret);
559+ goto end;
560+ }
561+
562+ chan->is_rx_stopped = true;
563+
564+end:
565+ spin_unlock_irqrestore(&chan->rx_lock, flags);
566+ return ret;
567+}
568+
569+static int qmc_chan_stop_tx(struct qmc_chan *chan)
570+{
571+ unsigned long flags;
572+ int ret;
573+
574+ spin_lock_irqsave(&chan->tx_lock, flags);
575+
576+ /* Send STOP TRANSMIT command */
577+ ret = qmc_chan_command(chan, 0x1);
578+ if (ret) {
579+ dev_err(chan->qmc->dev, "chan %u: Send STOP TRANSMIT failed (%d)\n",
580+ chan->id, ret);
581+ goto end;
582+ }
583+
584+ chan->is_tx_stopped = true;
585+
586+end:
587+ spin_unlock_irqrestore(&chan->tx_lock, flags);
588+ return ret;
589+}
590+
591+int qmc_chan_stop(struct qmc_chan *chan, int direction)
592+{
593+ int ret;
594+
595+ if (direction & QMC_CHAN_READ) {
596+ ret = qmc_chan_stop_rx(chan);
597+ if (ret)
598+ return ret;
599+ }
600+
601+ if (direction & QMC_CHAN_WRITE) {
602+ ret = qmc_chan_stop_tx(chan);
603+ if (ret)
604+ return ret;
605+ }
606+
607+ return 0;
608+}
609+EXPORT_SYMBOL(qmc_chan_stop);
610+
611+static void qmc_chan_start_rx(struct qmc_chan *chan)
612+{
613+ unsigned long flags;
614+
615+ spin_lock_irqsave(&chan->rx_lock, flags);
616+
617+ /* Restart the receiver */
618+ if (chan->mode == QMC_TRANSPARENT)
619+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
620+ else
621+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
622+ qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
623+ chan->is_rx_halted = false;
624+
625+ chan->is_rx_stopped = false;
626+
627+ spin_unlock_irqrestore(&chan->rx_lock, flags);
628+}
629+
630+static void qmc_chan_start_tx(struct qmc_chan *chan)
631+{
632+ unsigned long flags;
633+
634+ spin_lock_irqsave(&chan->tx_lock, flags);
635+
636+ /*
637+ * Enable channel transmitter as it could be disabled if
638+ * qmc_chan_reset() was called.
639+ */
640+ qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT);
641+
642+ /* Set the POL bit in the channel mode register */
643+ qmc_setbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_POL);
644+
645+ chan->is_tx_stopped = false;
646+
647+ spin_unlock_irqrestore(&chan->tx_lock, flags);
648+}
649+
650+int qmc_chan_start(struct qmc_chan *chan, int direction)
651+{
652+ if (direction & QMC_CHAN_READ)
653+ qmc_chan_start_rx(chan);
654+
655+ if (direction & QMC_CHAN_WRITE)
656+ qmc_chan_start_tx(chan);
657+
658+ return 0;
659+}
660+EXPORT_SYMBOL(qmc_chan_start);
661+
662+static void qmc_chan_reset_rx(struct qmc_chan *chan)
663+{
664+ struct qmc_xfer_desc *xfer_desc;
665+ unsigned long flags;
666+ cbd_t *__iomem bd;
667+ u16 ctrl;
668+
669+ spin_lock_irqsave(&chan->rx_lock, flags);
670+ bd = chan->rxbds;
671+ do {
672+ ctrl = qmc_read16(&bd->cbd_sc);
673+ qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_RX_UB | QMC_BD_RX_E));
674+
675+ xfer_desc = &chan->rx_desc[bd - chan->rxbds];
676+ xfer_desc->rx_complete = NULL;
677+ xfer_desc->context = NULL;
678+
679+ bd++;
680+ } while (!(ctrl & QMC_BD_RX_W));
681+
682+ chan->rxbd_free = chan->rxbds;
683+ chan->rxbd_done = chan->rxbds;
684+ qmc_write16(chan->s_param + QMC_SPE_RBPTR,
685+ qmc_read16(chan->s_param + QMC_SPE_RBASE));
686+
687+ chan->rx_pending = 0;
688+ chan->is_rx_stopped = false;
689+
690+ spin_unlock_irqrestore(&chan->rx_lock, flags);
691+}
692+
693+static void qmc_chan_reset_tx(struct qmc_chan *chan)
694+{
695+ struct qmc_xfer_desc *xfer_desc;
696+ unsigned long flags;
697+ cbd_t *__iomem bd;
698+ u16 ctrl;
699+
700+ spin_lock_irqsave(&chan->tx_lock, flags);
701+
702+ /* Disable transmitter. It will be re-enable on qmc_chan_start() */
703+ qmc_clrbits16(chan->s_param + QMC_SPE_CHAMR, QMC_SPE_CHAMR_ENT);
704+
705+ bd = chan->txbds;
706+ do {
707+ ctrl = qmc_read16(&bd->cbd_sc);
708+ qmc_write16(&bd->cbd_sc, ctrl & ~(QMC_BD_TX_UB | QMC_BD_TX_R));
709+
710+ xfer_desc = &chan->tx_desc[bd - chan->txbds];
711+ xfer_desc->tx_complete = NULL;
712+ xfer_desc->context = NULL;
713+
714+ bd++;
715+ } while (!(ctrl & QMC_BD_TX_W));
716+
717+ chan->txbd_free = chan->txbds;
718+ chan->txbd_done = chan->txbds;
719+ qmc_write16(chan->s_param + QMC_SPE_TBPTR,
720+ qmc_read16(chan->s_param + QMC_SPE_TBASE));
721+
722+ /* Reset TSTATE and ZISTATE to their initial value */
723+ qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000);
724+ qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100);
725+
726+ spin_unlock_irqrestore(&chan->tx_lock, flags);
727+}
728+
729+int qmc_chan_reset(struct qmc_chan *chan, int direction)
730+{
731+ if (direction & QMC_CHAN_READ)
732+ qmc_chan_reset_rx(chan);
733+
734+ if (direction & QMC_CHAN_WRITE)
735+ qmc_chan_reset_tx(chan);
736+
737+ return 0;
738+}
739+EXPORT_SYMBOL(qmc_chan_reset);
740+
741+static int qmc_check_chans(struct qmc *qmc)
742+{
743+ struct tsa_serial_info info;
744+ bool is_one_table = false;
745+ struct qmc_chan *chan;
746+ u64 tx_ts_mask = 0;
747+ u64 rx_ts_mask = 0;
748+ u64 tx_ts_assigned_mask;
749+ u64 rx_ts_assigned_mask;
750+ int ret;
751+
752+ /* Retrieve info from the TSA related serial */
753+ ret = tsa_serial_get_info(qmc->tsa_serial, &info);
754+ if (ret)
755+ return ret;
756+
757+ if ((info.nb_tx_ts > 64) || (info.nb_rx_ts > 64)) {
758+ dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned not supported\n");
759+ return -EINVAL;
760+ }
761+
762+ /*
763+ * If more than 32 TS are assigned to this serial, one common table is
764+ * used for Tx and Rx and so masks must be equal for all channels.
765+ */
766+ if ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) {
767+ if (info.nb_tx_ts != info.nb_rx_ts) {
768+ dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are not equal\n");
769+ return -EINVAL;
770+ }
771+ is_one_table = true;
772+ }
773+
774+ tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_tx_ts) - 1;
775+ rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_rx_ts) - 1;
776+
777+ list_for_each_entry(chan, &qmc->chan_head, list) {
778+ if (chan->tx_ts_mask > tx_ts_assigned_mask) {
779+ dev_err(qmc->dev, "chan %u uses TSA unassigned Tx TS\n", chan->id);
780+ return -EINVAL;
781+ }
782+ if (tx_ts_mask & chan->tx_ts_mask) {
783+ dev_err(qmc->dev, "chan %u uses an already used Tx TS\n", chan->id);
784+ return -EINVAL;
785+ }
786+
787+ if (chan->rx_ts_mask > rx_ts_assigned_mask) {
788+ dev_err(qmc->dev, "chan %u uses TSA unassigned Rx TS\n", chan->id);
789+ return -EINVAL;
790+ }
791+ if (rx_ts_mask & chan->rx_ts_mask) {
792+ dev_err(qmc->dev, "chan %u uses an already used Rx TS\n", chan->id);
793+ return -EINVAL;
794+ }
795+
796+ if (is_one_table && (chan->tx_ts_mask != chan->rx_ts_mask)) {
797+ dev_err(qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id);
798+ return -EINVAL;
799+ }
800+
801+ tx_ts_mask |= chan->tx_ts_mask;
802+ rx_ts_mask |= chan->rx_ts_mask;
803+ }
804+
805+ return 0;
806+}
807+
808+static unsigned int qmc_nb_chans(struct qmc *qmc)
809+{
810+ unsigned int count = 0;
811+ struct qmc_chan *chan;
812+
813+ list_for_each_entry(chan, &qmc->chan_head, list)
814+ count++;
815+
816+ return count;
817+}
818+
819+static int qmc_of_parse_chans(struct qmc *qmc, struct device_node *np)
820+{
821+ struct device_node *chan_np;
822+ struct qmc_chan *chan;
823+ const char *mode;
824+ u32 chan_id;
825+ u64 ts_mask;
826+ int ret;
827+
828+ for_each_available_child_of_node(np, chan_np) {
829+ ret = of_property_read_u32(chan_np, "reg", &chan_id);
830+ if (ret) {
831+ dev_err(qmc->dev, "%pOF: failed to read reg\n", chan_np);
832+ of_node_put(chan_np);
833+ return ret;
834+ }
835+ if (chan_id > 63) {
836+ dev_err(qmc->dev, "%pOF: Invalid chan_id\n", chan_np);
837+ of_node_put(chan_np);
838+ return -EINVAL;
839+ }
840+
841+ chan = devm_kzalloc(qmc->dev, sizeof(*chan), GFP_KERNEL);
842+ if (!chan) {
843+ of_node_put(chan_np);
844+ return -ENOMEM;
845+ }
846+
847+ chan->id = chan_id;
848+ spin_lock_init(&chan->rx_lock);
849+ spin_lock_init(&chan->tx_lock);
850+
851+ ret = of_property_read_u64(chan_np, "fsl,tx-ts-mask", &ts_mask);
852+ if (ret) {
853+ dev_err(qmc->dev, "%pOF: failed to read fsl,tx-ts-mask\n",
854+ chan_np);
855+ of_node_put(chan_np);
856+ return ret;
857+ }
858+ chan->tx_ts_mask = ts_mask;
859+
860+ ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", &ts_mask);
861+ if (ret) {
862+ dev_err(qmc->dev, "%pOF: failed to read fsl,rx-ts-mask\n",
863+ chan_np);
864+ of_node_put(chan_np);
865+ return ret;
866+ }
867+ chan->rx_ts_mask = ts_mask;
868+
869+ mode = "transparent";
870+ ret = of_property_read_string(chan_np, "fsl,operational-mode", &mode);
871+ if (ret && ret != -EINVAL) {
872+ dev_err(qmc->dev, "%pOF: failed to read fsl,operational-mode\n",
873+ chan_np);
874+ of_node_put(chan_np);
875+ return ret;
876+ }
877+ if (!strcmp(mode, "transparent")) {
878+ chan->mode = QMC_TRANSPARENT;
879+ } else if (!strcmp(mode, "hdlc")) {
880+ chan->mode = QMC_HDLC;
881+ } else {
882+ dev_err(qmc->dev, "%pOF: Invalid fsl,operational-mode (%s)\n",
883+ chan_np, mode);
884+ of_node_put(chan_np);
885+ return -EINVAL;
886+ }
887+
888+ chan->is_reverse_data = of_property_read_bool(chan_np,
889+ "fsl,reverse-data");
890+
891+ list_add_tail(&chan->list, &qmc->chan_head);
892+ qmc->chans[chan->id] = chan;
893+ }
894+
895+ return qmc_check_chans(qmc);
896+}
897+
898+static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *info)
899+{
900+ struct qmc_chan *chan;
901+ unsigned int i;
902+ u16 val;
903+
904+ /*
905+ * Use a common Tx/Rx 64 entries table.
906+ * Everything was previously checked, Tx and Rx related stuffs are
907+ * identical -> Used Rx related stuff to build the table
908+ */
909+
910+ /* Invalidate all entries */
911+ for (i = 0; i < 64; i++)
912+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000);
913+
914+ /* Set entries based on Rx stuff*/
915+ list_for_each_entry(chan, &qmc->chan_head, list) {
916+ for (i = 0; i < info->nb_rx_ts; i++) {
917+ if (!(chan->rx_ts_mask & (((u64)1) << i)))
918+ continue;
919+
920+ val = QMC_TSA_VALID | QMC_TSA_MASK |
921+ QMC_TSA_CHANNEL(chan->id);
922+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), val);
923+ }
924+ }
925+
926+ /* Set Wrap bit on last entry */
927+ qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2),
928+ QMC_TSA_WRAP);
929+
930+ /* Init pointers to the table */
931+ val = qmc->scc_pram_offset + QMC_GBL_TSATRX;
932+ qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val);
933+ qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val);
934+ qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val);
935+ qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val);
936+
937+ return 0;
938+}
939+
940+static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info *info)
941+{
942+ struct qmc_chan *chan;
943+ unsigned int i;
944+ u16 val;
945+
946+ /*
947+ * Use a Tx 32 entries table and a Rx 32 entries table.
948+ * Everything was previously checked.
949+ */
950+
951+ /* Invalidate all entries */
952+ for (i = 0; i < 32; i++) {
953+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), 0x0000);
954+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), 0x0000);
955+ }
956+
957+ /* Set entries based on Rx and Tx stuff*/
958+ list_for_each_entry(chan, &qmc->chan_head, list) {
959+ /* Rx part */
960+ for (i = 0; i < info->nb_rx_ts; i++) {
961+ if (!(chan->rx_ts_mask & (((u64)1) << i)))
962+ continue;
963+
964+ val = QMC_TSA_VALID | QMC_TSA_MASK |
965+ QMC_TSA_CHANNEL(chan->id);
966+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), val);
967+ }
968+ /* Tx part */
969+ for (i = 0; i < info->nb_tx_ts; i++) {
970+ if (!(chan->tx_ts_mask & (((u64)1) << i)))
971+ continue;
972+
973+ val = QMC_TSA_VALID | QMC_TSA_MASK |
974+ QMC_TSA_CHANNEL(chan->id);
975+ qmc_write16(qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), val);
976+ }
977+ }
978+
979+ /* Set Wrap bit on last entries */
980+ qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATRX + ((info->nb_rx_ts - 1) * 2),
981+ QMC_TSA_WRAP);
982+ qmc_setbits16(qmc->scc_pram + QMC_GBL_TSATTX + ((info->nb_tx_ts - 1) * 2),
983+ QMC_TSA_WRAP);
984+
985+ /* Init Rx pointers ...*/
986+ val = qmc->scc_pram_offset + QMC_GBL_TSATRX;
987+ qmc_write16(qmc->scc_pram + QMC_GBL_RX_S_PTR, val);
988+ qmc_write16(qmc->scc_pram + QMC_GBL_RXPTR, val);
989+
990+ /* ... and Tx pointers */
991+ val = qmc->scc_pram_offset + QMC_GBL_TSATTX;
992+ qmc_write16(qmc->scc_pram + QMC_GBL_TX_S_PTR, val);
993+ qmc_write16(qmc->scc_pram + QMC_GBL_TXPTR, val);
994+
995+ return 0;
996+}
997+
998+static int qmc_setup_tsa(struct qmc *qmc)
999+{
1000+ struct tsa_serial_info info;
1001+ int ret;
1002+
1003+ /* Retrieve info from the TSA related serial */
1004+ ret = tsa_serial_get_info(qmc->tsa_serial, &info);
1005+ if (ret)
1006+ return ret;
1007+
1008+ /*
1009+ * Setup one common 64 entries table or two 32 entries (one for Tx and
1010+ * one for Tx) according to assigned TS numbers.
1011+ */
1012+ return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
1013+ qmc_setup_tsa_64rxtx(qmc, &info) :
1014+ qmc_setup_tsa_32rx_32tx(qmc, &info);
1015+}
1016+
1017+static int qmc_setup_chan_trnsync(struct qmc *qmc, struct qmc_chan *chan)
1018+{
1019+ struct tsa_serial_info info;
1020+ u16 first_rx, last_tx;
1021+ u16 trnsync;
1022+ int ret;
1023+
1024+ /* Retrieve info from the TSA related serial */
1025+ ret = tsa_serial_get_info(chan->qmc->tsa_serial, &info);
1026+ if (ret)
1027+ return ret;
1028+
1029+ /* Find the first Rx TS allocated to the channel */
1030+ first_rx = chan->rx_ts_mask ? __ffs64(chan->rx_ts_mask) + 1 : 0;
1031+
1032+ /* Find the last Tx TS allocated to the channel */
1033+ last_tx = fls64(chan->tx_ts_mask);
1034+
1035+ trnsync = 0;
1036+ if (info.nb_rx_ts)
1037+ trnsync |= QMC_SPE_TRNSYNC_RX((first_rx % info.nb_rx_ts) * 2);
1038+ if (info.nb_tx_ts)
1039+ trnsync |= QMC_SPE_TRNSYNC_TX((last_tx % info.nb_tx_ts) * 2);
1040+
1041+ qmc_write16(chan->s_param + QMC_SPE_TRNSYNC, trnsync);
1042+
1043+ dev_dbg(qmc->dev, "chan %u: trnsync=0x%04x, rx %u/%u 0x%llx, tx %u/%u 0x%llx\n",
1044+ chan->id, trnsync,
1045+ first_rx, info.nb_rx_ts, chan->rx_ts_mask,
1046+ last_tx, info.nb_tx_ts, chan->tx_ts_mask);
1047+
1048+ return 0;
1049+}
1050+
1051+static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan)
1052+{
1053+ unsigned int i;
1054+ cbd_t __iomem *bd;
1055+ int ret;
1056+ u16 val;
1057+
1058+ chan->qmc = qmc;
1059+
1060+ /* Set channel specific parameter base address */
1061+ chan->s_param = qmc->dpram + (chan->id * 64);
1062+ /* 16 bd per channel (8 rx and 8 tx) */
1063+ chan->txbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS));
1064+ chan->rxbds = qmc->bd_table + (chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS;
1065+
1066+ chan->txbd_free = chan->txbds;
1067+ chan->txbd_done = chan->txbds;
1068+ chan->rxbd_free = chan->rxbds;
1069+ chan->rxbd_done = chan->rxbds;
1070+
1071+ /* TBASE and TBPTR*/
1072+ val = chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS) * sizeof(cbd_t);
1073+ qmc_write16(chan->s_param + QMC_SPE_TBASE, val);
1074+ qmc_write16(chan->s_param + QMC_SPE_TBPTR, val);
1075+
1076+ /* RBASE and RBPTR*/
1077+ val = ((chan->id * (QMC_NB_TXBDS + QMC_NB_RXBDS)) + QMC_NB_TXBDS) * sizeof(cbd_t);
1078+ qmc_write16(chan->s_param + QMC_SPE_RBASE, val);
1079+ qmc_write16(chan->s_param + QMC_SPE_RBPTR, val);
1080+ qmc_write32(chan->s_param + QMC_SPE_TSTATE, 0x30000000);
1081+ qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
1082+ qmc_write32(chan->s_param + QMC_SPE_ZISTATE, 0x00000100);
1083+ if (chan->mode == QMC_TRANSPARENT) {
1084+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
1085+ qmc_write16(chan->s_param + QMC_SPE_TMRBLR, 60);
1086+ val = QMC_SPE_CHAMR_MODE_TRANSP | QMC_SPE_CHAMR_TRANSP_SYNC;
1087+ if (chan->is_reverse_data)
1088+ val |= QMC_SPE_CHAMR_TRANSP_RD;
1089+ qmc_write16(chan->s_param + QMC_SPE_CHAMR, val);
1090+ ret = qmc_setup_chan_trnsync(qmc, chan);
1091+ if (ret)
1092+ return ret;
1093+ } else {
1094+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
1095+ qmc_write16(chan->s_param + QMC_SPE_MFLR, 60);
1096+ qmc_write16(chan->s_param + QMC_SPE_CHAMR,
1097+ QMC_SPE_CHAMR_MODE_HDLC | QMC_SPE_CHAMR_HDLC_IDLM);
1098+ }
1099+
1100+ /* Do not enable interrupts now. They will be enabled later */
1101+ qmc_write16(chan->s_param + QMC_SPE_INTMSK, 0x0000);
1102+
1103+ /* Init Rx BDs and set Wrap bit on last descriptor */
1104+ BUILD_BUG_ON(QMC_NB_RXBDS == 0);
1105+ val = QMC_BD_RX_I;
1106+ for (i = 0; i < QMC_NB_RXBDS; i++) {
1107+ bd = chan->rxbds + i;
1108+ qmc_write16(&bd->cbd_sc, val);
1109+ }
1110+ bd = chan->rxbds + QMC_NB_RXBDS - 1;
1111+ qmc_write16(&bd->cbd_sc, val | QMC_BD_RX_W);
1112+
1113+ /* Init Tx BDs and set Wrap bit on last descriptor */
1114+ BUILD_BUG_ON(QMC_NB_TXBDS == 0);
1115+ val = QMC_BD_TX_I;
1116+ if (chan->mode == QMC_HDLC)
1117+ val |= QMC_BD_TX_L | QMC_BD_TX_TC;
1118+ for (i = 0; i < QMC_NB_TXBDS; i++) {
1119+ bd = chan->txbds + i;
1120+ qmc_write16(&bd->cbd_sc, val);
1121+ }
1122+ bd = chan->txbds + QMC_NB_TXBDS - 1;
1123+ qmc_write16(&bd->cbd_sc, val | QMC_BD_TX_W);
1124+
1125+ return 0;
1126+}
1127+
1128+static int qmc_setup_chans(struct qmc *qmc)
1129+{
1130+ struct qmc_chan *chan;
1131+ int ret;
1132+
1133+ list_for_each_entry(chan, &qmc->chan_head, list) {
1134+ ret = qmc_setup_chan(qmc, chan);
1135+ if (ret)
1136+ return ret;
1137+ }
1138+
1139+ return 0;
1140+}
1141+
1142+static int qmc_finalize_chans(struct qmc *qmc)
1143+{
1144+ struct qmc_chan *chan;
1145+ int ret;
1146+
1147+ list_for_each_entry(chan, &qmc->chan_head, list) {
1148+ /* Unmask channel interrupts */
1149+ if (chan->mode == QMC_HDLC) {
1150+ qmc_write16(chan->s_param + QMC_SPE_INTMSK,
1151+ QMC_INT_NID | QMC_INT_IDL | QMC_INT_MRF |
1152+ QMC_INT_UN | QMC_INT_RXF | QMC_INT_BSY |
1153+ QMC_INT_TXB | QMC_INT_RXB);
1154+ } else {
1155+ qmc_write16(chan->s_param + QMC_SPE_INTMSK,
1156+ QMC_INT_UN | QMC_INT_BSY |
1157+ QMC_INT_TXB | QMC_INT_RXB);
1158+ }
1159+
1160+ /* Forced stop the channel */
1161+ ret = qmc_chan_stop(chan, QMC_CHAN_ALL);
1162+ if (ret)
1163+ return ret;
1164+ }
1165+
1166+ return 0;
1167+}
1168+
1169+static int qmc_setup_ints(struct qmc *qmc)
1170+{
1171+ unsigned int i;
1172+ u16 __iomem *last;
1173+
1174+ /* Raz all entries */
1175+ for (i = 0; i < (qmc->int_size / sizeof(u16)); i++)
1176+ qmc_write16(qmc->int_table + i, 0x0000);
1177+
1178+ /* Set Wrap bit on last entry */
1179+ if (qmc->int_size >= sizeof(u16)) {
1180+ last = qmc->int_table + (qmc->int_size / sizeof(u16)) - 1;
1181+ qmc_write16(last, QMC_INT_W);
1182+ }
1183+
1184+ return 0;
1185+}
1186+
1187+static void qmc_irq_gint(struct qmc *qmc)
1188+{
1189+ struct qmc_chan *chan;
1190+ unsigned int chan_id;
1191+ unsigned long flags;
1192+ u16 int_entry;
1193+
1194+ int_entry = qmc_read16(qmc->int_curr);
1195+ while (int_entry & QMC_INT_V) {
1196+ /* Clear all but the Wrap bit */
1197+ qmc_write16(qmc->int_curr, int_entry & QMC_INT_W);
1198+
1199+ chan_id = QMC_INT_GET_CHANNEL(int_entry);
1200+ chan = qmc->chans[chan_id];
1201+ if (!chan) {
1202+ dev_err(qmc->dev, "interrupt on invalid chan %u\n", chan_id);
1203+ goto int_next;
1204+ }
1205+
1206+ if (int_entry & QMC_INT_TXB)
1207+ qmc_chan_write_done(chan);
1208+
1209+ if (int_entry & QMC_INT_UN) {
1210+ dev_info(qmc->dev, "intr chan %u, 0x%04x (UN)\n", chan_id,
1211+ int_entry);
1212+ chan->nb_tx_underrun++;
1213+ }
1214+
1215+ if (int_entry & QMC_INT_BSY) {
1216+ dev_info(qmc->dev, "intr chan %u, 0x%04x (BSY)\n", chan_id,
1217+ int_entry);
1218+ chan->nb_rx_busy++;
1219+ /* Restart the receiver if needed */
1220+ spin_lock_irqsave(&chan->rx_lock, flags);
1221+ if (chan->rx_pending && !chan->is_rx_stopped) {
1222+ if (chan->mode == QMC_TRANSPARENT)
1223+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x18000080);
1224+ else
1225+ qmc_write32(chan->s_param + QMC_SPE_ZDSTATE, 0x00000080);
1226+ qmc_write32(chan->s_param + QMC_SPE_RSTATE, 0x31000000);
1227+ chan->is_rx_halted = false;
1228+ } else {
1229+ chan->is_rx_halted = true;
1230+ }
1231+ spin_unlock_irqrestore(&chan->rx_lock, flags);
1232+ }
1233+
1234+ if (int_entry & QMC_INT_RXB)
1235+ qmc_chan_read_done(chan);
1236+
1237+int_next:
1238+ if (int_entry & QMC_INT_W)
1239+ qmc->int_curr = qmc->int_table;
1240+ else
1241+ qmc->int_curr++;
1242+ int_entry = qmc_read16(qmc->int_curr);
1243+ }
1244+}
1245+
1246+static irqreturn_t qmc_irq_handler(int irq, void *priv)
1247+{
1248+ struct qmc *qmc = (struct qmc *)priv;
1249+ u16 scce;
1250+
1251+ scce = qmc_read16(qmc->scc_regs + SCC_SCCE);
1252+ qmc_write16(qmc->scc_regs + SCC_SCCE, scce);
1253+
1254+ if (unlikely(scce & SCC_SCCE_IQOV))
1255+ dev_info(qmc->dev, "IRQ queue overflow\n");
1256+
1257+ if (unlikely(scce & SCC_SCCE_GUN))
1258+ dev_err(qmc->dev, "Global transmitter underrun\n");
1259+
1260+ if (unlikely(scce & SCC_SCCE_GOV))
1261+ dev_err(qmc->dev, "Global receiver overrun\n");
1262+
1263+ /* normal interrupt */
1264+ if (likely(scce & SCC_SCCE_GINT))
1265+ qmc_irq_gint(qmc);
1266+
1267+ return IRQ_HANDLED;
1268+}
1269+
1270+static int qmc_probe(struct platform_device *pdev)
1271+{
1272+ struct device_node *np = pdev->dev.of_node;
1273+ unsigned int nb_chans;
1274+ struct resource *res;
1275+ struct qmc *qmc;
1276+ int irq;
1277+ int ret;
1278+
1279+ qmc = devm_kzalloc(&pdev->dev, sizeof(*qmc), GFP_KERNEL);
1280+ if (!qmc)
1281+ return -ENOMEM;
1282+
1283+ qmc->dev = &pdev->dev;
1284+ INIT_LIST_HEAD(&qmc->chan_head);
1285+
1286+ qmc->scc_regs = devm_platform_ioremap_resource_byname(pdev, "scc_regs");
1287+ if (IS_ERR(qmc->scc_regs))
1288+ return PTR_ERR(qmc->scc_regs);
1289+
1290+
1291+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "scc_pram");
1292+ if (!res)
1293+ return -EINVAL;
1294+ qmc->scc_pram_offset = res->start - get_immrbase();
1295+ qmc->scc_pram = devm_ioremap_resource(qmc->dev, res);
1296+ if (IS_ERR(qmc->scc_pram))
1297+ return PTR_ERR(qmc->scc_pram);
1298+
1299+ qmc->dpram = devm_platform_ioremap_resource_byname(pdev, "dpram");
1300+ if (IS_ERR(qmc->dpram))
1301+ return PTR_ERR(qmc->dpram);
1302+
1303+ qmc->tsa_serial = devm_tsa_serial_get_byphandle(qmc->dev, np, "fsl,tsa-serial");
1304+ if (IS_ERR(qmc->tsa_serial)) {
1305+ return dev_err_probe(qmc->dev, PTR_ERR(qmc->tsa_serial),
1306+ "Failed to get TSA serial\n");
1307+ }
1308+
1309+ /* Connect the serial (SCC) to TSA */
1310+ ret = tsa_serial_connect(qmc->tsa_serial);
1311+ if (ret) {
1312+ dev_err(qmc->dev, "Failed to connect TSA serial\n");
1313+ return ret;
1314+ }
1315+
1316+ /* Parse channels informationss */
1317+ ret = qmc_of_parse_chans(qmc, np);
1318+ if (ret)
1319+ goto err_tsa_serial_disconnect;
1320+
1321+ nb_chans = qmc_nb_chans(qmc);
1322+
1323+ /* Init GMSR_H and GMSR_L registers */
1324+ qmc_write32(qmc->scc_regs + SCC_GSMRH,
1325+ SCC_GSMRH_CDS | SCC_GSMRH_CTSS | SCC_GSMRH_CDP | SCC_GSMRH_CTSP);
1326+
1327+ /* enable QMC mode */
1328+ qmc_write32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_MODE_QMC);
1329+
1330+ /*
1331+ * Allocate the buffer descriptor table
1332+ * 8 rx and 8 tx descriptors per channel
1333+ */
1334+ qmc->bd_size = (nb_chans * (QMC_NB_TXBDS + QMC_NB_RXBDS)) * sizeof(cbd_t);
1335+ qmc->bd_table = dmam_alloc_coherent(qmc->dev, qmc->bd_size,
1336+ &qmc->bd_dma_addr, GFP_KERNEL);
1337+ if (!qmc->bd_table) {
1338+ dev_err(qmc->dev, "Failed to allocate bd table\n");
1339+ ret = -ENOMEM;
1340+ goto err_tsa_serial_disconnect;
1341+ }
1342+ memset(qmc->bd_table, 0, qmc->bd_size);
1343+
1344+ qmc_write32(qmc->scc_pram + QMC_GBL_MCBASE, qmc->bd_dma_addr);
1345+
1346+ /* Allocate the interrupt table */
1347+ qmc->int_size = QMC_NB_INTS * sizeof(u16);
1348+ qmc->int_table = dmam_alloc_coherent(qmc->dev, qmc->int_size,
1349+ &qmc->int_dma_addr, GFP_KERNEL);
1350+ if (!qmc->int_table) {
1351+ dev_err(qmc->dev, "Failed to allocate interrupt table\n");
1352+ ret = -ENOMEM;
1353+ goto err_tsa_serial_disconnect;
1354+ }
1355+ memset(qmc->int_table, 0, qmc->int_size);
1356+
1357+ qmc->int_curr = qmc->int_table;
1358+ qmc_write32(qmc->scc_pram + QMC_GBL_INTBASE, qmc->int_dma_addr);
1359+ qmc_write32(qmc->scc_pram + QMC_GBL_INTPTR, qmc->int_dma_addr);
1360+
1361+ /* Set MRBLR (valid for HDLC only) max MRU + max CRC */
1362+ qmc_write16(qmc->scc_pram + QMC_GBL_MRBLR, HDLC_MAX_MRU + 4);
1363+
1364+ qmc_write16(qmc->scc_pram + QMC_GBL_GRFTHR, 1);
1365+ qmc_write16(qmc->scc_pram + QMC_GBL_GRFCNT, 1);
1366+
1367+ qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3);
1368+ qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8);
1369+
1370+ ret = qmc_setup_tsa(qmc);
1371+ if (ret)
1372+ goto err_tsa_serial_disconnect;
1373+
1374+ qmc_write16(qmc->scc_pram + QMC_GBL_QMCSTATE, 0x8000);
1375+
1376+ ret = qmc_setup_chans(qmc);
1377+ if (ret)
1378+ goto err_tsa_serial_disconnect;
1379+
1380+ /* Init interrupts table */
1381+ ret = qmc_setup_ints(qmc);
1382+ if (ret)
1383+ goto err_tsa_serial_disconnect;
1384+
1385+ /* Disable and clear interrupts, set the irq handler */
1386+ qmc_write16(qmc->scc_regs + SCC_SCCM, 0x0000);
1387+ qmc_write16(qmc->scc_regs + SCC_SCCE, 0x000F);
1388+ irq = platform_get_irq(pdev, 0);
1389+ if (irq < 0)
1390+ goto err_tsa_serial_disconnect;
1391+ ret = devm_request_irq(qmc->dev, irq, qmc_irq_handler, 0, "qmc", qmc);
1392+ if (ret < 0)
1393+ goto err_tsa_serial_disconnect;
1394+
1395+ /* Enable interrupts */
1396+ qmc_write16(qmc->scc_regs + SCC_SCCM,
1397+ SCC_SCCE_IQOV | SCC_SCCE_GINT | SCC_SCCE_GUN | SCC_SCCE_GOV);
1398+
1399+ ret = qmc_finalize_chans(qmc);
1400+ if (ret < 0)
1401+ goto err_disable_intr;
1402+
1403+ /* Enable transmiter and receiver */
1404+ qmc_setbits32(qmc->scc_regs + SCC_GSMRL, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
1405+
1406+ platform_set_drvdata(pdev, qmc);
1407+
1408+ return 0;
1409+
1410+err_disable_intr:
1411+ qmc_write16(qmc->scc_regs + SCC_SCCM, 0);
1412+
1413+err_tsa_serial_disconnect:
1414+ tsa_serial_disconnect(qmc->tsa_serial);
1415+ return ret;
1416+}
1417+
1418+static int qmc_remove(struct platform_device *pdev)
1419+{
1420+ struct qmc *qmc = platform_get_drvdata(pdev);
1421+
1422+ /* Disable transmiter and receiver */
1423+ qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0);
1424+
1425+ /* Disable interrupts */
1426+ qmc_write16(qmc->scc_regs + SCC_SCCM, 0);
1427+
1428+ /* Disconnect the serial from TSA */
1429+ tsa_serial_disconnect(qmc->tsa_serial);
1430+
1431+ return 0;
1432+}
1433+
1434+static const struct of_device_id qmc_id_table[] = {
1435+ { .compatible = "fsl,cpm1-scc-qmc" },
1436+ {} /* sentinel */
1437+};
1438+MODULE_DEVICE_TABLE(of, qmc_id_table);
1439+
1440+static struct platform_driver qmc_driver = {
1441+ .driver = {
1442+ .name = "fsl-qmc",
1443+ .of_match_table = of_match_ptr(qmc_id_table),
1444+ },
1445+ .probe = qmc_probe,
1446+ .remove = qmc_remove,
1447+};
1448+module_platform_driver(qmc_driver);
1449+
1450+struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name)
1451+{
1452+ struct of_phandle_args out_args;
1453+ struct platform_device *pdev;
1454+ struct qmc_chan *qmc_chan;
1455+ struct qmc *qmc;
1456+ int ret;
1457+
1458+ ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0,
1459+ &out_args);
1460+ if (ret < 0)
1461+ return ERR_PTR(ret);
1462+
1463+ if (!of_match_node(qmc_driver.driver.of_match_table, out_args.np)) {
1464+ of_node_put(out_args.np);
1465+ return ERR_PTR(-EINVAL);
1466+ }
1467+
1468+ pdev = of_find_device_by_node(out_args.np);
1469+ of_node_put(out_args.np);
1470+ if (!pdev)
1471+ return ERR_PTR(-ENODEV);
1472+
1473+ qmc = platform_get_drvdata(pdev);
1474+ if (!qmc) {
1475+ platform_device_put(pdev);
1476+ return ERR_PTR(-EPROBE_DEFER);
1477+ }
1478+
1479+ if (out_args.args_count != 1) {
1480+ platform_device_put(pdev);
1481+ return ERR_PTR(-EINVAL);
1482+ }
1483+
1484+ if (out_args.args[0] >= ARRAY_SIZE(qmc->chans)) {
1485+ platform_device_put(pdev);
1486+ return ERR_PTR(-EINVAL);
1487+ }
1488+
1489+ qmc_chan = qmc->chans[out_args.args[0]];
1490+ if (!qmc_chan) {
1491+ platform_device_put(pdev);
1492+ return ERR_PTR(-ENOENT);
1493+ }
1494+
1495+ return qmc_chan;
1496+}
1497+EXPORT_SYMBOL(qmc_chan_get_byphandle);
1498+
1499+void qmc_chan_put(struct qmc_chan *chan)
1500+{
1501+ put_device(chan->qmc->dev);
1502+}
1503+EXPORT_SYMBOL(qmc_chan_put);
1504+
1505+static void devm_qmc_chan_release(struct device *dev, void *res)
1506+{
1507+ struct qmc_chan **qmc_chan = res;
1508+
1509+ qmc_chan_put(*qmc_chan);
1510+}
1511+
1512+struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev,
1513+ struct device_node *np,
1514+ const char *phandle_name)
1515+{
1516+ struct qmc_chan *qmc_chan;
1517+ struct qmc_chan **dr;
1518+
1519+ dr = devres_alloc(devm_qmc_chan_release, sizeof(*dr), GFP_KERNEL);
1520+ if (!dr)
1521+ return ERR_PTR(-ENOMEM);
1522+
1523+ qmc_chan = qmc_chan_get_byphandle(np, phandle_name);
1524+ if (!IS_ERR(qmc_chan)) {
1525+ *dr = qmc_chan;
1526+ devres_add(dev, dr);
1527+ } else {
1528+ devres_free(dr);
1529+ }
1530+
1531+ return qmc_chan;
1532+}
1533+EXPORT_SYMBOL(devm_qmc_chan_get_byphandle);
1534+
1535+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
1536+MODULE_DESCRIPTION("CPM QMC driver");
1537+MODULE_LICENSE("GPL");
drivers/soc/fsl/qe/tsa.c+846−0
@@ -0,0 +1,846 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * TSA driver
4+ *
5+ * Copyright 2022 CS GROUP France
6+ *
7+ * Author: Herve Codina <herve.codina@bootlin.com>
8+ */
9+
10+#include "tsa.h"
11+#include <dt-bindings/soc/cpm1-fsl,tsa.h>
12+#include <linux/clk.h>
13+#include <linux/io.h>
14+#include <linux/module.h>
15+#include <linux/of.h>
16+#include <linux/of_platform.h>
17+#include <linux/platform_device.h>
18+#include <linux/slab.h>
19+
20+
21+/* TSA SI RAM routing tables entry */
22+#define TSA_SIRAM_ENTRY_LAST (1 << 16)
23+#define TSA_SIRAM_ENTRY_BYTE (1 << 17)
24+#define TSA_SIRAM_ENTRY_CNT(x) (((x) & 0x0f) << 18)
25+#define TSA_SIRAM_ENTRY_CSEL_MASK (0x7 << 22)
26+#define TSA_SIRAM_ENTRY_CSEL_NU (0x0 << 22)
27+#define TSA_SIRAM_ENTRY_CSEL_SCC2 (0x2 << 22)
28+#define TSA_SIRAM_ENTRY_CSEL_SCC3 (0x3 << 22)
29+#define TSA_SIRAM_ENTRY_CSEL_SCC4 (0x4 << 22)
30+#define TSA_SIRAM_ENTRY_CSEL_SMC1 (0x5 << 22)
31+#define TSA_SIRAM_ENTRY_CSEL_SMC2 (0x6 << 22)
32+
33+/* SI mode register (32 bits) */
34+#define TSA_SIMODE 0x00
35+#define TSA_SIMODE_SMC2 0x80000000
36+#define TSA_SIMODE_SMC1 0x00008000
37+#define TSA_SIMODE_TDMA(x) ((x) << 0)
38+#define TSA_SIMODE_TDMB(x) ((x) << 16)
39+#define TSA_SIMODE_TDM_MASK 0x0fff
40+#define TSA_SIMODE_TDM_SDM_MASK 0x0c00
41+#define TSA_SIMODE_TDM_SDM_NORM 0x0000
42+#define TSA_SIMODE_TDM_SDM_ECHO 0x0400
43+#define TSA_SIMODE_TDM_SDM_INTL_LOOP 0x0800
44+#define TSA_SIMODE_TDM_SDM_LOOP_CTRL 0x0c00
45+#define TSA_SIMODE_TDM_RFSD(x) ((x) << 8)
46+#define TSA_SIMODE_TDM_DSC 0x0080
47+#define TSA_SIMODE_TDM_CRT 0x0040
48+#define TSA_SIMODE_TDM_STZ 0x0020
49+#define TSA_SIMODE_TDM_CE 0x0010
50+#define TSA_SIMODE_TDM_FE 0x0008
51+#define TSA_SIMODE_TDM_GM 0x0004
52+#define TSA_SIMODE_TDM_TFSD(x) ((x) << 0)
53+
54+/* SI global mode register (8 bits) */
55+#define TSA_SIGMR 0x04
56+#define TSA_SIGMR_ENB (1<<3)
57+#define TSA_SIGMR_ENA (1<<2)
58+#define TSA_SIGMR_RDM_MASK 0x03
59+#define TSA_SIGMR_RDM_STATIC_TDMA 0x00
60+#define TSA_SIGMR_RDM_DYN_TDMA 0x01
61+#define TSA_SIGMR_RDM_STATIC_TDMAB 0x02
62+#define TSA_SIGMR_RDM_DYN_TDMAB 0x03
63+
64+/* SI status register (8 bits) */
65+#define TSA_SISTR 0x06
66+
67+/* SI command register (8 bits) */
68+#define TSA_SICMR 0x07
69+
70+/* SI clock route register (32 bits) */
71+#define TSA_SICR 0x0C
72+#define TSA_SICR_SCC2(x) ((x) << 8)
73+#define TSA_SICR_SCC3(x) ((x) << 16)
74+#define TSA_SICR_SCC4(x) ((x) << 24)
75+#define TSA_SICR_SCC_MASK 0x0ff
76+#define TSA_SICR_SCC_GRX (1 << 7)
77+#define TSA_SICR_SCC_SCX_TSA (1 << 6)
78+#define TSA_SICR_SCC_RXCS_MASK (0x7 << 3)
79+#define TSA_SICR_SCC_RXCS_BRG1 (0x0 << 3)
80+#define TSA_SICR_SCC_RXCS_BRG2 (0x1 << 3)
81+#define TSA_SICR_SCC_RXCS_BRG3 (0x2 << 3)
82+#define TSA_SICR_SCC_RXCS_BRG4 (0x3 << 3)
83+#define TSA_SICR_SCC_RXCS_CLK15 (0x4 << 3)
84+#define TSA_SICR_SCC_RXCS_CLK26 (0x5 << 3)
85+#define TSA_SICR_SCC_RXCS_CLK37 (0x6 << 3)
86+#define TSA_SICR_SCC_RXCS_CLK48 (0x7 << 3)
87+#define TSA_SICR_SCC_TXCS_MASK (0x7 << 0)
88+#define TSA_SICR_SCC_TXCS_BRG1 (0x0 << 0)
89+#define TSA_SICR_SCC_TXCS_BRG2 (0x1 << 0)
90+#define TSA_SICR_SCC_TXCS_BRG3 (0x2 << 0)
91+#define TSA_SICR_SCC_TXCS_BRG4 (0x3 << 0)
92+#define TSA_SICR_SCC_TXCS_CLK15 (0x4 << 0)
93+#define TSA_SICR_SCC_TXCS_CLK26 (0x5 << 0)
94+#define TSA_SICR_SCC_TXCS_CLK37 (0x6 << 0)
95+#define TSA_SICR_SCC_TXCS_CLK48 (0x7 << 0)
96+
97+/* Serial interface RAM pointer register (32 bits) */
98+#define TSA_SIRP 0x10
99+
100+struct tsa_entries_area {
101+ void *__iomem entries_start;
102+ void *__iomem entries_next;
103+ void *__iomem last_entry;
104+};
105+
106+struct tsa_tdm {
107+ bool is_enable;
108+ struct clk *l1rclk_clk;
109+ struct clk *l1rsync_clk;
110+ struct clk *l1tclk_clk;
111+ struct clk *l1tsync_clk;
112+ u32 simode_tdm;
113+};
114+
115+#define TSA_TDMA 0
116+#define TSA_TDMB 1
117+
118+struct tsa {
119+ struct device *dev;
120+ void *__iomem si_regs;
121+ void *__iomem si_ram;
122+ resource_size_t si_ram_sz;
123+ spinlock_t lock;
124+ int tdms; /* TSA_TDMx ORed */
125+ struct tsa_tdm tdm[2]; /* TDMa and TDMb */
126+ struct tsa_serial {
127+ unsigned int id;
128+ struct tsa_serial_info info;
129+ } serials[6];
130+};
131+
132+static inline struct tsa *tsa_serial_get_tsa(struct tsa_serial *tsa_serial)
133+{
134+ /* The serials table is indexed by the serial id */
135+ return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]);
136+}
137+
138+static inline void tsa_write32(void *__iomem addr, u32 val)
139+{
140+ iowrite32be(val, addr);
141+}
142+
143+static inline void tsa_write8(void *__iomem addr, u32 val)
144+{
145+ iowrite8(val, addr);
146+}
147+
148+static inline u32 tsa_read32(void *__iomem addr)
149+{
150+ return ioread32be(addr);
151+}
152+
153+static inline void tsa_clrbits32(void *__iomem addr, u32 clr)
154+{
155+ tsa_write32(addr, tsa_read32(addr) & ~clr);
156+}
157+
158+static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set)
159+{
160+ tsa_write32(addr, (tsa_read32(addr) & ~clr) | set);
161+}
162+
163+int tsa_serial_connect(struct tsa_serial *tsa_serial)
164+{
165+ struct tsa *tsa = tsa_serial_get_tsa(tsa_serial);
166+ unsigned long flags;
167+ u32 clear;
168+ u32 set;
169+
170+ switch (tsa_serial->id) {
171+ case FSL_CPM_TSA_SCC2:
172+ clear = TSA_SICR_SCC2(TSA_SICR_SCC_MASK);
173+ set = TSA_SICR_SCC2(TSA_SICR_SCC_SCX_TSA);
174+ break;
175+ case FSL_CPM_TSA_SCC3:
176+ clear = TSA_SICR_SCC3(TSA_SICR_SCC_MASK);
177+ set = TSA_SICR_SCC3(TSA_SICR_SCC_SCX_TSA);
178+ break;
179+ case FSL_CPM_TSA_SCC4:
180+ clear = TSA_SICR_SCC4(TSA_SICR_SCC_MASK);
181+ set = TSA_SICR_SCC4(TSA_SICR_SCC_SCX_TSA);
182+ break;
183+ default:
184+ dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id);
185+ return -EINVAL;
186+ }
187+
188+ spin_lock_irqsave(&tsa->lock, flags);
189+ tsa_clrsetbits32(tsa->si_regs + TSA_SICR, clear, set);
190+ spin_unlock_irqrestore(&tsa->lock, flags);
191+
192+ return 0;
193+}
194+EXPORT_SYMBOL(tsa_serial_connect);
195+
196+int tsa_serial_disconnect(struct tsa_serial *tsa_serial)
197+{
198+ struct tsa *tsa = tsa_serial_get_tsa(tsa_serial);
199+ unsigned long flags;
200+ u32 clear;
201+
202+ switch (tsa_serial->id) {
203+ case FSL_CPM_TSA_SCC2:
204+ clear = TSA_SICR_SCC2(TSA_SICR_SCC_MASK);
205+ break;
206+ case FSL_CPM_TSA_SCC3:
207+ clear = TSA_SICR_SCC3(TSA_SICR_SCC_MASK);
208+ break;
209+ case FSL_CPM_TSA_SCC4:
210+ clear = TSA_SICR_SCC4(TSA_SICR_SCC_MASK);
211+ break;
212+ default:
213+ dev_err(tsa->dev, "Unsupported serial id %u\n", tsa_serial->id);
214+ return -EINVAL;
215+ }
216+
217+ spin_lock_irqsave(&tsa->lock, flags);
218+ tsa_clrsetbits32(tsa->si_regs + TSA_SICR, clear, 0);
219+ spin_unlock_irqrestore(&tsa->lock, flags);
220+
221+ return 0;
222+}
223+EXPORT_SYMBOL(tsa_serial_disconnect);
224+
225+int tsa_serial_get_info(struct tsa_serial *tsa_serial, struct tsa_serial_info *info)
226+{
227+ memcpy(info, &tsa_serial->info, sizeof(*info));
228+ return 0;
229+}
230+EXPORT_SYMBOL(tsa_serial_get_info);
231+
232+static void tsa_init_entries_area(struct tsa *tsa, struct tsa_entries_area *area,
233+ u32 tdms, u32 tdm_id, bool is_rx)
234+{
235+ resource_size_t quarter;
236+ resource_size_t half;
237+
238+ quarter = tsa->si_ram_sz/4;
239+ half = tsa->si_ram_sz/2;
240+
241+ if (tdms == BIT(TSA_TDMA)) {
242+ /* Only TDMA */
243+ if (is_rx) {
244+ /* First half of si_ram */
245+ area->entries_start = tsa->si_ram;
246+ area->entries_next = area->entries_start + half;
247+ area->last_entry = NULL;
248+ } else {
249+ /* Second half of si_ram */
250+ area->entries_start = tsa->si_ram + half;
251+ area->entries_next = area->entries_start + half;
252+ area->last_entry = NULL;
253+ }
254+ } else {
255+ /* Only TDMB or both TDMs */
256+ if (tdm_id == TSA_TDMA) {
257+ if (is_rx) {
258+ /* First half of first half of si_ram */
259+ area->entries_start = tsa->si_ram;
260+ area->entries_next = area->entries_start + quarter;
261+ area->last_entry = NULL;
262+ } else {
263+ /* First half of second half of si_ram */
264+ area->entries_start = tsa->si_ram + (2 * quarter);
265+ area->entries_next = area->entries_start + quarter;
266+ area->last_entry = NULL;
267+ }
268+ } else {
269+ if (is_rx) {
270+ /* Second half of first half of si_ram */
271+ area->entries_start = tsa->si_ram + quarter;
272+ area->entries_next = area->entries_start + quarter;
273+ area->last_entry = NULL;
274+ } else {
275+ /* Second half of second half of si_ram */
276+ area->entries_start = tsa->si_ram + (3 * quarter);
277+ area->entries_next = area->entries_start + quarter;
278+ area->last_entry = NULL;
279+ }
280+ }
281+ }
282+}
283+
284+static const char *tsa_serial_id2name(struct tsa *tsa, u32 serial_id)
285+{
286+ switch (serial_id) {
287+ case FSL_CPM_TSA_NU: return "Not used";
288+ case FSL_CPM_TSA_SCC2: return "SCC2";
289+ case FSL_CPM_TSA_SCC3: return "SCC3";
290+ case FSL_CPM_TSA_SCC4: return "SCC4";
291+ case FSL_CPM_TSA_SMC1: return "SMC1";
292+ case FSL_CPM_TSA_SMC2: return "SMC2";
293+ default:
294+ break;
295+ }
296+ return NULL;
297+}
298+
299+static u32 tsa_serial_id2csel(struct tsa *tsa, u32 serial_id)
300+{
301+ switch (serial_id) {
302+ case FSL_CPM_TSA_SCC2: return TSA_SIRAM_ENTRY_CSEL_SCC2;
303+ case FSL_CPM_TSA_SCC3: return TSA_SIRAM_ENTRY_CSEL_SCC3;
304+ case FSL_CPM_TSA_SCC4: return TSA_SIRAM_ENTRY_CSEL_SCC4;
305+ case FSL_CPM_TSA_SMC1: return TSA_SIRAM_ENTRY_CSEL_SMC1;
306+ case FSL_CPM_TSA_SMC2: return TSA_SIRAM_ENTRY_CSEL_SMC2;
307+ default:
308+ break;
309+ }
310+ return TSA_SIRAM_ENTRY_CSEL_NU;
311+}
312+
313+static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area,
314+ u32 count, u32 serial_id)
315+{
316+ void *__iomem addr;
317+ u32 left;
318+ u32 val;
319+ u32 cnt;
320+ u32 nb;
321+
322+ addr = area->last_entry ? area->last_entry + 4 : area->entries_start;
323+
324+ nb = DIV_ROUND_UP(count, 8);
325+ if ((addr + (nb * 4)) > area->entries_next) {
326+ dev_err(tsa->dev, "si ram area full\n");
327+ return -ENOSPC;
328+ }
329+
330+ if (area->last_entry) {
331+ /* Clear last flag */
332+ tsa_clrbits32(area->last_entry, TSA_SIRAM_ENTRY_LAST);
333+ }
334+
335+ left = count;
336+ while (left) {
337+ val = TSA_SIRAM_ENTRY_BYTE | tsa_serial_id2csel(tsa, serial_id);
338+
339+ if (left > 16) {
340+ cnt = 16;
341+ } else {
342+ cnt = left;
343+ val |= TSA_SIRAM_ENTRY_LAST;
344+ area->last_entry = addr;
345+ }
346+ val |= TSA_SIRAM_ENTRY_CNT(cnt - 1);
347+
348+ tsa_write32(addr, val);
349+ addr += 4;
350+ left -= cnt;
351+ }
352+
353+ return 0;
354+}
355+
356+static int tsa_of_parse_tdm_route(struct tsa *tsa, struct device_node *tdm_np,
357+ u32 tdms, u32 tdm_id, bool is_rx)
358+{
359+ struct tsa_entries_area area;
360+ const char *route_name;
361+ u32 serial_id;
362+ int len, i;
363+ u32 count;
364+ const char *serial_name;
365+ struct tsa_serial_info *serial_info;
366+ struct tsa_tdm *tdm;
367+ int ret;
368+ u32 ts;
369+
370+ route_name = is_rx ? "fsl,rx-ts-routes" : "fsl,tx-ts-routes";
371+
372+ len = of_property_count_u32_elems(tdm_np, route_name);
373+ if (len < 0) {
374+ dev_err(tsa->dev, "%pOF: failed to read %s\n", tdm_np, route_name);
375+ return len;
376+ }
377+ if (len % 2 != 0) {
378+ dev_err(tsa->dev, "%pOF: wrong %s format\n", tdm_np, route_name);
379+ return -EINVAL;
380+ }
381+
382+ tsa_init_entries_area(tsa, &area, tdms, tdm_id, is_rx);
383+ ts = 0;
384+ for (i = 0; i < len; i += 2) {
385+ of_property_read_u32_index(tdm_np, route_name, i, &count);
386+ of_property_read_u32_index(tdm_np, route_name, i + 1, &serial_id);
387+
388+ if (serial_id >= ARRAY_SIZE(tsa->serials)) {
389+ dev_err(tsa->dev, "%pOF: invalid serial id (%u)\n",
390+ tdm_np, serial_id);
391+ return -EINVAL;
392+ }
393+
394+ serial_name = tsa_serial_id2name(tsa, serial_id);
395+ if (!serial_name) {
396+ dev_err(tsa->dev, "%pOF: unsupported serial id (%u)\n",
397+ tdm_np, serial_id);
398+ return -EINVAL;
399+ }
400+
401+ dev_dbg(tsa->dev, "tdm_id=%u, %s ts %u..%u -> %s\n",
402+ tdm_id, route_name, ts, ts+count-1, serial_name);
403+ ts += count;
404+
405+ ret = tsa_add_entry(tsa, &area, count, serial_id);
406+ if (ret)
407+ return ret;
408+
409+ serial_info = &tsa->serials[serial_id].info;
410+ tdm = &tsa->tdm[tdm_id];
411+ if (is_rx) {
412+ serial_info->rx_fs_rate = clk_get_rate(tdm->l1rsync_clk);
413+ serial_info->rx_bit_rate = clk_get_rate(tdm->l1rclk_clk);
414+ serial_info->nb_rx_ts += count;
415+ } else {
416+ serial_info->tx_fs_rate = tdm->l1tsync_clk ?
417+ clk_get_rate(tdm->l1tsync_clk) :
418+ clk_get_rate(tdm->l1rsync_clk);
419+ serial_info->tx_bit_rate = tdm->l1tclk_clk ?
420+ clk_get_rate(tdm->l1tclk_clk) :
421+ clk_get_rate(tdm->l1rclk_clk);
422+ serial_info->nb_tx_ts += count;
423+ }
424+ }
425+ return 0;
426+}
427+
428+static inline int tsa_of_parse_tdm_rx_route(struct tsa *tsa,
429+ struct device_node *tdm_np,
430+ u32 tdms, u32 tdm_id)
431+{
432+ return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, true);
433+}
434+
435+static inline int tsa_of_parse_tdm_tx_route(struct tsa *tsa,
436+ struct device_node *tdm_np,
437+ u32 tdms, u32 tdm_id)
438+{
439+ return tsa_of_parse_tdm_route(tsa, tdm_np, tdms, tdm_id, false);
440+}
441+
442+static int tsa_of_parse_tdms(struct tsa *tsa, struct device_node *np)
443+{
444+ struct device_node *tdm_np;
445+ struct tsa_tdm *tdm;
446+ struct clk *clk;
447+ u32 tdm_id, val;
448+ int ret;
449+ int i;
450+
451+ tsa->tdms = 0;
452+ tsa->tdm[0].is_enable = false;
453+ tsa->tdm[1].is_enable = false;
454+
455+ for_each_available_child_of_node(np, tdm_np) {
456+ ret = of_property_read_u32(tdm_np, "reg", &tdm_id);
457+ if (ret) {
458+ dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np);
459+ of_node_put(tdm_np);
460+ return ret;
461+ }
462+ switch (tdm_id) {
463+ case 0:
464+ tsa->tdms |= BIT(TSA_TDMA);
465+ break;
466+ case 1:
467+ tsa->tdms |= BIT(TSA_TDMB);
468+ break;
469+ default:
470+ dev_err(tsa->dev, "%pOF: Invalid tdm_id (%u)\n", tdm_np,
471+ tdm_id);
472+ of_node_put(tdm_np);
473+ return -EINVAL;
474+ }
475+ }
476+
477+ for_each_available_child_of_node(np, tdm_np) {
478+ ret = of_property_read_u32(tdm_np, "reg", &tdm_id);
479+ if (ret) {
480+ dev_err(tsa->dev, "%pOF: failed to read reg\n", tdm_np);
481+ of_node_put(tdm_np);
482+ return ret;
483+ }
484+
485+ tdm = &tsa->tdm[tdm_id];
486+ tdm->simode_tdm = TSA_SIMODE_TDM_SDM_NORM;
487+
488+ val = 0;
489+ ret = of_property_read_u32(tdm_np, "fsl,rx-frame-sync-delay-bits",
490+ &val);
491+ if (ret && ret != -EINVAL) {
492+ dev_err(tsa->dev,
493+ "%pOF: failed to read fsl,rx-frame-sync-delay-bits\n",
494+ tdm_np);
495+ of_node_put(tdm_np);
496+ return ret;
497+ }
498+ if (val > 3) {
499+ dev_err(tsa->dev,
500+ "%pOF: Invalid fsl,rx-frame-sync-delay-bits (%u)\n",
501+ tdm_np, val);
502+ of_node_put(tdm_np);
503+ return -EINVAL;
504+ }
505+ tdm->simode_tdm |= TSA_SIMODE_TDM_RFSD(val);
506+
507+ val = 0;
508+ ret = of_property_read_u32(tdm_np, "fsl,tx-frame-sync-delay-bits",
509+ &val);
510+ if (ret && ret != -EINVAL) {
511+ dev_err(tsa->dev,
512+ "%pOF: failed to read fsl,tx-frame-sync-delay-bits\n",
513+ tdm_np);
514+ of_node_put(tdm_np);
515+ return ret;
516+ }
517+ if (val > 3) {
518+ dev_err(tsa->dev,
519+ "%pOF: Invalid fsl,tx-frame-sync-delay-bits (%u)\n",
520+ tdm_np, val);
521+ of_node_put(tdm_np);
522+ return -EINVAL;
523+ }
524+ tdm->simode_tdm |= TSA_SIMODE_TDM_TFSD(val);
525+
526+ if (of_property_read_bool(tdm_np, "fsl,common-rxtx-pins"))
527+ tdm->simode_tdm |= TSA_SIMODE_TDM_CRT;
528+
529+ if (of_property_read_bool(tdm_np, "fsl,clock-falling-edge"))
530+ tdm->simode_tdm |= TSA_SIMODE_TDM_CE;
531+
532+ if (of_property_read_bool(tdm_np, "fsl,fsync-rising-edge"))
533+ tdm->simode_tdm |= TSA_SIMODE_TDM_FE;
534+
535+ if (of_property_read_bool(tdm_np, "fsl,double-speed-clock"))
536+ tdm->simode_tdm |= TSA_SIMODE_TDM_DSC;
537+
538+ clk = of_clk_get_by_name(tdm_np, "l1rsync");
539+ if (IS_ERR(clk)) {
540+ ret = PTR_ERR(clk);
541+ of_node_put(tdm_np);
542+ goto err;
543+ }
544+ ret = clk_prepare_enable(clk);
545+ if (ret) {
546+ clk_put(clk);
547+ of_node_put(tdm_np);
548+ goto err;
549+ }
550+ tdm->l1rsync_clk = clk;
551+
552+ clk = of_clk_get_by_name(tdm_np, "l1rclk");
553+ if (IS_ERR(clk)) {
554+ ret = PTR_ERR(clk);
555+ of_node_put(tdm_np);
556+ goto err;
557+ }
558+ ret = clk_prepare_enable(clk);
559+ if (ret) {
560+ clk_put(clk);
561+ of_node_put(tdm_np);
562+ goto err;
563+ }
564+ tdm->l1rclk_clk = clk;
565+
566+ if (!(tdm->simode_tdm & TSA_SIMODE_TDM_CRT)) {
567+ clk = of_clk_get_by_name(tdm_np, "l1tsync");
568+ if (IS_ERR(clk)) {
569+ ret = PTR_ERR(clk);
570+ of_node_put(tdm_np);
571+ goto err;
572+ }
573+ ret = clk_prepare_enable(clk);
574+ if (ret) {
575+ clk_put(clk);
576+ of_node_put(tdm_np);
577+ goto err;
578+ }
579+ tdm->l1tsync_clk = clk;
580+
581+ clk = of_clk_get_by_name(tdm_np, "l1tclk");
582+ if (IS_ERR(clk)) {
583+ ret = PTR_ERR(clk);
584+ of_node_put(tdm_np);
585+ goto err;
586+ }
587+ ret = clk_prepare_enable(clk);
588+ if (ret) {
589+ clk_put(clk);
590+ of_node_put(tdm_np);
591+ goto err;
592+ }
593+ tdm->l1tclk_clk = clk;
594+ }
595+
596+ ret = tsa_of_parse_tdm_rx_route(tsa, tdm_np, tsa->tdms, tdm_id);
597+ if (ret) {
598+ of_node_put(tdm_np);
599+ goto err;
600+ }
601+
602+ ret = tsa_of_parse_tdm_tx_route(tsa, tdm_np, tsa->tdms, tdm_id);
603+ if (ret) {
604+ of_node_put(tdm_np);
605+ goto err;
606+ }
607+
608+ tdm->is_enable = true;
609+ }
610+ return 0;
611+
612+err:
613+ for (i = 0; i < 2; i++) {
614+ if (tsa->tdm[i].l1rsync_clk) {
615+ clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
616+ clk_put(tsa->tdm[i].l1rsync_clk);
617+ }
618+ if (tsa->tdm[i].l1rclk_clk) {
619+ clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
620+ clk_put(tsa->tdm[i].l1rclk_clk);
621+ }
622+ if (tsa->tdm[i].l1tsync_clk) {
623+ clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
624+ clk_put(tsa->tdm[i].l1rsync_clk);
625+ }
626+ if (tsa->tdm[i].l1tclk_clk) {
627+ clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
628+ clk_put(tsa->tdm[i].l1rclk_clk);
629+ }
630+ }
631+ return ret;
632+}
633+
634+static void tsa_init_si_ram(struct tsa *tsa)
635+{
636+ resource_size_t i;
637+
638+ /* Fill all entries as the last one */
639+ for (i = 0; i < tsa->si_ram_sz; i += 4)
640+ tsa_write32(tsa->si_ram + i, TSA_SIRAM_ENTRY_LAST);
641+}
642+
643+static int tsa_probe(struct platform_device *pdev)
644+{
645+ struct device_node *np = pdev->dev.of_node;
646+ struct resource *res;
647+ struct tsa *tsa;
648+ unsigned int i;
649+ u32 val;
650+ int ret;
651+
652+ tsa = devm_kzalloc(&pdev->dev, sizeof(*tsa), GFP_KERNEL);
653+ if (!tsa)
654+ return -ENOMEM;
655+
656+ tsa->dev = &pdev->dev;
657+
658+ for (i = 0; i < ARRAY_SIZE(tsa->serials); i++)
659+ tsa->serials[i].id = i;
660+
661+ spin_lock_init(&tsa->lock);
662+
663+ tsa->si_regs = devm_platform_ioremap_resource_byname(pdev, "si_regs");
664+ if (IS_ERR(tsa->si_regs))
665+ return PTR_ERR(tsa->si_regs);
666+
667+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "si_ram");
668+ if (!res) {
669+ dev_err(tsa->dev, "si_ram resource missing\n");
670+ return -EINVAL;
671+ }
672+ tsa->si_ram_sz = resource_size(res);
673+ tsa->si_ram = devm_ioremap_resource(&pdev->dev, res);
674+ if (IS_ERR(tsa->si_ram))
675+ return PTR_ERR(tsa->si_ram);
676+
677+ tsa_init_si_ram(tsa);
678+
679+ ret = tsa_of_parse_tdms(tsa, np);
680+ if (ret)
681+ return ret;
682+
683+ /* Set SIMODE */
684+ val = 0;
685+ if (tsa->tdm[0].is_enable)
686+ val |= TSA_SIMODE_TDMA(tsa->tdm[0].simode_tdm);
687+ if (tsa->tdm[1].is_enable)
688+ val |= TSA_SIMODE_TDMB(tsa->tdm[1].simode_tdm);
689+
690+ tsa_clrsetbits32(tsa->si_regs + TSA_SIMODE,
691+ TSA_SIMODE_TDMA(TSA_SIMODE_TDM_MASK) |
692+ TSA_SIMODE_TDMB(TSA_SIMODE_TDM_MASK),
693+ val);
694+
695+ /* Set SIGMR */
696+ val = (tsa->tdms == BIT(TSA_TDMA)) ?
697+ TSA_SIGMR_RDM_STATIC_TDMA : TSA_SIGMR_RDM_STATIC_TDMAB;
698+ if (tsa->tdms & BIT(TSA_TDMA))
699+ val |= TSA_SIGMR_ENA;
700+ if (tsa->tdms & BIT(TSA_TDMB))
701+ val |= TSA_SIGMR_ENB;
702+ tsa_write8(tsa->si_regs + TSA_SIGMR, val);
703+
704+ platform_set_drvdata(pdev, tsa);
705+
706+ return 0;
707+}
708+
709+static int tsa_remove(struct platform_device *pdev)
710+{
711+ struct tsa *tsa = platform_get_drvdata(pdev);
712+ int i;
713+
714+ for (i = 0; i < 2; i++) {
715+ if (tsa->tdm[i].l1rsync_clk) {
716+ clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
717+ clk_put(tsa->tdm[i].l1rsync_clk);
718+ }
719+ if (tsa->tdm[i].l1rclk_clk) {
720+ clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
721+ clk_put(tsa->tdm[i].l1rclk_clk);
722+ }
723+ if (tsa->tdm[i].l1tsync_clk) {
724+ clk_disable_unprepare(tsa->tdm[i].l1rsync_clk);
725+ clk_put(tsa->tdm[i].l1rsync_clk);
726+ }
727+ if (tsa->tdm[i].l1tclk_clk) {
728+ clk_disable_unprepare(tsa->tdm[i].l1rclk_clk);
729+ clk_put(tsa->tdm[i].l1rclk_clk);
730+ }
731+ }
732+ return 0;
733+}
734+
735+static const struct of_device_id tsa_id_table[] = {
736+ { .compatible = "fsl,cpm1-tsa" },
737+ {} /* sentinel */
738+};
739+MODULE_DEVICE_TABLE(of, tsa_id_table);
740+
741+static struct platform_driver tsa_driver = {
742+ .driver = {
743+ .name = "fsl-tsa",
744+ .of_match_table = of_match_ptr(tsa_id_table),
745+ },
746+ .probe = tsa_probe,
747+ .remove = tsa_remove,
748+};
749+module_platform_driver(tsa_driver);
750+
751+struct tsa_serial *tsa_serial_get_byphandle(struct device_node *np,
752+ const char *phandle_name)
753+{
754+ struct of_phandle_args out_args;
755+ struct platform_device *pdev;
756+ struct tsa_serial *tsa_serial;
757+ struct tsa *tsa;
758+ int ret;
759+
760+ ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0, &out_args);
761+ if (ret < 0)
762+ return ERR_PTR(ret);
763+
764+ if (!of_match_node(tsa_driver.driver.of_match_table, out_args.np)) {
765+ of_node_put(out_args.np);
766+ return ERR_PTR(-EINVAL);
767+ }
768+
769+ pdev = of_find_device_by_node(out_args.np);
770+ of_node_put(out_args.np);
771+ if (!pdev)
772+ return ERR_PTR(-ENODEV);
773+
774+ tsa = platform_get_drvdata(pdev);
775+ if (!tsa) {
776+ platform_device_put(pdev);
777+ return ERR_PTR(-EPROBE_DEFER);
778+ }
779+
780+ if (out_args.args_count != 1) {
781+ platform_device_put(pdev);
782+ return ERR_PTR(-EINVAL);
783+ }
784+
785+ if (out_args.args[0] >= ARRAY_SIZE(tsa->serials)) {
786+ platform_device_put(pdev);
787+ return ERR_PTR(-EINVAL);
788+ }
789+
790+ tsa_serial = &tsa->serials[out_args.args[0]];
791+
792+ /*
793+ * Be sure that the serial id matches the phandle arg.
794+ * The tsa_serials table is indexed by serial ids. The serial id is set
795+ * during the probe() call and needs to be coherent.
796+ */
797+ if (WARN_ON(tsa_serial->id != out_args.args[0])) {
798+ platform_device_put(pdev);
799+ return ERR_PTR(-EINVAL);
800+ }
801+
802+ return tsa_serial;
803+}
804+EXPORT_SYMBOL(tsa_serial_get_byphandle);
805+
806+void tsa_serial_put(struct tsa_serial *tsa_serial)
807+{
808+ struct tsa *tsa = tsa_serial_get_tsa(tsa_serial);
809+
810+ put_device(tsa->dev);
811+}
812+EXPORT_SYMBOL(tsa_serial_put);
813+
814+static void devm_tsa_serial_release(struct device *dev, void *res)
815+{
816+ struct tsa_serial **tsa_serial = res;
817+
818+ tsa_serial_put(*tsa_serial);
819+}
820+
821+struct tsa_serial *devm_tsa_serial_get_byphandle(struct device *dev,
822+ struct device_node *np,
823+ const char *phandle_name)
824+{
825+ struct tsa_serial *tsa_serial;
826+ struct tsa_serial **dr;
827+
828+ dr = devres_alloc(devm_tsa_serial_release, sizeof(*dr), GFP_KERNEL);
829+ if (!dr)
830+ return ERR_PTR(-ENOMEM);
831+
832+ tsa_serial = tsa_serial_get_byphandle(np, phandle_name);
833+ if (!IS_ERR(tsa_serial)) {
834+ *dr = tsa_serial;
835+ devres_add(dev, dr);
836+ } else {
837+ devres_free(dr);
838+ }
839+
840+ return tsa_serial;
841+}
842+EXPORT_SYMBOL(devm_tsa_serial_get_byphandle);
843+
844+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
845+MODULE_DESCRIPTION("CPM TSA driver");
846+MODULE_LICENSE("GPL");
drivers/soc/fsl/qe/tsa.h+42−0
@@ -0,0 +1,42 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * TSA management
4+ *
5+ * Copyright 2022 CS GROUP France
6+ *
7+ * Author: Herve Codina <herve.codina@bootlin.com>
8+ */
9+#ifndef __SOC_FSL_TSA_H__
10+#define __SOC_FSL_TSA_H__
11+
12+#include <linux/types.h>
13+
14+struct device_node;
15+struct device;
16+struct tsa_serial;
17+
18+struct tsa_serial *tsa_serial_get_byphandle(struct device_node *np,
19+ const char *phandle_name);
20+void tsa_serial_put(struct tsa_serial *tsa_serial);
21+struct tsa_serial *devm_tsa_serial_get_byphandle(struct device *dev,
22+ struct device_node *np,
23+ const char *phandle_name);
24+
25+/* Connect and disconnect the TSA serial */
26+int tsa_serial_connect(struct tsa_serial *tsa_serial);
27+int tsa_serial_disconnect(struct tsa_serial *tsa_serial);
28+
29+/* Cell information */
30+struct tsa_serial_info {
31+ unsigned long rx_fs_rate;
32+ unsigned long rx_bit_rate;
33+ u8 nb_rx_ts;
34+ unsigned long tx_fs_rate;
35+ unsigned long tx_bit_rate;
36+ u8 nb_tx_ts;
37+};
38+
39+/* Get information */
40+int tsa_serial_get_info(struct tsa_serial *tsa_serial, struct tsa_serial_info *info);
41+
42+#endif /* __SOC_FSL_TSA_H__ */
include/dt-bindings/soc/cpm1-fsl,tsa.h+13−0
@@ -0,0 +1,13 @@
1+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
2+
3+#ifndef __DT_BINDINGS_SOC_FSL_TSA_H
4+#define __DT_BINDINGS_SOC_FSL_TSA_H
5+
6+#define FSL_CPM_TSA_NU 0 /* Pseuso Cell Id for not used item */
7+#define FSL_CPM_TSA_SCC2 1
8+#define FSL_CPM_TSA_SCC3 2
9+#define FSL_CPM_TSA_SCC4 3
10+#define FSL_CPM_TSA_SMC1 4
11+#define FSL_CPM_TSA_SMC2 5
12+
13+#endif
include/dt-bindings/sound/cs35l45.h+57−0
@@ -17,4 +17,61 @@ · 16 unmodified lines
1717 #define CS35L45_ASP_TX_HIZ_UNUSED 0x1
1818 #define CS35L45_ASP_TX_HIZ_DISABLED 0x2
1919
20+/*
21+ * Optional GPIOX Sub-nodes:
22+ * The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])
23+ * sub-nodes for configuring the GPIO pins.
24+ *
25+ * - gpio-dir : GPIO pin direction. Valid only when 'gpio-ctrl'
26+ * is 1.
27+ * 0 = Output
28+ * 1 = Input (Default)
29+ *
30+ * - gpio-lvl : GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0.
31+ *
32+ * 0 = Low (Default)
33+ * 1 = High
34+ *
35+ * - gpio-op-cfg : GPIO output configuration. Valid only when 'gpio-ctrl' is 1
36+ * and 'gpio-dir' is 0.
37+ *
38+ * 0 = CMOS (Default)
39+ * 1 = Open Drain
40+ *
41+ * - gpio-pol : GPIO output polarity select. Valid only when 'gpio-ctrl' is 1
42+ * and 'gpio-dir' is 0.
43+ *
44+ * 0 = Non-inverted, Active High (Default)
45+ * 1 = Inverted, Active Low
46+ *
47+ * - gpio-invert : Defines the polarity of the GPIO pin if configured
48+ * as input.
49+ *
50+ * 0 = Not inverted (Default)
51+ * 1 = Inverted
52+ *
53+ * - gpio-ctrl : Defines the function of the GPIO pin.
54+ *
55+ * GPIO1:
56+ * 0 = High impedance input (Default)
57+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
58+ * 2 = Pin acts as MDSYNC, direction controlled by MDSYNC
59+ * 3-7 = Reserved
60+ *
61+ * GPIO2:
62+ * 0 = High impedance input (Default)
63+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
64+ * 2 = Pin acts as open drain INT
65+ * 3 = Reserved
66+ * 4 = Pin acts as push-pull output INT. Active low.
67+ * 5 = Pin acts as push-pull output INT. Active high.
68+ * 6,7 = Reserved
69+ *
70+ * GPIO3:
71+ * 0 = High impedance input (Default)
72+ * 1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
73+ * 2-7 = Reserved
74+ */
75+#define CS35L45_NUM_GPIOS 0x3
76+
2077 #endif /* DT_CS35L45_H */
include/linux/firmware/cirrus/cs_dsp.h+1−0
@@ -156,6 +156,7 @@ struct cs_dsp { · 155 unmodified lines
156156 unsigned int sysclk_reg;
157157 unsigned int sysclk_mask;
158158 unsigned int sysclk_shift;
159+ bool no_core_startstop;
159160
160161 struct list_head alg_regions;
161162
include/soc/fsl/qe/qmc.h+71−0
@@ -0,0 +1,71 @@
1+/* SPDX-License-Identifier: GPL-2.0-or-later */
2+/*
3+ * QMC management
4+ *
5+ * Copyright 2022 CS GROUP France
6+ *
7+ * Author: Herve Codina <herve.codina@bootlin.com>
8+ */
9+#ifndef __SOC_FSL_QMC_H__
10+#define __SOC_FSL_QMC_H__
11+
12+#include <linux/types.h>
13+
14+struct device_node;
15+struct device;
16+struct qmc_chan;
17+
18+struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name);
19+void qmc_chan_put(struct qmc_chan *chan);
20+struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct device_node *np,
21+ const char *phandle_name);
22+
23+enum qmc_mode {
24+ QMC_TRANSPARENT,
25+ QMC_HDLC,
26+};
27+
28+struct qmc_chan_info {
29+ enum qmc_mode mode;
30+ unsigned long rx_fs_rate;
31+ unsigned long rx_bit_rate;
32+ u8 nb_rx_ts;
33+ unsigned long tx_fs_rate;
34+ unsigned long tx_bit_rate;
35+ u8 nb_tx_ts;
36+};
37+
38+int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info);
39+
40+struct qmc_chan_param {
41+ enum qmc_mode mode;
42+ union {
43+ struct {
44+ u16 max_rx_buf_size;
45+ u16 max_rx_frame_size;
46+ bool is_crc32;
47+ } hdlc;
48+ struct {
49+ u16 max_rx_buf_size;
50+ } transp;
51+ };
52+};
53+
54+int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param);
55+
56+int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
57+ void (*complete)(void *context), void *context);
58+
59+int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
60+ void (*complete)(void *context, size_t length),
61+ void *context);
62+
63+#define QMC_CHAN_READ (1<<0)
64+#define QMC_CHAN_WRITE (1<<1)
65+#define QMC_CHAN_ALL (QMC_CHAN_READ | QMC_CHAN_WRITE)
66+
67+int qmc_chan_start(struct qmc_chan *chan, int direction);
68+int qmc_chan_stop(struct qmc_chan *chan, int direction);
69+int qmc_chan_reset(struct qmc_chan *chan, int direction);
70+
71+#endif /* __SOC_FSL_QMC_H__ */
include/sound/ac97_codec.h+3−0
@@ -335,6 +335,9 @@ static inline int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, · 334 unmodified lines
335335 #ifdef CONFIG_PM
336336 void snd_ac97_suspend(struct snd_ac97 *ac97);
337337 void snd_ac97_resume(struct snd_ac97 *ac97);
338+#else
339+static inline void snd_ac97_suspend(struct snd_ac97 *ac97) {}
340+static inline void snd_ac97_resume(struct snd_ac97 *ac97) {}
338341 #endif
339342 int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
340343 unsigned int id_mask);
include/sound/cs35l41.h+12−1
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #define __CS35L41_H
1212
1313 #include <linux/regmap.h>
14+#include <linux/completion.h>
1415 #include <linux/firmware/cirrus/cs_dsp.h>
1516
1617 #define CS35L41_FIRSTREG 0x00000000
@@ -677,6 +678,7 @@ · 660 unmodified lines
677678
678679 #define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F
679680 #define CS35L36_PUP_DONE_IRQ_MASK 0xBF
681+#define CS35L41_SYNC_EN_MASK BIT(8)
680682
681683 #define CS35L41_AMP_SHORT_ERR 0x80000000
682684 #define CS35L41_BST_SHORT_ERR 0x0100
@@ -686,6 +688,7 @@ · 3 unmodified lines
686688 #define CS35L41_BST_DCM_UVP_ERR 0x80
687689 #define CS35L41_OTP_BOOT_DONE 0x02
688690 #define CS35L41_PLL_UNLOCK 0x10
691+#define CS35L41_PLL_LOCK BIT(1)
689692 #define CS35L41_OTP_BOOT_ERR 0x80000000
690693
691694 #define CS35L41_AMP_SHORT_ERR_RLS 0x02
@@ -705,6 +708,8 @@ · 13 unmodified lines
705708 #define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F
706709 #define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF
707710 #define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF
711+#define CS35L41_INT3_PLL_LOCK_SHIFT 1
712+#define CS35L41_INT3_PLL_LOCK_MASK BIT(CS35L41_INT3_PLL_LOCK_SHIFT)
708713
709714 #define CS35L41_GPIO_DIR_MASK 0x80000000
710715 #define CS35L41_GPIO_DIR_SHIFT 31
@@ -742,6 +747,11 @@ · 31 unmodified lines
742747 enum cs35l41_boost_type {
743748 CS35L41_INT_BOOST,
744749 CS35L41_EXT_BOOST,
750+ CS35L41_SHD_BOOST_ACTV,
751+ CS35L41_SHD_BOOST_PASS,
752+
753+ // Not present in Binding Documentation, so no system should use this value.
754+ // This value is only used in CLSA0100 Laptop
745755 CS35L41_EXT_BOOST_NO_VSPK_SWITCH,
746756 };
747757
@@ -891,6 +901,7 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); · 143 unmodified lines
891901 int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
892902 struct cs35l41_hw_cfg *hw_cfg);
893903 bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
894−int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable);
904+int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
905+ struct completion *pll_lock);
895906
896907 #endif /* __CS35L41_H */
include/sound/cs35l56.h+266−0
@@ -0,0 +1,266 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Common definitions for Cirrus Logic CS35L56 smart amp
4+ *
5+ * Copyright (C) 2023 Cirrus Logic, Inc. and
6+ * Cirrus Logic International Semiconductor Ltd.
7+ */
8+
9+#ifndef __CS35L56_H
10+#define __CS35L56_H
11+
12+#include <linux/firmware/cirrus/cs_dsp.h>
13+#include <linux/regulator/consumer.h>
14+#include <linux/regmap.h>
15+
16+#define CS35L56_DEVID 0x0000000
17+#define CS35L56_REVID 0x0000004
18+#define CS35L56_RELID 0x000000C
19+#define CS35L56_OTPID 0x0000010
20+#define CS35L56_SFT_RESET 0x0000020
21+#define CS35L56_GLOBAL_ENABLES 0x0002014
22+#define CS35L56_BLOCK_ENABLES 0x0002018
23+#define CS35L56_BLOCK_ENABLES2 0x000201C
24+#define CS35L56_REFCLK_INPUT 0x0002C04
25+#define CS35L56_GLOBAL_SAMPLE_RATE 0x0002C0C
26+#define CS35L56_ASP1_ENABLES1 0x0004800
27+#define CS35L56_ASP1_CONTROL1 0x0004804
28+#define CS35L56_ASP1_CONTROL2 0x0004808
29+#define CS35L56_ASP1_CONTROL3 0x000480C
30+#define CS35L56_ASP1_FRAME_CONTROL1 0x0004810
31+#define CS35L56_ASP1_FRAME_CONTROL5 0x0004820
32+#define CS35L56_ASP1_DATA_CONTROL1 0x0004830
33+#define CS35L56_ASP1_DATA_CONTROL5 0x0004840
34+#define CS35L56_DACPCM1_INPUT 0x0004C00
35+#define CS35L56_DACPCM2_INPUT 0x0004C08
36+#define CS35L56_ASP1TX1_INPUT 0x0004C20
37+#define CS35L56_ASP1TX2_INPUT 0x0004C24
38+#define CS35L56_ASP1TX3_INPUT 0x0004C28
39+#define CS35L56_ASP1TX4_INPUT 0x0004C2C
40+#define CS35L56_DSP1RX1_INPUT 0x0004C40
41+#define CS35L56_DSP1RX2_INPUT 0x0004C44
42+#define CS35L56_SWIRE_DP3_CH1_INPUT 0x0004C70
43+#define CS35L56_SWIRE_DP3_CH2_INPUT 0x0004C74
44+#define CS35L56_SWIRE_DP3_CH3_INPUT 0x0004C78
45+#define CS35L56_SWIRE_DP3_CH4_INPUT 0x0004C7C
46+#define CS35L56_IRQ1_CFG 0x000E000
47+#define CS35L56_IRQ1_STATUS 0x000E004
48+#define CS35L56_IRQ1_EINT_1 0x000E010
49+#define CS35L56_IRQ1_EINT_2 0x000E014
50+#define CS35L56_IRQ1_EINT_4 0x000E01C
51+#define CS35L56_IRQ1_EINT_8 0x000E02C
52+#define CS35L56_IRQ1_EINT_18 0x000E054
53+#define CS35L56_IRQ1_EINT_20 0x000E05C
54+#define CS35L56_IRQ1_MASK_1 0x000E090
55+#define CS35L56_IRQ1_MASK_2 0x000E094
56+#define CS35L56_IRQ1_MASK_4 0x000E09C
57+#define CS35L56_IRQ1_MASK_8 0x000E0AC
58+#define CS35L56_IRQ1_MASK_18 0x000E0D4
59+#define CS35L56_IRQ1_MASK_20 0x000E0DC
60+#define CS35L56_DSP_VIRTUAL1_MBOX_1 0x0011020
61+#define CS35L56_DSP_VIRTUAL1_MBOX_2 0x0011024
62+#define CS35L56_DSP_VIRTUAL1_MBOX_3 0x0011028
63+#define CS35L56_DSP_VIRTUAL1_MBOX_4 0x001102C
64+#define CS35L56_DSP_VIRTUAL1_MBOX_5 0x0011030
65+#define CS35L56_DSP_VIRTUAL1_MBOX_6 0x0011034
66+#define CS35L56_DSP_VIRTUAL1_MBOX_7 0x0011038
67+#define CS35L56_DSP_VIRTUAL1_MBOX_8 0x001103C
68+#define CS35L56_DSP_RESTRICT_STS1 0x00190F0
69+#define CS35L56_DSP1_XMEM_PACKED_0 0x2000000
70+#define CS35L56_DSP1_XMEM_PACKED_6143 0x2005FFC
71+#define CS35L56_DSP1_XMEM_UNPACKED32_0 0x2400000
72+#define CS35L56_DSP1_XMEM_UNPACKED32_4095 0x2403FFC
73+#define CS35L56_DSP1_SYS_INFO_ID 0x25E0000
74+#define CS35L56_DSP1_SYS_INFO_END 0x25E004C
75+#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_0 0x25E2040
76+#define CS35L56_DSP1_AHBM_WINDOW_DEBUG_1 0x25E2044
77+#define CS35L56_DSP1_XMEM_UNPACKED24_0 0x2800000
78+#define CS35L56_DSP1_HALO_STATE_A1 0x2801E58
79+#define CS35L56_DSP1_HALO_STATE 0x28021E0
80+#define CS35L56_DSP1_PM_CUR_STATE_A1 0x2804000
81+#define CS35L56_DSP1_PM_CUR_STATE 0x2804308
82+#define CS35L56_DSP1_XMEM_UNPACKED24_8191 0x2807FFC
83+#define CS35L56_DSP1_CORE_BASE 0x2B80000
84+#define CS35L56_DSP1_SCRATCH1 0x2B805C0
85+#define CS35L56_DSP1_SCRATCH2 0x2B805C8
86+#define CS35L56_DSP1_SCRATCH3 0x2B805D0
87+#define CS35L56_DSP1_SCRATCH4 0x2B805D8
88+#define CS35L56_DSP1_YMEM_PACKED_0 0x2C00000
89+#define CS35L56_DSP1_YMEM_PACKED_4604 0x2C047F0
90+#define CS35L56_DSP1_YMEM_UNPACKED32_0 0x3000000
91+#define CS35L56_DSP1_YMEM_UNPACKED32_3070 0x3002FF8
92+#define CS35L56_DSP1_YMEM_UNPACKED24_0 0x3400000
93+#define CS35L56_MAIN_RENDER_USER_MUTE 0x3400024
94+#define CS35L56_MAIN_RENDER_USER_VOLUME 0x340002C
95+#define CS35L56_MAIN_POSTURE_NUMBER 0x3400094
96+#define CS35L56_PROTECTION_STATUS 0x34000D8
97+#define CS35L56_TRANSDUCER_ACTUAL_PS 0x3400150
98+#define CS35L56_DSP1_YMEM_UNPACKED24_6141 0x3405FF4
99+#define CS35L56_DSP1_PMEM_0 0x3800000
100+#define CS35L56_DSP1_PMEM_5114 0x3804FE8
101+
102+/* DEVID */
103+#define CS35L56_DEVID_MASK 0x00FFFFFF
104+
105+/* REVID */
106+#define CS35L56_AREVID_MASK 0x000000F0
107+#define CS35L56_MTLREVID_MASK 0x0000000F
108+#define CS35L56_REVID_B0 0x000000B0
109+
110+/* ASP_ENABLES1 */
111+#define CS35L56_ASP_RX2_EN_SHIFT 17
112+#define CS35L56_ASP_RX1_EN_SHIFT 16
113+#define CS35L56_ASP_TX4_EN_SHIFT 3
114+#define CS35L56_ASP_TX3_EN_SHIFT 2
115+#define CS35L56_ASP_TX2_EN_SHIFT 1
116+#define CS35L56_ASP_TX1_EN_SHIFT 0
117+
118+/* ASP_CONTROL1 */
119+#define CS35L56_ASP_BCLK_FREQ_MASK 0x0000003F
120+#define CS35L56_ASP_BCLK_FREQ_SHIFT 0
121+
122+/* ASP_CONTROL2 */
123+#define CS35L56_ASP_RX_WIDTH_MASK 0xFF000000
124+#define CS35L56_ASP_RX_WIDTH_SHIFT 24
125+#define CS35L56_ASP_TX_WIDTH_MASK 0x00FF0000
126+#define CS35L56_ASP_TX_WIDTH_SHIFT 16
127+#define CS35L56_ASP_FMT_MASK 0x00000700
128+#define CS35L56_ASP_FMT_SHIFT 8
129+#define CS35L56_ASP_BCLK_INV_MASK 0x00000040
130+#define CS35L56_ASP_FSYNC_INV_MASK 0x00000004
131+
132+/* ASP_CONTROL3 */
133+#define CS35L56_ASP1_DOUT_HIZ_CTRL_MASK 0x00000003
134+
135+/* ASP_DATA_CONTROL1 */
136+#define CS35L56_ASP_TX_WL_MASK 0x0000003F
137+
138+/* ASP_DATA_CONTROL5 */
139+#define CS35L56_ASP_RX_WL_MASK 0x0000003F
140+
141+/* ASPTXn_INPUT */
142+#define CS35L56_ASP_TXn_SRC_MASK 0x0000007F
143+
144+/* SWIRETX[1..7]_SRC SDWTXn INPUT */
145+#define CS35L56_SWIRETXn_SRC_MASK 0x0000007F
146+
147+/* IRQ1_STATUS */
148+#define CS35L56_IRQ1_STS_MASK 0x00000001
149+
150+/* IRQ1_EINT_1 */
151+#define CS35L56_AMP_SHORT_ERR_EINT1_MASK 0x80000000
152+
153+/* IRQ1_EINT_2 */
154+#define CS35L56_DSP_VIRTUAL2_MBOX_WR_EINT1_MASK 0x00200000
155+
156+/* IRQ1_EINT_4 */
157+#define CS35L56_OTP_BOOT_DONE_MASK 0x00000002
158+
159+/* IRQ1_EINT_8 */
160+#define CS35L56_TEMP_ERR_EINT1_MASK 0x80000000
161+
162+/* Mixer input sources */
163+#define CS35L56_INPUT_SRC_NONE 0x00
164+#define CS35L56_INPUT_SRC_ASP1RX1 0x08
165+#define CS35L56_INPUT_SRC_ASP1RX2 0x09
166+#define CS35L56_INPUT_SRC_VMON 0x18
167+#define CS35L56_INPUT_SRC_IMON 0x19
168+#define CS35L56_INPUT_SRC_ERR_VOL 0x20
169+#define CS35L56_INPUT_SRC_CLASSH 0x21
170+#define CS35L56_INPUT_SRC_VDDBMON 0x28
171+#define CS35L56_INPUT_SRC_VBSTMON 0x29
172+#define CS35L56_INPUT_SRC_DSP1TX1 0x32
173+#define CS35L56_INPUT_SRC_DSP1TX2 0x33
174+#define CS35L56_INPUT_SRC_DSP1TX3 0x34
175+#define CS35L56_INPUT_SRC_DSP1TX4 0x35
176+#define CS35L56_INPUT_SRC_DSP1TX5 0x36
177+#define CS35L56_INPUT_SRC_DSP1TX6 0x37
178+#define CS35L56_INPUT_SRC_DSP1TX7 0x38
179+#define CS35L56_INPUT_SRC_DSP1TX8 0x39
180+#define CS35L56_INPUT_SRC_TEMPMON 0x3A
181+#define CS35L56_INPUT_SRC_INTERPOLATOR 0x40
182+#define CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1 0x44
183+#define CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2 0x45
184+#define CS35L56_INPUT_MASK 0x7F
185+
186+#define CS35L56_NUM_INPUT_SRC 21
187+
188+/* ASP formats */
189+#define CS35L56_ASP_FMT_DSP_A 0
190+#define CS35L56_ASP_FMT_I2S 2
191+
192+/* ASP HiZ modes */
193+#define CS35L56_ASP_UNUSED_HIZ_OFF_HIZ 3
194+
195+/* MAIN_RENDER_ACTUAL_PS */
196+#define CS35L56_PS0 0
197+#define CS35L56_PS3 3
198+
199+/* CS35L56_DSP_RESTRICT_STS1 */
200+#define CS35L56_RESTRICTED_MASK 0x7
201+
202+/* CS35L56_MAIN_RENDER_USER_MUTE */
203+#define CS35L56_MAIN_RENDER_USER_MUTE_MASK 1
204+
205+/* CS35L56_MAIN_RENDER_USER_VOLUME */
206+#define CS35L56_MAIN_RENDER_USER_VOLUME_MIN -400
207+#define CS35L56_MAIN_RENDER_USER_VOLUME_MAX 400
208+#define CS35L56_MAIN_RENDER_USER_VOLUME_MASK 0x0000FFC0
209+#define CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT 6
210+#define CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT 9
211+
212+/* CS35L56_MAIN_POSTURE_NUMBER */
213+#define CS35L56_MAIN_POSTURE_MIN 0
214+#define CS35L56_MAIN_POSTURE_MAX 255
215+#define CS35L56_MAIN_POSTURE_MASK CS35L56_MAIN_POSTURE_MAX
216+
217+/* CS35L56_PROTECTION_STATUS */
218+#define CS35L56_FIRMWARE_MISSING BIT(0)
219+
220+/* Software Values */
221+#define CS35L56_HALO_STATE_SHUTDOWN 1
222+#define CS35L56_HALO_STATE_BOOT_DONE 2
223+
224+#define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001
225+#define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002
226+#define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001
227+#define CS35L56_MBOX_CMD_WAKEUP 0x02000002
228+#define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003
229+#define CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE 0x02000004
230+#define CS35L56_MBOX_CMD_SHUTDOWN 0x02000005
231+#define CS35L56_MBOX_CMD_SYSTEM_RESET 0x02000007
232+
233+#define CS35L56_MBOX_TIMEOUT_US 5000
234+#define CS35L56_MBOX_POLL_US 250
235+
236+#define CS35L56_PS0_POLL_US 500
237+#define CS35L56_PS0_TIMEOUT_US 50000
238+#define CS35L56_PS3_POLL_US 500
239+#define CS35L56_PS3_TIMEOUT_US 300000
240+
241+#define CS35L56_CONTROL_PORT_READY_US 2200
242+#define CS35L56_HALO_STATE_POLL_US 1000
243+#define CS35L56_HALO_STATE_TIMEOUT_US 50000
244+#define CS35L56_HIBERNATE_WAKE_POLL_US 500
245+#define CS35L56_HIBERNATE_WAKE_TIMEOUT_US 5000
246+#define CS35L56_RESET_PULSE_MIN_US 1100
247+
248+#define CS35L56_SDW1_PLAYBACK_PORT 1
249+#define CS35L56_SDW1_CAPTURE_PORT 3
250+
251+#define CS35L56_NUM_BULK_SUPPLIES 3
252+#define CS35L56_NUM_DSP_REGIONS 5
253+
254+extern struct regmap_config cs35l56_regmap_i2c;
255+extern struct regmap_config cs35l56_regmap_spi;
256+extern struct regmap_config cs35l56_regmap_sdw;
257+
258+extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
259+extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
260+extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
261+
262+void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap);
263+int cs35l56_get_bclk_freq_id(unsigned int freq);
264+void cs35l56_fill_supply_names(struct regulator_bulk_data *data);
265+
266+#endif /* ifndef __CS35L56_H */
include/sound/emu10k1.h+344−389
@@ -25,13 +25,9 @@ · 24 unmodified lines
2525 /* ------------------- DEFINES -------------------- */
2626
2727 #define EMUPAGESIZE 4096
28−#define MAXREQVOICES 8
2928 #define MAXPAGES0 4096 /* 32 bit mode */
3029 #define MAXPAGES1 8192 /* 31 bit mode */
31−#define RESERVED 0
32−#define NUM_MIDI 16
3330 #define NUM_G 64 /* use all channels */
34−#define NUM_FXSENDS 4
3531 #define NUM_EFX_PLAYBACK 16
3632
3733 /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
@@ -39,7 +35,6 @@ · 1 unmodified line
3935 #define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */
4036
4137 #define TMEMSIZE 256*1024
42−#define TMEMSIZEREG 4
4338
4439 #define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
4540
@@ -66,8 +61,8 @@ · 20 unmodified lines
6661 /* the relevant bits and zero to the other bits */
6762 #define IPR_P16V 0x80000000 /* Bit set when the CA0151 P16V chip wishes
6863 to interrupt */
69−#define IPR_GPIOMSG 0x20000000 /* GPIO message interrupt (RE'd, still not sure
70− which INTE bits enable it) */
64+#define IPR_WATERMARK_REACHED 0x40000000
65+#define IPR_A_GPIO 0x20000000 /* GPIO input pin change */
7166
7267 /* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
7368 #define IPR_A_MIDITRANSBUFEMPTY2 0x10000000 /* MIDI UART transmit buffer empty */
@@ -97,9 +92,9 @@ · 23 unmodified lines
9792 #define IPR_CHANNELLOOP 0x00000040 /* Channel (half) loop interrupt(s) pending */
9893 #define IPR_CHANNELNUMBERMASK 0x0000003f /* When IPR_CHANNELLOOP is set, indicates the */
9994 /* highest set channel in CLIPL, CLIPH, HLIPL, */
100− /* or HLIPH. When IP is written with CL set, */
95+ /* or HLIPH. When IPR is written with CL set, */
10196 /* the bit in H/CLIPL or H/CLIPH corresponding */
102− /* to the CIN value written will be cleared. */
97+ /* to the CN value written will be cleared. */
10398
10499 #define INTE 0x0c /* Interrupt enable register */
105100 #define INTE_VIRTUALSB_MASK 0xc0000000 /* Virtual Soundblaster I/O port capture */
@@ -127,10 +122,14 @@ · 21 unmodified lines
127122 /* behavior and possibly random segfaults and */
128123 /* lockups if enabled. */
129124
125+#define INTE_A_GPIOENABLE 0x00040000 /* Enable GPIO input change interrupts */
126+
130127 /* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
131128 #define INTE_A_MIDITXENABLE2 0x00020000 /* Enable MIDI transmit-buffer-empty interrupts */
132129 #define INTE_A_MIDIRXENABLE2 0x00010000 /* Enable MIDI receive-buffer-empty interrupts */
133130
131+#define INTE_A_SPDIF_BUFFULL_ENABLE 0x00008000
132+#define INTE_A_SPDIF_HALFBUFFULL_ENABLE 0x00004000
134133
135134 #define INTE_SAMPLERATETRACKER 0x00002000 /* Enable sample rate tracker interrupts */
136135 /* NOTE: This bit must always be enabled */
@@ -151,9 +150,10 @@ · 14 unmodified lines
151150 #define WC 0x10 /* Wall Clock register */
152151 #define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */
153152 #define WC_SAMPLECOUNTER 0x14060010
154−#define WC_CURRENTCHANNEL 0x0000003F /* Channel [0..63] currently being serviced */
153+#define WC_CURRENTCHANNEL_MASK 0x0000003F /* Channel [0..63] currently being serviced */
155154 /* NOTE: Each channel takes 1/64th of a sample */
156155 /* period to be serviced. */
156+#define WC_CURRENTCHANNEL 0x06000010
157157
158158 #define HCFG 0x14 /* Hardware config register */
159159 /* NOTE: There is no reason to use the legacy */
@@ -180,6 +180,7 @@ · 20 unmodified lines
180180 #define HCFG_CODECFORMAT_MASK 0x00030000 /* CODEC format */
181181
182182 /* Specific to Alice2, CA0102 */
183+
183184 #define HCFG_CODECFORMAT_AC97_1 0x00000000 /* AC97 CODEC format -- Ver 1.03 */
184185 #define HCFG_CODECFORMAT_AC97_2 0x00010000 /* AC97 CODEC format -- Ver 2.1 */
185186 #define HCFG_AUTOMUTE_ASYNC 0x00008000 /* When set, the async sample rate convertors */
@@ -200,9 +201,8 @@ · 14 unmodified lines
200201 /* I2S format input */
201202 /* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc. */
202203
203−
204−
205204 /* Older chips */
205+
206206 #define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */
207207 #define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */
208208 #define HCFG_GPINPUT0 0x00004000 /* External pin112 */
@@ -238,7 +238,7 @@ · 29 unmodified lines
238238 /* Should be set to 1 when the EMU10K1 is */
239239 /* completely initialized. */
240240
241−//For Audigy, MPU port move to 0x70-0x74 ptr register
241+// On Audigy, the MPU port moved to the 0x70-0x74 ptr registers
242242
243243 #define MUDATA 0x18 /* MPU401 data register (8 bits) */
244244
@@ -251,11 +251,17 @@ · 6 unmodified lines
251251 #define MUSTAT_IRDYN 0x80 /* 0 = MIDI data or command ACK */
252252 #define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */
253253
254−#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */
255−#define A_GPINPUT_MASK 0xff00
254+#define A_GPIO 0x18 /* GPIO on Audigy card (16bits) */
255+#define A_GPINPUT_MASK 0xff00 /* Alice/2 has 8 input pins */
256+#define A3_GPINPUT_MASK 0x3f00 /* ... while Tina/2 has only 6 */
256257 #define A_GPOUTPUT_MASK 0x00ff
257258
259+// The GPIO port is used for I/O config on Sound Blasters;
260+// card-specific info can be found in the emu_chip_details table.
261+// On E-MU cards the port is used as the interface to the FPGA.
262+
258263 // Audigy output/GPIO stuff taken from the kX drivers
264+#define A_IOCFG A_GPIO
259265 #define A_IOCFG_GPOUT0 0x0044 /* analog/digital */
260266 #define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */
261267 #define A_IOCFG_ENABLE_DIGITAL 0x0004
@@ -271,19 +277,12 @@ · 9 unmodified lines
271277 #define A_IOCFG_REAR_JACK 0x8000
272278 #define A_IOCFG_PHONES_JACK 0x0100 /* LiveDrive */
273279
274−/* outputs:
275− * for audigy2 platinum: 0xa00
276− * for a2 platinum ex: 0x1c00
277− * for a1 platinum: 0x0
278− */
279−
280280 #define TIMER 0x1a /* Timer terminal count register */
281281 /* NOTE: After the rate is changed, a maximum */
282282 /* of 1024 sample periods should be allowed */
283283 /* before the new rate is guaranteed accurate. */
284−#define TIMER_RATE_MASK 0x000003ff /* Timer interrupt rate in sample periods */
284+#define TIMER_RATE_MASK 0x03ff /* Timer interrupt rate in sample periods */
285285 /* 0 == 1024 periods, [1..4] are not useful */
286−#define TIMER_RATE 0x0a00001a
287286
288287 #define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
289288
@@ -317,7 +316,7 @@ · 27 unmodified lines
317316 /* 0x00000000 2-channel output. */
318317 /* 0x00000200 8-channel output. */
319318 /* 0x00000004 pauses stream/irq fail. */
320− /* Rest of bits no nothing to sound output */
319+ /* Rest of bits do nothing to sound output */
321320 /* bit 0: Enable P16V audio.
322321 * bit 1: Lock P16V record memory cache.
323322 * bit 2: Lock P16V playback memory cache.
@@ -331,6 +330,7 @@ · 7 unmodified lines
331330 */
332331 #define IPR3 0x38 /* Cdif interrupt pending register */
333332 #define INTE3 0x3c /* Cdif interrupt enable register. */
333+
334334 /************************************************************************************************/
335335 /* PCI function 1 registers, address = <val> + PCIBASE1 */
336336 /************************************************************************************************/
@@ -349,11 +349,38 @@ · 12 unmodified lines
349349 #define JOYSTICK_BUTTONS 0x0f /* Joystick button data */
350350 #define JOYSTICK_COMPARATOR 0xf0 /* Joystick comparator data */
351351
352−
353352 /********************************************************************************************************/
354353 /* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers */
355354 /********************************************************************************************************/
356355
356+// No official documentation was released for EMU10K1, but some info
357+// about playback can be extrapolated from the EMU8K documents:
358+// "AWE32/EMU8000 Programmer’s Guide" (emu8kpgm.pdf) - registers
359+// "AWE32 Developer's Information Pack" (adip301.pdf) - high-level view
360+
361+// The short version:
362+// - The engine has 64 playback channels, also called voices. The channels
363+// operate independently, except when paired for stereo (see below).
364+// - PCM samples are fetched into the cache; see description of CD0 below.
365+// - Samples are consumed at the rate CPF_CURRENTPITCH.
366+// - 8-bit samples are transformed upon use: cooked = (raw ^ 0x80) << 8
367+// - 8 samples are read at CCR_READADDRESS:CPF_FRACADDRESS and interpolated
368+// according to CCCA_INTERPROM_*. With CCCA_INTERPROM_0 selected and a zero
369+// CPF_FRACADDRESS, this results in CCR_READADDRESS[3] being used verbatim.
370+// - The value is multiplied by CVCF_CURRENTVOL.
371+// - The value goes through a filter with cutoff CVCF_CURRENTFILTER;
372+// delay stages Z1 and Z2.
373+// - The value is added by so-called `sends` to 4 (EMU10K1) / 8 (EMU10K2)
374+// of the 16 (EMU10K1) / 64 (EMU10K2) FX bus accumulators via FXRT*,
375+// multiplied by a per-send amount (*_FXSENDAMOUNT_*).
376+// The scaling of the send amounts is exponential-ish.
377+// - The DSP has a go at FXBUS* and outputs the values to EXTOUT* or EMU32OUT*.
378+// - The pitch, volume, and filter cutoff can be modulated by two envelope
379+// engines and two low frequency oscillators.
380+// - To avoid abrupt changes to the parameters (which may cause audible
381+// distortion), the modulation engine sets the target registers, towards
382+// which the current registers "swerve" gradually.
383+
357384 #define CPF 0x00 /* Current pitch and fraction register */
358385 #define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */
359386 #define CPF_CURRENTPITCH 0x10100000
@@ -393,7 +420,7 @@ · 33 unmodified lines
393420 #define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */
394421 #define PSST_LOOPSTARTADDR 0x18000006
395422
396−#define DSL 0x07 /* Send D amount and loop start address register */
423+#define DSL 0x07 /* Send D amount and loop end address register */
397424 #define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */
398425
399426 #define DSL_FXSENDAMOUNT_D 0x08180007
@@ -402,8 +429,9 @@ · 2 unmodified lines
402429 #define DSL_LOOPENDADDR 0x18000007
403430
404431 #define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */
405−#define CCCA_RESONANCE 0xf0000000 /* Lowpass filter resonance (Q) height */
406−#define CCCA_INTERPROMMASK 0x0e000000 /* Selects passband of interpolation ROM */
432+#define CCCA_RESONANCE_MASK 0xf0000000 /* Lowpass filter resonance (Q) height */
433+#define CCCA_RESONANCE 0x041c0008
434+#define CCCA_INTERPROM_MASK 0x0e000000 /* Selects passband of interpolation ROM */
407435 /* 1 == full band, 7 == lowpass */
408436 /* ROM 0 is used when pitch shifting downward or less */
409437 /* then 3 semitones upward. Increasingly higher ROM */
@@ -418,25 +446,28 @@ · 8 unmodified lines
418446 #define CCCA_INTERPROM_6 0x0c000000 /* Select interpolation ROM 6 */
419447 #define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */
420448 #define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */
449+ /* 8-bit samples are unsigned, 16-bit ones signed */
421450 #define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */
422451 #define CCCA_CURRADDR 0x18000008
423452
424453 #define CCR 0x09 /* Cache control register */
425454 #define CCR_CACHEINVALIDSIZE 0x07190009
426−#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples cache for this channel */
455+#define CCR_CACHEINVALIDSIZE_MASK 0xfe000000 /* Number of invalid samples before the read address */
427456 #define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */
428457 #define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */
458+ /* Auto-set from CPF_STEREO_MASK */
429459 #define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */
460+ /* Auto-set from CCCA_8BITSELECT */
430461 #define CCR_READADDRESS 0x06100009
431−#define CCR_READADDRESS_MASK 0x003f0000 /* Location of cache just beyond current cache service */
462+#define CCR_READADDRESS_MASK 0x003f0000 /* Next cached sample to play */
432463 #define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */
433464 /* NOTE: This is valid only if CACHELOOPFLAG is set */
434465 #define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */
435−#define CCR_CACHELOOPADDRHI 0x000000ff /* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
466+#define CCR_CACHELOOPADDRHI 0x000000ff /* CLP_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set */
436467
437468 #define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
438469 /* NOTE: This register is normally not used */
439−#define CLP_CACHELOOPADDR 0x0000ffff /* Cache loop address (DSL_LOOPSTARTADDR [0..15]) */
470+#define CLP_CACHELOOPADDR 0x0000ffff /* Cache loop address low word */
440471
441472 #define FXRT 0x0b /* Effects send routing register */
442473 /* NOTE: It is illegal to assign the same routing to */
@@ -446,9 +477,7 @@ · 3 unmodified lines
446477 #define FXRT_CHANNELC 0x0f000000 /* Effects send bus number for channel's effects send C */
447478 #define FXRT_CHANNELD 0xf0000000 /* Effects send bus number for channel's effects send D */
448479
449−#define A_HR 0x0b /* High Resolution. 24bit playback from host to DSP. */
450480 #define MAPA 0x0c /* Cache map A */
451−
452481 #define MAPB 0x0d /* Cache map B */
453482
454483 #define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */
@@ -457,22 +486,22 @@ · 2 unmodified lines
457486 #define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
458487 #define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
459488
460−/* 0x0e, 0x0f: Not used */
489+/* 0x0e, 0x0f: Internal state, at least on Audigy */
461490
462491 #define ENVVOL 0x10 /* Volume envelope register */
463492 #define ENVVOL_MASK 0x0000ffff /* Current value of volume envelope state variable */
464493 /* 0x8000-n == 666*n usec delay */
465494
466495 #define ATKHLDV 0x11 /* Volume envelope hold and attack register */
467−#define ATKHLDV_PHASE0 0x00008000 /* 0 = Begin attack phase */
496+#define ATKHLDV_PHASE0_MASK 0x00008000 /* 0 = Begin attack phase */
468497 #define ATKHLDV_HOLDTIME_MASK 0x00007f00 /* Envelope hold time (127-n == n*88.2msec) */
469498 #define ATKHLDV_ATTACKTIME_MASK 0x0000007f /* Envelope attack time, log encoded */
470499 /* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec */
471500
472501 #define DCYSUSV 0x12 /* Volume envelope sustain and decay register */
473−#define DCYSUSV_PHASE1_MASK 0x00008000 /* 0 = Begin attack phase, 1 = begin release phase */
502+#define DCYSUSV_PHASE1_MASK 0x00008000 /* 0 = Begin decay phase, 1 = begin release phase */
474503 #define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */
475−#define DCYSUSV_CHANNELENABLE_MASK 0x00000080 /* 1 = Inhibit envelope engine from writing values in */
504+#define DCYSUSV_CHANNELENABLE_MASK 0x00000080 /* 0 = Inhibit envelope engine from writing values in */
476505 /* this channel and from writing to pitch, filter and */
477506 /* volume targets. */
478507 #define DCYSUSV_DECAYTIME_MASK 0x0000007f /* Volume envelope decay time, log encoded */
@@ -487,13 +516,13 @@ · 8 unmodified lines
487516 /* 0x8000-n == 666*n usec delay */
488517
489518 #define ATKHLDM 0x15 /* Modulation envelope hold and attack register */
490−#define ATKHLDM_PHASE0 0x00008000 /* 0 = Begin attack phase */
519+#define ATKHLDM_PHASE0_MASK 0x00008000 /* 0 = Begin attack phase */
491520 #define ATKHLDM_HOLDTIME 0x00007f00 /* Envelope hold time (127-n == n*42msec) */
492521 #define ATKHLDM_ATTACKTIME 0x0000007f /* Envelope attack time, log encoded */
493522 /* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec */
494523
495524 #define DCYSUSM 0x16 /* Modulation envelope decay and sustain register */
496−#define DCYSUSM_PHASE1_MASK 0x00008000 /* 0 = Begin attack phase, 1 = begin release phase */
525+#define DCYSUSM_PHASE1_MASK 0x00008000 /* 0 = Begin decay phase, 1 = begin release phase */
497526 #define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */
498527 #define DCYSUSM_DECAYTIME_MASK 0x0000007f /* Envelope decay time, log encoded */
499528 /* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec */
@@ -515,7 +544,6 @@ · 15 unmodified lines
515544 #define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */
516545 #define IFATN_ATTENUATION 0x08000019
517546
518−
519547 #define PEFE 0x1a /* Pitch envelope and filter envelope amount register */
520548 #define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */
521549 /* Signed 2's complement, +/- one octave peak extremes */
@@ -523,19 +551,19 @@ · 1 unmodified line
523551 #define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */
524552 /* Signed 2's complement, +/- six octaves peak extremes */
525553 #define PEFE_FILTERAMOUNT 0x0800001a
554+
526555 #define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */
527556 #define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */
528557 /* Signed 2's complement, +/- one octave extremes */
529558 #define FMMOD_MOFILTER 0x000000ff /* Filter LFO modulation depth */
530559 /* Signed 2's complement, +/- three octave extremes */
531560
532−
533561 #define TREMFRQ 0x1c /* Tremolo amount and modulation LFO frequency register */
534562 #define TREMFRQ_DEPTH 0x0000ff00 /* Tremolo depth */
535563 /* Signed 2's complement, with +/- 12dB extremes */
536−
537564 #define TREMFRQ_FREQUENCY 0x000000ff /* Tremolo LFO frequency */
538565 /* ??Hz steps, maximum of ?? Hz. */
566+
539567 #define FM2FRQ2 0x1d /* Vibrato amount and vibrato LFO frequency register */
540568 #define FM2FRQ2_DEPTH 0x0000ff00 /* Vibrato LFO vibrato depth */
541569 /* Signed 2's complement, +/- one octave extremes */
@@ -603,20 +631,6 @@ · 61 unmodified lines
603631 /* is 16bit, 48KHz only. All 32 channels can be enabled */
604632 /* simultaneously. */
605633
606−#define FXWC_DEFAULTROUTE_C (1<<0) /* left emu out? */
607−#define FXWC_DEFAULTROUTE_B (1<<1) /* right emu out? */
608−#define FXWC_DEFAULTROUTE_A (1<<12)
609−#define FXWC_DEFAULTROUTE_D (1<<13)
610−#define FXWC_ADCLEFT (1<<18)
611−#define FXWC_CDROMSPDIFLEFT (1<<18)
612−#define FXWC_ADCRIGHT (1<<19)
613−#define FXWC_CDROMSPDIFRIGHT (1<<19)
614−#define FXWC_MIC (1<<20)
615−#define FXWC_ZOOMLEFT (1<<20)
616−#define FXWC_ZOOMRIGHT (1<<21)
617−#define FXWC_SPDIFLEFT (1<<22) /* 0x00400000 */
618−#define FXWC_SPDIFRIGHT (1<<23) /* 0x00800000 */
619−
620634 #define A_TBLSZ 0x43 /* Effects Tank Internal Table Size. Only low byte or register used */
621635
622636 #define TCBS 0x44 /* Tank cache buffer size register */
@@ -639,7 +653,7 @@ · 16 unmodified lines
639653 #define FXBA 0x47 /* FX Buffer Address */
640654 #define FXBA_MASK 0xfffff000 /* 20 bit base address */
641655
642−#define A_HWM 0x48 /* High PCI Water Mark - word access, defaults to 3f */
656+#define A_HWM 0x48 /* High PCI Water Mark - word access, defaults to 3f */
643657
644658 #define MICBS 0x49 /* Microphone buffer size register */
645659
@@ -647,9 +661,7 @@ · 1 unmodified line
647661
648662 #define FXBS 0x4b /* FX buffer size register */
649663
650−/* register: 0x4c..4f: ffff-ffff current amounts, per-channel */
651−
652−/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
664+/* The following mask values define the size of the ADC, MIC and FX buffers in bytes */
653665 #define ADCBS_BUFSIZE_NONE 0x00000000
654666 #define ADCBS_BUFSIZE_384 0x00000001
655667 #define ADCBS_BUFSIZE_448 0x00000002
@@ -683,38 +695,27 @@ · 27 unmodified lines
683695 #define ADCBS_BUFSIZE_57344 0x0000001e
684696 #define ADCBS_BUFSIZE_65536 0x0000001f
685697
686−/* Current Send B, A Amounts */
687−#define A_CSBA 0x4c
688−
689−/* Current Send D, C Amounts */
690−#define A_CSDC 0x4d
691−
692−/* Current Send F, E Amounts */
693−#define A_CSFE 0x4e
694−
695−/* Current Send H, G Amounts */
696−#define A_CSHG 0x4f
698+#define A_CSBA 0x4c /* FX send B & A current amounts */
699+#define A_CSDC 0x4d /* FX send D & C current amounts */
700+#define A_CSFE 0x4e /* FX send F & E current amounts */
701+#define A_CSHG 0x4f /* FX send H & G current amounts */
697702
703+// NOTE: 0x50,51,52: 64-bit (split over voices 0 & 1)
704+#define CDCS 0x50 /* CD-ROM digital channel status register */
698705
699−#define CDCS 0x50 /* CD-ROM digital channel status register */
706+#define GPSCS 0x51 /* General Purpose SPDIF channel status register */
700707
701−#define GPSCS 0x51 /* General Purpose SPDIF channel status register*/
708+// Corresponding EMU10K1_DBG_* constants are in the public header
709+#define DBG 0x52
702710
703−#define DBG 0x52 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
711+#define A_SPSC 0x52 /* S/PDIF Input C Channel Status */
704712
705−/* S/PDIF Input C Channel Status */
706−#define A_SPSC 0x52
713+#define REG53 0x53 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
707714
708−#define REG53 0x53 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
715+// Corresponding A_DBG_* constants are in the public header
716+#define A_DBG 0x53
709717
710−#define A_DBG 0x53
711−#define A_DBG_SINGLE_STEP 0x00020000 /* Set to zero to start dsp */
712−#define A_DBG_ZC 0x40000000 /* zero tram counter */
713−#define A_DBG_STEP_ADDR 0x000003ff
714−#define A_DBG_SATURATION_OCCURED 0x20000000
715−#define A_DBG_SATURATION_ADDR 0x0ffc0000
716−
717−// NOTE: 0x54,55,56: 64-bit
718+// NOTE: 0x54,55,56: 64-bit (split over voices 0 & 1)
718719 #define SPCS0 0x54 /* SPDIF output Channel Status 0 register */
719720
720721 #define SPCS1 0x55 /* SPDIF output Channel Status 1 register */
@@ -747,17 +748,14 @@ · 26 unmodified lines
747748
748749 /* 0x57: Not used */
749750
750−/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status */
751+/* The 32-bit CLIx and SOLEx registers all have one bit per channel control/status */
751752 #define CLIEL 0x58 /* Channel loop interrupt enable low register */
752−
753753 #define CLIEH 0x59 /* Channel loop interrupt enable high register */
754754
755755 #define CLIPL 0x5a /* Channel loop interrupt pending low register */
756−
757756 #define CLIPH 0x5b /* Channel loop interrupt pending high register */
758757
759758 #define SOLEL 0x5c /* Stop on loop enable low register */
760−
761759 #define SOLEH 0x5d /* Stop on loop enable high register */
762760
763761 #define SPBYPASS 0x5e /* SPDIF BYPASS mode register */
@@ -767,13 +765,12 @@ · 3 unmodified lines
767765 #define SPBYPASS_FORMAT 0x00000f00 /* If 1, SPDIF XX uses 24 bit, if 0 - 20 bit */
768766
769767 #define AC97SLOT 0x5f /* additional AC97 slots enable bits */
770−#define AC97SLOT_REAR_RIGHT 0x01 /* Rear left */
771−#define AC97SLOT_REAR_LEFT 0x02 /* Rear right */
772−#define AC97SLOT_CNTR 0x10 /* Center enable */
773−#define AC97SLOT_LFE 0x20 /* LFE enable */
768+#define AC97SLOT_REAR_RIGHT 0x01 /* Rear left */
769+#define AC97SLOT_REAR_LEFT 0x02 /* Rear right */
770+#define AC97SLOT_CNTR 0x10 /* Center enable */
771+#define AC97SLOT_LFE 0x20 /* LFE enable */
774772
775−/* PCB Revision */
776−#define A_PCB 0x5f
773+#define A_PCB 0x5f /* PCB Revision */
777774
778775 // NOTE: 0x60,61,62: 64-bit
779776 #define CDSRCS 0x60 /* CD-ROM Sample Rate Converter status register */
@@ -813,27 +810,21 @@ · 33 unmodified lines
813810 #define FXIDX_MASK 0x0000ffff /* 16-bit value */
814811 #define FXIDX_IDX 0x10000065
815812
816−/* The 32-bit HLIx and HLIPx registers all have one bit per channel control/status */
813+/* The 32-bit HLIEx and HLIPx registers all have one bit per channel control/status */
817814 #define HLIEL 0x66 /* Channel half loop interrupt enable low register */
818−
819815 #define HLIEH 0x67 /* Channel half loop interrupt enable high register */
820816
821817 #define HLIPL 0x68 /* Channel half loop interrupt pending low register */
822−
823818 #define HLIPH 0x69 /* Channel half loop interrupt pending high register */
824819
825−/* S/PDIF Host Record Index (bypasses SRC) */
826−#define A_SPRI 0x6a
827−/* S/PDIF Host Record Address */
828−#define A_SPRA 0x6b
829−/* S/PDIF Host Record Control */
830−#define A_SPRC 0x6c
831−/* Delayed Interrupt Counter & Enable */
832−#define A_DICE 0x6d
833−/* Tank Table Base */
834−#define A_TTB 0x6e
835−/* Tank Delay Offset */
836−#define A_TDOF 0x6f
820+#define A_SPRI 0x6a /* S/PDIF Host Record Index (bypasses SRC) */
821+#define A_SPRA 0x6b /* S/PDIF Host Record Address */
822+#define A_SPRC 0x6c /* S/PDIF Host Record Control */
823+
824+#define A_DICE 0x6d /* Delayed Interrupt Counter & Enable */
825+
826+#define A_TTB 0x6e /* Tank Table Base */
827+#define A_TDOF 0x6f /* Tank Delay Offset */
837828
838829 /* This is the MPU port on the card (via the game port) */
839830 #define A_MUDATA1 0x70
@@ -846,48 +837,53 @@ · 6 unmodified lines
846837 #define A_MUSTAT2 A_MUCMD2
847838
848839 /* The next two are the Audigy equivalent of FXWC */
849−/* the Audigy can record any output (16bit, 48kHz, up to 64 channel simultaneously) */
840+/* the Audigy can record any output (16bit, 48kHz, up to 64 channels simultaneously) */
850841 /* Each bit selects a channel for recording */
851842 #define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */
852843 #define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */
853844
854−/* Extended Hardware Control */
855−#define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */
856−#define A_SAMPLE_RATE 0x76 /* Various sample rate settings. */
857−#define A_SAMPLE_RATE_NOT_USED 0x0ffc111e /* Bits that are not used and cannot be set. */
858−#define A_SAMPLE_RATE_UNKNOWN 0xf0030001 /* Bits that can be set, but have unknown use. */
845+#define A_EHC 0x76 /* Extended Hardware Control */
846+
847+#define A_SPDIF_SAMPLERATE A_EHC /* Set the sample rate of SPDIF output */
859848 #define A_SPDIF_RATE_MASK 0x000000e0 /* Any other values for rates, just use 48000 */
860−#define A_SPDIF_48000 0x00000000
849+#define A_SPDIF_48000 0x00000000 /* kX calls this BYPASS */
861850 #define A_SPDIF_192000 0x00000020
862851 #define A_SPDIF_96000 0x00000040
863852 #define A_SPDIF_44100 0x00000080
853+#define A_SPDIF_MUTED 0x000000c0
864854
865855 #define A_I2S_CAPTURE_RATE_MASK 0x00000e00 /* This sets the capture PCM rate, but it is */
866−#define A_I2S_CAPTURE_48000 0x00000000 /* unclear if this sets the ADC rate as well. */
867−#define A_I2S_CAPTURE_192000 0x00000200
868−#define A_I2S_CAPTURE_96000 0x00000400
869−#define A_I2S_CAPTURE_44100 0x00000800
870−
871−#define A_PCM_RATE_MASK 0x0000e000 /* This sets the playback PCM rate on the P16V */
872−#define A_PCM_48000 0x00000000
873−#define A_PCM_192000 0x00002000
874−#define A_PCM_96000 0x00004000
875−#define A_PCM_44100 0x00008000
876−
877−/* I2S0 Sample Rate Tracker Status */
878−#define A_SRT3 0x77
879−
880−/* I2S1 Sample Rate Tracker Status */
881−#define A_SRT4 0x78
882−
883−/* I2S2 Sample Rate Tracker Status */
884−#define A_SRT5 0x79
856+#define A_I2S_CAPTURE_RATE 0x03090076 /* unclear if this sets the ADC rate as well. */
857+#define A_I2S_CAPTURE_48000 0x0
858+#define A_I2S_CAPTURE_192000 0x1
859+#define A_I2S_CAPTURE_96000 0x2
860+#define A_I2S_CAPTURE_44100 0x4
861+
862+#define A_EHC_SRC48_MASK 0x0000e000 /* This sets the playback PCM rate on the P16V */
863+#define A_EHC_SRC48_BYPASS 0x00000000
864+#define A_EHC_SRC48_192 0x00002000
865+#define A_EHC_SRC48_96 0x00004000
866+#define A_EHC_SRC48_44 0x00008000
867+#define A_EHC_SRC48_MUTED 0x0000c000
868+
869+#define A_EHC_P17V_TVM 0x00000001 /* Tank virtual memory mode */
870+#define A_EHC_P17V_SEL0_MASK 0x00030000 /* Aka A_EHC_P16V_PB_RATE; 00: 48, 01: 44.1, 10: 96, 11: 192 */
871+#define A_EHC_P17V_SEL1_MASK 0x000c0000
872+#define A_EHC_P17V_SEL2_MASK 0x00300000
873+#define A_EHC_P17V_SEL3_MASK 0x00c00000
874+
875+#define A_EHC_ASYNC_BYPASS 0x80000000
876+
877+#define A_SRT3 0x77 /* I2S0 Sample Rate Tracker Status */
878+#define A_SRT4 0x78 /* I2S1 Sample Rate Tracker Status */
879+#define A_SRT5 0x79 /* I2S2 Sample Rate Tracker Status */
885880 /* - default to 0x01080000 on my audigy 2 ZS --rlrevell */
886881
887−/* Tank Table DMA Address */
888−#define A_TTDA 0x7a
889−/* Tank Table DMA Data */
890−#define A_TTDD 0x7b
882+#define A_SRT_ESTSAMPLERATE 0x001fffff
883+#define A_SRT_RATELOCKED 0x01000000
884+
885+#define A_TTDA 0x7a /* Tank Table DMA Address */
886+#define A_TTDD 0x7b /* Tank Table DMA Data */
891887
892888 #define A_FXRT2 0x7c
893889 #define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */
@@ -900,6 +896,7 @@ · 6 unmodified lines
900896 #define A_FXSENDAMOUNT_F_MASK 0x00FF0000
901897 #define A_FXSENDAMOUNT_G_MASK 0x0000FF00
902898 #define A_FXSENDAMOUNT_H_MASK 0x000000FF
899+
903900 /* 0x7c, 0x7e "high bit is used for filtering" */
904901
905902 /* The send amounts for this one are the same as used with the emu10k1 */
@@ -910,55 +907,56 @@ · 4 unmodified lines
910907 #define A_FXRT_CHANNELD 0x3f000000
911908
912909 /* 0x7f: Not used */
913−/* Each FX general purpose register is 32 bits in length, all bits are used */
914−#define FXGPREGBASE 0x100 /* FX general purpose registers base */
915−#define A_FXGPREGBASE 0x400 /* Audigy GPRs, 0x400 to 0x5ff */
916−
917−#define A_TANKMEMCTLREGBASE 0x100 /* Tank memory control registers base - only for Audigy */
918−#define A_TANKMEMCTLREG_MASK 0x1f /* only 5 bits used - only for Audigy */
919−
920−/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is */
921−/* decompressed back to 20 bits on a read. There are a total of 160 locations, the last 32 */
922−/* locations are for external TRAM. */
923−#define TANKMEMDATAREGBASE 0x200 /* Tank memory data registers base */
924−#define TANKMEMDATAREG_MASK 0x000fffff /* 20 bit tank audio data field */
925−
926−/* Combined address field and memory opcode or flag field. 160 locations, last 32 are external */
927−#define TANKMEMADDRREGBASE 0x300 /* Tank memory address registers base */
928−#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */
929−#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */
930−#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */
931−#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */
932−#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */
933910
934−#define MICROCODEBASE 0x400 /* Microcode data base address */
911+/* The public header defines the GPR and TRAM base addresses that
912+ * are valid for _both_ CPU and DSP addressing. */
935913
936914 /* Each DSP microcode instruction is mapped into 2 doublewords */
937915 /* NOTE: When writing, always write the LO doubleword first. Reads can be in either order. */
938−#define LOWORD_OPX_MASK 0x000ffc00 /* Instruction operand X */
939−#define LOWORD_OPY_MASK 0x000003ff /* Instruction operand Y */
940−#define HIWORD_OPCODE_MASK 0x00f00000 /* Instruction opcode */
941−#define HIWORD_RESULT_MASK 0x000ffc00 /* Instruction result */
942−#define HIWORD_OPA_MASK 0x000003ff /* Instruction operand A */
916+#define MICROCODEBASE 0x400 /* Microcode data base address */
917+#define A_MICROCODEBASE 0x600
943918
944919
945−/* Audigy Soundcard have a different instruction format */
946−#define A_MICROCODEBASE 0x600
947−#define A_LOWORD_OPY_MASK 0x000007ff
948−#define A_LOWORD_OPX_MASK 0x007ff000
949−#define A_HIWORD_OPCODE_MASK 0x0f000000
950−#define A_HIWORD_RESULT_MASK 0x007ff000
951−#define A_HIWORD_OPA_MASK 0x000007ff
920+/************************************************************************************************/
921+/* E-MU Digital Audio System overview */
922+/************************************************************************************************/
923+
924+// - These cards use a regular PCI-attached Audigy chip (Alice2/Tina/Tina2);
925+// the PCIe variants simply put the Audigy chip behind a PCI bridge.
926+// - All physical PCM I/O is routed through an additional FPGA; the regular
927+// EXTIN/EXTOUT ports are unconnected.
928+// - The FPGA has a signal routing matrix, to connect each destination (output
929+// socket or capture channel) to a source (input socket or playback channel).
930+// - The FPGA is controlled via Audigy's GPIO port, while sample data is
931+// transmitted via proprietary EMU32 serial links. On first-generation
932+// E-MU 1010 cards, Audigy's I2S inputs are also used for sample data.
933+// - The Audio/Micro Dock is attached to Hana via EDI, a "network" link.
934+// - The Audigy chip operates in slave mode; the clock is supplied by the FPGA.
935+// Gen1 E-MU 1010 cards have two crystals (for 44.1 kHz and 48 kHz multiples),
936+// while the later cards use a single crystal and a PLL chip.
937+// - The whole card is switched to 2x/4x mode to achieve 88.2/96/176.4/192 kHz
938+// sample rates. Alice2/Tina keeps running at 44.1/48 kHz, but multiple channels
939+// are bundled.
940+// - The number of available EMU32/EDI channels is hit in 2x/4x mode, so the total
941+// number of usable inputs/outputs is limited, esp. with ADAT in use.
942+// - S/PDIF is unavailable in 4x mode (only over TOSLINK on newer 1010 cards) due
943+// to being unspecified at 176.4/192 kHz. Therefore, the Dock's S/PDIF channels
944+// can overlap with the Dock's ADC/DAC's high channels.
945+// - The code names are mentioned below and in the emu_chip_details table.
952946
953947 /************************************************************************************************/
954−/* EMU1010m HANA FPGA registers */
948+/* EMU1010 FPGA registers */
955949 /************************************************************************************************/
950+
956951 #define EMU_HANA_DESTHI 0x00 /* 0000xxx 3 bits Link Destination */
957952 #define EMU_HANA_DESTLO 0x01 /* 00xxxxx 5 bits */
953+
958954 #define EMU_HANA_SRCHI 0x02 /* 0000xxx 3 bits Link Source */
959955 #define EMU_HANA_SRCLO 0x03 /* 00xxxxx 5 bits */
956+
960957 #define EMU_HANA_DOCK_PWR 0x04 /* 000000x 1 bits Audio Dock power */
961958 #define EMU_HANA_DOCK_PWR_ON 0x01 /* Audio Dock power on */
959+
962960 #define EMU_HANA_WCLOCK 0x05 /* 0000xxx 3 bits Word Clock source select */
963961 /* Must be written after power on to reset DLL */
964962 /* One is unable to detect the Audio dock without this */
@@ -967,7 +965,7 @@ · 2 unmodified lines
967965 #define EMU_HANA_WCLOCK_INT_44_1K 0x01
968966 #define EMU_HANA_WCLOCK_HANA_SPDIF_IN 0x02
969967 #define EMU_HANA_WCLOCK_HANA_ADAT_IN 0x03
970−#define EMU_HANA_WCLOCK_SYNC_BNCN 0x04
968+#define EMU_HANA_WCLOCK_SYNC_BNC 0x04
971969 #define EMU_HANA_WCLOCK_2ND_HANA 0x05
972970 #define EMU_HANA_WCLOCK_SRC_RESERVED 0x06
973971 #define EMU_HANA_WCLOCK_OFF 0x07 /* For testing, forces fallback to DEFCLOCK */
@@ -996,10 +994,10 @@ · 22 unmodified lines
996994 #define EMU_HANA_IRQ_DOCK_LOST 0x08
997995
998996 #define EMU_HANA_SPDIF_MODE 0x0a /* 00xxxxx 5 bits SPDIF MODE */
999−#define EMU_HANA_SPDIF_MODE_TX_COMSUMER 0x00
997+#define EMU_HANA_SPDIF_MODE_TX_CONSUMER 0x00
1000998 #define EMU_HANA_SPDIF_MODE_TX_PRO 0x01
1001999 #define EMU_HANA_SPDIF_MODE_TX_NOCOPY 0x02
1002−#define EMU_HANA_SPDIF_MODE_RX_COMSUMER 0x00
1000+#define EMU_HANA_SPDIF_MODE_RX_CONSUMER 0x00
10031001 #define EMU_HANA_SPDIF_MODE_RX_PRO 0x04
10041002 #define EMU_HANA_SPDIF_MODE_RX_NOCOPY 0x08
10051003 #define EMU_HANA_SPDIF_MODE_RX_INVALID 0x10
@@ -1011,8 +1009,12 @@ · 5 unmodified lines
10111009 #define EMU_HANA_OPTICAL_OUT_ADAT 0x02
10121010
10131011 #define EMU_HANA_MIDI_IN 0x0c /* 000000x 1 bit Control MIDI */
1014−#define EMU_HANA_MIDI_IN_FROM_HAMOA 0x00 /* HAMOA MIDI in to Alice 2 MIDI B */
1015−#define EMU_HANA_MIDI_IN_FROM_DOCK 0x01 /* Audio Dock MIDI in to Alice 2 MIDI B */
1012+#define EMU_HANA_MIDI_INA_FROM_HAMOA 0x01 /* HAMOA MIDI in to Alice 2 MIDI A */
1013+#define EMU_HANA_MIDI_INA_FROM_DOCK1 0x02 /* Audio Dock-1 MIDI in to Alice 2 MIDI A */
1014+#define EMU_HANA_MIDI_INA_FROM_DOCK2 0x03 /* Audio Dock-2 MIDI in to Alice 2 MIDI A */
1015+#define EMU_HANA_MIDI_INB_FROM_HAMOA 0x08 /* HAMOA MIDI in to Alice 2 MIDI B */
1016+#define EMU_HANA_MIDI_INB_FROM_DOCK1 0x10 /* Audio Dock-1 MIDI in to Alice 2 MIDI B */
1017+#define EMU_HANA_MIDI_INB_FROM_DOCK2 0x18 /* Audio Dock-2 MIDI in to Alice 2 MIDI B */
10161018
10171019 #define EMU_HANA_DOCK_LEDS_1 0x0d /* 000xxxx 4 bit Audio Dock LEDs */
10181020 #define EMU_HANA_DOCK_LEDS_1_MIDI1 0x01 /* MIDI 1 LED on */
@@ -1037,51 +1039,49 @@ · 18 unmodified lines
10371039 #define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL 0x20 /* Manual Signal detection */
10381040
10391041 #define EMU_HANA_ADC_PADS 0x10 /* 0000xxx 3 bit Audio Dock ADC 14dB pads */
1040−#define EMU_HANA_DOCK_ADC_PAD1 0x01 /* 14dB Attenuation on Audio Dock ADC 1 */
1041−#define EMU_HANA_DOCK_ADC_PAD2 0x02 /* 14dB Attenuation on Audio Dock ADC 2 */
1042−#define EMU_HANA_DOCK_ADC_PAD3 0x04 /* 14dB Attenuation on Audio Dock ADC 3 */
1043−#define EMU_HANA_0202_ADC_PAD1 0x08 /* 14dB Attenuation on 0202 ADC 1 */
1042+#define EMU_HANA_DOCK_ADC_PAD1 0x01 /* 14dB Attenuation on Audio Dock ADC 1 */
1043+#define EMU_HANA_DOCK_ADC_PAD2 0x02 /* 14dB Attenuation on Audio Dock ADC 2 */
1044+#define EMU_HANA_DOCK_ADC_PAD3 0x04 /* 14dB Attenuation on Audio Dock ADC 3 */
1045+#define EMU_HANA_0202_ADC_PAD1 0x08 /* 14dB Attenuation on 0202 ADC 1 */
10441046
10451047 #define EMU_HANA_DOCK_MISC 0x11 /* 0xxxxxx 6 bit Audio Dock misc bits */
1046−#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */
1047−#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */
1048−#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */
1049−#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */
1048+#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */
1049+#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */
1050+#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */
1051+#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */
10501052 #define EMU_HANA_DOCK_PHONES_192_DAC1 0x00 /* DAC 1 Headphones source at 192kHz */
10511053 #define EMU_HANA_DOCK_PHONES_192_DAC2 0x10 /* DAC 2 Headphones source at 192kHz */
10521054 #define EMU_HANA_DOCK_PHONES_192_DAC3 0x20 /* DAC 3 Headphones source at 192kHz */
10531055 #define EMU_HANA_DOCK_PHONES_192_DAC4 0x30 /* DAC 4 Headphones source at 192kHz */
10541056
10551057 #define EMU_HANA_MIDI_OUT 0x12 /* 00xxxxx 5 bit Source for each MIDI out port */
1056−#define EMU_HANA_MIDI_OUT_0202 0x01 /* 0202 MIDI from Alice 2. 0 = A, 1 = B */
1057−#define EMU_HANA_MIDI_OUT_DOCK1 0x02 /* Audio Dock MIDI1 front, from Alice 2. 0 = A, 1 = B */
1058−#define EMU_HANA_MIDI_OUT_DOCK2 0x04 /* Audio Dock MIDI2 rear, from Alice 2. 0 = A, 1 = B */
1059−#define EMU_HANA_MIDI_OUT_SYNC2 0x08 /* Sync card. Not the actual MIDI out jack. 0 = A, 1 = B */
1060−#define EMU_HANA_MIDI_OUT_LOOP 0x10 /* 0 = bits (3:0) normal. 1 = MIDI loopback enabled. */
1058+#define EMU_HANA_MIDI_OUT_0202 0x01 /* 0202 MIDI from Alice 2. 0 = A, 1 = B */
1059+#define EMU_HANA_MIDI_OUT_DOCK1 0x02 /* Audio Dock MIDI1 front, from Alice 2. 0 = A, 1 = B */
1060+#define EMU_HANA_MIDI_OUT_DOCK2 0x04 /* Audio Dock MIDI2 rear, from Alice 2. 0 = A, 1 = B */
1061+#define EMU_HANA_MIDI_OUT_SYNC2 0x08 /* Sync card. Not the actual MIDI out jack. 0 = A, 1 = B */
1062+#define EMU_HANA_MIDI_OUT_LOOP 0x10 /* 0 = bits (3:0) normal. 1 = MIDI loopback enabled. */
10611063
10621064 #define EMU_HANA_DAC_PADS 0x13 /* 00xxxxx 5 bit DAC 14dB attenuation pads */
1063−#define EMU_HANA_DOCK_DAC_PAD1 0x01 /* 14dB Attenuation on AudioDock DAC 1. Left and Right */
1064−#define EMU_HANA_DOCK_DAC_PAD2 0x02 /* 14dB Attenuation on AudioDock DAC 2. Left and Right */
1065−#define EMU_HANA_DOCK_DAC_PAD3 0x04 /* 14dB Attenuation on AudioDock DAC 3. Left and Right */
1066−#define EMU_HANA_DOCK_DAC_PAD4 0x08 /* 14dB Attenuation on AudioDock DAC 4. Left and Right */
1067−#define EMU_HANA_0202_DAC_PAD1 0x10 /* 14dB Attenuation on 0202 DAC 1. Left and Right */
1065+#define EMU_HANA_DOCK_DAC_PAD1 0x01 /* 14dB Attenuation on AudioDock DAC 1. Left and Right */
1066+#define EMU_HANA_DOCK_DAC_PAD2 0x02 /* 14dB Attenuation on AudioDock DAC 2. Left and Right */
1067+#define EMU_HANA_DOCK_DAC_PAD3 0x04 /* 14dB Attenuation on AudioDock DAC 3. Left and Right */
1068+#define EMU_HANA_DOCK_DAC_PAD4 0x08 /* 14dB Attenuation on AudioDock DAC 4. Left and Right */
1069+#define EMU_HANA_0202_DAC_PAD1 0x10 /* 14dB Attenuation on 0202 DAC 1. Left and Right */
10681070
10691071 /* 0x14 - 0x1f Unused R/W registers */
1070−#define EMU_HANA_IRQ_STATUS 0x20 /* 000xxxx 4 bits IRQ Status */
1071−#if 0 /* Already defined for reg 0x09 IRQ_ENABLE */
1072−#define EMU_HANA_IRQ_WCLK_CHANGED 0x01
1073−#define EMU_HANA_IRQ_ADAT 0x02
1074−#define EMU_HANA_IRQ_DOCK 0x04
1075−#define EMU_HANA_IRQ_DOCK_LOST 0x08
1076−#endif
1072+
1073+#define EMU_HANA_IRQ_STATUS 0x20 /* 00xxxxx 5 bits IRQ Status */
1074+ /* Same bits as for EMU_HANA_IRQ_ENABLE */
1075+ /* Reading the register resets it. */
10771076
10781077 #define EMU_HANA_OPTION_CARDS 0x21 /* 000xxxx 4 bits Presence of option cards */
1079−#define EMU_HANA_OPTION_HAMOA 0x01 /* HAMOA card present */
1080−#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */
1081−#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio Dock online and FPGA configured */
1082−#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio Dock online and FPGA not configured */
1078+#define EMU_HANA_OPTION_HAMOA 0x01 /* Hamoa (analog I/O) card present */
1079+#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */
1080+#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio/Micro dock present and FPGA configured */
1081+#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio/Micro dock present and FPGA not configured */
10831082
1084−#define EMU_HANA_ID 0x22 /* 1010101 7 bits ID byte & 0x7f = 0x55 */
1083+#define EMU_HANA_ID 0x22 /* 1010101 7 bits ID byte & 0x7f = 0x55 with Alice2 */
1084+ /* 0010101 5 bits ID byte & 0x1f = 0x15 with Tina/2 */
10851085
10861086 #define EMU_HANA_MAJOR_REV 0x23 /* 0000xxx 3 bit Hana FPGA Major rev */
10871087 #define EMU_HANA_MINOR_REV 0x24 /* 0000xxx 3 bit Hana FPGA Minor rev */
@@ -1090,8 +1090,8 @@ · 2 unmodified lines
10901090 #define EMU_DOCK_MINOR_REV 0x26 /* 0000xxx 3 bit Audio Dock FPGA Minor rev */
10911091
10921092 #define EMU_DOCK_BOARD_ID 0x27 /* 00000xx 2 bits Audio Dock ID pins */
1093−#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */
1094−#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */
1093+#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */
1094+#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */
10951095
10961096 #define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */
10971097 #define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */
@@ -1104,31 +1104,35 @@ · 6 unmodified lines
11041104
11051105 #define EMU_HANA2_WC_SPDIF_HI 0x2e /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, upper 6 bits */
11061106 #define EMU_HANA2_WC_SPDIF_LO 0x2f /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, lower 6 bits */
1107+
11071108 /* 0x30 - 0x3f Unused Read only registers */
11081109
1110+// The meaning of this is not clear; kX-project just calls it "lock" in some info-only code.
1111+#define EMU_HANA_LOCK_STS_LO 0x38 /* 0xxxxxx lower 6 bits */
1112+#define EMU_HANA_LOCK_STS_HI 0x39 /* 0xxxxxx upper 6 bits */
1113+
11091114 /************************************************************************************************/
1110−/* EMU1010m HANA Destinations */
1115+/* EMU1010 Audio Destinations */
11111116 /************************************************************************************************/
1112−/* Hana, original 1010,1212,1820 using Alice2
1113− * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1117+/* Hana, original 1010,1212m,1820[m] using Alice2
11141118 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
1115− * 0x01, 0x10-0x1f: 32 Elink channels to Audio Dock
1116− * 0x01, 0x00: Dock DAC 1 Left
1117− * 0x01, 0x04: Dock DAC 1 Right
1118− * 0x01, 0x08: Dock DAC 2 Left
1119− * 0x01, 0x0c: Dock DAC 2 Right
1120− * 0x01, 0x10: Dock DAC 3 Left
1121− * 0x01, 0x12: PHONES Left
1122− * 0x01, 0x14: Dock DAC 3 Right
1123− * 0x01, 0x16: PHONES Right
1124− * 0x01, 0x18: Dock DAC 4 Left
1125− * 0x01, 0x1a: S/PDIF Left
1126− * 0x01, 0x1c: Dock DAC 4 Right
1127− * 0x01, 0x1e: S/PDIF Right
1119+ * 0x01, 0x00-0x1f: 32 EDI channels to Audio Dock
1120+ * 0x00: Dock DAC 1 Left
1121+ * 0x04: Dock DAC 1 Right
1122+ * 0x08: Dock DAC 2 Left
1123+ * 0x0c: Dock DAC 2 Right
1124+ * 0x10: Dock DAC 3 Left
1125+ * 0x12: PHONES Left (n/a in 2x/4x mode; output mirrors DAC4 Left)
1126+ * 0x14: Dock DAC 3 Right
1127+ * 0x16: PHONES Right (n/a in 2x/4x mode; output mirrors DAC4 Right)
1128+ * 0x18: Dock DAC 4 Left
1129+ * 0x1a: S/PDIF Left
1130+ * 0x1c: Dock DAC 4 Right
1131+ * 0x1e: S/PDIF Right
11281132 * 0x02, 0x00: Hana S/PDIF Left
11291133 * 0x02, 0x01: Hana S/PDIF Right
1130− * 0x03, 0x00: Hanoa DAC Left
1131− * 0x03, 0x01: Hanoa DAC Right
1134+ * 0x03, 0x00: Hamoa DAC Left
1135+ * 0x03, 0x01: Hamoa DAC Right
11321136 * 0x04, 0x00-0x07: Hana ADAT
11331137 * 0x05, 0x00: I2S0 Left to Alice2
11341138 * 0x05, 0x01: I2S0 Right to Alice2
@@ -1140,40 +1144,29 @@ · 5 unmodified lines
11401144 * Hana2 never released, but used Tina
11411145 * Not needed.
11421146 *
1143− * Hana3, rev2 1010,1212,1616 using Tina
1144− * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1147+ * Hana3, rev2 1010,1212m,1616[m] using Tina
11451148 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina
1146− * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock
1147− * 0x01, 0x00: Dock DAC 1 Left
1148− * 0x01, 0x04: Dock DAC 1 Right
1149− * 0x01, 0x08: Dock DAC 2 Left
1150− * 0x01, 0x0c: Dock DAC 2 Right
1151− * 0x01, 0x10: Dock DAC 3 Left
1152− * 0x01, 0x12: Dock S/PDIF Left
1153− * 0x01, 0x14: Dock DAC 3 Right
1154− * 0x01, 0x16: Dock S/PDIF Right
1155− * 0x01, 0x18-0x1f: Dock ADAT 0-7
1149+ * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
1150+ * 0x00: Dock DAC 1 Left
1151+ * 0x04: Dock DAC 1 Right
1152+ * 0x08: Dock DAC 2 Left
1153+ * 0x0c: Dock DAC 2 Right
1154+ * 0x10: Dock DAC 3 Left
1155+ * 0x12: Dock S/PDIF Left
1156+ * 0x14: Dock DAC 3 Right
1157+ * 0x16: Dock S/PDIF Right
1158+ * 0x18-0x1f: Dock ADAT 0-7
11561159 * 0x02, 0x00: Hana3 S/PDIF Left
11571160 * 0x02, 0x01: Hana3 S/PDIF Right
1158− * 0x03, 0x00: Hanoa DAC Left
1159− * 0x03, 0x01: Hanoa DAC Right
1161+ * 0x03, 0x00: Hamoa DAC Left
1162+ * 0x03, 0x01: Hamoa DAC Right
11601163 * 0x04, 0x00-0x07: Hana3 ADAT 0-7
11611164 * 0x05, 0x00-0x0f: 16 EMU32B channels to Tina
11621165 * 0x06-0x07: Not used
11631166 *
11641167 * HanaLite, rev1 0404 using Alice2
1165− * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1166− * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
1167− * 0x01: Not used
1168− * 0x02, 0x00: S/PDIF Left
1169− * 0x02, 0x01: S/PDIF Right
1170− * 0x03, 0x00: DAC Left
1171− * 0x03, 0x01: DAC Right
1172− * 0x04-0x07: Not used
1173− *
1174− * HanaLiteLite, rev2 0404 using Alice2
1175− * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1176− * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
1168+ * HanaLiteLite, rev2 0404 using Tina
1169+ * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2/Tina
11771170 * 0x01: Not used
11781171 * 0x02, 0x00: S/PDIF Left
11791172 * 0x02, 0x01: S/PDIF Right
@@ -1182,35 +1175,21 @@ · 2 unmodified lines
11821175 * 0x04-0x07: Not used
11831176 *
11841177 * Mana, Cardbus 1616 using Tina2
1185− * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
11861178 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina2
1187− * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock
1188− * 0x01, 0x00: Dock DAC 1 Left
1189− * 0x01, 0x04: Dock DAC 1 Right
1190− * 0x01, 0x08: Dock DAC 2 Left
1191− * 0x01, 0x0c: Dock DAC 2 Right
1192− * 0x01, 0x10: Dock DAC 3 Left
1193− * 0x01, 0x12: Dock S/PDIF Left
1194− * 0x01, 0x14: Dock DAC 3 Right
1195− * 0x01, 0x16: Dock S/PDIF Right
1196− * 0x01, 0x18-0x1f: Dock ADAT 0-7
1179+ * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
1180+ * (same as rev2 1010)
11971181 * 0x02: Not used
11981182 * 0x03, 0x00: Mana DAC Left
11991183 * 0x03, 0x01: Mana DAC Right
12001184 * 0x04, 0x00-0x0f: 16 EMU32B channels to Tina2
12011185 * 0x05-0x07: Not used
1202− *
1203− *
12041186 */
1187+
12051188 /* 32-bit destinations of signal in the Hana FPGA. Destinations are either
1206− * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture
1207− * - 16 x EMU_DST_ALICE2_EMU32_X.
1208− */
1209−/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */
1210−/* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture.
1211− * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on
1212− * setup of mixer control for each destination - see emumixer.c -
1213− * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
1189+ * physical outputs of Hana, or outputs going to Alice2/Tina for capture -
1190+ * 16 x EMU_DST_ALICE2_EMU32_X (2x on rev2 boards). Which data is fed into
1191+ * a channel depends on the mixer control setting for each destination - see
1192+ * emumixer.c - snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
12141193 */
12151194 #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */
12161195 #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */
@@ -1270,8 +1249,12 @@ · 53 unmodified lines
12701249 #define EMU_DST_DOCK_SPDIF_RIGHT2 0x011f /* Audio Dock SPDIF Right, 2nd or 96kHz */
12711250 #define EMU_DST_HANA_SPDIF_LEFT1 0x0200 /* Hana SPDIF Left, 1st or 48kHz only */
12721251 #define EMU_DST_HANA_SPDIF_LEFT2 0x0202 /* Hana SPDIF Left, 2nd or 96kHz */
1252+#define EMU_DST_HANA_SPDIF_LEFT3 0x0204 /* Hana SPDIF Left, 3rd or 192kHz */
1253+#define EMU_DST_HANA_SPDIF_LEFT4 0x0206 /* Hana SPDIF Left, 4th or 192kHz */
12731254 #define EMU_DST_HANA_SPDIF_RIGHT1 0x0201 /* Hana SPDIF Right, 1st or 48kHz only */
12741255 #define EMU_DST_HANA_SPDIF_RIGHT2 0x0203 /* Hana SPDIF Right, 2nd or 96kHz */
1256+#define EMU_DST_HANA_SPDIF_RIGHT3 0x0205 /* Hana SPDIF Right, 3rd or 192kHz */
1257+#define EMU_DST_HANA_SPDIF_RIGHT4 0x0207 /* Hana SPDIF Right, 4th or 192kHz */
12751258 #define EMU_DST_HAMOA_DAC_LEFT1 0x0300 /* Hamoa DAC Left, 1st or 48kHz only */
12761259 #define EMU_DST_HAMOA_DAC_LEFT2 0x0302 /* Hamoa DAC Left, 2nd or 96kHz */
12771260 #define EMU_DST_HAMOA_DAC_LEFT3 0x0304 /* Hamoa DAC Left, 3rd or 192kHz */
@@ -1280,6 +1263,7 @@ · 2 unmodified lines
12801263 #define EMU_DST_HAMOA_DAC_RIGHT2 0x0303 /* Hamoa DAC Right, 2nd or 96kHz */
12811264 #define EMU_DST_HAMOA_DAC_RIGHT3 0x0305 /* Hamoa DAC Right, 3rd or 192kHz */
12821265 #define EMU_DST_HAMOA_DAC_RIGHT4 0x0307 /* Hamoa DAC Right, 4th or 192kHz */
1266+// In S/MUX mode, the samples of one channel are adjacent.
12831267 #define EMU_DST_HANA_ADAT 0x0400 /* Hana ADAT 8 channel out +0 to +7 */
12841268 #define EMU_DST_ALICE_I2S0_LEFT 0x0500 /* Alice2 I2S0 Left */
12851269 #define EMU_DST_ALICE_I2S0_RIGHT 0x0501 /* Alice2 I2S0 Right */
@@ -1289,39 +1273,32 @@ · 3 unmodified lines
12891273 #define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */
12901274
12911275 /* Additional destinations for 1616(M)/Microdock */
1292−/* Microdock S/PDIF OUT Left, 1st or 48kHz only */
1293−#define EMU_DST_MDOCK_SPDIF_LEFT1 0x0112
1294−/* Microdock S/PDIF OUT Left, 2nd or 96kHz */
1295−#define EMU_DST_MDOCK_SPDIF_LEFT2 0x0113
1296−/* Microdock S/PDIF OUT Right, 1st or 48kHz only */
1297−#define EMU_DST_MDOCK_SPDIF_RIGHT1 0x0116
1298−/* Microdock S/PDIF OUT Right, 2nd or 96kHz */
1299−#define EMU_DST_MDOCK_SPDIF_RIGHT2 0x0117
1300−/* Microdock S/PDIF ADAT 8 channel out +8 to +f */
1301−#define EMU_DST_MDOCK_ADAT 0x0118
1302−
1303−/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
1304−#define EMU_DST_MANA_DAC_LEFT 0x0300
1305−/* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
1306−#define EMU_DST_MANA_DAC_RIGHT 0x0301
1276+
1277+#define EMU_DST_MDOCK_SPDIF_LEFT1 0x0112 /* Microdock S/PDIF OUT Left, 1st or 48kHz only */
1278+#define EMU_DST_MDOCK_SPDIF_LEFT2 0x0113 /* Microdock S/PDIF OUT Left, 2nd or 96kHz */
1279+#define EMU_DST_MDOCK_SPDIF_RIGHT1 0x0116 /* Microdock S/PDIF OUT Right, 1st or 48kHz only */
1280+#define EMU_DST_MDOCK_SPDIF_RIGHT2 0x0117 /* Microdock S/PDIF OUT Right, 2nd or 96kHz */
1281+#define EMU_DST_MDOCK_ADAT 0x0118 /* Microdock S/PDIF ADAT 8 channel out +8 to +f */
1282+
1283+#define EMU_DST_MANA_DAC_LEFT 0x0300 /* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
1284+#define EMU_DST_MANA_DAC_RIGHT 0x0301 /* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
13071285
13081286 /************************************************************************************************/
1309−/* EMU1010m HANA Sources */
1287+/* EMU1010 Audio Sources */
13101288 /************************************************************************************************/
1311−/* Hana, original 1010,1212,1820 using Alice2
1312− * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
1313− * 0x00,0x00-0x1f: Silence
1314− * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
1315− * 0x01, 0x00: Dock Mic A
1316− * 0x01, 0x04: Dock Mic B
1317− * 0x01, 0x08: Dock ADC 1 Left
1318− * 0x01, 0x0c: Dock ADC 1 Right
1319− * 0x01, 0x10: Dock ADC 2 Left
1320− * 0x01, 0x14: Dock ADC 2 Right
1321− * 0x01, 0x18: Dock ADC 3 Left
1322− * 0x01, 0x1c: Dock ADC 3 Right
1323− * 0x02, 0x00: Hana ADC Left
1324− * 0x02, 0x01: Hana ADC Right
1289+/* Hana, original 1010,1212m,1820[m] using Alice2
1290+ * 0x00, 0x00-0x1f: Silence
1291+ * 0x01, 0x00-0x1f: 32 EDI channels from Audio Dock
1292+ * 0x00: Dock Mic A
1293+ * 0x04: Dock Mic B
1294+ * 0x08: Dock ADC 1 Left
1295+ * 0x0c: Dock ADC 1 Right
1296+ * 0x10: Dock ADC 2 Left
1297+ * 0x14: Dock ADC 2 Right
1298+ * 0x18: Dock ADC 3 Left
1299+ * 0x1c: Dock ADC 3 Right
1300+ * 0x02, 0x00: Hamoa ADC Left
1301+ * 0x02, 0x01: Hamoa ADC Right
13251302 * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
13261303 * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
13271304 * 0x04, 0x00-0x07: Hana ADAT
@@ -1332,23 +1309,20 @@ · 4 unmodified lines
13321309 * Hana2 never released, but used Tina
13331310 * Not needed.
13341311 *
1335− * Hana3, rev2 1010,1212,1616 using Tina
1336− * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
1337− * 0x00,0x00-0x1f: Silence
1338− * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
1339− * 0x01, 0x00: Dock Mic A
1340− * 0x01, 0x04: Dock Mic B
1341− * 0x01, 0x08: Dock ADC 1 Left
1342− * 0x01, 0x0c: Dock ADC 1 Right
1343− * 0x01, 0x10: Dock ADC 2 Left
1344− * 0x01, 0x12: Dock S/PDIF Left
1345− * 0x01, 0x14: Dock ADC 2 Right
1346− * 0x01, 0x16: Dock S/PDIF Right
1347− * 0x01, 0x18-0x1f: Dock ADAT 0-7
1348− * 0x01, 0x18: Dock ADC 3 Left
1349− * 0x01, 0x1c: Dock ADC 3 Right
1350− * 0x02, 0x00: Hanoa ADC Left
1351− * 0x02, 0x01: Hanoa ADC Right
1312+ * Hana3, rev2 1010,1212m,1616[m] using Tina
1313+ * 0x00, 0x00-0x1f: Silence
1314+ * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
1315+ * 0x00: Dock Mic A
1316+ * 0x04: Dock Mic B
1317+ * 0x08: Dock ADC 1 Left
1318+ * 0x0c: Dock ADC 1 Right
1319+ * 0x10: Dock ADC 2 Left
1320+ * 0x12: Dock S/PDIF Left
1321+ * 0x14: Dock ADC 2 Right
1322+ * 0x16: Dock S/PDIF Right
1323+ * 0x18-0x1f: Dock ADAT 0-7
1324+ * 0x02, 0x00: Hamoa ADC Left
1325+ * 0x02, 0x01: Hamoa ADC Right
13521326 * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
13531327 * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
13541328 * 0x04, 0x00-0x07: Hana3 ADAT
@@ -1357,58 +1331,32 @@ · 2 unmodified lines
13571331 * 0x06-0x07: Not used
13581332 *
13591333 * HanaLite, rev1 0404 using Alice2
1360− * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
1361− * 0x00,0x00-0x1f: Silence
1362− * 0x01: Not used
1363− * 0x02, 0x00: ADC Left
1364− * 0x02, 0x01: ADC Right
1365− * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
1366− * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
1367− * 0x04: Not used
1368− * 0x05, 0x00: S/PDIF Left
1369− * 0x05, 0x01: S/PDIF Right
1370− * 0x06-0x07: Not used
1371− *
1372− * HanaLiteLite, rev2 0404 using Alice2
1373− * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
1374− * 0x00,0x00-0x1f: Silence
1334+ * HanaLiteLite, rev2 0404 using Tina
1335+ * 0x00, 0x00-0x1f: Silence
13751336 * 0x01: Not used
13761337 * 0x02, 0x00: ADC Left
13771338 * 0x02, 0x01: ADC Right
1378− * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
1379− * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
1339+ * 0x03, 0x00-0x0f: 16 inputs from Alice2/Tina Emu32A output
1340+ * 0x03, 0x10-0x1f: 16 inputs from Alice2/Tina Emu32B output
13801341 * 0x04: Not used
13811342 * 0x05, 0x00: S/PDIF Left
13821343 * 0x05, 0x01: S/PDIF Right
13831344 * 0x06-0x07: Not used
13841345 *
13851346 * Mana, Cardbus 1616 using Tina2
1386− * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz
1387− * 0x00,0x00-0x1f: Silence
1388− * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock
1389− * 0x01, 0x00: Dock Mic A
1390− * 0x01, 0x04: Dock Mic B
1391− * 0x01, 0x08: Dock ADC 1 Left
1392− * 0x01, 0x0c: Dock ADC 1 Right
1393− * 0x01, 0x10: Dock ADC 2 Left
1394− * 0x01, 0x12: Dock S/PDIF Left
1395− * 0x01, 0x14: Dock ADC 2 Right
1396− * 0x01, 0x16: Dock S/PDIF Right
1397− * 0x01, 0x18-0x1f: Dock ADAT 0-7
1398− * 0x01, 0x18: Dock ADC 3 Left
1399− * 0x01, 0x1c: Dock ADC 3 Right
1347+ * 0x00, 0x00-0x1f: Silence
1348+ * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
1349+ * (same as rev2 1010)
14001350 * 0x02: Not used
1401− * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
1402− * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
1351+ * 0x03, 0x00-0x0f: 16 inputs from Tina2 Emu32A output
1352+ * 0x03, 0x10-0x1f: 16 inputs from Tina2 Emu32B output
14031353 * 0x04-0x07: Not used
1404− *
14051354 */
14061355
14071356 /* 32-bit sources of signal in the Hana FPGA. The sources are routed to
1408− * destinations using mixer control for each destination - see emumixer.c
1409− * Sources are either physical inputs of FPGA,
1410− * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A +
1411− * 16 x EMU_SRC_ALICE_EMU32B
1357+ * destinations using a mixer control for each destination - see emumixer.c.
1358+ * Sources are either physical inputs of Hana, or inputs from Alice2/Tina -
1359+ * 16 x EMU_SRC_ALICE_EMU32A + 16 x EMU_SRC_ALICE_EMU32B.
14121360 */
14131361 #define EMU_SRC_SILENCE 0x0000 /* Silence */
14141362 #define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */
@@ -1453,23 +1401,24 @@ · 38 unmodified lines
14531401 #define EMU_SRC_HAMOA_ADC_RIGHT4 0x0207 /* Hamoa ADC Right, 4th or 192kHz */
14541402 #define EMU_SRC_ALICE_EMU32A 0x0300 /* Alice2 EMU32a 16 outputs. +0 to +0xf */
14551403 #define EMU_SRC_ALICE_EMU32B 0x0310 /* Alice2 EMU32b 16 outputs. +0 to +0xf */
1404+// In S/MUX mode, the samples of one channel are adjacent.
14561405 #define EMU_SRC_HANA_ADAT 0x0400 /* Hana ADAT 8 channel in +0 to +7 */
14571406 #define EMU_SRC_HANA_SPDIF_LEFT1 0x0500 /* Hana SPDIF Left, 1st or 48kHz only */
14581407 #define EMU_SRC_HANA_SPDIF_LEFT2 0x0502 /* Hana SPDIF Left, 2nd or 96kHz */
1408+#define EMU_SRC_HANA_SPDIF_LEFT3 0x0504 /* Hana SPDIF Left, 3rd or 192kHz */
1409+#define EMU_SRC_HANA_SPDIF_LEFT4 0x0506 /* Hana SPDIF Left, 4th or 192kHz */
14591410 #define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */
14601411 #define EMU_SRC_HANA_SPDIF_RIGHT2 0x0503 /* Hana SPDIF Right, 2nd or 96kHz */
1412+#define EMU_SRC_HANA_SPDIF_RIGHT3 0x0505 /* Hana SPDIF Right, 3rd or 192kHz */
1413+#define EMU_SRC_HANA_SPDIF_RIGHT4 0x0507 /* Hana SPDIF Right, 4th or 192kHz */
14611414
14621415 /* Additional inputs for 1616(M)/Microdock */
1463−/* Microdock S/PDIF Left, 1st or 48kHz only */
1464−#define EMU_SRC_MDOCK_SPDIF_LEFT1 0x0112
1465−/* Microdock S/PDIF Left, 2nd or 96kHz */
1466−#define EMU_SRC_MDOCK_SPDIF_LEFT2 0x0113
1467−/* Microdock S/PDIF Right, 1st or 48kHz only */
1468−#define EMU_SRC_MDOCK_SPDIF_RIGHT1 0x0116
1469−/* Microdock S/PDIF Right, 2nd or 96kHz */
1470−#define EMU_SRC_MDOCK_SPDIF_RIGHT2 0x0117
1471−/* Microdock ADAT 8 channel in +8 to +f */
1472−#define EMU_SRC_MDOCK_ADAT 0x0118
1416+
1417+#define EMU_SRC_MDOCK_SPDIF_LEFT1 0x0112 /* Microdock S/PDIF Left, 1st or 48kHz only */
1418+#define EMU_SRC_MDOCK_SPDIF_LEFT2 0x0113 /* Microdock S/PDIF Left, 2nd or 96kHz */
1419+#define EMU_SRC_MDOCK_SPDIF_RIGHT1 0x0116 /* Microdock S/PDIF Right, 1st or 48kHz only */
1420+#define EMU_SRC_MDOCK_SPDIF_RIGHT2 0x0117 /* Microdock S/PDIF Right, 2nd or 96kHz */
1421+#define EMU_SRC_MDOCK_ADAT 0x0118 /* Microdock ADAT 8 channel in +8 to +f */
14731422
14741423 /* 0x600 and 0x700 no used */
14751424
@@ -1485,7 +1434,6 @@ enum { · 9 unmodified lines
14851434 struct snd_emu10k1;
14861435
14871436 struct snd_emu10k1_voice {
1488− struct snd_emu10k1 *emu;
14891437 int number;
14901438 unsigned int use: 1,
14911439 pcm: 1,
@@ -1599,10 +1547,8 @@ struct snd_emu10k1_fx8010_pcm { · 107 unmodified lines
15991547 };
16001548
16011549 struct snd_emu10k1_fx8010 {
1602− unsigned short fxbus_mask; /* used FX buses (bitmask) */
1603− unsigned short extin_mask; /* used external inputs (bitmask) */
1604− unsigned short extout_mask; /* used external outputs (bitmask) */
1605− unsigned short pad1;
1550+ unsigned short extin_mask; /* used external inputs (bitmask); not used for Audigy */
1551+ unsigned short extout_mask; /* used external outputs (bitmask); not used for Audigy */
16061552 unsigned int itram_size; /* internal TRAM size in samples */
16071553 struct snd_dma_buffer etram_pages; /* external TRAM pages and size */
16081554 unsigned int dbg; /* FX debugger register */
@@ -1639,14 +1585,26 @@ enum { · 30 unmodified lines
16391585 EMU_MODEL_EMU0404,
16401586 };
16411587
1588+// Chip-o-logy:
1589+// - All SB Live! cards use EMU10K1 chips
1590+// - All SB Audigy cards use CA* chips, termed "emu10k2" by the driver
1591+// - Original Audigy uses CA0100 "Alice"
1592+// - Audigy 2 uses CA0102/CA10200 "Alice2"
1593+// - Has an interface for CA0151 (P16V) "Alice3"
1594+// - Audigy 2 Value uses CA0108/CA10300 "Tina"
1595+// - Approximately a CA0102 with an on-chip CA0151 (P17V)
1596+// - Audigy 2 ZS NB uses CA0109 "Tina2"
1597+// - Cardbus version of CA0108
16421598 struct snd_emu_chip_details {
16431599 u32 vendor;
16441600 u32 device;
16451601 u32 subsystem;
16461602 unsigned char revision;
16471603 unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */
1604+ /* Redundant with emu10k2_chip being unset. */
16481605 unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
16491606 unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
1607+ /* Redundant with ca0108_chip being unset. */
16501608 unsigned char ca0108_chip; /* Audigy 2 Value */
16511609 unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
16521610 unsigned char ca0151_chip; /* P16V */
@@ -1656,8 +1614,8 @@ struct snd_emu_chip_details { · 3 unmodified lines
16561614 unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */
16571615 unsigned char ecard; /* APS EEPROM */
16581616 unsigned char emu_model; /* EMU model type */
1659− unsigned char spi_dac; /* SPI interface for DAC */
1660− unsigned char i2c_adc; /* I2C interface for ADC */
1617+ unsigned char spi_dac; /* SPI interface for DAC; requires ca0108_chip */
1618+ unsigned char i2c_adc; /* I2C interface for ADC; requires ca0108_chip */
16611619 unsigned char adc_1361t; /* Use Philips 1361T ADC */
16621620 unsigned char invert_shared_spdif; /* analog/digital switch inverted */
16631621 const char *driver;
@@ -1691,7 +1649,6 @@ struct snd_emu10k1 { · 27 unmodified lines
16911649 unsigned int revision; /* chip revision */
16921650 unsigned int serial; /* serial number */
16931651 unsigned short model; /* subsystem id */
1694− unsigned int card_type; /* EMU10K1_CARD_* */
16951652 unsigned int ecard_ctrl; /* ecard control bits */
16961653 unsigned int address_mode; /* address mode */
16971654 unsigned long dma_mask; /* PCI DMA mask */
@@ -1732,15 +1689,13 @@ struct snd_emu10k1 { · 34 unmodified lines
17321689 void *synth;
17331690 int (*get_synth_voice)(struct snd_emu10k1 *emu);
17341691
1735− spinlock_t reg_lock;
1736− spinlock_t emu_lock;
1737− spinlock_t voice_lock;
1692+ spinlock_t reg_lock; // high-level driver lock
1693+ spinlock_t emu_lock; // low-level i/o lock
1694+ spinlock_t voice_lock; // voice allocator lock
17381695 spinlock_t spi_lock; /* serialises access to spi port */
17391696 spinlock_t i2c_lock; /* serialises access to i2c port */
17401697
17411698 struct snd_emu10k1_voice voices[NUM_G];
1742− struct snd_emu10k1_voice p16v_voices[4];
1743− struct snd_emu10k1_voice p16v_capture_voice;
17441699 int p16v_device_offset;
17451700 u32 p16v_capture_source;
17461701 u32 p16v_capture_channel;
@@ -1760,11 +1715,11 @@ struct snd_emu10k1 { · 13 unmodified lines
17601715 void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
17611716 void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
17621717 void (*dsp_interrupt)(struct snd_emu10k1 *emu);
1718+ void (*p16v_interrupt)(struct snd_emu10k1 *emu);
17631719
17641720 struct snd_pcm_substream *pcm_capture_substream;
17651721 struct snd_pcm_substream *pcm_capture_mic_substream;
17661722 struct snd_pcm_substream *pcm_capture_efx_substream;
1767− struct snd_pcm_substream *pcm_playback_efx_substream;
17681723
17691724 struct snd_timer *timer;
17701725
@@ -1824,9 +1779,9 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, · 53 unmodified lines
18241779 void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
18251780 int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
18261781 int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
1827−int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value);
1828−int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value);
1829−int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src);
1782+void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
1783+void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value);
1784+void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src);
18301785 unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
18311786 void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
18321787 void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
include/sound/hda-mlink.h+166−0
@@ -0,0 +1,166 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2+/*
3+ * This file is provided under a dual BSD/GPLv2 license. When using or
4+ * redistributing this file, you may do so under either license.
5+ *
6+ * Copyright(c) 2022-2023 Intel Corporation. All rights reserved.
7+ */
8+
9+struct hdac_bus;
10+struct hdac_ext_link;
11+
12+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
13+
14+int hda_bus_ml_init(struct hdac_bus *bus);
15+void hda_bus_ml_free(struct hdac_bus *bus);
16+
17+int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid);
18+void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable);
19+bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid);
20+
21+int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd);
22+int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd);
23+
24+int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid);
25+int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus);
26+
27+void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
28+void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink);
29+
30+int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid);
31+int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus);
32+
33+bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid);
34+bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus);
35+
36+int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
37+int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
38+
39+int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink);
40+int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
41+
42+int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink);
43+int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
44+
45+int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
46+
47+void hda_bus_ml_put_all(struct hdac_bus *bus);
48+void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
49+int hda_bus_ml_resume(struct hdac_bus *bus);
50+int hda_bus_ml_suspend(struct hdac_bus *bus);
51+
52+struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
53+struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
54+
55+struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid);
56+
57+int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable);
58+
59+#else
60+
61+static inline int
62+hda_bus_ml_init(struct hdac_bus *bus) { return 0; }
63+
64+static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
65+
66+static inline int
67+hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) { return 0; }
68+
69+static inline void
70+hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { }
71+
72+static inline bool
73+hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) { return false; }
74+
75+static inline int
76+hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd)
77+{
78+ return 0;
79+}
80+
81+static inline int
82+hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd)
83+{
84+ return 0;
85+}
86+
87+static inline int
88+hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
89+{
90+ return 0;
91+}
92+
93+static inline int
94+hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus) { return 0; }
95+
96+static inline void
97+hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { }
98+
99+static inline void
100+hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink) { }
101+
102+static inline int
103+hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) { return 0; }
104+
105+static inline int
106+hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus) { return 0; }
107+
108+static inline bool
109+hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid) { return false; }
110+
111+static inline bool
112+hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus) { return false; }
113+
114+static inline int
115+hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
116+{
117+ return 0;
118+}
119+
120+static inline int
121+hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
122+{
123+ return 0;
124+}
125+
126+static inline int
127+hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink)
128+{
129+ return 0;
130+}
131+
132+static inline int
133+hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
134+{
135+ return 0;
136+}
137+
138+static inline int
139+hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
140+
141+static inline int
142+hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
143+
144+static inline int
145+hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
146+
147+static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
148+static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
149+static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
150+static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
151+
152+static inline struct hdac_ext_link *
153+hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }
154+
155+static inline struct hdac_ext_link *
156+hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; }
157+
158+static inline struct mutex *
159+hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) { return NULL; }
160+
161+static inline int
162+hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable)
163+{
164+ return 0;
165+}
166+#endif /* CONFIG_SND_SOC_SOF_HDA */
include/sound/hda_register.h+38−2
@@ -258,14 +258,27 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; · 257 unmodified lines
258258 #define AZX_ML_BASE 0x40
259259 #define AZX_ML_INTERVAL 0x40
260260
261+/* HDaudio registers valid for HDaudio and HDaudio extended links */
261262 #define AZX_REG_ML_LCAP 0x00
262−#define AZX_REG_ML_LCTL 0x04
263263
264+#define AZX_ML_HDA_LCAP_ALT BIT(28)
265+#define AZX_ML_HDA_LCAP_ALT_HDA 0x0
266+#define AZX_ML_HDA_LCAP_ALT_HDA_EXT 0x1
267+
268+#define AZX_ML_HDA_LCAP_INTC BIT(27) /* only used if ALT == 1 */
269+#define AZX_ML_HDA_LCAP_OFLS BIT(26) /* only used if ALT == 1 */
270+#define AZX_ML_HDA_LCAP_LSS BIT(23) /* only used if ALT == 1 */
271+#define AZX_ML_HDA_LCAP_SLCOUNT GENMASK(22, 20) /* only used if ALT == 1 */
272+
273+#define AZX_REG_ML_LCTL 0x04
274+#define AZX_ML_LCTL_INTSTS BIT(31) /* only used if ALT == 1 */
264275 #define AZX_ML_LCTL_CPA BIT(23)
265276 #define AZX_ML_LCTL_CPA_SHIFT 23
266277 #define AZX_ML_LCTL_SPA BIT(16)
267278 #define AZX_ML_LCTL_SPA_SHIFT 16
268−#define AZX_ML_LCTL_SCF GENMASK(3, 0)
279+#define AZX_ML_LCTL_INTEN BIT(5) /* only used if ALT == 1 */
280+#define AZX_ML_LCTL_OFLEN BIT(4) /* only used if ALT == 1 */
281+#define AZX_ML_LCTL_SCF GENMASK(3, 0) /* only used if ALT == 0 */
269282
270283 #define AZX_REG_ML_LOSIDV 0x08
271284
@@ -273,12 +286,35 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; · 1 unmodified line
273286 #define AZX_ML_LOSIDV_STREAM_MASK 0xFFFE
274287
275288 #define AZX_REG_ML_LSDIID 0x0C
289+#define AZX_REG_ML_LSDIID_OFFSET(x) (0x0C + (x) * 0x02) /* only used if ALT == 1 */
290+
291+/* HDaudio registers only valid if LCAP.ALT == 0 */
276292 #define AZX_REG_ML_LPSOO 0x10
277293 #define AZX_REG_ML_LPSIO 0x12
278294 #define AZX_REG_ML_LWALFC 0x18
279295 #define AZX_REG_ML_LOUTPAY 0x20
280296 #define AZX_REG_ML_LINPAY 0x30
281297
298+/* HDaudio Extended link registers only valid if LCAP.ALT == 1 */
299+#define AZX_REG_ML_LSYNC 0x1C
300+
301+#define AZX_REG_ML_LSYNC_CMDSYNC BIT(24)
302+#define AZX_REG_ML_LSYNC_CMDSYNC_SHIFT 24
303+#define AZX_REG_ML_LSYNC_SYNCGO BIT(23)
304+#define AZX_REG_ML_LSYNC_SYNCPU BIT(20)
305+#define AZX_REG_ML_LSYNC_SYNCPRD GENMASK(19, 0)
306+
307+#define AZX_REG_ML_LEPTR 0x20
308+
309+#define AZX_REG_ML_LEPTR_ID GENMASK(31, 24)
310+#define AZX_REG_ML_LEPTR_ID_SHIFT 24
311+#define AZX_REG_ML_LEPTR_ID_SDW 0x00
312+#define AZX_REG_ML_LEPTR_ID_INTEL_SSP 0xC0
313+#define AZX_REG_ML_LEPTR_ID_INTEL_DMIC 0xC1
314+#define AZX_REG_ML_LEPTR_ID_INTEL_UAOL 0xC2
315+#define AZX_REG_ML_LEPTR_VER GENMASK(23, 20)
316+#define AZX_REG_ML_LEPTR_PTR GENMASK(19, 0)
317+
282318 /* registers for DMA Resume Capability Structure */
283319 #define AZX_DRSM_CAP_ID 0x5
284320 #define AZX_REG_DRSM_CTL 0x4
include/sound/pcm-indirect.h+16−6
@@ -44,7 +44,7 @@ snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream, · 43 unmodified lines
4444 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
4545 diff += runtime->boundary;
4646 if (diff < 0)
47− return -EINVAL;
47+ return -EPIPE;
4848 rec->sw_ready += (int)frames_to_bytes(runtime, diff);
4949 rec->appl_ptr = appl_ptr;
5050 }
@@ -83,6 +83,8 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream, · 32 unmodified lines
8383 struct snd_pcm_indirect *rec, unsigned int ptr)
8484 {
8585 int bytes = ptr - rec->hw_io;
86+ int err;
87+
8688 if (bytes < 0)
8789 bytes += rec->hw_buffer_size;
8890 rec->hw_io = ptr;
@@ -90,8 +92,11 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream, · 1 unmodified line
9092 rec->sw_io += bytes;
9193 if (rec->sw_io >= rec->sw_buffer_size)
9294 rec->sw_io -= rec->sw_buffer_size;
93− if (substream->ops->ack)
94− substream->ops->ack(substream);
95+ if (substream->ops->ack) {
96+ err = substream->ops->ack(substream);
97+ if (err == -EPIPE)
98+ return SNDRV_PCM_POS_XRUN;
99+ }
95100 return bytes_to_frames(substream->runtime, rec->sw_io);
96101 }
97102
@@ -112,7 +117,7 @@ snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, · 14 unmodified lines
112117 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
113118 diff += runtime->boundary;
114119 if (diff < 0)
115− return -EINVAL;
120+ return -EPIPE;
116121 rec->sw_ready -= frames_to_bytes(runtime, diff);
117122 rec->appl_ptr = appl_ptr;
118123 }
@@ -152,6 +157,8 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream, · 33 unmodified lines
152157 {
153158 int qsize;
154159 int bytes = ptr - rec->hw_io;
160+ int err;
161+
155162 if (bytes < 0)
156163 bytes += rec->hw_buffer_size;
157164 rec->hw_io = ptr;
@@ -162,8 +169,11 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream, · 4 unmodified lines
162169 rec->sw_io += bytes;
163170 if (rec->sw_io >= rec->sw_buffer_size)
164171 rec->sw_io -= rec->sw_buffer_size;
165− if (substream->ops->ack)
166− substream->ops->ack(substream);
172+ if (substream->ops->ack) {
173+ err = substream->ops->ack(substream);
174+ if (err == -EPIPE)
175+ return SNDRV_PCM_POS_XRUN;
176+ }
167177 return bytes_to_frames(substream->runtime, rec->sw_io);
168178 }
169179
include/sound/pcm.h+7−7
@@ -378,18 +378,18 @@ struct snd_pcm_runtime { · 377 unmodified lines
378378 unsigned int rate_den;
379379 unsigned int no_period_wakeup: 1;
380380
381− /* -- SW params -- */
382− int tstamp_mode; /* mmap timestamp is updated */
381+ /* -- SW params; see struct snd_pcm_sw_params for comments -- */
382+ int tstamp_mode;
383383 unsigned int period_step;
384384 snd_pcm_uframes_t start_threshold;
385385 snd_pcm_uframes_t stop_threshold;
386− snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
387− noise is nearest than this */
388− snd_pcm_uframes_t silence_size; /* Silence filling size */
389− snd_pcm_uframes_t boundary; /* pointers wrap point */
386+ snd_pcm_uframes_t silence_threshold;
387+ snd_pcm_uframes_t silence_size;
388+ snd_pcm_uframes_t boundary;
390389
390+ /* internal data of auto-silencer */
391391 snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
392− snd_pcm_uframes_t silence_filled; /* size filled with silence */
392+ snd_pcm_uframes_t silence_filled; /* already filled part of silence area */
393393
394394 union snd_pcm_sync_id sync; /* hardware synchronization ID */
395395
include/sound/soc-card.h+16−1
@@ -9,10 +9,25 @@ · 8 unmodified lines
99 #define __SOC_CARD_H
1010
1111 enum snd_soc_card_subclass {
12− SND_SOC_CARD_CLASS_INIT = 0,
12+ SND_SOC_CARD_CLASS_ROOT = 0,
1313 SND_SOC_CARD_CLASS_RUNTIME = 1,
1414 };
1515
16+static inline void snd_soc_card_mutex_lock_root(struct snd_soc_card *card)
17+{
18+ mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_ROOT);
19+}
20+
21+static inline void snd_soc_card_mutex_lock(struct snd_soc_card *card)
22+{
23+ mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
24+}
25+
26+static inline void snd_soc_card_mutex_unlock(struct snd_soc_card *card)
27+{
28+ mutex_unlock(&card->mutex);
29+}
30+
1631 struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
1732 const char *name);
1833 int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
include/sound/soc-dapm.h+0−5
@@ -527,11 +527,6 @@ enum snd_soc_dapm_type { · 526 unmodified lines
527527 SND_SOC_DAPM_TYPE_COUNT
528528 };
529529
530−enum snd_soc_dapm_subclass {
531− SND_SOC_DAPM_CLASS_INIT = 0,
532− SND_SOC_DAPM_CLASS_RUNTIME = 1,
533−};
534−
535530 /*
536531 * DAPM audio route definition.
537532 *
include/sound/soc-dpcm.h+0−1
@@ -91,7 +91,6 @@ struct snd_soc_dpcm_runtime { · 90 unmodified lines
9191 struct list_head fe_clients;
9292
9393 int users;
94− struct snd_pcm_runtime *runtime;
9594 struct snd_pcm_hw_params hw_params;
9695
9796 /* state and update */
include/sound/soc.h+109−10
@@ -684,8 +684,11 @@ struct snd_soc_dai_link { · 683 unmodified lines
684684
685685 int id; /* optional ID for machine driver link identification */
686686
687− const struct snd_soc_pcm_stream *params;
688− unsigned int num_params;
687+ /*
688+ * for Codec2Codec
689+ */
690+ const struct snd_soc_pcm_stream *c2c_params;
691+ unsigned int num_c2c_params;
689692
690693 unsigned int dai_fmt; /* format to set on init */
691694
@@ -1065,7 +1068,7 @@ struct snd_soc_pcm_runtime { · 373 unmodified lines
10651068 struct snd_soc_dai_link *dai_link;
10661069 struct snd_pcm_ops ops;
10671070
1068− unsigned int params_select; /* currently selected param for dai link */
1071+ unsigned int c2c_params_select; /* currently selected c2c_param for dai link */
10691072
10701073 /* Dynamic PCM BE runtime data */
10711074 struct snd_soc_dpcm_runtime dpcm[SNDRV_PCM_STREAM_LAST + 1];
@@ -1302,8 +1305,9 @@ int snd_soc_of_get_dai_link_cpus(struct device *dev, · 230 unmodified lines
13021305 struct snd_soc_dai_link *dai_link);
13031306 void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link);
13041307
1305−int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
1306− struct snd_soc_dai_link *dai_link);
1308+int snd_soc_add_pcm_runtimes(struct snd_soc_card *card,
1309+ struct snd_soc_dai_link *dai_link,
1310+ int num_dai_link);
13071311 void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
13081312 struct snd_soc_pcm_runtime *rtd);
13091313
@@ -1360,17 +1364,112 @@ extern struct dentry *snd_soc_debugfs_root; · 50 unmodified lines
13601364
13611365 extern const struct dev_pm_ops snd_soc_pm_ops;
13621366
1363−/* Helper functions */
1364−static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)
1367+/*
1368+ * DAPM helper functions
1369+ */
1370+enum snd_soc_dapm_subclass {
1371+ SND_SOC_DAPM_CLASS_ROOT = 0,
1372+ SND_SOC_DAPM_CLASS_RUNTIME = 1,
1373+};
1374+
1375+static inline void _snd_soc_dapm_mutex_lock_root_c(struct snd_soc_card *card)
1376+{
1377+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_ROOT);
1378+}
1379+
1380+static inline void _snd_soc_dapm_mutex_lock_c(struct snd_soc_card *card)
1381+{
1382+ mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1383+}
1384+
1385+static inline void _snd_soc_dapm_mutex_unlock_c(struct snd_soc_card *card)
1386+{
1387+ mutex_unlock(&card->dapm_mutex);
1388+}
1389+
1390+static inline void _snd_soc_dapm_mutex_assert_held_c(struct snd_soc_card *card)
1391+{
1392+ lockdep_assert_held(&card->dapm_mutex);
1393+}
1394+
1395+static inline void _snd_soc_dapm_mutex_lock_root_d(struct snd_soc_dapm_context *dapm)
1396+{
1397+ _snd_soc_dapm_mutex_lock_root_c(dapm->card);
1398+}
1399+
1400+static inline void _snd_soc_dapm_mutex_lock_d(struct snd_soc_dapm_context *dapm)
1401+{
1402+ _snd_soc_dapm_mutex_lock_c(dapm->card);
1403+}
1404+
1405+static inline void _snd_soc_dapm_mutex_unlock_d(struct snd_soc_dapm_context *dapm)
13651406 {
1366− mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1407+ _snd_soc_dapm_mutex_unlock_c(dapm->card);
13671408 }
13681409
1369−static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
1410+static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context *dapm)
13701411 {
1371− mutex_unlock(&dapm->card->dapm_mutex);
1412+ _snd_soc_dapm_mutex_assert_held_c(dapm->card);
13721413 }
13731414
1415+#define snd_soc_dapm_mutex_lock_root(x) _Generic((x), \
1416+ struct snd_soc_card * : _snd_soc_dapm_mutex_lock_root_c, \
1417+ struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_lock_root_d)(x)
1418+#define snd_soc_dapm_mutex_lock(x) _Generic((x), \
1419+ struct snd_soc_card * : _snd_soc_dapm_mutex_lock_c, \
1420+ struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_lock_d)(x)
1421+#define snd_soc_dapm_mutex_unlock(x) _Generic((x), \
1422+ struct snd_soc_card * : _snd_soc_dapm_mutex_unlock_c, \
1423+ struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_unlock_d)(x)
1424+#define snd_soc_dapm_mutex_assert_held(x) _Generic((x), \
1425+ struct snd_soc_card * : _snd_soc_dapm_mutex_assert_held_c, \
1426+ struct snd_soc_dapm_context * : _snd_soc_dapm_mutex_assert_held_d)(x)
1427+
1428+/*
1429+ * PCM helper functions
1430+ */
1431+static inline void _snd_soc_dpcm_mutex_lock_c(struct snd_soc_card *card)
1432+{
1433+ mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass);
1434+}
1435+
1436+static inline void _snd_soc_dpcm_mutex_unlock_c(struct snd_soc_card *card)
1437+{
1438+ mutex_unlock(&card->pcm_mutex);
1439+}
1440+
1441+static inline void _snd_soc_dpcm_mutex_assert_held_c(struct snd_soc_card *card)
1442+{
1443+ lockdep_assert_held(&card->pcm_mutex);
1444+}
1445+
1446+static inline void _snd_soc_dpcm_mutex_lock_r(struct snd_soc_pcm_runtime *rtd)
1447+{
1448+ _snd_soc_dpcm_mutex_lock_c(rtd->card);
1449+}
1450+
1451+static inline void _snd_soc_dpcm_mutex_unlock_r(struct snd_soc_pcm_runtime *rtd)
1452+{
1453+ _snd_soc_dpcm_mutex_unlock_c(rtd->card);
1454+}
1455+
1456+static inline void _snd_soc_dpcm_mutex_assert_held_r(struct snd_soc_pcm_runtime *rtd)
1457+{
1458+ _snd_soc_dpcm_mutex_assert_held_c(rtd->card);
1459+}
1460+
1461+#define snd_soc_dpcm_mutex_lock(x) _Generic((x), \
1462+ struct snd_soc_card * : _snd_soc_dpcm_mutex_lock_c, \
1463+ struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_lock_r)(x)
1464+
1465+#define snd_soc_dpcm_mutex_unlock(x) _Generic((x), \
1466+ struct snd_soc_card * : _snd_soc_dpcm_mutex_unlock_c, \
1467+ struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_unlock_r)(x)
1468+
1469+#define snd_soc_dpcm_mutex_assert_held(x) _Generic((x), \
1470+ struct snd_soc_card * : _snd_soc_dpcm_mutex_assert_held_c, \
1471+ struct snd_soc_pcm_runtime * : _snd_soc_dpcm_mutex_assert_held_r)(x)
1472+
13741473 #include <sound/soc-component.h>
13751474 #include <sound/soc-card.h>
13761475 #include <sound/soc-jack.h>
include/sound/sof.h+5−0
@@ -21,6 +21,7 @@ struct snd_sof_dev; · 20 unmodified lines
2121 /**
2222 * enum sof_fw_state - DSP firmware state definitions
2323 * @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started
24+ * @SOF_DSPLESS_MODE: DSP is not used
2425 * @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple)
2526 * @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress
2627 * @SOF_FW_BOOT_FAILED: firmware boot failed
@@ -31,6 +32,7 @@ struct snd_sof_dev; · 4 unmodified lines
3132 */
3233 enum sof_fw_state {
3334 SOF_FW_BOOT_NOT_STARTED = 0,
35+ SOF_DSPLESS_MODE,
3436 SOF_FW_BOOT_PREPARE,
3537 SOF_FW_BOOT_IN_PROGRESS,
3638 SOF_FW_BOOT_FAILED,
@@ -130,6 +132,9 @@ struct sof_dev_desc { · 93 unmodified lines
130132 unsigned int ipc_supported_mask;
131133 enum sof_ipc_type ipc_default;
132134
135+ /* The platform supports DSPless mode */
136+ bool dspless_mode_supported;
137+
133138 /* defaults paths for firmware, library and topology files */
134139 const char *default_fw_path[SOF_IPC_TYPE_COUNT];
135140 const char *default_lib_path[SOF_IPC_TYPE_COUNT];
include/sound/sof/ipc4/header.h+33−0
@@ -176,6 +176,10 @@ enum sof_ipc4_pipeline_state { · 175 unmodified lines
176176 #define SOF_IPC4_GLB_PIPE_EXT_LP_MASK BIT(0)
177177 #define SOF_IPC4_GLB_PIPE_EXT_LP(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_LP_SHIFT)
178178
179+#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID_SHIFT 20
180+#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID_MASK GENMASK(23, 20)
181+#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_CORE_ID_SHIFT)
182+
179183 /* pipeline set state ipc msg */
180184 #define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
181185 #define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
@@ -192,6 +196,35 @@ enum sof_ipc4_pipeline_state { · 10 unmodified lines
192196 #define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16
193197 #define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT)
194198
199+/* chain dma ipc message */
200+#define SOF_IPC4_GLB_CHAIN_DMA_HOST_ID_SHIFT 0
201+#define SOF_IPC4_GLB_CHAIN_DMA_HOST_ID_MASK GENMASK(4, 0)
202+#define SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(x) (((x) << SOF_IPC4_GLB_CHAIN_DMA_HOST_ID_SHIFT) & \
203+ SOF_IPC4_GLB_CHAIN_DMA_HOST_ID_MASK)
204+
205+#define SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_SHIFT 8
206+#define SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK GENMASK(12, 8)
207+#define SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(x) (((x) << SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_SHIFT) & \
208+ SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK)
209+
210+#define SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE_SHIFT 16
211+#define SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE_MASK BIT(16)
212+#define SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE(x) (((x) & 1) << SOF_IPC4_GLB_CHAIN_DMA_ALLOCATE_SHIFT)
213+
214+#define SOF_IPC4_GLB_CHAIN_DMA_ENABLE_SHIFT 17
215+#define SOF_IPC4_GLB_CHAIN_DMA_ENABLE_MASK BIT(17)
216+#define SOF_IPC4_GLB_CHAIN_DMA_ENABLE(x) (((x) & 1) << SOF_IPC4_GLB_CHAIN_DMA_ENABLE_SHIFT)
217+
218+#define SOF_IPC4_GLB_CHAIN_DMA_SCS_SHIFT 18
219+#define SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK BIT(18)
220+#define SOF_IPC4_GLB_CHAIN_DMA_SCS(x) (((x) & 1) << SOF_IPC4_GLB_CHAIN_DMA_SCS_SHIFT)
221+
222+#define SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE_SHIFT 0
223+#define SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE_MASK GENMASK(24, 0)
224+#define SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(x) (((x) << \
225+ SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE_SHIFT) & \
226+ SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE_MASK)
227+
195228 enum sof_ipc4_channel_config {
196229 /* one channel only. */
197230 SOF_IPC4_CHANNEL_CONFIG_MONO,
include/uapi/sound/asound.h+10−4
@@ -429,9 +429,14 @@ struct snd_pcm_sw_params { · 428 unmodified lines
429429 snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */
430430 snd_pcm_uframes_t xfer_align; /* obsolete: xfer size need to be a multiple */
431431 snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */
432− snd_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */
433− snd_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */
434− snd_pcm_uframes_t silence_size; /* silence block size */
432+ /*
433+ * The following two thresholds alleviate playback buffer underruns; when
434+ * hw_avail drops below the threshold, the respective action is triggered:
435+ */
436+ snd_pcm_uframes_t stop_threshold; /* - stop playback */
437+ snd_pcm_uframes_t silence_threshold; /* - pre-fill buffer with silence */
438+ snd_pcm_uframes_t silence_size; /* max size of silence pre-fill; when >= boundary,
439+ * fill played area with silence immediately */
435440 snd_pcm_uframes_t boundary; /* pointers wrap point */
436441 unsigned int proto; /* protocol version */
437442 unsigned int tstamp_type; /* timestamp type (req. proto >= 2.0.12) */
@@ -570,7 +575,8 @@ struct __snd_pcm_mmap_status64 { · 132 unmodified lines
570575 struct __snd_pcm_mmap_control64 {
571576 __pad_before_uframe __pad1;
572577 snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */
573− __pad_before_uframe __pad2;
578+ __pad_before_uframe __pad2; // This should be __pad_after_uframe, but binary
579+ // backwards compatibility constraints prevent a fix.
574580
575581 __pad_before_uframe __pad3;
576582 snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */
include/uapi/sound/emu10k1.h+96−54
@@ -15,9 +15,6 @@ · 14 unmodified lines
1515 * ---- FX8010 ----
1616 */
1717
18−#define EMU10K1_CARD_CREATIVE 0x00000000
19−#define EMU10K1_CARD_EMUAPS 0x00000001
20−
2118 #define EMU10K1_FX8010_PCM_COUNT 8
2219
2320 /*
@@ -46,6 +43,19 @@ · 22 unmodified lines
4643 #define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */
4744 #define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */
4845
46+#define LOWORD_OPX_MASK 0x000ffc00 /* Instruction operand X */
47+#define LOWORD_OPY_MASK 0x000003ff /* Instruction operand Y */
48+#define HIWORD_OPCODE_MASK 0x00f00000 /* Instruction opcode */
49+#define HIWORD_RESULT_MASK 0x000ffc00 /* Instruction result */
50+#define HIWORD_OPA_MASK 0x000003ff /* Instruction operand A */
51+
52+/* Audigy Soundcards have a different instruction format */
53+#define A_LOWORD_OPX_MASK 0x007ff000
54+#define A_LOWORD_OPY_MASK 0x000007ff
55+#define A_HIWORD_OPCODE_MASK 0x0f000000
56+#define A_HIWORD_RESULT_MASK 0x007ff000
57+#define A_HIWORD_OPA_MASK 0x000007ff
58+
4959 /* GPRs */
5060 #define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */
5161 #define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */
@@ -53,6 +63,16 @@ · 1 unmodified line
5363 #define FXBUS2(x) (0x30 + (x)) /* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */
5464 /* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */
5565
66+#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f FX buses */
67+#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x0f physical ins */
68+#define A_P16VIN(x) (0x50 + (x)) /* x = 0x00 - 0x0f p16v ins (A2 only) "EMU32 inputs" */
69+#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f physical outs -> A_FXWC1 0x79-7f unknown */
70+#define A_FXBUS2(x) (0x80 + (x)) /* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
71+#define A_EMU32OUTH(x) (0xa0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" */
72+#define A_EMU32OUTL(x) (0xb0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_01 - _0F" */
73+#define A3_EMU32IN(x) (0x160 + (x)) /* x = 0x00 - 0x1f "EMU32_IN_00 - _1F" - Only when .device = 0x0008 */
74+#define A3_EMU32OUT(x) (0x1E0 + (x)) /* x = 0x00 - 0x1f "EMU32_OUT_00 - _1F" - Only when .device = 0x0008 */
75+
5676 #define C_00000000 0x40
5777 #define C_00000001 0x41
5878 #define C_00000002 0x42
@@ -81,12 +101,66 @@ · 22 unmodified lines
81101 #define GPR_NOISE1 0x59 /* noise source */
82102 #define GPR_IRQ 0x5a /* IRQ register */
83103 #define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */
104+
105+/* Audigy constants */
106+#define A_C_00000000 0xc0
107+#define A_C_00000001 0xc1
108+#define A_C_00000002 0xc2
109+#define A_C_00000003 0xc3
110+#define A_C_00000004 0xc4
111+#define A_C_00000008 0xc5
112+#define A_C_00000010 0xc6
113+#define A_C_00000020 0xc7
114+#define A_C_00000100 0xc8
115+#define A_C_00010000 0xc9
116+#define A_C_00000800 0xca
117+#define A_C_10000000 0xcb
118+#define A_C_20000000 0xcc
119+#define A_C_40000000 0xcd
120+#define A_C_80000000 0xce
121+#define A_C_7fffffff 0xcf
122+#define A_C_ffffffff 0xd0
123+#define A_C_fffffffe 0xd1
124+#define A_C_c0000000 0xd2
125+#define A_C_4f1bbcdc 0xd3
126+#define A_C_5a7ef9db 0xd4
127+#define A_C_00100000 0xd5
128+#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */
129+#define A_GPR_COND 0xd7 /* CCR, condition register */
130+#define A_GPR_NOISE0 0xd8 /* noise source */
131+#define A_GPR_NOISE1 0xd9 /* noise source */
132+#define A_GPR_IRQ 0xda /* IRQ register */
133+#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */
134+#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */
135+
136+/* Each FX general purpose register is 32 bits in length, all bits are used */
137+#define FXGPREGBASE 0x100 /* FX general purpose registers base */
138+#define A_FXGPREGBASE 0x400 /* Audigy GPRs, 0x400 to 0x5ff */
139+
140+#define A_TANKMEMCTLREGBASE 0x100 /* Tank memory control registers base - only for Audigy */
141+#define A_TANKMEMCTLREG_MASK 0x1f /* only 5 bits used - only for Audigy */
142+
143+/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is */
144+/* decompressed back to 20 bits on a read. There are a total of 160 locations, the last 32 */
145+/* locations are for external TRAM. */
146+#define TANKMEMDATAREGBASE 0x200 /* Tank memory data registers base */
147+#define TANKMEMDATAREG_MASK 0x000fffff /* 20 bit tank audio data field */
148+
149+/* Combined address field and memory opcode or flag field. 160 locations, last 32 are external */
150+#define TANKMEMADDRREGBASE 0x300 /* Tank memory address registers base */
151+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */
152+#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */
153+#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */
154+#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */
155+#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */
156+
84157 #define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
85158 #define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
86159 #define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
87160 #define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
88161 #define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
89162
163+#define A_GPR(x) (A_FXGPREGBASE + (x))
90164 #define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
91165 #define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
92166 #define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
@@ -94,17 +168,6 @@ · 1 unmodified line
94168 #define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
95169 #define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
96170
97−#define A_FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x3f FX buses */
98−#define A_EXTIN(x) (0x40 + (x)) /* x = 0x00 - 0x0f physical ins */
99−#define A_P16VIN(x) (0x50 + (x)) /* x = 0x00 - 0x0f p16v ins (A2 only) "EMU32 inputs" */
100−#define A_EXTOUT(x) (0x60 + (x)) /* x = 0x00 - 0x1f physical outs -> A_FXWC1 0x79-7f unknown */
101−#define A_FXBUS2(x) (0x80 + (x)) /* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
102−#define A_EMU32OUTH(x) (0xa0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
103−#define A_EMU32OUTL(x) (0xb0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
104−#define A3_EMU32IN(x) (0x160 + (x)) /* x = 0x00 - 0x3f "EMU32_IN_00 - _3F" - Only when .device = 0x0008 */
105−#define A3_EMU32OUT(x) (0x1E0 + (x)) /* x = 0x00 - 0x0f "EMU32_OUT_00 - _3F" - Only when .device = 0x0008 */
106−#define A_GPR(x) (A_FXGPREGBASE + (x))
107−
108171 /* cc_reg constants */
109172 #define CC_REG_NORMALIZED C_00000001
110173 #define CC_REG_BORROW C_00000002
@@ -113,7 +176,17 @@ · 2 unmodified lines
113176 #define CC_REG_SATURATE C_00000010
114177 #define CC_REG_NONZERO C_00000100
115178
179+#define A_CC_REG_NORMALIZED A_C_00000001
180+#define A_CC_REG_BORROW A_C_00000002
181+#define A_CC_REG_MINUS A_C_00000004
182+#define A_CC_REG_ZERO A_C_00000008
183+#define A_CC_REG_SATURATE A_C_00000010
184+#define A_CC_REG_NONZERO A_C_00000100
185+
116186 /* FX buses */
187+// These are arbitrary mappings; our DSP code simply expects
188+// the config files to route the channels this way.
189+// The numbers are documented in {audigy,sb-live}-mixer.rst.
117190 #define FXBUS_PCM_LEFT 0x00
118191 #define FXBUS_PCM_RIGHT 0x01
119192 #define FXBUS_PCM_LEFT_REAR 0x02
@@ -203,38 +276,7 @@ · 83 unmodified lines
203276 #define A_EXTOUT_ADC_CAP_R 0x17 /* right */
204277 #define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */
205278
206−/* Audigy constants */
207−#define A_C_00000000 0xc0
208−#define A_C_00000001 0xc1
209−#define A_C_00000002 0xc2
210−#define A_C_00000003 0xc3
211−#define A_C_00000004 0xc4
212−#define A_C_00000008 0xc5
213−#define A_C_00000010 0xc6
214−#define A_C_00000020 0xc7
215−#define A_C_00000100 0xc8
216−#define A_C_00010000 0xc9
217−#define A_C_00000800 0xca
218−#define A_C_10000000 0xcb
219−#define A_C_20000000 0xcc
220−#define A_C_40000000 0xcd
221−#define A_C_80000000 0xce
222−#define A_C_7fffffff 0xcf
223−#define A_C_ffffffff 0xd0
224−#define A_C_fffffffe 0xd1
225−#define A_C_c0000000 0xd2
226−#define A_C_4f1bbcdc 0xd3
227−#define A_C_5a7ef9db 0xd4
228−#define A_C_00100000 0xd5
229−#define A_GPR_ACCU 0xd6 /* ACCUM, accumulator */
230−#define A_GPR_COND 0xd7 /* CCR, condition register */
231−#define A_GPR_NOISE0 0xd8 /* noise source */
232−#define A_GPR_NOISE1 0xd9 /* noise source */
233−#define A_GPR_IRQ 0xda /* IRQ register */
234−#define A_GPR_DBAC 0xdb /* TRAM Delay Base Address Counter - internal */
235−#define A_GPR_DBACE 0xde /* TRAM Delay Base Address Counter - external */
236−
237−/* definitions for debug register */
279+/* Definitions for debug register. Note that these are for emu10k1 ONLY. */
238280 #define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */
239281 #define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */
240282 #define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */
@@ -243,14 +285,14 @@ · 2 unmodified lines
243285 #define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */
244286 #define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */
245287
246−/* tank memory address line */
247−#ifndef __KERNEL__
248−#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */
249−#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */
250−#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */
251−#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */
252−#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */
253−#endif
288+/* Definitions for emu10k2 debug register. */
289+#define A_DBG_ZC 0x40000000 /* zero tram counter */
290+#define A_DBG_SATURATION_OCCURED 0x20000000
291+#define A_DBG_SATURATION_ADDR 0x0ffc0000
292+#define A_DBG_SINGLE_STEP 0x00020000 /* Set to zero to start dsp */
293+#define A_DBG_STEP 0x00010000
294+#define A_DBG_CONDITION_CODE 0x0000f800
295+#define A_DBG_STEP_ADDR 0x000003ff
254296
255297 struct snd_emu10k1_fx8010_info {
256298 unsigned int internal_tram_size; /* in samples */
include/uapi/sound/sof/abi.h+2−0
@@ -60,5 +60,7 @@ · 59 unmodified lines
6060
6161 /* SOF ABI magic number "SOF\0". */
6262 #define SOF_ABI_MAGIC 0x00464F53
63+/* SOF IPC4 ABI magic number "SOF4". */
64+#define SOF_IPC4_ABI_MAGIC 0x34464F53
6365
6466 #endif
include/uapi/sound/sof/header.h+19−8
@@ -11,19 +11,30 @@ · 10 unmodified lines
1111
1212 #include <linux/types.h>
1313
14−/*
15− * Header for all non IPC ABI data.
14+/**
15+ * struct sof_abi_hdr - Header for all non IPC ABI data.
16+ * @magic: Magic number for validation
17+ * for IPC3 data: 0x00464F53 ('S', 'O', 'F', '\0')
18+ * for IPC4 data: 0x34464F53 ('S', 'O', 'F', '4')
19+ * @type: module specific parameter
20+ * for IPC3: Component specific type
21+ * for IPC4: parameter ID (param_id) of the data
22+ * @size: The size in bytes of the data, excluding this struct
23+ * @abi: SOF ABI version. The version is valid in scope of the 'magic', IPC3 and
24+ * IPC4 ABI version numbers have no relationship.
25+ * @reserved: Reserved for future use
26+ * @data: Component data - opaque to core
1627 *
1728 * Identifies data type, size and ABI.
1829 * Used by any bespoke component data structures or binary blobs.
1930 */
2031 struct sof_abi_hdr {
21− __u32 magic; /**< 'S', 'O', 'F', '\0' */
22− __u32 type; /**< component specific type */
23− __u32 size; /**< size in bytes of data excl. this struct */
24− __u32 abi; /**< SOF ABI version */
25− __u32 reserved[4]; /**< reserved for future use */
26− __u32 data[]; /**< Component data - opaque to core */
32+ __u32 magic;
33+ __u32 type;
34+ __u32 size;
35+ __u32 abi;
36+ __u32 reserved[4];
37+ __u32 data[];
2738 } __packed;
2839
2940 #define SOF_MANIFEST_DATA_TYPE_NHLT 1
include/uapi/sound/sof/tokens.h+13−8
@@ -54,6 +54,7 @@ · 53 unmodified lines
5454 #define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
5555 #define SOF_TKN_SCHED_LP_MODE 207
5656 #define SOF_TKN_SCHED_MEM_USAGE 208
57+#define SOF_TKN_SCHED_USE_CHAIN_DMA 209
5758
5859 /* volume */
5960 #define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
@@ -88,14 +89,16 @@ · 28 unmodified lines
8889 #define SOF_TKN_COMP_CPC 406
8990 #define SOF_TKN_COMP_IS_PAGES 409
9091 #define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410
91−#define SOF_TKN_COMP_NUM_SINK_PINS 411
92−#define SOF_TKN_COMP_NUM_SOURCE_PINS 412
92+#define SOF_TKN_COMP_NUM_INPUT_PINS 411
93+#define SOF_TKN_COMP_NUM_OUTPUT_PINS 412
9394 /*
94− * The token for sink/source pin binding, it specifies the widget
95− * name that the sink/source pin is connected from/to.
95+ * The token for input/output pin binding, it specifies the widget
96+ * name that the input/output pin is connected from/to.
9697 */
97−#define SOF_TKN_COMP_SINK_PIN_BINDING_WNAME 413
98−#define SOF_TKN_COMP_SRC_PIN_BINDING_WNAME 414
98+#define SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME 413
99+#define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 414
100+#define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415
101+#define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416
99102
100103
101104 /* SSP */
@@ -173,17 +176,18 @@ · 71 unmodified lines
173176 /* CAVS AUDIO FORMAT */
174177 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900
175178 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901
176−#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902
179+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT_DEPTH 1902
177180 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903
178181 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904
179182 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905
180183 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906
181184 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907
182185 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908
186+#define SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX 1909
183187 /* intentional token numbering discontinuity, reserved for future use */
184188 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930
185189 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931
186−#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932
190+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT_DEPTH 1932
187191 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933
188192 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934
189193 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935
@@ -197,6 +201,7 @@ · 7 unmodified lines
197201
198202 /* COPIER */
199203 #define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980
204+#define SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS 1981
200205
201206 /* ACP I2S */
202207 #define SOF_TKN_AMD_ACPI2S_RATE 1700
sound/ac97_bus.c+0−11
@@ -75,19 +75,8 @@ int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id, · 74 unmodified lines
7575 }
7676 EXPORT_SYMBOL_GPL(snd_ac97_reset);
7777
78−/*
79− * Let drivers decide whether they want to support given codec from their
80− * probe method. Drivers have direct access to the struct snd_ac97
81− * structure and may decide based on the id field amongst other things.
82− */
83−static int ac97_bus_match(struct device *dev, struct device_driver *drv)
84−{
85− return 1;
86−}
87−
8878 struct bus_type ac97_bus_type = {
8979 .name = "ac97",
90− .match = ac97_bus_match,
9180 };
9281
9382 static int __init ac97_bus_init(void)
sound/arm/pxa2xx-ac97.c+2−4
@@ -262,7 +262,7 @@ err_dev: · 261 unmodified lines
262262 return ret;
263263 }
264264
265−static int pxa2xx_ac97_remove(struct platform_device *dev)
265+static void pxa2xx_ac97_remove(struct platform_device *dev)
266266 {
267267 struct snd_card *card = platform_get_drvdata(dev);
268268
@@ -270,13 +270,11 @@ static int pxa2xx_ac97_remove(struct platform_device *dev) · 1 unmodified line
270270 snd_card_free(card);
271271 pxa2xx_ac97_hw_remove(dev);
272272 }
273−
274− return 0;
275273 }
276274
277275 static struct platform_driver pxa2xx_ac97_driver = {
278276 .probe = pxa2xx_ac97_probe,
279− .remove = pxa2xx_ac97_remove,
277+ .remove_new = pxa2xx_ac97_remove,
280278 .driver = {
281279 .name = "pxa2xx-ac97",
282280 #ifdef CONFIG_PM_SLEEP
sound/atmel/ac97c.c+2−4
@@ -843,7 +843,7 @@ static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume · 842 unmodified lines
843843 #define ATMEL_AC97C_PM_OPS NULL
844844 #endif
845845
846−static int atmel_ac97c_remove(struct platform_device *pdev)
846+static void atmel_ac97c_remove(struct platform_device *pdev)
847847 {
848848 struct snd_card *card = platform_get_drvdata(pdev);
849849 struct atmel_ac97c *chip = get_chip(card);
@@ -858,13 +858,11 @@ static int atmel_ac97c_remove(struct platform_device *pdev) · 8 unmodified lines
858858 free_irq(chip->irq, chip);
859859
860860 snd_card_free(card);
861−
862− return 0;
863861 }
864862
865863 static struct platform_driver atmel_ac97c_driver = {
866864 .probe = atmel_ac97c_probe,
867− .remove = atmel_ac97c_remove,
865+ .remove_new = atmel_ac97c_remove,
868866 .driver = {
869867 .name = "atmel_ac97c",
870868 .pm = ATMEL_AC97C_PM_OPS,
sound/core/pcm_lib.c+41−56
@@ -42,70 +42,56 @@ static int fill_silence_frames(struct snd_pcm_substream *substream, · 41 unmodified lines
4242 *
4343 * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
4444 */
45−void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)
45+void snd_pcm_playback_silence(struct snd_pcm_substream *substream)
4646 {
4747 struct snd_pcm_runtime *runtime = substream->runtime;
48− snd_pcm_uframes_t frames, ofs, transfer;
48+ snd_pcm_uframes_t appl_ptr = READ_ONCE(runtime->control->appl_ptr);
49+ snd_pcm_sframes_t added, hw_avail, frames;
50+ snd_pcm_uframes_t noise_dist, ofs, transfer;
4951 int err;
5052
53+ added = appl_ptr - runtime->silence_start;
54+ if (added) {
55+ if (added < 0)
56+ added += runtime->boundary;
57+ if (added < runtime->silence_filled)
58+ runtime->silence_filled -= added;
59+ else
60+ runtime->silence_filled = 0;
61+ runtime->silence_start = appl_ptr;
62+ }
63+
64+ // This will "legitimately" turn negative on underrun, and will be mangled
65+ // into a huge number by the boundary crossing handling. The initial state
66+ // might also be not quite sane. The code below MUST account for these cases.
67+ hw_avail = appl_ptr - runtime->status->hw_ptr;
68+ if (hw_avail < 0)
69+ hw_avail += runtime->boundary;
70+
71+ noise_dist = hw_avail + runtime->silence_filled;
5172 if (runtime->silence_size < runtime->boundary) {
52− snd_pcm_sframes_t noise_dist, n;
53− snd_pcm_uframes_t appl_ptr = READ_ONCE(runtime->control->appl_ptr);
54− if (runtime->silence_start != appl_ptr) {
55− n = appl_ptr - runtime->silence_start;
56− if (n < 0)
57− n += runtime->boundary;
58− if ((snd_pcm_uframes_t)n < runtime->silence_filled)
59− runtime->silence_filled -= n;
60− else
61− runtime->silence_filled = 0;
62− runtime->silence_start = appl_ptr;
63− }
64− if (runtime->silence_filled >= runtime->buffer_size)
65− return;
66− noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
67− if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
68− return;
6973 frames = runtime->silence_threshold - noise_dist;
74+ if (frames <= 0)
75+ return;
7076 if (frames > runtime->silence_size)
7177 frames = runtime->silence_size;
7278 } else {
73− if (new_hw_ptr == ULONG_MAX) { /* initialization */
74− snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
75− if (avail > runtime->buffer_size)
76− avail = runtime->buffer_size;
77− runtime->silence_filled = avail > 0 ? avail : 0;
78− runtime->silence_start = (runtime->status->hw_ptr +
79− runtime->silence_filled) %
80− runtime->boundary;
81− } else {
82− ofs = runtime->status->hw_ptr;
83− frames = new_hw_ptr - ofs;
84− if ((snd_pcm_sframes_t)frames < 0)
85− frames += runtime->boundary;
86− runtime->silence_filled -= frames;
87− if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
88− runtime->silence_filled = 0;
89− runtime->silence_start = new_hw_ptr;
90− } else {
91− runtime->silence_start = ofs;
92− }
93− }
94− frames = runtime->buffer_size - runtime->silence_filled;
79+ frames = runtime->buffer_size - noise_dist;
80+ if (frames <= 0)
81+ return;
9582 }
83+
9684 if (snd_BUG_ON(frames > runtime->buffer_size))
9785 return;
98− if (frames == 0)
99− return;
100− ofs = runtime->silence_start % runtime->buffer_size;
101− while (frames > 0) {
86+ ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
87+ do {
10288 transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
10389 err = fill_silence_frames(substream, ofs, transfer);
10490 snd_BUG_ON(err < 0);
10591 runtime->silence_filled += transfer;
10692 frames -= transfer;
10793 ofs = 0;
108− }
94+ } while (frames > 0);
10995 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
11096 }
11197
@@ -439,10 +425,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 327 unmodified lines
439425 return 0;
440426 }
441427
442− if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
443− runtime->silence_size > 0)
444− snd_pcm_playback_silence(substream, new_hw_ptr);
445−
446428 if (in_interrupt) {
447429 delta = new_hw_ptr - runtime->hw_ptr_interrupt;
448430 if (delta < 0)
@@ -460,6 +442,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 11 unmodified lines
460442 runtime->hw_ptr_wrap += runtime->boundary;
461443 }
462444
445+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
446+ runtime->silence_size > 0)
447+ snd_pcm_playback_silence(substream);
448+
463449 update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
464450
465451 return snd_pcm_update_state(substream, runtime);
@@ -1878,15 +1864,14 @@ static int wait_for_avail(struct snd_pcm_substream *substream, · 1412 unmodified lines
18781864 if (substream->wait_time) {
18791865 wait_time = substream->wait_time;
18801866 } else {
1881− wait_time = 10;
1867+ wait_time = 100;
18821868
18831869 if (runtime->rate) {
1884− long t = runtime->period_size * 2 /
1885− runtime->rate;
1870+ long t = runtime->buffer_size * 1100 / runtime->rate;
18861871 wait_time = max(t, wait_time);
18871872 }
1888− wait_time = msecs_to_jiffies(wait_time * 1000);
18891873 }
1874+ wait_time = msecs_to_jiffies(wait_time);
18901875 }
18911876
18921877 for (;;) {
@@ -1934,8 +1919,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream, · 41 unmodified lines
19341919 }
19351920 if (!tout) {
19361921 pcm_dbg(substream->pcm,
1937− "%s write error (DMA or IRQ trouble?)\n",
1938− is_playback ? "playback" : "capture");
1922+ "%s timeout (DMA or IRQ trouble?)\n",
1923+ is_playback ? "playback write" : "capture read");
19391924 err = -EIO;
19401925 break;
19411926 }
sound/core/pcm_local.h+1−2
@@ -29,8 +29,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, · 28 unmodified lines
2929 struct snd_pcm_runtime *runtime);
3030 int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
3131
32−void snd_pcm_playback_silence(struct snd_pcm_substream *substream,
33− snd_pcm_uframes_t new_hw_ptr);
32+void snd_pcm_playback_silence(struct snd_pcm_substream *substream);
3433
3534 static inline snd_pcm_uframes_t
3635 snd_pcm_avail(struct snd_pcm_substream *substream)
sound/core/pcm_native.c+7−7
@@ -958,7 +958,7 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, · 957 unmodified lines
958958 if (snd_pcm_running(substream)) {
959959 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
960960 runtime->silence_size > 0)
961− snd_pcm_playback_silence(substream, ULONG_MAX);
961+ snd_pcm_playback_silence(substream);
962962 err = snd_pcm_update_state(substream, runtime);
963963 }
964964 snd_pcm_stream_unlock_irq(substream);
@@ -1455,7 +1455,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, · 490 unmodified lines
14551455 __snd_pcm_set_state(runtime, state);
14561456 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
14571457 runtime->silence_size > 0)
1458− snd_pcm_playback_silence(substream, ULONG_MAX);
1458+ snd_pcm_playback_silence(substream);
14591459 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
14601460 }
14611461
@@ -1916,7 +1916,7 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, · 454 unmodified lines
19161916 runtime->control->appl_ptr = runtime->status->hw_ptr;
19171917 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
19181918 runtime->silence_size > 0)
1919− snd_pcm_playback_silence(substream, ULONG_MAX);
1919+ snd_pcm_playback_silence(substream);
19201920 snd_pcm_stream_unlock_irq(substream);
19211921 }
19221922
@@ -2159,12 +2159,12 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, · 236 unmodified lines
21592159 if (runtime->no_period_wakeup)
21602160 tout = MAX_SCHEDULE_TIMEOUT;
21612161 else {
2162− tout = 10;
2162+ tout = 100;
21632163 if (runtime->rate) {
2164− long t = runtime->period_size * 2 / runtime->rate;
2164+ long t = runtime->buffer_size * 1100 / runtime->rate;
21652165 tout = max(t, tout);
21662166 }
2167− tout = msecs_to_jiffies(tout * 1000);
2167+ tout = msecs_to_jiffies(tout);
21682168 }
21692169 tout = schedule_timeout(tout);
21702170
@@ -2187,7 +2187,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, · 16 unmodified lines
21872187 result = -ESTRPIPE;
21882188 else {
21892189 dev_dbg(substream->pcm->card->dev,
2190− "playback drain error (DMA or IRQ trouble?)\n");
2190+ "playback drain timeout (DMA or IRQ trouble?)\n");
21912191 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
21922192 result = -EIO;
21932193 }
sound/drivers/mts64.c+2−4
@@ -999,19 +999,17 @@ __err: · 998 unmodified lines
999999 return err;
10001000 }
10011001
1002−static int snd_mts64_remove(struct platform_device *pdev)
1002+static void snd_mts64_remove(struct platform_device *pdev)
10031003 {
10041004 struct snd_card *card = platform_get_drvdata(pdev);
10051005
10061006 if (card)
10071007 snd_card_free(card);
1008−
1009− return 0;
10101008 }
10111009
10121010 static struct platform_driver snd_mts64_driver = {
10131011 .probe = snd_mts64_probe,
1014− .remove = snd_mts64_remove,
1012+ .remove_new = snd_mts64_remove,
10151013 .driver = {
10161014 .name = PLATFORM_DRIVER,
10171015 }
sound/drivers/portman2x4.c+2−14
@@ -182,21 +182,11 @@ static inline void portman_write_command(struct portman *pm, u8 value) · 181 unmodified lines
182182 parport_write_control(pm->pardev->port, value);
183183 }
184184
185−static inline u8 portman_read_command(struct portman *pm)
186−{
187− return parport_read_control(pm->pardev->port);
188−}
189−
190185 static inline u8 portman_read_status(struct portman *pm)
191186 {
192187 return parport_read_status(pm->pardev->port);
193188 }
194189
195−static inline u8 portman_read_data(struct portman *pm)
196−{
197− return parport_read_data(pm->pardev->port);
198−}
199−
200190 static inline void portman_write_data(struct portman *pm, u8 value)
201191 {
202192 parport_write_data(pm->pardev->port, value);
@@ -795,20 +785,18 @@ __err: · 592 unmodified lines
795785 return err;
796786 }
797787
798−static int snd_portman_remove(struct platform_device *pdev)
788+static void snd_portman_remove(struct platform_device *pdev)
799789 {
800790 struct snd_card *card = platform_get_drvdata(pdev);
801791
802792 if (card)
803793 snd_card_free(card);
804−
805− return 0;
806794 }
807795
808796
809797 static struct platform_driver snd_portman_driver = {
810798 .probe = snd_portman_probe,
811− .remove = snd_portman_remove,
799+ .remove_new = snd_portman_remove,
812800 .driver = {
813801 .name = PLATFORM_DRIVER,
814802 }
sound/mips/hal2.c+2−3
@@ -877,17 +877,16 @@ static int hal2_probe(struct platform_device *pdev) · 876 unmodified lines
877877 return 0;
878878 }
879879
880−static int hal2_remove(struct platform_device *pdev)
880+static void hal2_remove(struct platform_device *pdev)
881881 {
882882 struct snd_card *card = platform_get_drvdata(pdev);
883883
884884 snd_card_free(card);
885− return 0;
886885 }
887886
888887 static struct platform_driver hal2_driver = {
889888 .probe = hal2_probe,
890− .remove = hal2_remove,
889+ .remove_new = hal2_remove,
891890 .driver = {
892891 .name = "sgihal2",
893892 }
sound/mips/sgio2audio.c+2−3
@@ -908,17 +908,16 @@ static int snd_sgio2audio_probe(struct platform_device *pdev) · 907 unmodified lines
908908 return 0;
909909 }
910910
911−static int snd_sgio2audio_remove(struct platform_device *pdev)
911+static void snd_sgio2audio_remove(struct platform_device *pdev)
912912 {
913913 struct snd_card *card = platform_get_drvdata(pdev);
914914
915915 snd_card_free(card);
916− return 0;
917916 }
918917
919918 static struct platform_driver sgio2audio_driver = {
920919 .probe = snd_sgio2audio_probe,
921− .remove = snd_sgio2audio_remove,
920+ .remove_new = snd_sgio2audio_remove,
922921 .driver = {
923922 .name = "sgio2audio",
924923 }
sound/pci/Kconfig+2−2
@@ -461,7 +461,7 @@ config SND_INDIGODJX · 460 unmodified lines
461461 will be called snd-indigodjx
462462
463463 config SND_EMU10K1
464− tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
464+ tristate "Emu10k1 (SB Live!, Audigy, E-MU APS/0404/1010/1212/1616/1820)"
465465 select FW_LOADER
466466 select SND_HWDEP
467467 select SND_RAWMIDI
@@ -471,7 +471,7 @@ config SND_EMU10K1 · 3 unmodified lines
471471 depends on ZONE_DMA
472472 help
473473 Say Y to include support for Sound Blaster PCI 512, Live!,
474− Audigy and E-mu APS (partially supported) soundcards.
474+ Audigy and E-MU APS/0404/1010/1212/1616/1820 soundcards.
475475
476476 The confusing multitude of mixer controls is documented in
477477 <file:Documentation/sound/cards/sb-live-mixer.rst> and
sound/pci/asihpi/hpi6000.c+0−2
@@ -1253,7 +1253,6 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, · 1252 unmodified lines
12531253 int local_count = count;
12541254 int xfer_size;
12551255 u32 *pdata = dest;
1256− u32 loop_count = 0;
12571256
12581257 while (local_count) {
12591258 if (local_count > c6711_burst_size)
@@ -1273,7 +1272,6 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, · 13 unmodified lines
12731272 pdata += xfer_size;
12741273 local_hpi_address += sizeof(u32) * xfer_size;
12751274 local_count -= xfer_size;
1276− loop_count++;
12771275 }
12781276
12791277 if (time_out)
sound/pci/emu10k1/emu10k1.c+0−11
@@ -68,17 +68,6 @@ static const struct pci_device_id snd_emu10k1_ids[] = { · 67 unmodified lines
6868 { 0, }
6969 };
7070
71−/*
72− * Audigy 2 Value notes:
73− * A_IOCFG Input (GPIO)
74− * 0x400 = Front analog jack plugged in. (Green socket)
75− * 0x1000 = Read analog jack plugged in. (Black socket)
76− * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
77− * A_IOCFG Output (GPIO)
78− * 0x60 = Sound out of front Left.
79− * Win sets it to 0xXX61
80− */
81−
8271 MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
8372
8473 static int snd_card_emu10k1_probe(struct pci_dev *pci,
sound/pci/emu10k1/emu10k1_callback.c+1−4
@@ -531,8 +531,5 @@ set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp) · 530 unmodified lines
531531 static void
532532 set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
533533 {
534− unsigned int val;
535− val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
536− val |= (vp->reg.parm.filterQ << 28);
537− snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
534+ snd_emu10k1_ptr_write(hw, CCCA_RESONANCE, vp->ch, vp->reg.parm.filterQ);
538535 }
sound/pci/emu10k1/emu10k1_main.c+97−159
@@ -140,7 +140,7 @@ static const unsigned int i2c_adc_init[][2] = { · 139 unmodified lines
140140 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
141141 };
142142
143−static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
143+static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir)
144144 {
145145 unsigned int silent_page;
146146 int ch;
@@ -162,6 +162,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 15 unmodified lines
162162 outl(0, emu->port + INTE);
163163 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
164164 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
165+
166+ /* disable stop on loop end */
165167 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
166168 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
167169
@@ -181,13 +183,11 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 13 unmodified lines
181183 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
182184 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
183185
184− if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
186+ if (emu->card_capabilities->emu_model) {
187+ } else if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
185188 /* Hacks for Alice3 to work independent of haP16V driver */
186189 /* Setup SRCMulti_I2S SamplingRate */
187− tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
188− tmp &= 0xfffff1ff;
189− tmp |= (0x2<<9);
190− snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
190+ snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, 0, A_I2S_CAPTURE_96000);
191191
192192 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
193193 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
@@ -199,32 +199,26 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 5 unmodified lines
199199 outl(0x0201, emu->port + HCFG2);
200200 /* Set playback routing. */
201201 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
202− }
203− if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
202+ } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
204203 /* Hacks for Alice3 to work independent of haP16V driver */
205204 dev_info(emu->card->dev, "Audigy2 value: Special config.\n");
206205 /* Setup SRCMulti_I2S SamplingRate */
207− tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
208− tmp &= 0xfffff1ff;
209− tmp |= (0x2<<9);
210− snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
206+ snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, 0, A_I2S_CAPTURE_96000);
211207
212208 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
213− outl(0x600000, emu->port + 0x20);
214− outl(0x14, emu->port + 0x24);
209+ snd_emu10k1_ptr20_write(emu, P17V_SRCSel, 0, 0x14);
215210
216211 /* Setup SRCMulti Input Audio Enable */
217− outl(0x7b0000, emu->port + 0x20);
218− outl(0xFF000000, emu->port + 0x24);
212+ snd_emu10k1_ptr20_write(emu, P17V_MIXER_I2S_ENABLE, 0, 0xFF000000);
219213
220214 /* Setup SPDIF Out Audio Enable */
221215 /* The Audigy 2 Value has a separate SPDIF out,
222216 * so no need for a mixer switch
223217 */
224− outl(0x7a0000, emu->port + 0x20);
225− outl(0xFF000000, emu->port + 0x24);
226− tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
227− outl(tmp, emu->port + A_IOCFG);
218+ snd_emu10k1_ptr20_write(emu, P17V_MIXER_SPDIF_ENABLE, 0, 0xFF000000);
219+
220+ tmp = inw(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
221+ outw(tmp, emu->port + A_IOCFG);
228222 }
229223 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
230224 int size, n;
@@ -244,15 +238,15 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 13 unmodified lines
244238 * GPIO6: Unknown
245239 * GPIO7: Unknown
246240 */
247− outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
241+ outw(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
248242 }
249243 if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */
250244 int size, n;
251245
252246 snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f);
253− tmp = inl(emu->port + A_IOCFG);
254− outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */
255− tmp = inl(emu->port + A_IOCFG);
247+ tmp = inw(emu->port + A_IOCFG);
248+ outw(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */
249+ tmp = inw(emu->port + A_IOCFG);
256250 size = ARRAY_SIZE(i2c_adc_init);
257251 for (n = 0; n < size; n++)
258252 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
@@ -308,12 +302,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 49 unmodified lines
308302 } else if (emu->card_capabilities->i2c_adc) {
309303 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
310304 } else if (emu->audigy) {
311− unsigned int reg = inl(emu->port + A_IOCFG);
312− outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
305+ u16 reg = inw(emu->port + A_IOCFG);
306+ outw(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
313307 udelay(500);
314− outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
308+ outw(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
315309 udelay(100);
316− outl(reg, emu->port + A_IOCFG);
310+ outw(reg, emu->port + A_IOCFG);
317311 } else {
318312 unsigned int reg = inl(emu->port + HCFG);
319313 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
@@ -329,8 +323,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 9 unmodified lines
329323 } else if (emu->card_capabilities->i2c_adc) {
330324 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
331325 } else if (emu->audigy) { /* enable analog output */
332− unsigned int reg = inl(emu->port + A_IOCFG);
333− outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
326+ u16 reg = inw(emu->port + A_IOCFG);
327+ outw(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
334328 }
335329
336330 if (emu->address_mode == 0) {
@@ -354,19 +348,19 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) · 17 unmodified lines
354348 } else if (emu->card_capabilities->i2c_adc) {
355349 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
356350 } else if (emu->audigy) {
357− outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
351+ outw(inw(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
358352
359353 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
360354 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
361355 * This has to be done after init ALice3 I2SOut beyond 48KHz.
362356 * So, sequence is important. */
363− outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
357+ outw(inw(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
364358 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
365359 /* Unmute Analog now. */
366− outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
360+ outw(inw(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
367361 } else {
368362 /* Disable routing from AC97 line out to Front speakers */
369− outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
363+ outw(inw(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
370364 }
371365 }
372366
@@ -651,26 +645,27 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 278 unmodified lines
651645 const struct firmware *fw_entry)
652646 {
653647 int n, i;
654− int reg;
655− int value;
656− __always_unused unsigned int write_post;
648+ u16 reg;
649+ u8 value;
650+ __always_unused u16 write_post;
657651 unsigned long flags;
658652
659653 if (!fw_entry)
660654 return -EIO;
661655
662656 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
657+ /* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
663658 /* GPIO7 -> FPGA PGMN
664659 * GPIO6 -> FPGA CCLK
665660 * GPIO5 -> FPGA DIN
666661 * FPGA CONFIG OFF -> FPGA PGMN
667662 */
668663 spin_lock_irqsave(&emu->emu_lock, flags);
669− outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */
670− write_post = inl(emu->port + A_IOCFG);
664+ outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
665+ write_post = inw(emu->port + A_GPIO);
671666 udelay(100);
672− outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
673− write_post = inl(emu->port + A_IOCFG);
667+ outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
668+ write_post = inw(emu->port + A_GPIO);
674669 udelay(100); /* Allow FPGA memory to clean */
675670 for (n = 0; n < fw_entry->size; n++) {
676671 value = fw_entry->data[n];
@@ -679,15 +674,15 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 2 unmodified lines
679674 if (value & 0x1)
680675 reg = reg | 0x20;
681676 value = value >> 1;
682− outl(reg, emu->port + A_IOCFG);
683− write_post = inl(emu->port + A_IOCFG);
684− outl(reg | 0x40, emu->port + A_IOCFG);
685− write_post = inl(emu->port + A_IOCFG);
677+ outw(reg, emu->port + A_GPIO);
678+ write_post = inw(emu->port + A_GPIO);
679+ outw(reg | 0x40, emu->port + A_GPIO);
680+ write_post = inw(emu->port + A_GPIO);
686681 }
687682 }
688683 /* After programming, set GPIO bit 4 high again. */
689− outl(0x10, emu->port + A_IOCFG);
690− write_post = inl(emu->port + A_IOCFG);
684+ outw(0x10, emu->port + A_GPIO);
685+ write_post = inw(emu->port + A_GPIO);
691686 spin_unlock_irqrestore(&emu->emu_lock, flags);
692687
693688 return 0;
@@ -782,7 +777,7 @@ static void emu1010_firmware_work(struct work_struct *work) · 88 unmodified lines
782777 } else if (!reg && emu->emu1010.last_reg) {
783778 /* Audio Dock removed */
784779 dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");
785− /* Unmute all */
780+ /* The hardware auto-mutes all, so we unmute again */
786781 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
787782 }
788783
@@ -794,29 +789,6 @@ static void emu1010_firmware_work(struct work_struct *work) · 5 unmodified lines
794789 }
795790
796791 /*
797− * EMU-1010 - details found out from this driver, official MS Win drivers,
798− * testing the card:
799− *
800− * Audigy2 (aka Alice2):
801− * ---------------------
802− * * communication over PCI
803− * * conversion of 32-bit data coming over EMU32 links from HANA FPGA
804− * to 2 x 16-bit, using internal DSP instructions
805− * * slave mode, clock supplied by HANA
806− * * linked to HANA using:
807− * 32 x 32-bit serial EMU32 output channels
808− * 16 x EMU32 input channels
809− * (?) x I2S I/O channels (?)
810− *
811− * FPGA (aka HANA):
812− * ---------------
813− * * provides all (?) physical inputs and outputs of the card
814− * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.)
815− * * provides clock signal for the card and Alice2
816− * * two crystals - for 44.1kHz and 48kHz multiples
817− * * provides internal routing of signal sources to signal destinations
818− * * inputs/outputs to Alice2 - see above
819− *
820792 * Current status of the driver:
821793 * ----------------------------
822794 * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz)
@@ -831,24 +803,10 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 8 unmodified lines
831803 int err;
832804
833805 dev_info(emu->card->dev, "emu1010: Special config.\n");
834− /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
835− * Lock Sound Memory Cache, Lock Tank Memory Cache,
836− * Mute all codecs.
837− */
838− outl(0x0005a00c, emu->port + HCFG);
839− /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
840− * Lock Tank Memory Cache,
841− * Mute all codecs.
842− */
843− outl(0x0005a004, emu->port + HCFG);
844− /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
845− * Mute all codecs.
846− */
847− outl(0x0005a000, emu->port + HCFG);
848− /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
849− * Mute all codecs.
850− */
851− outl(0x0005a000, emu->port + HCFG);
806+
807+ /* Mute, and disable audio and lock cache, just in case.
808+ * Proper init follows in snd_emu10k1_init(). */
809+ outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
852810
853811 /* Disable 48Volt power to Audio Dock */
854812 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
@@ -897,34 +855,20 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 42 unmodified lines
897855
898856 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
899857 dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);
900− snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
901− dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);
902− snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp);
903858 /* Optical -> ADAT I/O */
904− /* 0 : SPDIF
905− * 1 : ADAT
906− */
907859 emu->emu1010.optical_in = 1; /* IN_ADAT */
908− emu->emu1010.optical_out = 1; /* IN_ADAT */
909− tmp = 0;
860+ emu->emu1010.optical_out = 1; /* OUT_ADAT */
910861 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
911862 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
912863 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
913− snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
914864 /* Set no attenuation on Audio Dock pads. */
915865 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
916866 emu->emu1010.adc_pads = 0x00;
917− snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
918867 /* Unmute Audio dock DACs, Headphone source DAC-4. */
919868 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
920− snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
921− snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp);
922869 /* DAC PADs. */
923870 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
924871 emu->emu1010.dac_pads = 0x0f;
925− snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
926− snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
927− snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
928872 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
929873 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
930874 /* MIDI routing */
@@ -936,8 +880,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 5 unmodified lines
936880 /* IRQ Enable: All off */
937881 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
938882
939− snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
940− dev_info(emu->card->dev, "emu1010: Card options3 = 0x%x\n", reg);
883+ emu->emu1010.internal_clock = 1; /* 48000 */
941884 /* Default WCLK set to 48kHz. */
942885 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
943886 /* Word Clock source, Internal 48kHz x1 */
@@ -1073,29 +1016,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 129 unmodified lines
10731016 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
10741017 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
10751018
1076− snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1077−
1078− /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1079− * Lock Sound Memory Cache, Lock Tank Memory Cache,
1080− * Mute all codecs.
1081− */
1082− outl(0x0000a000, emu->port + HCFG);
1083− /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1084− * Lock Sound Memory Cache, Lock Tank Memory Cache,
1085− * Un-Mute all codecs.
1086− */
1087− outl(0x0000a001, emu->port + HCFG);
1088−
1089− /* Initial boot complete. Now patches */
1090−
1091− snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1092− snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1093− snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1094− snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1095− snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1096− snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
1097− snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
1098−
10991019 #if 0
11001020 snd_emu1010_fpga_link_dst_src_write(emu,
11011021 EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
@@ -1215,21 +1135,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 113 unmodified lines
12151135 EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
12161136 emu->emu1010.output_source[23] = 28;
12171137 }
1218− /* TEMP: Select SPDIF in/out */
1219− /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */
1220−
1221− /* TEMP: Select 48kHz SPDIF out */
1222− snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
1223− snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
1224− /* Word Clock source, Internal 48kHz x1 */
1225− snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
1226− /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
1227− emu->emu1010.internal_clock = 1; /* 48000 */
1228− snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */
1229− snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
1230− /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */
1231− /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */
1232− /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
12331138
12341139 return 0;
12351140 }
@@ -1343,6 +1248,15 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 107 unmodified lines
13431248 * AC97: STAC9750
13441249 * CA0151: None
13451250 */
1251+ /*
1252+ * A_IOCFG Input (GPIO)
1253+ * 0x400 = Front analog jack plugged in. (Green socket)
1254+ * 0x1000 = Rear analog jack plugged in. (Black socket)
1255+ * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
1256+ * A_IOCFG Output (GPIO)
1257+ * 0x60 = Sound out of front Left.
1258+ * Win sets it to 0xXX61
1259+ */
13461260 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
13471261 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
13481262 .id = "Audigy2",
@@ -1391,6 +1305,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 42 unmodified lines
13911305 .spi_dac = 1,
13921306 .i2c_adc = 1,
13931307 .spk71 = 1} ,
1308+ /* This is MAEM8950 "Mana" */
1309+ /* Attach MicroDock[M] to make it an E-MU 1616[m]. */
1310+ /* Does NOT support sync daughter card (obviously). */
13941311 /* Tested by James@superbug.co.uk 4th Nov 2007. */
13951312 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
13961313 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
@@ -1401,7 +1318,10 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 4 unmodified lines
14011318 .spk71 = 1 ,
14021319 .emu_model = EMU_MODEL_EMU1616},
14031320 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1404− /* This is MAEM8960, 0202 is MAEM 8980 */
1321+ /* This is MAEM8960 "Hana3", 0202 is MAEM8980 */
1322+ /* Attach 0202 daughter card to make it an E-MU 1212m, OR a
1323+ * MicroDock[M] to make it an E-MU 1616[m]. */
1324+ /* Does NOT support sync daughter card. */
14051325 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
14061326 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
14071327 .id = "EMU1010",
@@ -1411,6 +1331,11 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 3 unmodified lines
14111331 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
14121332 /* Tested by Maxim Kachur <mcdebugger@duganet.ru> 17th Oct 2012. */
14131333 /* This is MAEM8986, 0202 is MAEM8980 */
1334+ /* Attach 0202 daughter card to make it an E-MU 1212m, OR a
1335+ * MicroDockM to make it an E-MU 1616m. The non-m
1336+ * version was never sold with this card, but should
1337+ * still work. */
1338+ /* Does NOT support sync daughter card. */
14141339 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40071102,
14151340 .driver = "Audigy2", .name = "E-mu 1010 PCIe [MAEM8986]",
14161341 .id = "EMU1010",
@@ -1419,7 +1344,10 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 2 unmodified lines
14191344 .spk71 = 1,
14201345 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 PCIe */
14211346 /* Tested by James@superbug.co.uk 8th July 2005. */
1422− /* This is MAEM8810, 0202 is MAEM8820 */
1347+ /* This is MAEM8810 "Hana", 0202 is MAEM8820 "Hamoa" */
1348+ /* Attach 0202 daughter card to make it an E-MU 1212m, OR an
1349+ * AudioDock[M] to make it an E-MU 1820[m]. */
1350+ /* Supports sync daughter card. */
14231351 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
14241352 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
14251353 .id = "EMU1010",
@@ -1427,7 +1355,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
14271355 .ca0102_chip = 1,
14281356 .spk71 = 1,
14291357 .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */
1430− /* EMU0404b */
1358+ /* This is MAEM8852 "HanaLiteLite" */
1359+ /* Supports sync daughter card. */
1360+ /* Tested by oswald.buddenhagen@gmx.de Mar 2023. */
14311361 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
14321362 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
14331363 .id = "EMU0404",
@@ -1435,6 +1365,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
14351365 .ca0108_chip = 1,
14361366 .spk71 = 1,
14371367 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
1368+ /* This is MAEM8850 "HanaLite" */
1369+ /* Supports sync daughter card. */
14381370 /* Tested by James@superbug.co.uk 20-3-2007. */
14391371 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
14401372 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
@@ -1444,6 +1376,7 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 3 unmodified lines
14441376 .spk71 = 1,
14451377 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
14461378 /* EMU0404 PCIe */
1379+ /* Does NOT support sync daughter card. */
14471380 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,
14481381 .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",
14491382 .id = "EMU0404",
@@ -1451,7 +1384,6 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
14511384 .ca0108_chip = 1,
14521385 .spk71 = 1,
14531386 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */
1454− /* Note that all E-mu cards require kernel 2.6 or newer. */
14551387 {.vendor = 0x1102, .device = 0x0008,
14561388 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
14571389 .id = "Audigy2",
@@ -1532,6 +1464,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 74 unmodified lines
15321464 .spdif_bug = 1,
15331465 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
15341466 .ac97_chip = 1} ,
1467+ /* Audigy 2 Platinum EX */
1468+ /* Win driver sets A_IOCFG output to 0x1c00 */
15351469 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
15361470 .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]",
15371471 .id = "Audigy2",
@@ -1552,6 +1486,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 14 unmodified lines
15521486 .spdif_bug = 1,
15531487 .invert_shared_spdif = 1, /* digital/analog switch swapped */
15541488 .ac97_chip = 1} ,
1489+ /* Audigy 2 Platinum */
1490+ /* Win driver sets A_IOCFG output to 0xa00 */
15551491 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
15561492 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
15571493 .id = "Audigy2",
@@ -1657,6 +1593,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 99 unmodified lines
16571593 .emu10k1_chip = 1,
16581594 .ac97_chip = 1,
16591595 .sblive51 = 1} ,
1596+ /* SB Live! Platinum */
1597+ /* Win driver sets A_IOCFG output to 0 */
1598+ /* Tested by Jonathan Dowland <jon@dow.land> Apr 2023. */
16601599 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
16611600 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
16621601 .id = "Live",
@@ -1901,11 +1840,12 @@ int snd_emu10k1_create(struct snd_card *card, · 238 unmodified lines
19011840
19021841 pci_set_master(pci);
19031842
1904− emu->fx8010.fxbus_mask = 0x303f;
1843+ // The masks are not used for Audigy.
1844+ // FIXME: these should come from the card_capabilites table.
19051845 if (extin_mask == 0)
1906− extin_mask = 0x3fcf;
1846+ extin_mask = 0x3fcf; // EXTIN_*
19071847 if (extout_mask == 0)
1908− extout_mask = 0x7fff;
1848+ extout_mask = 0x7fff; // EXTOUT_*
19091849 emu->fx8010.extin_mask = extin_mask;
19101850 emu->fx8010.extout_mask = extout_mask;
19111851 emu->enable_ir = enable_ir;
@@ -1970,12 +1910,10 @@ int snd_emu10k1_create(struct snd_card *card, · 58 unmodified lines
19701910 pgtbl[idx] = cpu_to_le32(silent_page | idx);
19711911
19721912 /* set up voice indices */
1973− for (idx = 0; idx < NUM_G; idx++) {
1974− emu->voices[idx].emu = emu;
1913+ for (idx = 0; idx < NUM_G; idx++)
19751914 emu->voices[idx].number = idx;
1976− }
19771915
1978− err = snd_emu10k1_init(emu, enable_ir, 0);
1916+ err = snd_emu10k1_init(emu, enable_ir);
19791917 if (err < 0)
19801918 return err;
19811919 #ifdef CONFIG_PM_SLEEP
@@ -2007,7 +1945,7 @@ static const unsigned char saved_regs[] = { · 25 unmodified lines
20071945 0xff /* end */
20081946 };
20091947 static const unsigned char saved_regs_audigy[] = {
2010− A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
1948+ A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_EHC,
20111949 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
20121950 0xff /* end */
20131951 };
@@ -2054,7 +1992,7 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) · 40 unmodified lines
20541992 *val = snd_emu10k1_ptr_read(emu, *reg, i);
20551993 }
20561994 if (emu->audigy)
2057− emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
1995+ emu->saved_a_iocfg = inw(emu->port + A_IOCFG);
20581996 emu->saved_hcfg = inl(emu->port + HCFG);
20591997 }
20601998
@@ -2068,7 +2006,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) · 7 unmodified lines
20682006 snd_emu10k1_emu1010_init(emu);
20692007 else
20702008 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
2071− snd_emu10k1_init(emu, emu->enable_ir, 1);
2009+ snd_emu10k1_init(emu, emu->enable_ir);
20722010 }
20732011
20742012 void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
@@ -2081,7 +2019,7 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) · 6 unmodified lines
20812019
20822020 /* resore for spdif */
20832021 if (emu->audigy)
2084− outl(emu->saved_a_iocfg, emu->port + A_IOCFG);
2022+ outw(emu->saved_a_iocfg, emu->port + A_IOCFG);
20852023 outl(emu->saved_hcfg, emu->port + HCFG);
20862024
20872025 val = emu->saved_ptr;
sound/pci/emu10k1/emufx.c+32−37
@@ -641,8 +641,8 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, · 640 unmodified lines
641641 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
642642 kcontrol = ctl->kcontrol;
643643 if (kcontrol->id.iface == id->iface &&
644− !strcmp(kcontrol->id.name, id->name) &&
645− kcontrol->id.index == id->index)
644+ kcontrol->id.index == id->index &&
645+ !strcmp(kcontrol->id.name, id->name))
646646 return ctl;
647647 }
648648 return NULL;
@@ -1187,8 +1187,8 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl · 538 unmodified lines
11871187 }
11881188
11891189 /*
1190− * Used for emu1010 - conversion from 32-bit capture inputs from HANA
1191− * to 2 x 16-bit registers in audigy - their values are read via DMA.
1190+ * Used for emu1010 - conversion from 32-bit capture inputs from the FPGA
1191+ * to 2 x 16-bit registers in Audigy - their values are read via DMA.
11921192 * Conversion is performed by Audigy DSP instructions of FX8010.
11931193 */
11941194 static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
@@ -1213,7 +1213,7 @@ static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( · 18 unmodified lines
12131213
12141214 static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
12151215 {
1216− int err, i, z, gpr, nctl;
1216+ int err, z, gpr, nctl;
12171217 int bit_shifter16;
12181218 const int playback = 10;
12191219 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
@@ -1245,12 +1245,10 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) · 25 unmodified lines
12451245 icode->code = icode->tram_addr_map + 256;
12461246
12471247 /* clear free GPRs */
1248− for (i = 0; i < 512; i++)
1249− set_bit(i, icode->gpr_valid);
1248+ memset(icode->gpr_valid, 0xff, 512 / 8);
12501249
12511250 /* clear TRAM data & address lines */
1252− for (i = 0; i < 256; i++)
1253− set_bit(i, icode->tram_valid);
1251+ memset(icode->tram_valid, 0xff, 256 / 8);
12541252
12551253 strcpy(icode->name, "Audigy DSP code for ALSA");
12561254 ptr = 0;
@@ -1261,9 +1259,6 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) · 4 unmodified lines
12611259 gpr_map[gpr++] = 0x0000ffff;
12621260 bit_shifter16 = gpr;
12631261
1264− /* stop FX processor */
1265− snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1266−
12671262 #if 1
12681263 /* PCM front Playback Volume (independent from stereo mix)
12691264 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)
@@ -1332,8 +1327,9 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) · 62 unmodified lines
13321327 #define A_ADD_VOLUME_IN(var,vol,input) \
13331328 A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
13341329
1335− /* emu1212 DSP 0 and DSP 1 Capture */
13361330 if (emu->card_capabilities->emu_model) {
1331+ /* EMU1010 DSP 0 and DSP 1 Capture */
1332+ // The 24 MSB hold the actual value. We implicitly discard the 16 LSB.
13371333 if (emu->card_capabilities->ca0108_chip) {
13381334 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
13391335 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);
@@ -1638,8 +1634,11 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) · 298 unmodified lines
16381634 #endif
16391635
16401636 if (emu->card_capabilities->emu_model) {
1637+ /* Capture 16 channels of S32_LE sound. */
16411638 if (emu->card_capabilities->ca0108_chip) {
16421639 dev_info(emu->card->dev, "EMU2 inputs on\n");
1640+ /* Note that the Tina[2] DSPs have 16 more EMU32 inputs which we don't use. */
1641+
16431642 for (z = 0; z < 0x10; z++) {
16441643 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
16451644 bit_shifter16,
@@ -1648,7 +1647,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) · 2 unmodified lines
16481647 }
16491648 } else {
16501649 dev_info(emu->card->dev, "EMU inputs on\n");
1651− /* Capture 16 (originally 8) channels of S32_LE sound */
1650+ /* Note that the Alice2 DSPs have 6 I2S inputs which we don't use. */
16521651
16531652 /*
16541653 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",
@@ -1886,12 +1885,10 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) · 231 unmodified lines
18861885 icode->code = icode->tram_addr_map + 160;
18871886
18881887 /* clear free GPRs */
1889− for (i = 0; i < 256; i++)
1890− set_bit(i, icode->gpr_valid);
1888+ memset(icode->gpr_valid, 0xff, 256 / 8);
18911889
18921890 /* clear TRAM data & address lines */
1893− for (i = 0; i < 160; i++)
1894− set_bit(i, icode->tram_valid);
1891+ memset(icode->tram_valid, 0xff, 160 / 8);
18951892
18961893 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
18971894 ptr = 0; i = 0;
@@ -1903,9 +1900,6 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) · 5 unmodified lines
19031900 tmp = 0x88; /* we need 4 temporary GPR */
19041901 /* from 0x8c to 0xff is the area for tone control */
19051902
1906− /* stop FX processor */
1907− snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1908−
19091903 /*
19101904 * Process FX Buses
19111905 */
@@ -2523,7 +2517,7 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, · 611 unmodified lines
25232517 struct snd_emu10k1_fx8010_info *info)
25242518 {
25252519 const char * const *fxbus, * const *extin, * const *extout;
2526− unsigned short fxbus_mask, extin_mask, extout_mask;
2520+ unsigned short extin_mask, extout_mask;
25272521 int res;
25282522
25292523 info->internal_tram_size = emu->fx8010.itram_size;
@@ -2531,11 +2525,10 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, · 1 unmodified line
25312525 fxbus = fxbuses;
25322526 extin = emu->audigy ? audigy_ins : creative_ins;
25332527 extout = emu->audigy ? audigy_outs : creative_outs;
2534− fxbus_mask = emu->fx8010.fxbus_mask;
2535− extin_mask = emu->fx8010.extin_mask;
2536− extout_mask = emu->fx8010.extout_mask;
2528+ extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask;
2529+ extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask;
25372530 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2538− copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2531+ copy_string(info->fxbus_names[res], *fxbus, "FXBUS", res);
25392532 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
25402533 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
25412534 }
@@ -2651,17 +2644,19 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un · 109 unmodified lines
26512644 return -EPERM;
26522645 if (get_user(addr, (unsigned int __user *)argp))
26532646 return -EFAULT;
2654− if (addr > 0x1ff)
2655− return -EINVAL;
2656− if (emu->audigy)
2657− snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2658− else
2659− snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2660− udelay(10);
2661− if (emu->audigy)
2662− snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2663− else
2664− snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2647+ if (emu->audigy) {
2648+ if (addr > A_DBG_STEP_ADDR)
2649+ return -EINVAL;
2650+ snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2651+ udelay(10);
2652+ snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_STEP | addr);
2653+ } else {
2654+ if (addr > EMU10K1_DBG_SINGLE_STEP_ADDR)
2655+ return -EINVAL;
2656+ snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2657+ udelay(10);
2658+ snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_STEP | addr);
2659+ }
26652660 return 0;
26662661 case SNDRV_EMU10K1_IOCTL_DBG_READ:
26672662 if (emu->audigy)
sound/pci/emu10k1/emumixer.c+23−22
@@ -346,7 +346,7 @@ static const unsigned int emu1616_output_dst[] = { · 345 unmodified lines
346346 };
347347
348348 /*
349− * Data destinations - HANA outputs going to Alice2 (audigy) for
349+ * Data destinations - FPGA outputs going to Alice2 (Audigy) for
350350 * capture (EMU32 + I2S links)
351351 * Each destination has an enum mixer control to choose a data source
352352 */
@@ -367,6 +367,7 @@ static const unsigned int emu1010_input_dst[] = { · 14 unmodified lines
367367 EMU_DST_ALICE2_EMU32_D,
368368 EMU_DST_ALICE2_EMU32_E,
369369 EMU_DST_ALICE2_EMU32_F,
370+ /* These exist only on rev1 EMU1010 cards. */
370371 EMU_DST_ALICE_I2S0_LEFT,
371372 EMU_DST_ALICE_I2S0_RIGHT,
372373 EMU_DST_ALICE_I2S1_LEFT,
@@ -708,7 +709,7 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, · 335 unmodified lines
708709 /* 44100 */
709710 /* Mute all */
710711 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
711− /* Default fallback clock 48kHz */
712+ /* Default fallback clock 44.1kHz */
712713 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );
713714 /* Word Clock source, Internal 44.1kHz x1 */
714715 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
@@ -924,7 +925,7 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, · 209 unmodified lines
924925 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
925926 unsigned int source_id;
926927 unsigned int ngain, ogain;
927− u32 gpio;
928+ u16 gpio;
928929 int change = 0;
929930 unsigned long flags;
930931 u32 source;
@@ -941,11 +942,11 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, · 10 unmodified lines
941942 if (change) {
942943 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
943944 spin_lock_irqsave(&emu->emu_lock, flags);
944− gpio = inl(emu->port + A_IOCFG);
945+ gpio = inw(emu->port + A_IOCFG);
945946 if (source_id==0)
946− outl(gpio | 0x4, emu->port + A_IOCFG);
947+ outw(gpio | 0x4, emu->port + A_IOCFG);
947948 else
948− outl(gpio & ~0x4, emu->port + A_IOCFG);
949+ outw(gpio & ~0x4, emu->port + A_IOCFG);
949950 spin_unlock_irqrestore(&emu->emu_lock, flags);
950951
951952 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
@@ -1005,7 +1006,7 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, · 53 unmodified lines
10051006 {
10061007 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
10071008 unsigned int ogain;
1008− unsigned int ngain;
1009+ unsigned int ngain0, ngain1;
10091010 unsigned int source_id;
10101011 int change = 0;
10111012
@@ -1014,24 +1015,24 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, · 2 unmodified lines
10141015 /* capture_source: uinfo->value.enumerated.items = 2 */
10151016 if (source_id >= 2)
10161017 return -EINVAL;
1018+ ngain0 = ucontrol->value.integer.value[0];
1019+ ngain1 = ucontrol->value.integer.value[1];
1020+ if (ngain0 > 0xff)
1021+ return -EINVAL;
1022+ if (ngain1 > 0xff)
1023+ return -EINVAL;
10171024 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
1018− ngain = ucontrol->value.integer.value[0];
1019− if (ngain > 0xff)
1020− return 0;
1021− if (ogain != ngain) {
1025+ if (ogain != ngain0) {
10221026 if (emu->i2c_capture_source == source_id)
1023− snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
1024− emu->i2c_capture_volume[source_id][0] = ngain;
1027+ snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ngain0);
1028+ emu->i2c_capture_volume[source_id][0] = ngain0;
10251029 change = 1;
10261030 }
10271031 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
1028− ngain = ucontrol->value.integer.value[1];
1029− if (ngain > 0xff)
1030− return 0;
1031− if (ogain != ngain) {
1032+ if (ogain != ngain1) {
10321033 if (emu->i2c_capture_source == source_id)
1033− snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
1034− emu->i2c_capture_volume[source_id][1] = ngain;
1034+ snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ngain1);
1035+ emu->i2c_capture_volume[source_id][1] = ngain1;
10351036 change = 1;
10361037 }
10371038
@@ -1632,7 +1633,7 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, · 594 unmodified lines
16321633 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
16331634
16341635 if (emu->audigy)
1635− ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
1636+ ucontrol->value.integer.value[0] = inw(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
16361637 else
16371638 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
16381639 if (emu->card_capabilities->invert_shared_spdif)
@@ -1657,13 +1658,13 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, · 18 unmodified lines
16571658 if ( emu->card_capabilities->i2c_adc) {
16581659 /* Do nothing for Audigy 2 ZS Notebook */
16591660 } else if (emu->audigy) {
1660− reg = inl(emu->port + A_IOCFG);
1661+ reg = inw(emu->port + A_IOCFG);
16611662 val = sw ? A_IOCFG_GPOUT0 : 0;
16621663 change = (reg & A_IOCFG_GPOUT0) != val;
16631664 if (change) {
16641665 reg &= ~A_IOCFG_GPOUT0;
16651666 reg |= val;
1666− outl(reg | val, emu->port + A_IOCFG);
1667+ outw(reg | val, emu->port + A_IOCFG);
16671668 }
16681669 }
16691670 reg = inl(emu->port + HCFG);
sound/pci/emu10k1/emupcm.c+13−67
@@ -76,23 +76,6 @@ static void snd_emu10k1_pcm_efx_interrupt(struct snd_emu10k1 *emu, · 75 unmodified lines
7676 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
7777 }
7878
79−static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(struct snd_pcm_substream *substream)
80−{
81− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
82− struct snd_pcm_runtime *runtime = substream->runtime;
83− struct snd_emu10k1_pcm *epcm = runtime->private_data;
84− unsigned int ptr;
85−
86− if (!epcm->running)
87− return 0;
88− ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
89− ptr += runtime->buffer_size;
90− ptr -= epcm->ccca_start_addr;
91− ptr %= runtime->buffer_size;
92−
93− return ptr;
94−}
95−
9679 static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)
9780 {
9881 int err, i;
@@ -343,7 +326,6 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, · 244 unmodified lines
343326 } else
344327 snd_emu10k1_ptr_write(emu, FXRT, voice,
345328 snd_emu10k1_compose_send_routing(send_routing));
346− /* Stop CA */
347329 /* Assumption that PT is already 0 so no harm overwriting */
348330 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
349331 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
@@ -429,36 +411,6 @@ static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream, · 79 unmodified lines
429411 }
430412
431413 static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream)
432−{
433− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
434− struct snd_pcm_runtime *runtime = substream->runtime;
435− struct snd_emu10k1_pcm *epcm;
436−
437− if (runtime->private_data == NULL)
438− return 0;
439− epcm = runtime->private_data;
440− if (epcm->extra) {
441− snd_emu10k1_voice_free(epcm->emu, epcm->extra);
442− epcm->extra = NULL;
443− }
444− if (epcm->voices[1]) {
445− snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
446− epcm->voices[1] = NULL;
447− }
448− if (epcm->voices[0]) {
449− snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
450− epcm->voices[0] = NULL;
451− }
452− if (epcm->memblk) {
453− snd_emu10k1_free_pages(emu, epcm->memblk);
454− epcm->memblk = NULL;
455− epcm->start_addr = 0;
456− }
457− snd_pcm_lib_free_pages(substream);
458− return 0;
459−}
460−
461−static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
462414 {
463415 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
464416 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -527,9 +479,6 @@ static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream) · 62 unmodified lines
527479 start_addr = epcm->start_addr;
528480 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
529481
530− /*
531− * the kX driver leaves some space between voices
532− */
533482 channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
534483
535484 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
@@ -1091,8 +1040,6 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream) · 555 unmodified lines
10911040 epcm->type = PLAYBACK_EFX;
10921041 epcm->substream = substream;
10931042
1094− emu->pcm_playback_efx_substream = substream;
1095−
10961043 runtime->private_data = epcm;
10971044 runtime->private_free = snd_emu10k1_pcm_free_substream;
10981045 runtime->hw = snd_emu10k1_efx_playback;
@@ -1267,9 +1214,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) · 168 unmodified lines
12671214 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
12681215 spin_lock_irq(&emu->reg_lock);
12691216 if (emu->card_capabilities->emu_model) {
1270− /* Nb. of channels has been increased to 16 */
12711217 /* TODO
1272− * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
12731218 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
12741219 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
12751220 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
@@ -1280,13 +1225,14 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) · 4 unmodified lines
12801225 * Need to add mixer control to fix sample rate
12811226 *
12821227 * There are 32 mono channels of 16bits each.
1283− * 24bit Audio uses 2x channels over 16bit
1284− * 96kHz uses 2x channels over 48kHz
1285− * 192kHz uses 4x channels over 48kHz
1286− * So, for 48kHz 24bit, one has 16 channels
1287− * for 96kHz 24bit, one has 8 channels
1288− * for 192kHz 24bit, one has 4 channels
1289− *
1228+ * 24bit Audio uses 2x channels over 16bit,
1229+ * 96kHz uses 2x channels over 48kHz,
1230+ * 192kHz uses 4x channels over 48kHz.
1231+ * So, for 48kHz 24bit, one has 16 channels,
1232+ * for 96kHz 24bit, one has 8 channels,
1233+ * for 192kHz 24bit, one has 4 channels.
1234+ * 1010rev2 and 1616(m) cards have double that,
1235+ * but we don't exceed 16 channels anyway.
12901236 */
12911237 #if 1
12921238 switch (emu->emu1010.internal_clock) {
@@ -1372,10 +1318,10 @@ static const struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { · 79 unmodified lines
13721318 .open = snd_emu10k1_efx_playback_open,
13731319 .close = snd_emu10k1_efx_playback_close,
13741320 .hw_params = snd_emu10k1_playback_hw_params,
1375− .hw_free = snd_emu10k1_efx_playback_hw_free,
1321+ .hw_free = snd_emu10k1_playback_hw_free,
13761322 .prepare = snd_emu10k1_efx_playback_prepare,
13771323 .trigger = snd_emu10k1_efx_playback_trigger,
1378− .pointer = snd_emu10k1_efx_playback_pointer,
1324+ .pointer = snd_emu10k1_playback_pointer,
13791325 };
13801326
13811327 int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device)
@@ -1508,11 +1454,12 @@ static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, st · 126 unmodified lines
15081454 nval[idx / 32] |= 1 << (idx % 32);
15091455 bits++;
15101456 }
1511−
1457+
1458+ // Check that the number of requested channels is a power of two
1459+ // not bigger than the number of available channels.
15121460 for (idx = 0; idx < nefxb; idx++)
15131461 if (1 << idx == bits)
15141462 break;
1515−
15161463 if (idx >= nefxb)
15171464 return -EINVAL;
15181465
@@ -1802,7 +1749,6 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device) · 283 unmodified lines
18021749 * to these
18031750 */
18041751
1805− /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
18061752 if (emu->audigy) {
18071753 emu->efx_voices_mask[0] = 0;
18081754 if (emu->card_capabilities->emu_model)
sound/pci/emu10k1/emuproc.c+1−4
@@ -477,10 +477,7 @@ static void snd_emu_proc_ptr_reg_read(struct snd_info_entry *entry, · 476 unmodified lines
477477 for(i = offset; i < offset+length; i++) {
478478 snd_iprintf(buffer, "%02X: ",i);
479479 for (j = 0; j < voices; j++) {
480− if(iobase == 0)
481− value = snd_ptr_read(emu, 0, i, j);
482− else
483− value = snd_ptr_read(emu, 0x20, i, j);
480+ value = snd_ptr_read(emu, iobase, i, j);
484481 snd_iprintf(buffer, "%08lX ", value);
485482 }
486483 snd_iprintf(buffer, "\n");
sound/pci/emu10k1/io.c+27−34
@@ -233,56 +233,57 @@ int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, · 232 unmodified lines
233233 return err;
234234 }
235235
236−int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)
236+void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
237237 {
238238 unsigned long flags;
239239
240− if (reg > 0x3f)
241− return 1;
240+ if (snd_BUG_ON(reg > 0x3f))
241+ return;
242242 reg += 0x40; /* 0x40 upwards are registers. */
243− if (value > 0x3f) /* 0 to 0x3f are values */
244− return 1;
243+ if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */
244+ return;
245245 spin_lock_irqsave(&emu->emu_lock, flags);
246− outl(reg, emu->port + A_IOCFG);
246+ outw(reg, emu->port + A_GPIO);
247247 udelay(10);
248− outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
248+ outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
249249 udelay(10);
250− outl(value, emu->port + A_IOCFG);
250+ outw(value, emu->port + A_GPIO);
251251 udelay(10);
252− outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
252+ outw(value | 0x80 , emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
253253 spin_unlock_irqrestore(&emu->emu_lock, flags);
254−
255− return 0;
256254 }
257255
258−int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value)
256+void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
259257 {
258+ // The higest input pin is used as the designated interrupt trigger,
259+ // so it needs to be masked out.
260+ u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
260261 unsigned long flags;
261− if (reg > 0x3f)
262− return 1;
262+ if (snd_BUG_ON(reg > 0x3f))
263+ return;
263264 reg += 0x40; /* 0x40 upwards are registers. */
264265 spin_lock_irqsave(&emu->emu_lock, flags);
265− outl(reg, emu->port + A_IOCFG);
266+ outw(reg, emu->port + A_GPIO);
266267 udelay(10);
267− outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
268+ outw(reg | 0x80, emu->port + A_GPIO); /* High bit clocks the value into the fpga. */
268269 udelay(10);
269− *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
270+ *value = ((inw(emu->port + A_GPIO) >> 8) & mask);
270271 spin_unlock_irqrestore(&emu->emu_lock, flags);
271−
272− return 0;
273272 }
274273
275274 /* Each Destination has one and only one Source,
276275 * but one Source can feed any number of Destinations simultaneously.
277276 */
278−int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src)
277+void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
279278 {
280− snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
281− snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
282− snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
283− snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
284−
285− return 0;
279+ if (snd_BUG_ON(dst & ~0x71f))
280+ return;
281+ if (snd_BUG_ON(src & ~0x71f))
282+ return;
283+ snd_emu1010_fpga_write(emu, 0x00, dst >> 8);
284+ snd_emu1010_fpga_write(emu, 0x01, dst & 0x1f);
285+ snd_emu1010_fpga_write(emu, 0x02, src >> 8);
286+ snd_emu1010_fpga_write(emu, 0x03, src & 0x1f);
286287 }
287288
288289 void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
@@ -313,7 +314,6 @@ void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenu · 24 unmodified lines
313314 unsigned int val;
314315
315316 spin_lock_irqsave(&emu->emu_lock, flags);
316− /* voice interrupt */
317317 if (voicenum >= 32) {
318318 outl(CLIEH << 16, emu->port + PTR);
319319 val = inl(emu->port + DATA);
@@ -333,7 +333,6 @@ void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicen · 13 unmodified lines
333333 unsigned int val;
334334
335335 spin_lock_irqsave(&emu->emu_lock, flags);
336− /* voice interrupt */
337336 if (voicenum >= 32) {
338337 outl(CLIEH << 16, emu->port + PTR);
339338 val = inl(emu->port + DATA);
@@ -352,7 +351,6 @@ void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum) · 12 unmodified lines
352351 unsigned long flags;
353352
354353 spin_lock_irqsave(&emu->emu_lock, flags);
355− /* voice interrupt */
356354 if (voicenum >= 32) {
357355 outl(CLIPH << 16, emu->port + PTR);
358356 voicenum = 1 << (voicenum - 32);
@@ -370,7 +368,6 @@ void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned i · 11 unmodified lines
370368 unsigned int val;
371369
372370 spin_lock_irqsave(&emu->emu_lock, flags);
373− /* voice interrupt */
374371 if (voicenum >= 32) {
375372 outl(HLIEH << 16, emu->port + PTR);
376373 val = inl(emu->port + DATA);
@@ -390,7 +387,6 @@ void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned · 13 unmodified lines
390387 unsigned int val;
391388
392389 spin_lock_irqsave(&emu->emu_lock, flags);
393− /* voice interrupt */
394390 if (voicenum >= 32) {
395391 outl(HLIEH << 16, emu->port + PTR);
396392 val = inl(emu->port + DATA);
@@ -409,7 +405,6 @@ void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int · 12 unmodified lines
409405 unsigned long flags;
410406
411407 spin_lock_irqsave(&emu->emu_lock, flags);
412− /* voice interrupt */
413408 if (voicenum >= 32) {
414409 outl(HLIPH << 16, emu->port + PTR);
415410 voicenum = 1 << (voicenum - 32);
@@ -427,7 +422,6 @@ void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voice · 11 unmodified lines
427422 unsigned int sol;
428423
429424 spin_lock_irqsave(&emu->emu_lock, flags);
430− /* voice interrupt */
431425 if (voicenum >= 32) {
432426 outl(SOLEH << 16, emu->port + PTR);
433427 sol = inl(emu->port + DATA);
@@ -447,7 +441,6 @@ void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voi · 13 unmodified lines
447441 unsigned int sol;
448442
449443 spin_lock_irqsave(&emu->emu_lock, flags);
450− /* voice interrupt */
451444 if (voicenum >= 32) {
452445 outl(SOLEH << 16, emu->port + PTR);
453446 sol = inl(emu->port + DATA);
sound/pci/emu10k1/irq.c+5−27
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)
1919 {
2020 struct snd_emu10k1 *emu = dev_id;
21− unsigned int status, status2, orig_status, orig_status2;
21+ unsigned int status, orig_status;
2222 int handled = 0;
2323 int timeout = 0;
2424
@@ -139,32 +139,10 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) · 114 unmodified lines
139139 status &= ~IPR_FXDSP;
140140 }
141141 if (status & IPR_P16V) {
142− while ((status2 = inl(emu->port + IPR2)) != 0) {
143− u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
144− struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]);
145− struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice);
146−
147− /* dev_dbg(emu->card->dev, "status2=0x%x\n", status2); */
148− orig_status2 = status2;
149− if(status2 & mask) {
150− if(pvoice->use) {
151− snd_pcm_period_elapsed(pvoice->epcm->substream);
152− } else {
153− dev_err(emu->card->dev,
154− "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n",
155− status2, mask, pvoice,
156− pvoice->use);
157− }
158− }
159− if(status2 & 0x110000) {
160− /* dev_info(emu->card->dev, "capture int found\n"); */
161− if(cvoice->use) {
162− /* dev_info(emu->card->dev, "capture period_elapsed\n"); */
163− snd_pcm_period_elapsed(cvoice->epcm->substream);
164− }
165− }
166− outl(orig_status2, emu->port + IPR2); /* ack all */
167− }
142+ if (emu->p16v_interrupt)
143+ emu->p16v_interrupt(emu);
144+ else
145+ outl(0, emu->port + INTE2);
168146 status &= ~IPR_P16V;
169147 }
170148
sound/pci/emu10k1/p16v.c+44−69
@@ -149,42 +149,19 @@ static const struct snd_pcm_hardware snd_p16v_capture_hw = { · 148 unmodified lines
149149 .fifo_size = 0,
150150 };
151151
152−static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
153−{
154− struct snd_emu10k1_pcm *epcm = runtime->private_data;
155−
156− kfree(epcm);
157−}
158−
159152 /* open_playback callback */
160153 static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
161154 {
162− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
163− struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
164− struct snd_emu10k1_pcm *epcm;
165155 struct snd_pcm_runtime *runtime = substream->runtime;
166156 int err;
167157
168− epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
169− /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
170−
171− if (epcm == NULL)
172− return -ENOMEM;
173− epcm->emu = emu;
174− epcm->substream = substream;
175158 /*
176159 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
177160 substream->pcm->device, channel_id);
178161 */
179− runtime->private_data = epcm;
180− runtime->private_free = snd_p16v_pcm_free_substream;
181162
182163 runtime->hw = snd_p16v_playback_hw;
183164
184− channel->emu = emu;
185− channel->number = channel_id;
186−
187− channel->use=1;
188165 #if 0 /* debug */
189166 dev_dbg(emu->card->dev,
190167 "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
@@ -193,7 +170,6 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea · 2 unmodified lines
193170 channel_id, chip, channel);
194171 #endif /* debug */
195172 /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
196− channel->epcm = epcm;
197173 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
198174 if (err < 0)
199175 return err;
@@ -205,44 +181,20 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea · 5 unmodified lines
205181
206182 return 0;
207183 }
184+
208185 /* open_capture callback */
209186 static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
210187 {
211− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
212− struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
213− struct snd_emu10k1_pcm *epcm;
214188 struct snd_pcm_runtime *runtime = substream->runtime;
215189 int err;
216190
217− epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
218− /* dev_dbg(emu->card->dev, "epcm kcalloc: %p\n", epcm); */
219−
220− if (epcm == NULL)
221− return -ENOMEM;
222− epcm->emu = emu;
223− epcm->substream = substream;
224191 /*
225192 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
226193 substream->pcm->device, channel_id);
227194 */
228− runtime->private_data = epcm;
229− runtime->private_free = snd_p16v_pcm_free_substream;
230195
231196 runtime->hw = snd_p16v_capture_hw;
232197
233− channel->emu = emu;
234− channel->number = channel_id;
235−
236− channel->use=1;
237−#if 0 /* debug */
238− dev_dbg(emu->card->dev,
239− "p16v: open channel_id=%d, channel=%p, use=0x%x\n",
240− channel_id, channel, channel->use);
241− dev_dbg(emu->card->dev, "open:channel_id=%d, chip=%p, channel=%p\n",
242− channel_id, chip, channel);
243−#endif /* debug */
244− /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
245− channel->epcm = epcm;
246198 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
247199 if (err < 0)
248200 return err;
@@ -254,22 +206,12 @@ static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream · 5 unmodified lines
254206 /* close callback */
255207 static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
256208 {
257− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
258− //struct snd_pcm_runtime *runtime = substream->runtime;
259− //struct snd_emu10k1_pcm *epcm = runtime->private_data;
260− emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
261− /* FIXME: maybe zero others */
262209 return 0;
263210 }
264211
265212 /* close callback */
266213 static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
267214 {
268− struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
269− //struct snd_pcm_runtime *runtime = substream->runtime;
270− //struct snd_emu10k1_pcm *epcm = runtime->private_data;
271− emu->p16v_capture_voice.use = 0;
272− /* FIXME: maybe zero others */
273215 return 0;
274216 }
275217
@@ -411,13 +353,48 @@ static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb) · 135 unmodified lines
411353 spin_unlock_irqrestore(&emu->emu_lock, flags);
412354 }
413355
356+static void snd_p16v_interrupt(struct snd_emu10k1 *emu)
357+{
358+ unsigned int status;
359+
360+ while ((status = inl(emu->port + IPR2)) != 0) {
361+ u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
362+
363+ /* dev_dbg(emu->card->dev, "p16v status=0x%x\n", status); */
364+ if (status & mask) {
365+ struct snd_pcm_substream *substream =
366+ emu->pcm_p16v->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
367+ struct snd_pcm_runtime *runtime = substream->runtime;
368+
369+ if (runtime && runtime->private_data) {
370+ snd_pcm_period_elapsed(substream);
371+ } else {
372+ dev_err(emu->card->dev,
373+ "p16v: status: 0x%08x, mask=0x%08x\n",
374+ status, mask);
375+ }
376+ }
377+ if (status & 0x110000) {
378+ struct snd_pcm_substream *substream =
379+ emu->pcm_p16v->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
380+ struct snd_pcm_runtime *runtime = substream->runtime;
381+
382+ /* dev_info(emu->card->dev, "capture int found\n"); */
383+ if (runtime && runtime->private_data) {
384+ /* dev_info(emu->card->dev, "capture period_elapsed\n"); */
385+ snd_pcm_period_elapsed(substream);
386+ }
387+ }
388+ outl(status, emu->port + IPR2); /* ack all */
389+ }
390+}
391+
414392 /* trigger_playback callback */
415393 static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
416394 int cmd)
417395 {
418396 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
419397 struct snd_pcm_runtime *runtime;
420− struct snd_emu10k1_pcm *epcm;
421398 int channel;
422399 int result = 0;
423400 struct snd_pcm_substream *s;
@@ -439,10 +416,9 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, · 15 unmodified lines
439416 s->stream != SNDRV_PCM_STREAM_PLAYBACK)
440417 continue;
441418 runtime = s->runtime;
442− epcm = runtime->private_data;
443419 channel = substream->pcm->device-emu->p16v_device_offset;
444420 /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */
445− epcm->running = running;
421+ runtime->private_data = (void *)(ptrdiff_t)running;
446422 basic |= (0x1<<channel);
447423 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
448424 snd_pcm_trigger_done(s, substream);
@@ -471,7 +447,6 @@ static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream, · 22 unmodified lines
471447 {
472448 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
473449 struct snd_pcm_runtime *runtime = substream->runtime;
474− struct snd_emu10k1_pcm *epcm = runtime->private_data;
475450 int channel = 0;
476451 int result = 0;
477452 u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
@@ -480,13 +455,13 @@ static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream, · 2 unmodified lines
480455 case SNDRV_PCM_TRIGGER_START:
481456 snd_p16v_intr_enable(emu, inte);
482457 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
483− epcm->running = 1;
458+ runtime->private_data = (void *)1;
484459 break;
485460 case SNDRV_PCM_TRIGGER_STOP:
486461 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
487462 snd_p16v_intr_disable(emu, inte);
488463 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
489− epcm->running = 0;
464+ runtime->private_data = NULL;
490465 break;
491466 default:
492467 result = -EINVAL;
@@ -501,10 +476,10 @@ snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream) · 8 unmodified lines
501476 {
502477 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
503478 struct snd_pcm_runtime *runtime = substream->runtime;
504− struct snd_emu10k1_pcm *epcm = runtime->private_data;
505479 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
506480 int channel = substream->pcm->device - emu->p16v_device_offset;
507− if (!epcm->running)
481+
482+ if (!runtime->private_data)
508483 return 0;
509484
510485 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
@@ -526,11 +501,10 @@ snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream) · 15 unmodified lines
526501 {
527502 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
528503 struct snd_pcm_runtime *runtime = substream->runtime;
529− struct snd_emu10k1_pcm *epcm = runtime->private_data;
530504 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
531505 int channel = 0;
532506
533− if (!epcm->running)
507+ if (!runtime->private_data)
534508 return 0;
535509
536510 ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
@@ -591,6 +565,7 @@ int snd_p16v_pcm(struct snd_emu10k1 *emu, int device) · 54 unmodified lines
591565 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
592566 strcpy(pcm->name, "p16v");
593567 emu->pcm_p16v = pcm;
568+ emu->p16v_interrupt = snd_p16v_interrupt;
594569
595570 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
596571 substream;
sound/pci/emu10k1/p16v.h+1−1
@@ -64,7 +64,7 @@ · 63 unmodified lines
6464 */
6565
6666 /********************************************************************************************************/
67−/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */
67+/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */
6868 /********************************************************************************************************/
6969
7070 /* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.
sound/pci/emu10k1/p17v.h+2−2
@@ -6,8 +6,8 @@ · 5 unmodified lines
66 */
77
88 /******************************************************************************/
9−/* Audigy2Value Tina (P17V) pointer-offset register set,
10− * accessed through the PTR20 and DATA24 registers */
9+/* Audigy2Value Tina (P17V) pointer-offset register set, */
10+/* accessed through the PTR2 and DATA2 registers */
1111 /******************************************************************************/
1212
1313 /* 00 - 07: Not used */
sound/pci/hda/cs35l41_hda.c+3−3
@@ -514,13 +514,13 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action) · 513 unmodified lines
514514 break;
515515 case HDA_GEN_PCM_ACT_PREPARE:
516516 mutex_lock(&cs35l41->fw_mutex);
517− ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1);
517+ ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1, NULL);
518518 mutex_unlock(&cs35l41->fw_mutex);
519519 break;
520520 case HDA_GEN_PCM_ACT_CLEANUP:
521521 mutex_lock(&cs35l41->fw_mutex);
522522 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
523− ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0);
523+ ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0, NULL);
524524 mutex_unlock(&cs35l41->fw_mutex);
525525 break;
526526 case HDA_GEN_PCM_ACT_CLOSE:
@@ -672,7 +672,7 @@ static int cs35l41_runtime_suspend(struct device *dev) · 145 unmodified lines
672672 if (cs35l41->playback_started) {
673673 regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
674674 ARRAY_SIZE(cs35l41_hda_mute));
675− cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
675+ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0, NULL);
676676 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
677677 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
678678 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
sound/pci/hda/hda_intel.c+3−0
@@ -2528,6 +2528,9 @@ static const struct pci_device_id azx_ids[] = { · 2527 unmodified lines
25282528 /* Meteorlake-P */
25292529 { PCI_DEVICE(0x8086, 0x7e28),
25302530 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2531+ /* Lunarlake-P */
2532+ { PCI_DEVICE(0x8086, 0xa828),
2533+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
25312534 /* Broxton-P(Apollolake) */
25322535 { PCI_DEVICE(0x8086, 0x5a98),
25332536 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
sound/pci/hda/hda_tegra.c+2−4
@@ -580,12 +580,10 @@ static void hda_tegra_probe_work(struct work_struct *work) · 579 unmodified lines
580580 return; /* no error return from async probe */
581581 }
582582
583−static int hda_tegra_remove(struct platform_device *pdev)
583+static void hda_tegra_remove(struct platform_device *pdev)
584584 {
585585 snd_card_free(dev_get_drvdata(&pdev->dev));
586586 pm_runtime_disable(&pdev->dev);
587−
588− return 0;
589587 }
590588
591589 static void hda_tegra_shutdown(struct platform_device *pdev)
@@ -607,7 +605,7 @@ static struct platform_driver tegra_platform_hda = { · 15 unmodified lines
607605 .of_match_table = hda_tegra_match,
608606 },
609607 .probe = hda_tegra_probe,
610− .remove = hda_tegra_remove,
608+ .remove_new = hda_tegra_remove,
611609 .shutdown = hda_tegra_shutdown,
612610 };
613611 module_platform_driver(tegra_platform_hda);
sound/pci/hda/patch_hdmi.c+4−8
@@ -2104,10 +2104,6 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, · 2103 unmodified lines
21042104 goto unlock;
21052105 }
21062106
2107− if (snd_BUG_ON(pin_idx < 0)) {
2108− err = -EINVAL;
2109− goto unlock;
2110− }
21112107 per_pin = get_pin(spec, pin_idx);
21122108
21132109 /* Verify pin:cvt selections to avoid silent audio after S3.
@@ -2199,13 +2195,13 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, · 85 unmodified lines
21992195 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
22002196 clear_bit(pcm_idx, &spec->pcm_in_use);
22012197 pin_idx = hinfo_to_pin_index(codec, hinfo);
2198+ /*
2199+ * In such a case, return 0 to match the behavior in
2200+ * hdmi_pcm_open()
2201+ */
22022202 if (pin_idx < 0)
22032203 goto unlock;
22042204
2205− if (snd_BUG_ON(pin_idx < 0)) {
2206− err = -EINVAL;
2207− goto unlock;
2208− }
22092205 per_pin = get_pin(spec, pin_idx);
22102206
22112207 if (spec->dyn_pin_out) {
sound/pci/rme9652/hdspm.c+0−6
@@ -6146,12 +6146,6 @@ static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file) · 6145 unmodified lines
61466146 return 0;
61476147 }
61486148
6149−static inline int copy_u32_le(void __user *dest, void __iomem *src)
6150−{
6151− u32 val = readl(src);
6152− return copy_to_user(dest, &val, 4);
6153−}
6154−
61556149 static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
61566150 unsigned int cmd, unsigned long arg)
61576151 {
sound/pci/ymfpci/ymfpci.c+26−13
@@ -98,8 +98,10 @@ static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, · 97 unmodified lines
9898 case 0x204: legacy_ctrl2 |= 2 << 6; break;
9999 case 0x205: legacy_ctrl2 |= 3 << 6; break;
100100 default:
101− dev_err(chip->card->dev,
102− "invalid joystick port %#x", io_port);
101+ if (io_port > 0)
102+ dev_err(chip->card->dev,
103+ "The %s does not support arbitrary IO ports for the game port (requested 0x%x)\n",
104+ chip->card->shortname, (unsigned int)io_port);
103105 return -EINVAL;
104106 }
105107 }
@@ -186,6 +188,13 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 80 unmodified lines
186188 default: model = str = "???"; break;
187189 }
188190
191+ strcpy(card->driver, str);
192+ sprintf(card->shortname, "Yamaha %s (%s)", model, str);
193+ sprintf(card->longname, "%s at 0x%lx, irq %i",
194+ card->shortname,
195+ chip->reg_area_phys,
196+ chip->irq);
197+
189198 legacy_ctrl = 0;
190199 legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
191200
@@ -218,7 +227,13 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 26 unmodified lines
218227 case 0x398: legacy_ctrl2 |= 1; break;
219228 case 0x3a0: legacy_ctrl2 |= 2; break;
220229 case 0x3a8: legacy_ctrl2 |= 3; break;
221− default: fm_port[dev] = 0; break;
230+ default:
231+ if (fm_port[dev] > 0)
232+ dev_err(card->dev,
233+ "The %s does not support arbitrary IO ports for FM (requested 0x%x)\n",
234+ card->shortname, (unsigned int)fm_port[dev]);
235+ fm_port[dev] = 0;
236+ break;
222237 }
223238 if (fm_port[dev] > 0)
224239 fm_res = devm_request_region(&pci->dev, fm_port[dev],
@@ -234,7 +249,13 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 9 unmodified lines
234249 case 0x300: legacy_ctrl2 |= 1 << 4; break;
235250 case 0x332: legacy_ctrl2 |= 2 << 4; break;
236251 case 0x334: legacy_ctrl2 |= 3 << 4; break;
237− default: mpu_port[dev] = 0; break;
252+ default:
253+ if (mpu_port[dev] > 0)
254+ dev_err(card->dev,
255+ "The %s does not support arbitrary IO ports for MPU-401 (requested 0x%x)\n",
256+ card->shortname, (unsigned int)mpu_port[dev]);
257+ mpu_port[dev] = 0;
258+ break;
238259 }
239260 if (mpu_port[dev] > 0)
240261 mpu_res = devm_request_region(&pci->dev, mpu_port[dev],
@@ -257,12 +278,6 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 16 unmodified lines
257278 if (err < 0)
258279 return err;
259280
260− strcpy(card->driver, str);
261− sprintf(card->shortname, "Yamaha %s (%s)", model, str);
262− sprintf(card->longname, "%s at 0x%lx, irq %i",
263− card->shortname,
264− chip->reg_area_phys,
265− chip->irq);
266281 err = snd_ymfpci_pcm(chip, 0);
267282 if (err < 0)
268283 return err;
@@ -337,11 +352,9 @@ static struct pci_driver ymfpci_driver = { · 68 unmodified lines
337352 .name = KBUILD_MODNAME,
338353 .id_table = snd_ymfpci_ids,
339354 .probe = snd_card_ymfpci_probe,
340−#ifdef CONFIG_PM_SLEEP
341355 .driver = {
342− .pm = &snd_ymfpci_pm,
356+ .pm = pm_sleep_ptr(&snd_ymfpci_pm),
343357 },
344−#endif
345358 };
346359
347360 module_pci_driver(ymfpci_driver);
sound/pci/ymfpci/ymfpci.h+47−7
@@ -268,6 +268,49 @@ struct snd_ymfpci_pcm { · 267 unmodified lines
268268 u32 shift;
269269 };
270270
271+static const int saved_regs_index[] = {
272+ /* spdif */
273+ YDSXGR_SPDIFOUTCTRL,
274+ YDSXGR_SPDIFOUTSTATUS,
275+ YDSXGR_SPDIFINCTRL,
276+ /* volumes */
277+ YDSXGR_PRIADCLOOPVOL,
278+ YDSXGR_NATIVEDACINVOL,
279+ YDSXGR_NATIVEDACOUTVOL,
280+ YDSXGR_BUF441OUTVOL,
281+ YDSXGR_NATIVEADCINVOL,
282+ YDSXGR_SPDIFLOOPVOL,
283+ YDSXGR_SPDIFOUTVOL,
284+ YDSXGR_ZVOUTVOL,
285+ YDSXGR_LEGACYOUTVOL,
286+ /* address bases */
287+ YDSXGR_PLAYCTRLBASE,
288+ YDSXGR_RECCTRLBASE,
289+ YDSXGR_EFFCTRLBASE,
290+ YDSXGR_WORKBASE,
291+ /* capture set up */
292+ YDSXGR_MAPOFREC,
293+ YDSXGR_RECFORMAT,
294+ YDSXGR_RECSLOTSR,
295+ YDSXGR_ADCFORMAT,
296+ YDSXGR_ADCSLOTSR,
297+};
298+#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
299+
300+static const int pci_saved_regs_index[] = {
301+ /* All Chips */
302+ PCIR_DSXG_LEGACY,
303+ PCIR_DSXG_ELEGACY,
304+ /* YMF 744/754 */
305+ PCIR_DSXG_FMBASE,
306+ PCIR_DSXG_SBBASE,
307+ PCIR_DSXG_MPU401BASE,
308+ PCIR_DSXG_JOYBASE,
309+};
310+#define DSXG_PCI_NUM_SAVED_REGS ARRAY_SIZE(pci_saved_regs_index)
311+#define DSXG_PCI_NUM_SAVED_LEGACY_REGS 2
312+static_assert(DSXG_PCI_NUM_SAVED_LEGACY_REGS <= DSXG_PCI_NUM_SAVED_REGS);
313+
271314 struct snd_ymfpci {
272315 int irq;
273316
@@ -276,7 +319,7 @@ struct snd_ymfpci { · 2 unmodified lines
276319 unsigned long reg_area_phys;
277320 void __iomem *reg_area_virt;
278321
279− unsigned short old_legacy_ctrl;
322+ u16 old_legacy_ctrl;
280323 #ifdef SUPPORT_JOYSTICK
281324 struct gameport *gameport;
282325 #endif
@@ -345,17 +388,14 @@ struct snd_ymfpci { · 62 unmodified lines
345388 const struct firmware *dsp_microcode;
346389 const struct firmware *controller_microcode;
347390
348−#ifdef CONFIG_PM_SLEEP
349− u32 *saved_regs;
391+ u32 saved_regs[YDSXGR_NUM_SAVED_REGS];
350392 u32 saved_ydsxgr_mode;
351− u16 saved_dsxg_legacy;
352− u16 saved_dsxg_elegacy;
353−#endif
393+ u16 saved_dsxg_pci_regs[DSXG_PCI_NUM_SAVED_REGS];
354394 };
355395
356396 int snd_ymfpci_create(struct snd_card *card,
357397 struct pci_dev *pci,
358− unsigned short old_legacy_ctrl);
398+ u16 old_legacy_ctrl);
359399 void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
360400
361401 extern const struct dev_pm_ops snd_ymfpci_pm;
sound/pci/ymfpci/ymfpci_main.c+22−57
@@ -31,11 +31,6 @@ · 30 unmodified lines
3131
3232 static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);
3333
34−static inline u8 snd_ymfpci_readb(struct snd_ymfpci *chip, u32 offset)
35−{
36− return readb(chip->reg_area_virt + offset);
37−}
38−
3934 static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)
4035 {
4136 writeb(val, chip->reg_area_virt + offset);
@@ -2219,57 +2214,33 @@ static void snd_ymfpci_free(struct snd_card *card) · 2177 unmodified lines
22192214
22202215 snd_ymfpci_free_gameport(chip);
22212216
2222− pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
2217+ pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, chip->old_legacy_ctrl);
22232218
22242219 release_firmware(chip->dsp_microcode);
22252220 release_firmware(chip->controller_microcode);
22262221 }
22272222
2228−#ifdef CONFIG_PM_SLEEP
2229−static const int saved_regs_index[] = {
2230− /* spdif */
2231− YDSXGR_SPDIFOUTCTRL,
2232− YDSXGR_SPDIFOUTSTATUS,
2233− YDSXGR_SPDIFINCTRL,
2234− /* volumes */
2235− YDSXGR_PRIADCLOOPVOL,
2236− YDSXGR_NATIVEDACINVOL,
2237− YDSXGR_NATIVEDACOUTVOL,
2238− YDSXGR_BUF441OUTVOL,
2239− YDSXGR_NATIVEADCINVOL,
2240− YDSXGR_SPDIFLOOPVOL,
2241− YDSXGR_SPDIFOUTVOL,
2242− YDSXGR_ZVOUTVOL,
2243− YDSXGR_LEGACYOUTVOL,
2244− /* address bases */
2245− YDSXGR_PLAYCTRLBASE,
2246− YDSXGR_RECCTRLBASE,
2247− YDSXGR_EFFCTRLBASE,
2248− YDSXGR_WORKBASE,
2249− /* capture set up */
2250− YDSXGR_MAPOFREC,
2251− YDSXGR_RECFORMAT,
2252− YDSXGR_RECSLOTSR,
2253− YDSXGR_ADCFORMAT,
2254− YDSXGR_ADCSLOTSR,
2255−};
2256−#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
2257−
22582223 static int snd_ymfpci_suspend(struct device *dev)
22592224 {
22602225 struct snd_card *card = dev_get_drvdata(dev);
22612226 struct snd_ymfpci *chip = card->private_data;
2262− unsigned int i;
2263−
2227+ unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS;
2228+
2229+ if (chip->pci->device >= 0x0010) /* YMF 744/754 */
2230+ legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
2231+
22642232 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
22652233 snd_ac97_suspend(chip->ac97);
2234+
22662235 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
22672236 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2237+
22682238 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2269− pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
2270− &chip->saved_dsxg_legacy);
2271− pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2272− &chip->saved_dsxg_elegacy);
2239+
2240+ for (i = 0; i < legacy_reg_count; i++)
2241+ pci_read_config_word(chip->pci, pci_saved_regs_index[i],
2242+ chip->saved_dsxg_pci_regs + i);
2243+
22732244 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
22742245 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
22752246 snd_ymfpci_disable_dsp(chip);
@@ -2281,7 +2252,10 @@ static int snd_ymfpci_resume(struct device *dev) · 5 unmodified lines
22812252 struct pci_dev *pci = to_pci_dev(dev);
22822253 struct snd_card *card = dev_get_drvdata(dev);
22832254 struct snd_ymfpci *chip = card->private_data;
2284− unsigned int i;
2255+ unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS;
2256+
2257+ if (chip->pci->device >= 0x0010) /* YMF 744/754 */
2258+ legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
22852259
22862260 snd_ymfpci_aclink_reset(pci);
22872261 snd_ymfpci_codec_ready(chip, 0);
@@ -2293,10 +2267,9 @@ static int snd_ymfpci_resume(struct device *dev) · 5 unmodified lines
22932267
22942268 snd_ac97_resume(chip->ac97);
22952269
2296− pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
2297− chip->saved_dsxg_legacy);
2298− pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2299− chip->saved_dsxg_elegacy);
2270+ for (i = 0; i < legacy_reg_count; i++)
2271+ pci_write_config_word(chip->pci, pci_saved_regs_index[i],
2272+ chip->saved_dsxg_pci_regs[i]);
23002273
23012274 /* start hw again */
23022275 if (chip->start_count > 0) {
@@ -2309,12 +2282,11 @@ static int snd_ymfpci_resume(struct device *dev) · 6 unmodified lines
23092282 return 0;
23102283 }
23112284
2312−SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
2313−#endif /* CONFIG_PM_SLEEP */
2285+DEFINE_SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
23142286
23152287 int snd_ymfpci_create(struct snd_card *card,
23162288 struct pci_dev *pci,
2317− unsigned short old_legacy_ctrl)
2289+ u16 old_legacy_ctrl)
23182290 {
23192291 struct snd_ymfpci *chip = card->private_data;
23202292 int err;
@@ -2379,13 +2351,6 @@ int snd_ymfpci_create(struct snd_card *card, · 58 unmodified lines
23792351 if (err < 0)
23802352 return err;
23812353
2382−#ifdef CONFIG_PM_SLEEP
2383− chip->saved_regs = devm_kmalloc_array(&pci->dev, YDSXGR_NUM_SAVED_REGS,
2384− sizeof(u32), GFP_KERNEL);
2385− if (!chip->saved_regs)
2386− return -ENOMEM;
2387−#endif
2388−
23892354 snd_ymfpci_proc_init(card, chip);
23902355
23912356 return 0;
sound/ppc/powermac.c+2−3
@@ -130,10 +130,9 @@ __error: · 129 unmodified lines
130130 }
131131
132132
133−static int snd_pmac_remove(struct platform_device *devptr)
133+static void snd_pmac_remove(struct platform_device *devptr)
134134 {
135135 snd_card_free(platform_get_drvdata(devptr));
136− return 0;
137136 }
138137
139138 #ifdef CONFIG_PM_SLEEP
@@ -161,7 +160,7 @@ static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_r · 21 unmodified lines
161160
162161 static struct platform_driver snd_pmac_driver = {
163162 .probe = snd_pmac_probe,
164− .remove = snd_pmac_remove,
163+ .remove_new = snd_pmac_remove,
165164 .driver = {
166165 .name = SND_PMAC_DRIVER,
167166 .pm = SND_PMAC_PM_OPS,
sound/ppc/tumbler.c+2−2
@@ -1361,9 +1361,9 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip) · 1360 unmodified lines
13611361
13621362 for_each_child_of_node(chip->node, np) {
13631363 if (of_node_name_eq(np, "sound")) {
1364− if (of_get_property(np, "has-anded-reset", NULL))
1364+ if (of_property_read_bool(np, "has-anded-reset"))
13651365 mix->anded_reset = 1;
1366− if (of_get_property(np, "layout-id", NULL))
1366+ if (of_property_present(np, "layout-id"))
13671367 mix->reset_on_sleep = 0;
13681368 of_node_put(np);
13691369 break;
sound/sh/aica.c+2−5
@@ -539,15 +539,12 @@ static int add_aicamixer_controls(struct snd_card_aica *dreamcastcard) · 538 unmodified lines
539539 return 0;
540540 }
541541
542−static int snd_aica_remove(struct platform_device *devptr)
542+static void snd_aica_remove(struct platform_device *devptr)
543543 {
544544 struct snd_card_aica *dreamcastcard;
545545 dreamcastcard = platform_get_drvdata(devptr);
546− if (unlikely(!dreamcastcard))
547− return -ENODEV;
548546 snd_card_free(dreamcastcard->card);
549547 kfree(dreamcastcard);
550− return 0;
551548 }
552549
553550 static int snd_aica_probe(struct platform_device *devptr)
@@ -594,7 +591,7 @@ static int snd_aica_probe(struct platform_device *devptr) · 40 unmodified lines
594591
595592 static struct platform_driver snd_aica_driver = {
596593 .probe = snd_aica_probe,
597− .remove = snd_aica_remove,
594+ .remove_new = snd_aica_remove,
598595 .driver = {
599596 .name = SND_AICA_DRIVER,
600597 },
sound/sh/sh_dac_audio.c+2−3
@@ -257,10 +257,9 @@ static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device) · 256 unmodified lines
257257
258258
259259 /* driver .remove -- destructor */
260−static int snd_sh_dac_remove(struct platform_device *devptr)
260+static void snd_sh_dac_remove(struct platform_device *devptr)
261261 {
262262 snd_card_free(platform_get_drvdata(devptr));
263− return 0;
264263 }
265264
266265 /* free -- it has been defined by create */
@@ -403,7 +402,7 @@ probe_error: · 136 unmodified lines
403402 */
404403 static struct platform_driver sh_dac_driver = {
405404 .probe = snd_sh_dac_probe,
406− .remove = snd_sh_dac_remove,
405+ .remove_new = snd_sh_dac_remove,
407406 .driver = {
408407 .name = "dac_audio",
409408 },
sound/soc/adi/axi-i2s.c+2−4
@@ -274,13 +274,11 @@ err_clk_disable: · 273 unmodified lines
274274 return ret;
275275 }
276276
277−static int axi_i2s_dev_remove(struct platform_device *pdev)
277+static void axi_i2s_dev_remove(struct platform_device *pdev)
278278 {
279279 struct axi_i2s *i2s = platform_get_drvdata(pdev);
280280
281281 clk_disable_unprepare(i2s->clk);
282−
283− return 0;
284282 }
285283
286284 static const struct of_device_id axi_i2s_of_match[] = {
@@ -295,7 +293,7 @@ static struct platform_driver axi_i2s_driver = { · 8 unmodified lines
295293 .of_match_table = axi_i2s_of_match,
296294 },
297295 .probe = axi_i2s_probe,
298− .remove = axi_i2s_dev_remove,
296+ .remove_new = axi_i2s_dev_remove,
299297 };
300298 module_platform_driver(axi_i2s_driver);
301299
sound/soc/adi/axi-spdif.c+2−4
@@ -239,13 +239,11 @@ err_clk_disable: · 238 unmodified lines
239239 return ret;
240240 }
241241
242−static int axi_spdif_dev_remove(struct platform_device *pdev)
242+static void axi_spdif_dev_remove(struct platform_device *pdev)
243243 {
244244 struct axi_spdif *spdif = platform_get_drvdata(pdev);
245245
246246 clk_disable_unprepare(spdif->clk);
247−
248− return 0;
249247 }
250248
251249 static const struct of_device_id axi_spdif_of_match[] = {
@@ -260,7 +258,7 @@ static struct platform_driver axi_spdif_driver = { · 8 unmodified lines
260258 .of_match_table = axi_spdif_of_match,
261259 },
262260 .probe = axi_spdif_probe,
263− .remove = axi_spdif_dev_remove,
261+ .remove_new = axi_spdif_dev_remove,
264262 };
265263 module_platform_driver(axi_spdif_driver);
266264
sound/soc/amd/Kconfig+2−0
@@ -90,6 +90,7 @@ config SND_SOC_AMD_VANGOGH_MACH · 89 unmodified lines
9090
9191 config SND_SOC_AMD_ACP6x
9292 tristate "AMD Audio Coprocessor-v6.x Yellow Carp support"
93+ select SND_AMD_ACP_CONFIG
9394 depends on X86 && PCI
9495 help
9596 This option enables Audio Coprocessor i.e ACP v6.x support on
@@ -130,6 +131,7 @@ config SND_SOC_AMD_RPL_ACP6x · 34 unmodified lines
130131
131132 config SND_SOC_AMD_PS
132133 tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
134+ select SND_AMD_ACP_CONFIG
133135 depends on X86 && PCI && ACPI
134136 help
135137 This option enables Audio Coprocessor i.e ACP v6.3 support on
sound/soc/amd/acp-pcm-dma.c+2−4
@@ -1323,7 +1323,7 @@ static int acp_audio_probe(struct platform_device *pdev) · 1322 unmodified lines
13231323 return status;
13241324 }
13251325
1326−static int acp_audio_remove(struct platform_device *pdev)
1326+static void acp_audio_remove(struct platform_device *pdev)
13271327 {
13281328 int status;
13291329 struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev);
@@ -1332,8 +1332,6 @@ static int acp_audio_remove(struct platform_device *pdev) · 2 unmodified lines
13321332 if (status)
13331333 dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
13341334 pm_runtime_disable(&pdev->dev);
1335−
1336− return 0;
13371335 }
13381336
13391337 static int acp_pcm_resume(struct device *dev)
@@ -1428,7 +1426,7 @@ static const struct dev_pm_ops acp_pm_ops = { · 88 unmodified lines
14281426
14291427 static struct platform_driver acp_dma_driver = {
14301428 .probe = acp_audio_probe,
1431− .remove = acp_audio_remove,
1429+ .remove_new = acp_audio_remove,
14321430 .driver = {
14331431 .name = DRV_NAME,
14341432 .pm = &acp_pm_ops,
sound/soc/amd/acp/acp-rembrandt.c+3−10
@@ -366,28 +366,21 @@ static int rembrandt_audio_probe(struct platform_device *pdev) · 365 unmodified lines
366366 return 0;
367367 }
368368
369−static int rembrandt_audio_remove(struct platform_device *pdev)
369+static void rembrandt_audio_remove(struct platform_device *pdev)
370370 {
371371 struct device *dev = &pdev->dev;
372372 struct acp_dev_data *adata = dev_get_drvdata(dev);
373− struct acp_chip_info *chip;
374−
375− chip = dev_get_platdata(&pdev->dev);
376− if (!chip || !chip->base) {
377− dev_err(&pdev->dev, "ACP chip data is NULL\n");
378− return -ENODEV;
379− }
373+ struct acp_chip_info *chip = dev_get_platdata(dev);
380374
381375 rmb_acp_deinit(chip->base);
382376
383377 acp6x_disable_interrupts(adata);
384378 acp_platform_unregister(dev);
385− return 0;
386379 }
387380
388381 static struct platform_driver rembrandt_driver = {
389382 .probe = rembrandt_audio_probe,
390− .remove = rembrandt_audio_remove,
383+ .remove_new = rembrandt_audio_remove,
391384 .driver = {
392385 .name = "acp_asoc_rembrandt",
393386 },
sound/soc/amd/acp/acp-renoir.c+2−3
@@ -313,7 +313,7 @@ static int renoir_audio_probe(struct platform_device *pdev) · 312 unmodified lines
313313 return 0;
314314 }
315315
316−static int renoir_audio_remove(struct platform_device *pdev)
316+static void renoir_audio_remove(struct platform_device *pdev)
317317 {
318318 struct device *dev = &pdev->dev;
319319 struct acp_dev_data *adata = dev_get_drvdata(dev);
@@ -329,12 +329,11 @@ static int renoir_audio_remove(struct platform_device *pdev) · 9 unmodified lines
329329 dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret));
330330
331331 acp_platform_unregister(dev);
332− return 0;
333332 }
334333
335334 static struct platform_driver renoir_driver = {
336335 .probe = renoir_audio_probe,
337− .remove = renoir_audio_remove,
336+ .remove_new = renoir_audio_remove,
338337 .driver = {
339338 .name = "acp_asoc_renoir",
340339 },
sound/soc/amd/ps/acp63.h+2−0
@@ -111,3 +111,5 @@ struct acp63_dev_data { · 110 unmodified lines
111111 u16 pdev_count;
112112 u16 pdm_dev_index;
113113 };
114+
115+int snd_amd_acp_find_config(struct pci_dev *pci);
sound/soc/amd/ps/pci-ps.c+7−3
@@ -91,7 +91,6 @@ static int acp63_init(void __iomem *acp_base, struct device *dev) · 90 unmodified lines
9191 dev_err(dev, "ACP reset failed\n");
9292 return ret;
9393 }
94− acp63_writel(0x03, acp_base + ACP_CLKMUX_SEL);
9594 acp63_enable_interrupts(acp_base);
9695 return 0;
9796 }
@@ -106,7 +105,6 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) · 8 unmodified lines
106105 dev_err(dev, "ACP reset failed\n");
107106 return ret;
108107 }
109− acp63_writel(0, acp_base + ACP_CLKMUX_SEL);
110108 acp63_writel(0, acp_base + ACP_CONTROL);
111109 return 0;
112110 }
@@ -249,11 +247,17 @@ static int snd_acp63_probe(struct pci_dev *pci, · 136 unmodified lines
249247 {
250248 struct acp63_dev_data *adata;
251249 u32 addr;
252− u32 irqflags;
250+ u32 irqflags, flag;
253251 int val;
254252 int ret;
255253
256254 irqflags = IRQF_SHARED;
255+
256+ /* Return if acp config flag is defined */
257+ flag = snd_amd_acp_find_config(pci);
258+ if (flag)
259+ return -ENODEV;
260+
257261 /* Pink Sardine device check */
258262 switch (pci->revision) {
259263 case 0x63:
sound/soc/amd/ps/ps-pdm-dma.c+2−3
@@ -399,10 +399,9 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev) · 398 unmodified lines
399399 return 0;
400400 }
401401
402−static int acp63_pdm_audio_remove(struct platform_device *pdev)
402+static void acp63_pdm_audio_remove(struct platform_device *pdev)
403403 {
404404 pm_runtime_disable(&pdev->dev);
405− return 0;
406405 }
407406
408407 static int __maybe_unused acp63_pdm_resume(struct device *dev)
@@ -451,7 +450,7 @@ static const struct dev_pm_ops acp63_pdm_pm_ops = { · 42 unmodified lines
451450
452451 static struct platform_driver acp63_pdm_dma_driver = {
453452 .probe = acp63_pdm_audio_probe,
454− .remove = acp63_pdm_audio_remove,
453+ .remove_new = acp63_pdm_audio_remove,
455454 .driver = {
456455 .name = "acp_ps_pdm_dma",
457456 .pm = &acp63_pdm_pm_ops,
sound/soc/amd/raven/acp3x-pcm-dma.c+2−3
@@ -421,10 +421,9 @@ static int acp3x_audio_probe(struct platform_device *pdev) · 420 unmodified lines
421421 return 0;
422422 }
423423
424−static int acp3x_audio_remove(struct platform_device *pdev)
424+static void acp3x_audio_remove(struct platform_device *pdev)
425425 {
426426 pm_runtime_disable(&pdev->dev);
427− return 0;
428427 }
429428
430429 static int acp3x_resume(struct device *dev)
@@ -509,7 +508,7 @@ static const struct dev_pm_ops acp3x_pm_ops = { · 78 unmodified lines
509508
510509 static struct platform_driver acp3x_dma_driver = {
511510 .probe = acp3x_audio_probe,
512− .remove = acp3x_audio_remove,
511+ .remove_new = acp3x_audio_remove,
513512 .driver = {
514513 .name = "acp3x_rv_i2s_dma",
515514 .pm = &acp3x_pm_ops,
sound/soc/amd/renoir/acp3x-pdm-dma.c+2−3
@@ -435,10 +435,9 @@ static int acp_pdm_audio_probe(struct platform_device *pdev) · 434 unmodified lines
435435 return 0;
436436 }
437437
438−static int acp_pdm_audio_remove(struct platform_device *pdev)
438+static void acp_pdm_audio_remove(struct platform_device *pdev)
439439 {
440440 pm_runtime_disable(&pdev->dev);
441− return 0;
442441 }
443442
444443 static int acp_pdm_resume(struct device *dev)
@@ -489,7 +488,7 @@ static const struct dev_pm_ops acp_pdm_pm_ops = { · 44 unmodified lines
489488
490489 static struct platform_driver acp_pdm_dma_driver = {
491490 .probe = acp_pdm_audio_probe,
492− .remove = acp_pdm_audio_remove,
491+ .remove_new = acp_pdm_audio_remove,
493492 .driver = {
494493 .name = "acp_rn_pdm_dma",
495494 .pm = &acp_pdm_pm_ops,
sound/soc/amd/vangogh/acp5x-mach.c+144−153
@@ -6,37 +6,40 @@ · 5 unmodified lines
66 * Copyright 2021 Advanced Micro Devices, Inc.
77 */
88
9−#include <sound/soc.h>
10−#include <sound/soc-dapm.h>
11−#include <linux/module.h>
12−#include <linux/io.h>
13−#include <sound/pcm.h>
14−#include <sound/pcm_params.h>
15−
16−#include <sound/jack.h>
17−#include <linux/clk.h>
18−#include <linux/gpio.h>
19−#include <linux/gpio/consumer.h>
20−#include <linux/i2c.h>
21−#include <linux/input.h>
229 #include <linux/acpi.h>
2310 #include <linux/dmi.h>
11+#include <linux/gpio/consumer.h>
12+#include <linux/i2c.h>
13+#include <linux/input-event-codes.h>
14+#include <linux/module.h>
15+#include <sound/jack.h>
16+#include <sound/pcm_params.h>
17+#include <sound/soc.h>
18+#include <sound/soc-dapm.h>
2419
2520 #include "../../codecs/nau8821.h"
26−#include "../../codecs/cs35l41.h"
27−
2821 #include "acp5x.h"
2922
30−#define DRV_NAME "acp5x_mach"
31−#define DUAL_CHANNEL 2
32−#define ACP5X_NUVOTON_CODEC_DAI "nau8821-hifi"
33−#define VG_JUPITER 1
34−#define ACP5X_NUVOTON_BCLK 3072000
35−#define ACP5X_NAU8821_FREQ_OUT 12288000
23+#define DRV_NAME "acp5x_mach"
24+#define DUAL_CHANNEL 2
25+#define VG_JUPITER 1
26+#define ACP5X_NAU8821_BCLK 3072000
27+#define ACP5X_NAU8821_FREQ_OUT 12288000
28+#define ACP5X_NAU8821_COMP_NAME "i2c-NVTN2020:00"
29+#define ACP5X_NAU8821_DAI_NAME "nau8821-hifi"
30+#define ACP5X_CS35L41_COMP_LNAME "spi-VLV1776:00"
31+#define ACP5X_CS35L41_COMP_RNAME "spi-VLV1776:01"
32+#define ACP5X_CS35L41_DAI_NAME "cs35l41-pcm"
3633
3734 static unsigned long acp5x_machine_id;
3835 static struct snd_soc_jack vg_headset;
3936
37+SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
38+SND_SOC_DAILINK_DEF(acp5x_i2s, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0")));
39+SND_SOC_DAILINK_DEF(acp5x_bt, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1")));
40+SND_SOC_DAILINK_DEF(nau8821, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_NAU8821_COMP_NAME,
41+ ACP5X_NAU8821_DAI_NAME)));
42+
4043 static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = {
4144 {
4245 .pin = "Headphone",
@@ -48,18 +51,54 @@ static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = { · 5 unmodified lines
4851 },
4952 };
5053
54+static const struct snd_kcontrol_new acp5x_8821_controls[] = {
55+ SOC_DAPM_PIN_SWITCH("Headphone"),
56+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
57+ SOC_DAPM_PIN_SWITCH("Int Mic"),
58+};
59+
60+static int platform_clock_control(struct snd_soc_dapm_widget *w,
61+ struct snd_kcontrol *k, int event)
62+{
63+ struct snd_soc_dapm_context *dapm = w->dapm;
64+ struct snd_soc_card *card = dapm->card;
65+ struct snd_soc_dai *dai;
66+ int ret = 0;
67+
68+ dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
69+ if (!dai) {
70+ dev_err(card->dev, "Codec dai not found\n");
71+ return -EIO;
72+ }
73+
74+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
75+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_INTERNAL, 0, SND_SOC_CLOCK_IN);
76+ if (ret < 0) {
77+ dev_err(card->dev, "set sysclk err = %d\n", ret);
78+ return -EIO;
79+ }
80+ } else {
81+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
82+ if (ret < 0)
83+ dev_err(dai->dev, "can't set BLK clock %d\n", ret);
84+ ret = snd_soc_dai_set_pll(dai, 0, 0, ACP5X_NAU8821_BCLK, ACP5X_NAU8821_FREQ_OUT);
85+ if (ret < 0)
86+ dev_err(dai->dev, "can't set FLL: %d\n", ret);
87+ }
88+
89+ return ret;
90+}
91+
5192 static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd)
5293 {
94+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
5395 int ret;
54− struct snd_soc_card *card = rtd->card;
55− struct snd_soc_component *component =
56− asoc_rtd_to_codec(rtd, 0)->component;
5796
5897 /*
5998 * Headset buttons map to the google Reference headset.
6099 * These can be configured by userspace.
61100 */
62− ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
101+ ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
63102 SND_JACK_HEADSET | SND_JACK_BTN_0,
64103 &vg_headset, acp5x_nau8821_jack_pins,
65104 ARRAY_SIZE(acp5x_nau8821_jack_pins));
@@ -70,12 +109,8 @@ static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd) · 4 unmodified lines
70109
71110 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_MEDIA);
72111 nau8821_enable_jack_detect(component, &vg_headset);
73− return ret;
74−}
75112
76−static int acp5x_cs35l41_init(struct snd_soc_pcm_runtime *rtd)
77−{
78− return 0;
113+ return ret;
79114 }
80115
81116 static const unsigned int rates[] = {
@@ -109,8 +144,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) · 27 unmodified lines
109144 {
110145 struct snd_pcm_runtime *runtime = substream->runtime;
111146 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
112− struct snd_soc_card *card = rtd->card;
113− struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);
147+ struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
114148
115149 machine->play_i2s_instance = I2S_SP_INSTANCE;
116150 machine->cap_i2s_instance = I2S_SP_INSTANCE;
@@ -123,6 +157,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) · 6 unmodified lines
123157 snd_pcm_hw_constraint_list(substream->runtime, 0,
124158 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
125159 &constraints_sample_bits);
160+
126161 return 0;
127162 }
128163
@@ -131,29 +166,36 @@ static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines
131166 {
132167 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
133168 struct snd_soc_card *card = rtd->card;
134− struct snd_soc_dai *codec_dai =
135− snd_soc_card_get_codec_dai(card,
136− ACP5X_NUVOTON_CODEC_DAI);
137− int ret;
169+ struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
170+ int ret, bclk;
138171
139− ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
140− SND_SOC_CLOCK_IN);
172+ ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
141173 if (ret < 0)
142174 dev_err(card->dev, "can't set FS clock %d\n", ret);
143− ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),
144− params_rate(params) * 256);
175+
176+ bclk = snd_soc_params_to_bclk(params);
177+ if (bclk < 0) {
178+ dev_err(dai->dev, "Fail to get BCLK rate: %d\n", bclk);
179+ return bclk;
180+ }
181+
182+ ret = snd_soc_dai_set_pll(dai, 0, 0, bclk, params_rate(params) * 256);
145183 if (ret < 0)
146184 dev_err(card->dev, "can't set FLL: %d\n", ret);
147185
148186 return ret;
149187 }
150188
189+static const struct snd_soc_ops acp5x_8821_ops = {
190+ .startup = acp5x_8821_startup,
191+ .hw_params = acp5x_nau8821_hw_params,
192+};
193+
151194 static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)
152195 {
153− struct snd_pcm_runtime *runtime = substream->runtime;
154196 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
155− struct snd_soc_card *card = rtd->card;
156− struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);
197+ struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
198+ struct snd_pcm_runtime *runtime = substream->runtime;
157199
158200 machine->play_i2s_instance = I2S_HS_INSTANCE;
159201
@@ -162,6 +204,7 @@ static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream) · 2 unmodified lines
162204 &constraints_channels);
163205 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
164206 &constraints_rates);
207+
165208 return 0;
166209 }
167210
@@ -169,80 +212,66 @@ static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line
169212 struct snd_pcm_hw_params *params)
170213 {
171214 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
172− struct snd_soc_card *card = rtd->card;
173− struct snd_soc_dai *codec_dai;
215+ unsigned int bclk, rate = params_rate(params);
216+ struct snd_soc_component *comp;
174217 int ret, i;
175− unsigned int num_codecs = rtd->dai_link->num_codecs;
176− unsigned int bclk_val;
177−
178− ret = 0;
179− for (i = 0; i < num_codecs; i++) {
180− codec_dai = asoc_rtd_to_codec(rtd, i);
181− if (strcmp(codec_dai->name, "cs35l41-pcm") == 0) {
182− switch (params_rate(params)) {
183− case 48000:
184− bclk_val = 1536000;
185− break;
186− default:
187− dev_err(card->dev, "Invalid Samplerate:0x%x\n",
188− params_rate(params));
218+
219+ switch (rate) {
220+ case 48000:
221+ bclk = 1536000;
222+ break;
223+ default:
224+ bclk = 0;
225+ break;
226+ }
227+
228+ for_each_rtd_components(rtd, i, comp) {
229+ if (!(strcmp(comp->name, ACP5X_CS35L41_COMP_LNAME)) ||
230+ !(strcmp(comp->name, ACP5X_CS35L41_COMP_RNAME))) {
231+ if (!bclk) {
232+ dev_err(comp->dev, "Invalid sample rate: 0x%x\n", rate);
189233 return -EINVAL;
190234 }
191− ret = snd_soc_component_set_sysclk(codec_dai->component,
192− 0, 0, bclk_val, SND_SOC_CLOCK_IN);
193− if (ret < 0) {
194− dev_err(card->dev, "failed to set sysclk for CS35l41 dai\n");
235+
236+ ret = snd_soc_component_set_sysclk(comp, 0, 0, bclk, SND_SOC_CLOCK_IN);
237+ if (ret) {
238+ dev_err(comp->dev, "failed to set SYSCLK: %d\n", ret);
195239 return ret;
196240 }
197241 }
198242 }
199243
200− return ret;
201−}
244+ return 0;
202245
203−static const struct snd_soc_ops acp5x_8821_ops = {
204− .startup = acp5x_8821_startup,
205− .hw_params = acp5x_nau8821_hw_params,
206−};
246+}
207247
208248 static const struct snd_soc_ops acp5x_cs35l41_play_ops = {
209249 .startup = acp5x_cs35l41_startup,
210250 .hw_params = acp5x_cs35l41_hw_params,
211251 };
212252
213−static struct snd_soc_codec_conf cs35l41_conf[] = {
253+static struct snd_soc_codec_conf acp5x_cs35l41_conf[] = {
214254 {
215− .dlc = COMP_CODEC_CONF("spi-VLV1776:00"),
255+ .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_LNAME),
216256 .name_prefix = "Left",
217257 },
218258 {
219− .dlc = COMP_CODEC_CONF("spi-VLV1776:01"),
259+ .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_RNAME),
220260 .name_prefix = "Right",
221261 },
222262 };
223263
224−SND_SOC_DAILINK_DEF(acp5x_i2s,
225− DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0")));
264+SND_SOC_DAILINK_DEF(cs35l41, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_CS35L41_COMP_LNAME,
265+ ACP5X_CS35L41_DAI_NAME),
266+ COMP_CODEC(ACP5X_CS35L41_COMP_RNAME,
267+ ACP5X_CS35L41_DAI_NAME)));
226268
227−SND_SOC_DAILINK_DEF(acp5x_bt,
228− DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1")));
229−
230−SND_SOC_DAILINK_DEF(nau8821,
231− DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
232− "nau8821-hifi")));
233−
234−SND_SOC_DAILINK_DEF(cs35l41,
235− DAILINK_COMP_ARRAY(COMP_CODEC("spi-VLV1776:00", "cs35l41-pcm"),
236− COMP_CODEC("spi-VLV1776:01", "cs35l41-pcm")));
237−
238−SND_SOC_DAILINK_DEF(platform,
239− DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
240−
241−static struct snd_soc_dai_link acp5x_dai[] = {
269+static struct snd_soc_dai_link acp5x_8821_35l41_dai[] = {
242270 {
243271 .name = "acp5x-8821-play",
244272 .stream_name = "Playback/Capture",
245− .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
273+ .dai_fmt = SND_SOC_DAIFMT_I2S |
274+ SND_SOC_DAIFMT_NB_NF |
246275 SND_SOC_DAIFMT_CBC_CFC,
247276 .dpcm_playback = 1,
248277 .dpcm_capture = 1,
@@ -253,65 +282,28 @@ static struct snd_soc_dai_link acp5x_dai[] = { · 4 unmodified lines
253282 {
254283 .name = "acp5x-CS35L41-Stereo",
255284 .stream_name = "CS35L41 Stereo Playback",
256− .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
285+ .dai_fmt = SND_SOC_DAIFMT_I2S |
286+ SND_SOC_DAIFMT_NB_NF |
257287 SND_SOC_DAIFMT_CBC_CFC,
258288 .dpcm_playback = 1,
259289 .playback_only = 1,
260290 .ops = &acp5x_cs35l41_play_ops,
261− .init = acp5x_cs35l41_init,
262291 SND_SOC_DAILINK_REG(acp5x_bt, cs35l41, platform),
263292 },
264293 };
265294
266−static int platform_clock_control(struct snd_soc_dapm_widget *w,
267− struct snd_kcontrol *k, int event)
268−{
269− struct snd_soc_dapm_context *dapm = w->dapm;
270− struct snd_soc_card *card = dapm->card;
271− struct snd_soc_dai *codec_dai;
272− int ret = 0;
273295
274− codec_dai = snd_soc_card_get_codec_dai(card, ACP5X_NUVOTON_CODEC_DAI);
275− if (!codec_dai) {
276− dev_err(card->dev, "Codec dai not found\n");
277− return -EIO;
278− }
279296
280− if (SND_SOC_DAPM_EVENT_OFF(event)) {
281− ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,
282− 0, SND_SOC_CLOCK_IN);
283− if (ret < 0) {
284− dev_err(card->dev, "set sysclk err = %d\n", ret);
285− return -EIO;
286− }
287− } else {
288− ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
289− SND_SOC_CLOCK_IN);
290− if (ret < 0)
291− dev_err(codec_dai->dev, "can't set BLK clock %d\n", ret);
292− ret = snd_soc_dai_set_pll(codec_dai, 0, 0, ACP5X_NUVOTON_BCLK,
293− ACP5X_NAU8821_FREQ_OUT);
294− if (ret < 0)
295− dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
296− }
297− return ret;
298−}
299−
300−static const struct snd_kcontrol_new acp5x_8821_controls[] = {
301− SOC_DAPM_PIN_SWITCH("Headphone"),
302− SOC_DAPM_PIN_SWITCH("Headset Mic"),
303− SOC_DAPM_PIN_SWITCH("Int Mic"),
304−};
305−
306−static const struct snd_soc_dapm_widget acp5x_8821_widgets[] = {
297+static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = {
307298 SND_SOC_DAPM_HP("Headphone", NULL),
308299 SND_SOC_DAPM_MIC("Headset Mic", NULL),
309300 SND_SOC_DAPM_MIC("Int Mic", NULL),
310301 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
311− platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
302+ platform_clock_control,
303+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
312304 };
313305
314−static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = {
306+static const struct snd_soc_dapm_route acp5x_8821_35l41_audio_route[] = {
315307 /* HP jack connectors - unknown if we have jack detection */
316308 { "Headphone", NULL, "HPOL" },
317309 { "Headphone", NULL, "HPOR" },
@@ -324,17 +316,17 @@ static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = { · 6 unmodified lines
324316 { "Int Mic", NULL, "Platform Clock" },
325317 };
326318
327−static struct snd_soc_card acp5x_card = {
319+static struct snd_soc_card acp5x_8821_35l41_card = {
328320 .name = "acp5x",
329321 .owner = THIS_MODULE,
330− .dai_link = acp5x_dai,
331− .num_links = ARRAY_SIZE(acp5x_dai),
332− .dapm_widgets = acp5x_8821_widgets,
333− .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_widgets),
334− .dapm_routes = acp5x_8821_audio_route,
335− .num_dapm_routes = ARRAY_SIZE(acp5x_8821_audio_route),
336− .codec_conf = cs35l41_conf,
337− .num_configs = ARRAY_SIZE(cs35l41_conf),
322+ .dai_link = acp5x_8821_35l41_dai,
323+ .num_links = ARRAY_SIZE(acp5x_8821_35l41_dai),
324+ .dapm_widgets = acp5x_8821_35l41_widgets,
325+ .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_35l41_widgets),
326+ .dapm_routes = acp5x_8821_35l41_audio_route,
327+ .num_dapm_routes = ARRAY_SIZE(acp5x_8821_35l41_audio_route),
328+ .codec_conf = acp5x_cs35l41_conf,
329+ .num_configs = ARRAY_SIZE(acp5x_cs35l41_conf),
338330 .controls = acp5x_8821_controls,
339331 .num_controls = ARRAY_SIZE(acp5x_8821_controls),
340332 };
@@ -342,6 +334,7 @@ static struct snd_soc_card acp5x_card = { · 1 unmodified line
342334 static int acp5x_vg_quirk_cb(const struct dmi_system_id *id)
343335 {
344336 acp5x_machine_id = VG_JUPITER;
337+
345338 return 1;
346339 }
347340
@@ -358,33 +351,31 @@ static const struct dmi_system_id acp5x_vg_quirk_table[] = { · 10 unmodified lines
358351
359352 static int acp5x_probe(struct platform_device *pdev)
360353 {
361− int ret;
362354 struct acp5x_platform_info *machine;
355+ struct device *dev = &pdev->dev;
363356 struct snd_soc_card *card;
357+ int ret;
364358
365− machine = devm_kzalloc(&pdev->dev, sizeof(struct acp5x_platform_info),
366− GFP_KERNEL);
359+ machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);
367360 if (!machine)
368361 return -ENOMEM;
369362
370363 dmi_check_system(acp5x_vg_quirk_table);
371364 switch (acp5x_machine_id) {
372365 case VG_JUPITER:
373− card = &acp5x_card;
374− acp5x_card.dev = &pdev->dev;
366+ card = &acp5x_8821_35l41_card;
375367 break;
376368 default:
377369 return -ENODEV;
378370 }
371+ card->dev = dev;
379372 platform_set_drvdata(pdev, card);
380373 snd_soc_card_set_drvdata(card, machine);
381374
382− ret = devm_snd_soc_register_card(&pdev->dev, card);
383− if (ret) {
384− return dev_err_probe(&pdev->dev, ret,
385− "snd_soc_register_card(%s) failed\n",
386− acp5x_card.name);
387− }
375+ ret = devm_snd_soc_register_card(dev, card);
376+ if (ret)
377+ return dev_err_probe(dev, ret, "Register card (%s) failed\n", card->name);
378+
388379 return 0;
389380 }
390381
sound/soc/amd/vangogh/acp5x-pcm-dma.c+2−3
@@ -415,10 +415,9 @@ static int acp5x_audio_probe(struct platform_device *pdev) · 414 unmodified lines
415415 return 0;
416416 }
417417
418−static int acp5x_audio_remove(struct platform_device *pdev)
418+static void acp5x_audio_remove(struct platform_device *pdev)
419419 {
420420 pm_runtime_disable(&pdev->dev);
421− return 0;
422421 }
423422
424423 static int __maybe_unused acp5x_pcm_resume(struct device *dev)
@@ -500,7 +499,7 @@ static const struct dev_pm_ops acp5x_pm_ops = { · 75 unmodified lines
500499
501500 static struct platform_driver acp5x_dma_driver = {
502501 .probe = acp5x_audio_probe,
503− .remove = acp5x_audio_remove,
502+ .remove_new = acp5x_audio_remove,
504503 .driver = {
505504 .name = "acp5x_i2s_dma",
506505 .pm = &acp5x_pm_ops,
sound/soc/amd/yc/acp6x-mach.c+21−0
@@ -45,6 +45,13 @@ static struct snd_soc_card acp6x_card = { · 44 unmodified lines
4545 };
4646
4747 static const struct dmi_system_id yc_acp_quirk_table[] = {
48+ {
49+ .driver_data = &acp6x_card,
50+ .matches = {
51+ DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
52+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"),
53+ }
54+ },
4855 {
4956 .driver_data = &acp6x_card,
5057 .matches = {
@@ -178,6 +185,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 127 unmodified lines
178185 DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
179186 }
180187 },
188+ {
189+ .driver_data = &acp6x_card,
190+ .matches = {
191+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
192+ DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
193+ }
194+ },
181195 {
182196 .driver_data = &acp6x_card,
183197 .matches = {
@@ -262,6 +276,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 78 unmodified lines
262276 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
263277 }
264278 },
279+ {
280+ .driver_data = &acp6x_card,
281+ .matches = {
282+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
283+ DMI_MATCH(DMI_BOARD_NAME, "8A42"),
284+ }
285+ },
265286 {
266287 .driver_data = &acp6x_card,
267288 .matches = {
sound/soc/amd/yc/acp6x-pdm-dma.c+2−3
@@ -388,10 +388,9 @@ static int acp6x_pdm_audio_probe(struct platform_device *pdev) · 387 unmodified lines
388388 return 0;
389389 }
390390
391−static int acp6x_pdm_audio_remove(struct platform_device *pdev)
391+static void acp6x_pdm_audio_remove(struct platform_device *pdev)
392392 {
393393 pm_runtime_disable(&pdev->dev);
394− return 0;
395394 }
396395
397396 static int __maybe_unused acp6x_pdm_resume(struct device *dev)
@@ -440,7 +439,7 @@ static const struct dev_pm_ops acp6x_pdm_pm_ops = { · 42 unmodified lines
440439
441440 static struct platform_driver acp6x_pdm_dma_driver = {
442441 .probe = acp6x_pdm_audio_probe,
443− .remove = acp6x_pdm_audio_remove,
442+ .remove_new = acp6x_pdm_audio_remove,
444443 .driver = {
445444 .name = "acp_yc_pdm_dma",
446445 .pm = &acp6x_pdm_pm_ops,
sound/soc/amd/yc/acp6x.h+3−0
@@ -105,3 +105,6 @@ static inline void acp6x_writel(u32 val, void __iomem *base_addr) · 104 unmodified lines
105105 {
106106 writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
107107 }
108+
109+int snd_amd_acp_find_config(struct pci_dev *pci);
110+
sound/soc/amd/yc/pci-acp6x.c+7−1
@@ -149,10 +149,16 @@ static int snd_acp6x_probe(struct pci_dev *pci, · 148 unmodified lines
149149 int index = 0;
150150 int val = 0x00;
151151 u32 addr;
152− unsigned int irqflags;
152+ unsigned int irqflags, flag;
153153 int ret;
154154
155155 irqflags = IRQF_SHARED;
156+
157+ /* Return if acp config flag is defined */
158+ flag = snd_amd_acp_find_config(pci);
159+ if (flag)
160+ return -ENODEV;
161+
156162 /* Yellow Carp device check */
157163 switch (pci->revision) {
158164 case 0x60:
sound/soc/apple/mca.c+2−3
@@ -1159,13 +1159,12 @@ err_release: · 1158 unmodified lines
11591159 return ret;
11601160 }
11611161
1162−static int apple_mca_remove(struct platform_device *pdev)
1162+static void apple_mca_remove(struct platform_device *pdev)
11631163 {
11641164 struct mca_data *mca = platform_get_drvdata(pdev);
11651165
11661166 snd_soc_unregister_component(&pdev->dev);
11671167 apple_mca_release(mca);
1168− return 0;
11691168 }
11701169
11711170 static const struct of_device_id apple_mca_of_match[] = {
@@ -1180,7 +1179,7 @@ static struct platform_driver apple_mca_driver = { · 8 unmodified lines
11801179 .of_match_table = apple_mca_of_match,
11811180 },
11821181 .probe = apple_mca_probe,
1183− .remove = apple_mca_remove,
1182+ .remove_new = apple_mca_remove,
11841183 };
11851184 module_platform_driver(apple_mca_driver);
11861185
sound/soc/atmel/atmel-classd.c+1−4
@@ -473,24 +473,21 @@ static int atmel_classd_asoc_card_init(struct device *dev, · 472 unmodified lines
473473 if (!dai_link)
474474 return -ENOMEM;
475475
476− comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
476+ comp = devm_kzalloc(dev, 2 * sizeof(*comp), GFP_KERNEL);
477477 if (!comp)
478478 return -ENOMEM;
479479
480480 dai_link->cpus = &comp[0];
481481 dai_link->codecs = &comp[1];
482− dai_link->platforms = &comp[2];
483482
484483 dai_link->num_cpus = 1;
485484 dai_link->num_codecs = 1;
486− dai_link->num_platforms = 1;
487485
488486 dai_link->name = "CLASSD";
489487 dai_link->stream_name = "CLASSD PCM";
490488 dai_link->codecs->dai_name = "snd-soc-dummy-dai";
491489 dai_link->cpus->dai_name = dev_name(dev);
492490 dai_link->codecs->name = "snd-soc-dummy";
493− dai_link->platforms->name = dev_name(dev);
494491
495492 card->dai_link = dai_link;
496493 card->num_links = 1;
sound/soc/atmel/atmel-i2s.c+2−4
@@ -717,13 +717,11 @@ static int atmel_i2s_probe(struct platform_device *pdev) · 716 unmodified lines
717717 return 0;
718718 }
719719
720−static int atmel_i2s_remove(struct platform_device *pdev)
720+static void atmel_i2s_remove(struct platform_device *pdev)
721721 {
722722 struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
723723
724724 clk_disable_unprepare(dev->pclk);
725−
726− return 0;
727725 }
728726
729727 static struct platform_driver atmel_i2s_driver = {
@@ -732,7 +730,7 @@ static struct platform_driver atmel_i2s_driver = { · 2 unmodified lines
732730 .of_match_table = of_match_ptr(atmel_i2s_dt_ids),
733731 },
734732 .probe = atmel_i2s_probe,
735− .remove = atmel_i2s_remove,
733+ .remove_new = atmel_i2s_remove,
736734 };
737735 module_platform_driver(atmel_i2s_driver);
738736
sound/soc/atmel/atmel-pdmic.c+1−4
@@ -496,24 +496,21 @@ static int atmel_pdmic_asoc_card_init(struct device *dev, · 495 unmodified lines
496496 if (!dai_link)
497497 return -ENOMEM;
498498
499− comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
499+ comp = devm_kzalloc(dev, 2 * sizeof(*comp), GFP_KERNEL);
500500 if (!comp)
501501 return -ENOMEM;
502502
503503 dai_link->cpus = &comp[0];
504504 dai_link->codecs = &comp[1];
505− dai_link->platforms = &comp[2];
506505
507506 dai_link->num_cpus = 1;
508507 dai_link->num_codecs = 1;
509− dai_link->num_platforms = 1;
510508
511509 dai_link->name = "PDMIC";
512510 dai_link->stream_name = "PDMIC PCM";
513511 dai_link->codecs->dai_name = "snd-soc-dummy-dai";
514512 dai_link->cpus->dai_name = dev_name(dev);
515513 dai_link->codecs->name = "snd-soc-dummy";
516− dai_link->platforms->name = dev_name(dev);
517514
518515 card->dai_link = dai_link;
519516 card->num_links = 1;
sound/soc/atmel/atmel_wm8904.c+2−4
@@ -161,7 +161,7 @@ err_set_audio: · 160 unmodified lines
161161 return ret;
162162 }
163163
164−static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
164+static void atmel_asoc_wm8904_remove(struct platform_device *pdev)
165165 {
166166 struct snd_soc_card *card = platform_get_drvdata(pdev);
167167 struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
@@ -171,8 +171,6 @@ static int atmel_asoc_wm8904_remove(struct platform_device *pdev) · 3 unmodified lines
171171
172172 snd_soc_unregister_card(card);
173173 atmel_ssc_put_audio(id);
174−
175− return 0;
176174 }
177175
178176 #ifdef CONFIG_OF
@@ -190,7 +188,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = { · 11 unmodified lines
190188 .pm = &snd_soc_pm_ops,
191189 },
192190 .probe = atmel_asoc_wm8904_probe,
193− .remove = atmel_asoc_wm8904_remove,
191+ .remove_new = atmel_asoc_wm8904_remove,
194192 };
195193
196194 module_platform_driver(atmel_asoc_wm8904_driver);
sound/soc/atmel/mchp-i2s-mcc.c+2−4
@@ -1088,13 +1088,11 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev) · 1087 unmodified lines
10881088 return 0;
10891089 }
10901090
1091−static int mchp_i2s_mcc_remove(struct platform_device *pdev)
1091+static void mchp_i2s_mcc_remove(struct platform_device *pdev)
10921092 {
10931093 struct mchp_i2s_mcc_dev *dev = platform_get_drvdata(pdev);
10941094
10951095 clk_disable_unprepare(dev->pclk);
1096−
1097− return 0;
10981096 }
10991097
11001098 static struct platform_driver mchp_i2s_mcc_driver = {
@@ -1103,7 +1101,7 @@ static struct platform_driver mchp_i2s_mcc_driver = { · 2 unmodified lines
11031101 .of_match_table = of_match_ptr(mchp_i2s_mcc_dt_ids),
11041102 },
11051103 .probe = mchp_i2s_mcc_probe,
1106− .remove = mchp_i2s_mcc_remove,
1104+ .remove_new = mchp_i2s_mcc_remove,
11071105 };
11081106 module_platform_driver(mchp_i2s_mcc_driver);
11091107
sound/soc/atmel/mchp-pdmc.c+9−16
@@ -8,6 +8,7 @@ · 7 unmodified lines
88
99 #include <dt-bindings/sound/microchip,pdmc.h>
1010
11+#include <linux/bitfield.h>
1112 #include <linux/clk.h>
1213 #include <linux/module.h>
1314 #include <linux/of.h>
@@ -49,8 +50,6 @@ · 35 unmodified lines
4950 #define MCHP_PDMC_MR_OSR256 (3 << 16)
5051
5152 #define MCHP_PDMC_MR_SINCORDER_MASK GENMASK(23, 20)
52−#define MCHP_PDMC_MR_SINCORDER(order) (((order) << 20) & \
53− MCHP_PDMC_MR_SINCORDER_MASK)
5453
5554 #define MCHP_PDMC_MR_SINC_OSR_MASK GENMASK(27, 24)
5655 #define MCHP_PDMC_MR_SINC_OSR_DIS (0 << 24)
@@ -62,8 +61,6 @@ · 5 unmodified lines
6261 #define MCHP_PDMC_MR_SINC_OSR_256 (6 << 24)
6362
6463 #define MCHP_PDMC_MR_CHUNK_MASK GENMASK(31, 28)
65−#define MCHP_PDMC_MR_CHUNK(chunk) (((chunk) << 28) & \
66− MCHP_PDMC_MR_CHUNK_MASK)
6764
6865 /*
6966 * ---- Configuration Register (Read/Write) ----
@@ -617,10 +614,10 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream, · 547 unmodified lines
617614
618615 mr_val |= mchp_pdmc_mr_set_osr(dd->audio_filter_en, osr);
619616
620− mr_val |= MCHP_PDMC_MR_SINCORDER(dd->sinc_order);
617+ mr_val |= FIELD_PREP(MCHP_PDMC_MR_SINCORDER_MASK, dd->sinc_order);
621618
622619 dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream));
623− mr_val |= MCHP_PDMC_MR_CHUNK(dd->addr.maxburst);
620+ mr_val |= FIELD_PREP(MCHP_PDMC_MR_CHUNK_MASK, dd->addr.maxburst);
624621 dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);
625622
626623 snd_soc_component_update_bits(comp, MCHP_PDMC_MR,
@@ -762,12 +759,10 @@ static int mchp_pdmc_pcm_new(struct snd_soc_pcm_runtime *rtd, · 135 unmodified lines
762759 int ret;
763760
764761 ret = mchp_pdmc_add_chmap_ctls(rtd->pcm, dd);
765− if (ret < 0) {
762+ if (ret < 0)
766763 dev_err(dd->dev, "failed to add channel map controls: %d\n", ret);
767− return ret;
768− }
769764
770− return 0;
765+ return ret;
771766 }
772767
773768 static struct snd_soc_dai_driver mchp_pdmc_dai = {
@@ -788,7 +783,7 @@ static struct snd_soc_dai_driver mchp_pdmc_dai = { · 14 unmodified lines
788783 /* PDMC interrupt handler */
789784 static irqreturn_t mchp_pdmc_interrupt(int irq, void *dev_id)
790785 {
791− struct mchp_pdmc *dd = (struct mchp_pdmc *)dev_id;
786+ struct mchp_pdmc *dd = dev_id;
792787 u32 isr, msr, pending;
793788 irqreturn_t ret = IRQ_NONE;
794789
@@ -1082,7 +1077,7 @@ static int mchp_pdmc_probe(struct platform_device *pdev) · 287 unmodified lines
10821077 }
10831078
10841079 ret = devm_request_irq(dev, irq, mchp_pdmc_interrupt, 0,
1085− dev_name(&pdev->dev), (void *)dd);
1080+ dev_name(&pdev->dev), dd);
10861081 if (ret < 0) {
10871082 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
10881083 irq, ret);
@@ -1134,7 +1129,7 @@ pm_runtime_suspend: · 45 unmodified lines
11341129 return ret;
11351130 }
11361131
1137−static int mchp_pdmc_remove(struct platform_device *pdev)
1132+static void mchp_pdmc_remove(struct platform_device *pdev)
11381133 {
11391134 struct mchp_pdmc *dd = platform_get_drvdata(pdev);
11401135
@@ -1142,8 +1137,6 @@ static int mchp_pdmc_remove(struct platform_device *pdev) · 1 unmodified line
11421137 mchp_pdmc_runtime_suspend(dd->dev);
11431138
11441139 pm_runtime_disable(dd->dev);
1145−
1146− return 0;
11471140 }
11481141
11491142 static const struct of_device_id mchp_pdmc_of_match[] = {
@@ -1168,7 +1161,7 @@ static struct platform_driver mchp_pdmc_driver = { · 18 unmodified lines
11681161 .pm = pm_ptr(&mchp_pdmc_pm_ops),
11691162 },
11701163 .probe = mchp_pdmc_probe,
1171− .remove = mchp_pdmc_remove,
1164+ .remove_new = mchp_pdmc_remove,
11721165 };
11731166 module_platform_driver(mchp_pdmc_driver);
11741167
sound/soc/atmel/mchp-spdifrx.c+2−4
@@ -1183,20 +1183,18 @@ pm_runtime_disable: · 1182 unmodified lines
11831183 return err;
11841184 }
11851185
1186−static int mchp_spdifrx_remove(struct platform_device *pdev)
1186+static void mchp_spdifrx_remove(struct platform_device *pdev)
11871187 {
11881188 struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev);
11891189
11901190 pm_runtime_disable(dev->dev);
11911191 if (!pm_runtime_status_suspended(dev->dev))
11921192 mchp_spdifrx_runtime_suspend(dev->dev);
1193−
1194− return 0;
11951193 }
11961194
11971195 static struct platform_driver mchp_spdifrx_driver = {
11981196 .probe = mchp_spdifrx_probe,
1199− .remove = mchp_spdifrx_remove,
1197+ .remove_new = mchp_spdifrx_remove,
12001198 .driver = {
12011199 .name = "mchp_spdifrx",
12021200 .of_match_table = of_match_ptr(mchp_spdifrx_dt_ids),
sound/soc/atmel/mchp-spdiftx.c+17−34
@@ -72,11 +72,9 @@ · 71 unmodified lines
7272
7373 /* Valid Bits per Sample */
7474 #define SPDIFTX_MR_VBPS_MASK GENMASK(13, 8)
75−#define SPDIFTX_MR_VBPS(bps) FIELD_PREP(SPDIFTX_MR_VBPS_MASK, bps)
7675
7776 /* Chunk Size */
7877 #define SPDIFTX_MR_CHUNK_MASK GENMASK(19, 16)
79−#define SPDIFTX_MR_CHUNK(size) FIELD_PREP(SPDIFTX_MR_CHUNK_MASK, size)
8078
8179 /* Validity Bits for Channels 1 and 2 */
8280 #define SPDIFTX_MR_VALID1 BIT(24)
@@ -89,7 +87,6 @@ · 6 unmodified lines
8987
9088 /* Bytes per Sample */
9189 #define SPDIFTX_MR_BPS_MASK GENMASK(29, 28)
92−#define SPDIFTX_MR_BPS(bytes) FIELD_PREP(SPDIFTX_MR_BPS_MASK, (bytes - 1))
9390
9491 /*
9592 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
@@ -309,15 +306,10 @@ static int mchp_spdiftx_trigger(struct snd_pcm_substream *substream, int cmd, · 213 unmodified lines
309306 {
310307 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
311308 struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
312− u32 mr;
313− int running;
314309 int ret;
315310
316311 /* do not start/stop while channel status or user data is updated */
317312 spin_lock(&ctrl->lock);
318− regmap_read(dev->regmap, SPDIFTX_MR, &mr);
319− running = !!(mr & SPDIFTX_MR_TXEN_ENABLE);
320−
321313 switch (cmd) {
322314 case SNDRV_PCM_TRIGGER_RESUME:
323315 case SNDRV_PCM_TRIGGER_START:
@@ -326,10 +318,8 @@ static int mchp_spdiftx_trigger(struct snd_pcm_substream *substream, int cmd, · 2 unmodified lines
326318 dev->suspend_irq = 0;
327319 fallthrough;
328320 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
329− if (!running) {
330− mr &= ~SPDIFTX_MR_TXEN_MASK;
331− mr |= SPDIFTX_MR_TXEN_ENABLE;
332− }
321+ ret = regmap_update_bits(dev->regmap, SPDIFTX_MR, SPDIFTX_MR_TXEN_MASK,
322+ SPDIFTX_MR_TXEN_ENABLE);
333323 break;
334324 case SNDRV_PCM_TRIGGER_SUSPEND:
335325 regmap_read(dev->regmap, SPDIFTX_IMR, &dev->suspend_irq);
@@ -339,20 +329,15 @@ static int mchp_spdiftx_trigger(struct snd_pcm_substream *substream, int cmd, · 3 unmodified lines
339329 SPDIFTX_IR_TXUDR | SPDIFTX_IR_TXOVR);
340330 fallthrough;
341331 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
342− if (running) {
343− mr &= ~SPDIFTX_MR_TXEN_MASK;
344− mr |= SPDIFTX_MR_TXEN_DISABLE;
345− }
332+ ret = regmap_update_bits(dev->regmap, SPDIFTX_MR, SPDIFTX_MR_TXEN_MASK,
333+ SPDIFTX_MR_TXEN_DISABLE);
346334 break;
347335 default:
348− spin_unlock(&ctrl->lock);
349− return -EINVAL;
336+ ret = -EINVAL;
350337 }
351−
352− ret = regmap_write(dev->regmap, SPDIFTX_MR, mr);
353338 spin_unlock(&ctrl->lock);
354339 if (ret)
355− dev_err(dev->dev, "unable to disable TX: %d\n", ret);
340+ dev_err(dev->dev, "unable to start/stop TX: %d\n", ret);
356341
357342 return ret;
358343 }
@@ -402,47 +387,47 @@ static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream, · 43 unmodified lines
402387 params_channels(params));
403388 return -EINVAL;
404389 }
405− mr |= SPDIFTX_MR_CHUNK(dev->playback.maxburst);
390+ mr |= FIELD_PREP(SPDIFTX_MR_CHUNK_MASK, dev->playback.maxburst);
406391
407392 switch (params_format(params)) {
408393 case SNDRV_PCM_FORMAT_S8:
409− mr |= SPDIFTX_MR_VBPS(8);
394+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 8);
410395 break;
411396 case SNDRV_PCM_FORMAT_S16_BE:
412397 mr |= SPDIFTX_MR_ENDIAN_BIG;
413398 fallthrough;
414399 case SNDRV_PCM_FORMAT_S16_LE:
415− mr |= SPDIFTX_MR_VBPS(16);
400+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 16);
416401 break;
417402 case SNDRV_PCM_FORMAT_S18_3BE:
418403 mr |= SPDIFTX_MR_ENDIAN_BIG;
419404 fallthrough;
420405 case SNDRV_PCM_FORMAT_S18_3LE:
421− mr |= SPDIFTX_MR_VBPS(18);
406+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 18);
422407 break;
423408 case SNDRV_PCM_FORMAT_S20_3BE:
424409 mr |= SPDIFTX_MR_ENDIAN_BIG;
425410 fallthrough;
426411 case SNDRV_PCM_FORMAT_S20_3LE:
427− mr |= SPDIFTX_MR_VBPS(20);
412+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 20);
428413 break;
429414 case SNDRV_PCM_FORMAT_S24_3BE:
430415 mr |= SPDIFTX_MR_ENDIAN_BIG;
431416 fallthrough;
432417 case SNDRV_PCM_FORMAT_S24_3LE:
433− mr |= SPDIFTX_MR_VBPS(24);
418+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 24);
434419 break;
435420 case SNDRV_PCM_FORMAT_S24_BE:
436421 mr |= SPDIFTX_MR_ENDIAN_BIG;
437422 fallthrough;
438423 case SNDRV_PCM_FORMAT_S24_LE:
439− mr |= SPDIFTX_MR_VBPS(24);
424+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 24);
440425 break;
441426 case SNDRV_PCM_FORMAT_S32_BE:
442427 mr |= SPDIFTX_MR_ENDIAN_BIG;
443428 fallthrough;
444429 case SNDRV_PCM_FORMAT_S32_LE:
445− mr |= SPDIFTX_MR_VBPS(32);
430+ mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 32);
446431 break;
447432 default:
448433 dev_err(dev->dev, "unsupported PCM format: %d\n",
@@ -450,7 +435,7 @@ static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line
450435 return -EINVAL;
451436 }
452437
453− mr |= SPDIFTX_MR_BPS(bps);
438+ mr |= FIELD_PREP(SPDIFTX_MR_BPS_MASK, bps - 1);
454439
455440 switch (params_rate(params)) {
456441 case 22050:
@@ -891,7 +876,7 @@ pm_runtime_suspend: · 434 unmodified lines
891876 return err;
892877 }
893878
894−static int mchp_spdiftx_remove(struct platform_device *pdev)
879+static void mchp_spdiftx_remove(struct platform_device *pdev)
895880 {
896881 struct mchp_spdiftx_dev *dev = platform_get_drvdata(pdev);
897882
@@ -899,13 +884,11 @@ static int mchp_spdiftx_remove(struct platform_device *pdev) · 1 unmodified line
899884 mchp_spdiftx_runtime_suspend(dev->dev);
900885
901886 pm_runtime_disable(dev->dev);
902−
903− return 0;
904887 }
905888
906889 static struct platform_driver mchp_spdiftx_driver = {
907890 .probe = mchp_spdiftx_probe,
908− .remove = mchp_spdiftx_remove,
891+ .remove_new = mchp_spdiftx_remove,
909892 .driver = {
910893 .name = "mchp_spdiftx",
911894 .of_match_table = of_match_ptr(mchp_spdiftx_dt_ids),
sound/soc/atmel/mikroe-proto.c+2−4
@@ -155,11 +155,9 @@ put_codec_node: · 154 unmodified lines
155155 return ret;
156156 }
157157
158−static int snd_proto_remove(struct platform_device *pdev)
158+static void snd_proto_remove(struct platform_device *pdev)
159159 {
160160 snd_soc_unregister_card(&snd_proto);
161−
162− return 0;
163161 }
164162
165163 static const struct of_device_id snd_proto_of_match[] = {
@@ -174,7 +172,7 @@ static struct platform_driver snd_proto_driver = { · 8 unmodified lines
174172 .of_match_table = snd_proto_of_match,
175173 },
176174 .probe = snd_proto_probe,
177− .remove = snd_proto_remove,
175+ .remove_new = snd_proto_remove,
178176 };
179177
180178 module_platform_driver(snd_proto_driver);
sound/soc/atmel/sam9g20_wm8731.c+2−4
@@ -186,14 +186,12 @@ err: · 185 unmodified lines
186186 return ret;
187187 }
188188
189−static int at91sam9g20ek_audio_remove(struct platform_device *pdev)
189+static void at91sam9g20ek_audio_remove(struct platform_device *pdev)
190190 {
191191 struct snd_soc_card *card = platform_get_drvdata(pdev);
192192
193193 snd_soc_unregister_card(card);
194194 atmel_ssc_put_audio(0);
195−
196− return 0;
197195 }
198196
199197 #ifdef CONFIG_OF
@@ -210,7 +208,7 @@ static struct platform_driver at91sam9g20ek_audio_driver = { · 10 unmodified lines
210208 .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
211209 },
212210 .probe = at91sam9g20ek_audio_probe,
213− .remove = at91sam9g20ek_audio_remove,
211+ .remove_new = at91sam9g20ek_audio_remove,
214212 };
215213
216214 module_platform_driver(at91sam9g20ek_audio_driver);
sound/soc/atmel/sam9x5_wm8731.c+2−4
@@ -176,14 +176,12 @@ out: · 175 unmodified lines
176176 return ret;
177177 }
178178
179−static int sam9x5_wm8731_driver_remove(struct platform_device *pdev)
179+static void sam9x5_wm8731_driver_remove(struct platform_device *pdev)
180180 {
181181 struct snd_soc_card *card = platform_get_drvdata(pdev);
182182 struct sam9x5_drvdata *priv = card->drvdata;
183183
184184 atmel_ssc_put_audio(priv->ssc_id);
185−
186− return 0;
187185 }
188186
189187 static const struct of_device_id sam9x5_wm8731_of_match[] = {
@@ -198,7 +196,7 @@ static struct platform_driver sam9x5_wm8731_driver = { · 8 unmodified lines
198196 .of_match_table = of_match_ptr(sam9x5_wm8731_of_match),
199197 },
200198 .probe = sam9x5_wm8731_driver_probe,
201− .remove = sam9x5_wm8731_driver_remove,
199+ .remove_new = sam9x5_wm8731_driver_remove,
202200 };
203201 module_platform_driver(sam9x5_wm8731_driver);
204202
sound/soc/atmel/tse850-pcm5142.c+2−4
@@ -412,15 +412,13 @@ err_disable_ana: · 411 unmodified lines
412412 return ret;
413413 }
414414
415−static int tse850_remove(struct platform_device *pdev)
415+static void tse850_remove(struct platform_device *pdev)
416416 {
417417 struct snd_soc_card *card = platform_get_drvdata(pdev);
418418 struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
419419
420420 snd_soc_unregister_card(card);
421421 regulator_disable(tse850->ana);
422−
423− return 0;
424422 }
425423
426424 static const struct of_device_id tse850_dt_ids[] = {
@@ -435,7 +433,7 @@ static struct platform_driver tse850_driver = { · 8 unmodified lines
435433 .of_match_table = of_match_ptr(tse850_dt_ids),
436434 },
437435 .probe = tse850_probe,
438− .remove = tse850_remove,
436+ .remove_new = tse850_remove,
439437 };
440438
441439 module_platform_driver(tse850_driver);
sound/soc/au1x/ac97c.c+2−4
@@ -285,7 +285,7 @@ static int au1xac97c_drvprobe(struct platform_device *pdev) · 284 unmodified lines
285285 return 0;
286286 }
287287
288−static int au1xac97c_drvremove(struct platform_device *pdev)
288+static void au1xac97c_drvremove(struct platform_device *pdev)
289289 {
290290 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
291291
@@ -294,8 +294,6 @@ static int au1xac97c_drvremove(struct platform_device *pdev) · 2 unmodified lines
294294 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
295295
296296 ac97c_workdata = NULL; /* MDEV */
297−
298− return 0;
299297 }
300298
301299 #ifdef CONFIG_PM
@@ -338,7 +336,7 @@ static struct platform_driver au1xac97c_driver = { · 36 unmodified lines
338336 .pm = AU1XPSCAC97_PMOPS,
339337 },
340338 .probe = au1xac97c_drvprobe,
341− .remove = au1xac97c_drvremove,
339+ .remove_new = au1xac97c_drvremove,
342340 };
343341
344342 module_platform_driver(au1xac97c_driver);
sound/soc/au1x/i2sc.c+2−4
@@ -270,15 +270,13 @@ static int au1xi2s_drvprobe(struct platform_device *pdev) · 269 unmodified lines
270270 &au1xi2s_dai_driver, 1);
271271 }
272272
273−static int au1xi2s_drvremove(struct platform_device *pdev)
273+static void au1xi2s_drvremove(struct platform_device *pdev)
274274 {
275275 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
276276
277277 snd_soc_unregister_component(&pdev->dev);
278278
279279 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
280−
281− return 0;
282280 }
283281
284282 #ifdef CONFIG_PM
@@ -315,7 +313,7 @@ static struct platform_driver au1xi2s_driver = { · 30 unmodified lines
315313 .pm = AU1XI2SC_PMOPS,
316314 },
317315 .probe = au1xi2s_drvprobe,
318− .remove = au1xi2s_drvremove,
316+ .remove_new = au1xi2s_drvremove,
319317 };
320318
321319 module_platform_driver(au1xi2s_driver);
sound/soc/au1x/psc-ac97.c+2−4
@@ -421,7 +421,7 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) · 420 unmodified lines
421421 return 0;
422422 }
423423
424−static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
424+static void au1xpsc_ac97_drvremove(struct platform_device *pdev)
425425 {
426426 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
427427
@@ -434,8 +434,6 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) · 6 unmodified lines
434434 wmb(); /* drain writebuffer */
435435
436436 au1xpsc_ac97_workdata = NULL; /* MDEV */
437−
438− return 0;
439437 }
440438
441439 #ifdef CONFIG_PM
@@ -488,7 +486,7 @@ static struct platform_driver au1xpsc_ac97_driver = { · 46 unmodified lines
488486 .pm = AU1XPSCAC97_PMOPS,
489487 },
490488 .probe = au1xpsc_ac97_drvprobe,
491− .remove = au1xpsc_ac97_drvremove,
489+ .remove_new = au1xpsc_ac97_drvremove,
492490 };
493491
494492 module_platform_driver(au1xpsc_ac97_driver);
sound/soc/au1x/psc-i2s.c+2−4
@@ -344,7 +344,7 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) · 343 unmodified lines
344344 &au1xpsc_i2s_component, &wd->dai_drv, 1);
345345 }
346346
347−static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
347+static void au1xpsc_i2s_drvremove(struct platform_device *pdev)
348348 {
349349 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
350350
@@ -352,8 +352,6 @@ static int au1xpsc_i2s_drvremove(struct platform_device *pdev) · 1 unmodified line
352352 wmb(); /* drain writebuffer */
353353 __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
354354 wmb(); /* drain writebuffer */
355−
356− return 0;
357355 }
358356
359357 #ifdef CONFIG_PM
@@ -406,7 +404,7 @@ static struct platform_driver au1xpsc_i2s_driver = { · 46 unmodified lines
406404 .pm = AU1XPSCI2S_PMOPS,
407405 },
408406 .probe = au1xpsc_i2s_drvprobe,
409− .remove = au1xpsc_i2s_drvremove,
407+ .remove_new = au1xpsc_i2s_drvremove,
410408 };
411409
412410 module_platform_driver(au1xpsc_i2s_driver);
sound/soc/bcm/bcm63xx-i2s-whistler.c+2−3
@@ -289,10 +289,9 @@ static int bcm63xx_i2s_dev_probe(struct platform_device *pdev) · 288 unmodified lines
289289 return ret;
290290 }
291291
292−static int bcm63xx_i2s_dev_remove(struct platform_device *pdev)
292+static void bcm63xx_i2s_dev_remove(struct platform_device *pdev)
293293 {
294294 bcm63xx_soc_platform_remove(pdev);
295− return 0;
296295 }
297296
298297 #ifdef CONFIG_OF
@@ -308,7 +307,7 @@ static struct platform_driver bcm63xx_i2s_driver = { · 9 unmodified lines
308307 .of_match_table = of_match_ptr(snd_soc_bcm_audio_match),
309308 },
310309 .probe = bcm63xx_i2s_dev_probe,
311− .remove = bcm63xx_i2s_dev_remove,
310+ .remove_new = bcm63xx_i2s_dev_remove,
312311 };
313312
314313 module_platform_driver(bcm63xx_i2s_driver);
sound/soc/bcm/cygnus-ssp.c+2−4
@@ -1377,11 +1377,9 @@ static int cygnus_ssp_probe(struct platform_device *pdev) · 1376 unmodified lines
13771377 return 0;
13781378 }
13791379
1380−static int cygnus_ssp_remove(struct platform_device *pdev)
1380+static void cygnus_ssp_remove(struct platform_device *pdev)
13811381 {
13821382 cygnus_soc_platform_unregister(&pdev->dev);
1383−
1384− return 0;
13851383 }
13861384
13871385 static const struct of_device_id cygnus_ssp_of_match[] = {
@@ -1392,7 +1390,7 @@ MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match); · 4 unmodified lines
13921390
13931391 static struct platform_driver cygnus_ssp_driver = {
13941392 .probe = cygnus_ssp_probe,
1395− .remove = cygnus_ssp_remove,
1393+ .remove_new = cygnus_ssp_remove,
13961394 .driver = {
13971395 .name = "cygnus-ssp",
13981396 .of_match_table = cygnus_ssp_of_match,
sound/soc/cirrus/Kconfig+5−1
@@ -8,7 +8,11 @@ config SND_EP93XX_SOC · 7 unmodified lines
88 the EP93xx I2S or AC97 interfaces.
99
1010 config SND_EP93XX_SOC_I2S
11− tristate
11+ tristate "I2S controller support for the Cirrus Logic EP93xx series"
12+ depends on SND_EP93XX_SOC
13+ help
14+ Say Y or M if you want to add support for codecs attached to
15+ the EP93xx I2S interface.
1216
1317 if SND_EP93XX_SOC_I2S
1418
sound/soc/cirrus/edb93xx.c+2−4
@@ -93,14 +93,12 @@ static int edb93xx_probe(struct platform_device *pdev) · 92 unmodified lines
9393 return ret;
9494 }
9595
96−static int edb93xx_remove(struct platform_device *pdev)
96+static void edb93xx_remove(struct platform_device *pdev)
9797 {
9898 struct snd_soc_card *card = platform_get_drvdata(pdev);
9999
100100 snd_soc_unregister_card(card);
101101 ep93xx_i2s_release();
102−
103− return 0;
104102 }
105103
106104 static struct platform_driver edb93xx_driver = {
@@ -108,7 +106,7 @@ static struct platform_driver edb93xx_driver = { · 1 unmodified line
108106 .name = "edb93xx-audio",
109107 },
110108 .probe = edb93xx_probe,
111− .remove = edb93xx_remove,
109+ .remove_new = edb93xx_remove,
112110 };
113111
114112 module_platform_driver(edb93xx_driver);
sound/soc/cirrus/ep93xx-i2s.c+21−4
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <linux/slab.h>
1616 #include <linux/clk.h>
1717 #include <linux/io.h>
18+#include <linux/of.h>
1819
1920 #include <sound/core.h>
2021 #include <sound/dmaengine_pcm.h>
@@ -208,6 +209,16 @@ static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) · 187 unmodified lines
208209 return 0;
209210 }
210211
212+static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
213+ struct snd_soc_dai *dai)
214+{
215+ struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
216+
217+ ep93xx_i2s_enable(info, substream->stream);
218+
219+ return 0;
220+}
221+
211222 static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
212223 struct snd_soc_dai *dai)
213224 {
@@ -348,7 +359,6 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream, · 134 unmodified lines
348359 if (err)
349360 return err;
350361
351− ep93xx_i2s_enable(info, substream->stream);
352362 return 0;
353363 }
354364
@@ -397,6 +407,7 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component) · 42 unmodified lines
397407 #endif
398408
399409 static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
410+ .startup = ep93xx_i2s_startup,
400411 .shutdown = ep93xx_i2s_shutdown,
401412 .hw_params = ep93xx_i2s_hw_params,
402413 .set_sysclk = ep93xx_i2s_set_sysclk,
@@ -495,21 +506,27 @@ fail: · 92 unmodified lines
495506 return err;
496507 }
497508
498−static int ep93xx_i2s_remove(struct platform_device *pdev)
509+static void ep93xx_i2s_remove(struct platform_device *pdev)
499510 {
500511 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
501512
502513 clk_put(info->lrclk);
503514 clk_put(info->sclk);
504515 clk_put(info->mclk);
505− return 0;
506516 }
507517
518+static const struct of_device_id ep93xx_i2s_of_ids[] = {
519+ { .compatible = "cirrus,ep9301-i2s" },
520+ {}
521+};
522+MODULE_DEVICE_TABLE(of, ep93xx_i2s_of_ids);
523+
508524 static struct platform_driver ep93xx_i2s_driver = {
509525 .probe = ep93xx_i2s_probe,
510− .remove = ep93xx_i2s_remove,
526+ .remove_new = ep93xx_i2s_remove,
511527 .driver = {
512528 .name = "ep93xx-i2s",
529+ .of_match_table = ep93xx_i2s_of_ids,
513530 },
514531 };
515532
sound/soc/codecs/Kconfig+62−0
@@ -68,6 +68,9 @@ config SND_SOC_ALL_CODECS · 67 unmodified lines
6868 imply SND_SOC_CS35L41_I2C
6969 imply SND_SOC_CS35L45_I2C
7070 imply SND_SOC_CS35L45_SPI
71+ imply SND_SOC_CS35L56_I2C
72+ imply SND_SOC_CS35L56_SPI
73+ imply SND_SOC_CS35L56_SDW
7174 imply SND_SOC_CS42L42
7275 imply SND_SOC_CS42L42_SDW
7376 imply SND_SOC_CS42L51_I2C
@@ -130,6 +133,7 @@ config SND_SOC_ALL_CODECS · 56 unmodified lines
130133 imply SND_SOC_MAX98925
131134 imply SND_SOC_MAX98926
132135 imply SND_SOC_MAX98927
136+ imply SND_SOC_MAX98363
133137 imply SND_SOC_MAX98373_I2C
134138 imply SND_SOC_MAX98373_SDW
135139 imply SND_SOC_MAX98390
@@ -200,6 +204,7 @@ config SND_SOC_ALL_CODECS · 64 unmodified lines
200204 imply SND_SOC_RT711_SDW
201205 imply SND_SOC_RT711_SDCA_SDW
202206 imply SND_SOC_RT712_SDCA_SDW
207+ imply SND_SOC_RT712_SDCA_DMIC_SDW
203208 imply SND_SOC_RT715_SDW
204209 imply SND_SOC_RT715_SDCA_SDW
205210 imply SND_SOC_RT1308_SDW
@@ -364,6 +369,9 @@ config SND_SOC_WM_ADSP · 158 unmodified lines
364369 default y if SND_SOC_WM2200=y
365370 default y if SND_SOC_CS35L41_SPI=y
366371 default y if SND_SOC_CS35L41_I2C=y
372+ default y if SND_SOC_CS35L45_SPI=y
373+ default y if SND_SOC_CS35L45_I2C=y
374+ default y if SND_SOC_CS35L56=y
367375 default m if SND_SOC_MADERA=m
368376 default m if SND_SOC_CS47L24=m
369377 default m if SND_SOC_WM5102=m
@@ -371,6 +379,9 @@ config SND_SOC_WM_ADSP · 1 unmodified line
371379 default m if SND_SOC_WM2200=m
372380 default m if SND_SOC_CS35L41_SPI=m
373381 default m if SND_SOC_CS35L41_I2C=m
382+ default m if SND_SOC_CS35L45_SPI=m
383+ default m if SND_SOC_CS35L45_I2C=m
384+ default m if SND_SOC_CS35L56=m
374385
375386 config SND_SOC_AB8500_CODEC
376387 tristate
@@ -711,6 +722,41 @@ config SND_SOC_CS35L45_I2C · 334 unmodified lines
711722 Enable support for Cirrus Logic CS35L45 smart speaker amplifier
712723 with I2C control.
713724
725+config SND_SOC_CS35L56
726+ tristate
727+
728+config SND_SOC_CS35L56_SHARED
729+ tristate
730+
731+config SND_SOC_CS35L56_I2C
732+ tristate "Cirrus Logic CS35L56 CODEC (I2C)"
733+ depends on I2C
734+ depends on SOUNDWIRE || !SOUNDWIRE
735+ select REGMAP_I2C
736+ select SND_SOC_CS35L56
737+ select SND_SOC_CS35L56_SHARED
738+ help
739+ Enable support for Cirrus Logic CS35L56 boosted amplifier with I2C control
740+
741+config SND_SOC_CS35L56_SPI
742+ tristate "Cirrus Logic CS35L56 CODEC (SPI)"
743+ depends on SPI_MASTER
744+ depends on SOUNDWIRE || !SOUNDWIRE
745+ select REGMAP_SPI
746+ select SND_SOC_CS35L56
747+ select SND_SOC_CS35L56_SHARED
748+ help
749+ Enable support for Cirrus Logic CS35L56 boosted amplifier with SPI control
750+
751+config SND_SOC_CS35L56_SDW
752+ tristate "Cirrus Logic CS35L56 CODEC (SDW)"
753+ depends on SOUNDWIRE
754+ select REGMAP
755+ select SND_SOC_CS35L56
756+ select SND_SOC_CS35L56_SHARED
757+ help
758+ Enable support for Cirrus Logic CS35L56 boosted amplifier with SoundWire control
759+
714760 config SND_SOC_CS42L42_CORE
715761 tristate
716762
@@ -1089,6 +1135,16 @@ config SND_SOC_MAX98520 · 372 unmodified lines
10891135
10901136 To compile this driver as a module, choose M here.
10911137
1138+config SND_SOC_MAX98363
1139+ tristate "Analog Devices MAX98363 Soundwire Speaker Amplifier"
1140+ depends on SOUNDWIRE
1141+ select REGMAP_SOUNDWIRE
1142+ help
1143+ Enable support for Analog Devices MAX98363 Soundwire
1144+ amplifier. MAX98363 supports the MIPI SoundWire v1.2
1145+ compatible interface for audio and control data.
1146+ This amplifier does not support I2C and I2S.
1147+
10921148 config SND_SOC_MAX98373
10931149 tristate
10941150
@@ -1477,6 +1533,12 @@ config SND_SOC_RT712_SDCA_SDW · 382 unmodified lines
14771533 select REGMAP_SOUNDWIRE
14781534 select REGMAP_SOUNDWIRE_MBQ
14791535
1536+config SND_SOC_RT712_SDCA_DMIC_SDW
1537+ tristate "Realtek RT712 SDCA DMIC Codec - SDW"
1538+ depends on SOUNDWIRE
1539+ select REGMAP_SOUNDWIRE
1540+ select REGMAP_SOUNDWIRE_MBQ
1541+
14801542 config SND_SOC_RT715
14811543 tristate
14821544
sound/soc/codecs/Makefile+14−0
@@ -66,6 +66,11 @@ snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o · 65 unmodified lines
6666 snd-soc-cs35l45-objs := cs35l45.o cs35l45-tables.o
6767 snd-soc-cs35l45-spi-objs := cs35l45-spi.o
6868 snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o
69+snd-soc-cs35l56-objs := cs35l56.o
70+snd-soc-cs35l56-shared-objs := cs35l56-shared.o
71+snd-soc-cs35l56-i2c-objs := cs35l56-i2c.o
72+snd-soc-cs35l56-spi-objs := cs35l56-spi.o
73+snd-soc-cs35l56-sdw-objs := cs35l56-sdw.o
6974 snd-soc-cs42l42-objs := cs42l42.o
7075 snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
7176 snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
@@ -143,6 +148,7 @@ snd-soc-max98925-objs := max98925.o · 71 unmodified lines
143148 snd-soc-max98926-objs := max98926.o
144149 snd-soc-max98927-objs := max98927.o
145150 snd-soc-max98520-objs := max98520.o
151+snd-soc-max98363-objs := max98363.o
146152 snd-soc-max98373-objs := max98373.o
147153 snd-soc-max98373-i2c-objs := max98373-i2c.o
148154 snd-soc-max98373-sdw-objs := max98373-sdw.o
@@ -228,6 +234,7 @@ snd-soc-rt700-objs := rt700.o rt700-sdw.o · 79 unmodified lines
228234 snd-soc-rt711-objs := rt711.o rt711-sdw.o
229235 snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o
230236 snd-soc-rt712-sdca-objs := rt712-sdca.o rt712-sdca-sdw.o
237+snd-soc-rt712-sdca-dmic-objs := rt712-sdca-dmic.o
231238 snd-soc-rt715-objs := rt715.o rt715-sdw.o
232239 snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o
233240 snd-soc-rt9120-objs := rt9120.o
@@ -433,6 +440,11 @@ obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o · 199 unmodified lines
433440 obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o
434441 obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o
435442 obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o
443+obj-$(CONFIG_SND_SOC_CS35L56) += snd-soc-cs35l56.o
444+obj-$(CONFIG_SND_SOC_CS35L56_SHARED) += snd-soc-cs35l56-shared.o
445+obj-$(CONFIG_SND_SOC_CS35L56_I2C) += snd-soc-cs35l56-i2c.o
446+obj-$(CONFIG_SND_SOC_CS35L56_SPI) += snd-soc-cs35l56-spi.o
447+obj-$(CONFIG_SND_SOC_CS35L56_SDW) += snd-soc-cs35l56-sdw.o
436448 obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o
437449 obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o
438450 obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o
@@ -505,6 +517,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o · 66 unmodified lines
505517 obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
506518 obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
507519 obj-$(CONFIG_SND_SOC_MAX98520) += snd-soc-max98520.o
520+obj-$(CONFIG_SND_SOC_MAX98363) += snd-soc-max98363.o
508521 obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o
509522 obj-$(CONFIG_SND_SOC_MAX98373_I2C) += snd-soc-max98373-i2c.o
510523 obj-$(CONFIG_SND_SOC_MAX98373_SDW) += snd-soc-max98373-sdw.o
@@ -591,6 +604,7 @@ obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o · 80 unmodified lines
591604 obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
592605 obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o
593606 obj-$(CONFIG_SND_SOC_RT712_SDCA_SDW) += snd-soc-rt712-sdca.o
607+obj-$(CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW) += snd-soc-rt712-sdca-dmic.o
594608 obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o
595609 obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o
596610 obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o
sound/soc/codecs/adau1977-spi.c+1−1
@@ -55,7 +55,7 @@ static const struct spi_device_id adau1977_spi_ids[] = { · 54 unmodified lines
5555 };
5656 MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
5757
58−static const struct of_device_id adau1977_spi_of_match[] = {
58+static const struct of_device_id adau1977_spi_of_match[] __maybe_unused = {
5959 { .compatible = "adi,adau1977" },
6060 { .compatible = "adi,adau1978" },
6161 { .compatible = "adi,adau1979" },
sound/soc/codecs/cs35l41-lib.c+72−1
@@ -1114,12 +1114,31 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = { · 1113 unmodified lines
11141114 { 0x00000040, 0x00000033 },
11151115 };
11161116
1117+static const struct reg_sequence cs35l41_actv_seq[] = {
1118+ /* SYNC_BST_CTL_RX_EN = 1; SYNC_BST_CTL_TX_EN = 1 */
1119+ {CS35L41_MDSYNC_EN, 0x00003000},
1120+ /* BST_CTL_SEL = MDSYNC */
1121+ {CS35L41_BSTCVRT_VCTRL2, 0x00000002},
1122+};
1123+
1124+static const struct reg_sequence cs35l41_pass_seq[] = {
1125+ /* SYNC_BST_CTL_RX_EN = 0; SYNC_BST_CTL_TX_EN = 1 */
1126+ {CS35L41_MDSYNC_EN, 0x00001000},
1127+ /* BST_EN = 0 */
1128+ {CS35L41_PWR_CTRL2, 0x00003300},
1129+ /* BST_CTL_SEL = MDSYNC */
1130+ {CS35L41_BSTCVRT_VCTRL2, 0x00000002},
1131+};
1132+
11171133 int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
11181134 struct cs35l41_hw_cfg *hw_cfg)
11191135 {
11201136 int ret;
11211137
11221138 switch (hw_cfg->bst_type) {
1139+ case CS35L41_SHD_BOOST_ACTV:
1140+ regmap_multi_reg_write(regmap, cs35l41_actv_seq, ARRAY_SIZE(cs35l41_actv_seq));
1141+ fallthrough;
11231142 case CS35L41_INT_BOOST:
11241143 ret = cs35l41_boost_config(dev, regmap, hw_cfg->bst_ind,
11251144 hw_cfg->bst_cap, hw_cfg->bst_ipk);
@@ -1138,6 +1157,10 @@ int cs35l41_init_boost(struct device *dev, struct regmap *regmap, · 12 unmodified lines
11381157 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
11391158 CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT);
11401159 break;
1160+ case CS35L41_SHD_BOOST_PASS:
1161+ ret = regmap_multi_reg_write(regmap, cs35l41_pass_seq,
1162+ ARRAY_SIZE(cs35l41_pass_seq));
1163+ break;
11411164 default:
11421165 dev_err(dev, "Boost type %d not supported\n", hw_cfg->bst_type);
11431166 ret = -EINVAL;
@@ -1165,11 +1188,59 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type) · 21 unmodified lines
11651188 }
11661189 EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
11671190
1168−int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)
1191+int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
1192+ struct completion *pll_lock)
11691193 {
11701194 int ret;
1195+ unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3;
1196+ struct reg_sequence cs35l41_mdsync_down_seq[] = {
1197+ {CS35L41_PWR_CTRL3, 0},
1198+ {CS35L41_GPIO_PAD_CONTROL, 0},
1199+ {CS35L41_PWR_CTRL1, 0, 3000},
1200+ };
1201+ struct reg_sequence cs35l41_mdsync_up_seq[] = {
1202+ {CS35L41_PWR_CTRL3, 0},
1203+ {CS35L41_PWR_CTRL1, 0x00000000, 3000},
1204+ {CS35L41_PWR_CTRL1, 0x00000001, 3000},
1205+ };
11711206
11721207 switch (b_type) {
1208+ case CS35L41_SHD_BOOST_ACTV:
1209+ case CS35L41_SHD_BOOST_PASS:
1210+ regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3);
1211+ regmap_read(regmap, CS35L41_GPIO_PAD_CONTROL, &pad_control);
1212+
1213+ pwr_ctrl3 &= ~CS35L41_SYNC_EN_MASK;
1214+ pwr_ctrl1 = enable << CS35L41_GLOBAL_EN_SHIFT;
1215+
1216+ gpio1_func = enable ? CS35L41_GPIO1_MDSYNC : CS35L41_GPIO1_HIZ;
1217+ gpio1_func <<= CS35L41_GPIO1_CTRL_SHIFT;
1218+
1219+ pad_control &= ~CS35L41_GPIO1_CTRL_MASK;
1220+ pad_control |= gpio1_func & CS35L41_GPIO1_CTRL_MASK;
1221+
1222+ cs35l41_mdsync_down_seq[0].def = pwr_ctrl3;
1223+ cs35l41_mdsync_down_seq[1].def = pad_control;
1224+ cs35l41_mdsync_down_seq[2].def = pwr_ctrl1;
1225+ ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_down_seq,
1226+ ARRAY_SIZE(cs35l41_mdsync_down_seq));
1227+ if (!enable)
1228+ break;
1229+
1230+ if (!pll_lock)
1231+ return -EINVAL;
1232+
1233+ ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
1234+ if (ret == 0) {
1235+ ret = -ETIMEDOUT;
1236+ } else {
1237+ regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3);
1238+ pwr_ctrl3 |= CS35L41_SYNC_EN_MASK;
1239+ cs35l41_mdsync_up_seq[0].def = pwr_ctrl3;
1240+ ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq,
1241+ ARRAY_SIZE(cs35l41_mdsync_up_seq));
1242+ }
1243+ break;
11731244 case CS35L41_INT_BOOST:
11741245 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
11751246 enable << CS35L41_GLOBAL_EN_SHIFT);
sound/soc/codecs/cs35l41.c+76−68
@@ -150,6 +150,7 @@ static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = { · 149 unmodified lines
150150 { 5644800, 16, 24 },
151151 { 6000000, 16, 24 },
152152 { 6144000, 16, 24 },
153+ { 12288000, 0, 0 },
153154 };
154155
155156 static int cs35l41_get_fs_mon_config_index(int freq)
@@ -356,6 +357,30 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { · 200 unmodified lines
356357 WM_ADSP_FW_CONTROL("DSP1", 0),
357358 };
358359
360+static void cs35l41_boost_enable(struct cs35l41_private *cs35l41, unsigned int enable)
361+{
362+ switch (cs35l41->hw_cfg.bst_type) {
363+ case CS35L41_INT_BOOST:
364+ case CS35L41_SHD_BOOST_ACTV:
365+ enable = enable ? CS35L41_BST_EN_DEFAULT : CS35L41_BST_DIS_FET_OFF;
366+ regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
367+ enable << CS35L41_BST_EN_SHIFT);
368+ break;
369+ default:
370+ break;
371+ }
372+}
373+
374+
375+static void cs35l41_error_release(struct cs35l41_private *cs35l41, unsigned int irq_err_bit,
376+ unsigned int rel_err_bit)
377+{
378+ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1, irq_err_bit);
379+ regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
380+ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, rel_err_bit, rel_err_bit);
381+ regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, rel_err_bit, 0);
382+}
383+
359384 static irqreturn_t cs35l41_irq(int irq, void *data)
360385 {
361386 struct cs35l41_private *cs35l41 = data;
@@ -392,94 +417,49 @@ static irqreturn_t cs35l41_irq(int irq, void *data) · 30 unmodified lines
392417 */
393418 if (status[0] & CS35L41_AMP_SHORT_ERR) {
394419 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
395− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
396− CS35L41_AMP_SHORT_ERR);
397− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
398− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
399− CS35L41_AMP_SHORT_ERR_RLS,
400− CS35L41_AMP_SHORT_ERR_RLS);
401− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
402− CS35L41_AMP_SHORT_ERR_RLS, 0);
420+ cs35l41_error_release(cs35l41, CS35L41_AMP_SHORT_ERR, CS35L41_AMP_SHORT_ERR_RLS);
403421 ret = IRQ_HANDLED;
404422 }
405423
406424 if (status[0] & CS35L41_TEMP_WARN) {
407425 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
408− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
409− CS35L41_TEMP_WARN);
410− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
411− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
412− CS35L41_TEMP_WARN_ERR_RLS,
413− CS35L41_TEMP_WARN_ERR_RLS);
414− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
415− CS35L41_TEMP_WARN_ERR_RLS, 0);
426+ cs35l41_error_release(cs35l41, CS35L41_TEMP_WARN, CS35L41_TEMP_WARN_ERR_RLS);
416427 ret = IRQ_HANDLED;
417428 }
418429
419430 if (status[0] & CS35L41_TEMP_ERR) {
420431 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
421− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
422− CS35L41_TEMP_ERR);
423− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
424− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
425− CS35L41_TEMP_ERR_RLS,
426− CS35L41_TEMP_ERR_RLS);
427− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
428− CS35L41_TEMP_ERR_RLS, 0);
432+ cs35l41_error_release(cs35l41, CS35L41_TEMP_ERR, CS35L41_TEMP_ERR_RLS);
429433 ret = IRQ_HANDLED;
430434 }
431435
432436 if (status[0] & CS35L41_BST_OVP_ERR) {
433437 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
434− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
435− CS35L41_BST_EN_MASK, 0);
436− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
437− CS35L41_BST_OVP_ERR);
438− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
439− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
440− CS35L41_BST_OVP_ERR_RLS,
441− CS35L41_BST_OVP_ERR_RLS);
442− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
443− CS35L41_BST_OVP_ERR_RLS, 0);
444− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
445− CS35L41_BST_EN_MASK,
446− CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
438+ cs35l41_boost_enable(cs35l41, 0);
439+ cs35l41_error_release(cs35l41, CS35L41_BST_OVP_ERR, CS35L41_BST_OVP_ERR_RLS);
440+ cs35l41_boost_enable(cs35l41, 1);
447441 ret = IRQ_HANDLED;
448442 }
449443
450444 if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
451445 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
452− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
453− CS35L41_BST_EN_MASK, 0);
454− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
455− CS35L41_BST_DCM_UVP_ERR);
456− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
457− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
458− CS35L41_BST_UVP_ERR_RLS,
459− CS35L41_BST_UVP_ERR_RLS);
460− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
461− CS35L41_BST_UVP_ERR_RLS, 0);
462− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
463− CS35L41_BST_EN_MASK,
464− CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
446+ cs35l41_boost_enable(cs35l41, 0);
447+ cs35l41_error_release(cs35l41, CS35L41_BST_DCM_UVP_ERR, CS35L41_BST_UVP_ERR_RLS);
448+ cs35l41_boost_enable(cs35l41, 1);
465449 ret = IRQ_HANDLED;
466450 }
467451
468452 if (status[0] & CS35L41_BST_SHORT_ERR) {
469453 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
470− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
471− CS35L41_BST_EN_MASK, 0);
472− regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
473− CS35L41_BST_SHORT_ERR);
474− regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
475− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
476− CS35L41_BST_SHORT_ERR_RLS,
477− CS35L41_BST_SHORT_ERR_RLS);
478− regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
479− CS35L41_BST_SHORT_ERR_RLS, 0);
480− regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
481− CS35L41_BST_EN_MASK,
482− CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
454+ cs35l41_boost_enable(cs35l41, 0);
455+ cs35l41_error_release(cs35l41, CS35L41_BST_SHORT_ERR, CS35L41_BST_SHORT_ERR_RLS);
456+ cs35l41_boost_enable(cs35l41, 1);
457+ ret = IRQ_HANDLED;
458+ }
459+
460+ if (status[2] & CS35L41_PLL_LOCK) {
461+ regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS3, CS35L41_PLL_LOCK);
462+ complete(&cs35l41->pll_lock);
483463 ret = IRQ_HANDLED;
484464 }
485465
@@ -520,10 +500,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, · 34 unmodified lines
520500 cs35l41_pup_patch,
521501 ARRAY_SIZE(cs35l41_pup_patch));
522502
523− cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1);
503+ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1,
504+ &cs35l41->pll_lock);
524505 break;
525506 case SND_SOC_DAPM_POST_PMD:
526− cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
507+ cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0,
508+ &cs35l41->pll_lock);
527509
528510 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
529511 val, val & CS35L41_PDN_DONE_MASK,
@@ -830,6 +812,10 @@ static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { · 300 unmodified lines
830812 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
831813 struct snd_soc_dai *dai)
832814 {
815+ struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
816+
817+ reinit_completion(&cs35l41->pll_lock);
818+
833819 if (substream->runtime)
834820 return snd_pcm_hw_constraint_list(substream->runtime, 0,
835821 SNDRV_PCM_HW_PARAM_RATE,
@@ -1037,9 +1023,21 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf · 201 unmodified lines
10371023 unsigned int val;
10381024 int ret;
10391025
1040− ret = device_property_read_u32(dev, "cirrus,boost-type", &val);
1041− if (ret >= 0)
1042− hw_cfg->bst_type = val;
1026+ /* Some ACPI systems received the Shared Boost feature before the upstream driver,
1027+ * leaving those systems with deprecated _DSD properties.
1028+ * To correctly configure those systems add shared-boost-active and shared-boost-passive
1029+ * properties mapped to the correct value in boost-type.
1030+ * These two are not DT properties and should not be used in new systems designs.
1031+ */
1032+ if (device_property_read_bool(dev, "cirrus,shared-boost-active")) {
1033+ hw_cfg->bst_type = CS35L41_SHD_BOOST_ACTV;
1034+ } else if (device_property_read_bool(dev, "cirrus,shared-boost-passive")) {
1035+ hw_cfg->bst_type = CS35L41_SHD_BOOST_PASS;
1036+ } else {
1037+ ret = device_property_read_u32(dev, "cirrus,boost-type", &val);
1038+ if (ret >= 0)
1039+ hw_cfg->bst_type = val;
1040+ }
10431041
10441042 ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
10451043 if (ret >= 0)
@@ -1280,6 +1278,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * · 234 unmodified lines
12801278 /* Set interrupt masks for critical errors */
12811279 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
12821280 CS35L41_INT1_MASK_DEFAULT);
1281+ if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS ||
1282+ cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV)
1283+ regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK,
1284+ 0 << CS35L41_INT3_PLL_LOCK_SHIFT);
12831285
12841286 ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
12851287 IRQF_ONESHOT | IRQF_SHARED | irq_pol,
@@ -1303,6 +1305,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * · 17 unmodified lines
13031305 if (ret < 0)
13041306 goto err;
13051307
1308+ init_completion(&cs35l41->pll_lock);
1309+
13061310 pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
13071311 pm_runtime_use_autosuspend(cs35l41->dev);
13081312 pm_runtime_mark_last_busy(cs35l41->dev);
@@ -1345,6 +1349,10 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) · 36 unmodified lines
13451349 pm_runtime_disable(cs35l41->dev);
13461350
13471351 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1352+ if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS ||
1353+ cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV)
1354+ regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK3, CS35L41_INT3_PLL_LOCK_MASK,
1355+ 1 << CS35L41_INT3_PLL_LOCK_SHIFT);
13481356 kfree(cs35l41->dsp.system_name);
13491357 wm_adsp2_remove(&cs35l41->dsp);
13501358 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
sound/soc/codecs/cs35l41.h+1−0
@@ -33,6 +33,7 @@ struct cs35l41_private { · 32 unmodified lines
3333 int irq;
3434 /* GPIO for /RST */
3535 struct gpio_desc *reset_gpio;
36+ struct completion pll_lock;
3637 };
3738
3839 int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg);
sound/soc/codecs/cs35l45-i2c.c+3−0
@@ -32,6 +32,9 @@ static int cs35l45_i2c_probe(struct i2c_client *client) · 31 unmodified lines
3232 }
3333
3434 cs35l45->dev = dev;
35+ cs35l45->irq = client->irq;
36+ cs35l45->bus_type = CONTROL_BUS_I2C;
37+ cs35l45->i2c_addr = client->addr;
3538
3639 return cs35l45_probe(cs35l45);
3740 }
sound/soc/codecs/cs35l45-spi.c+5−0
@@ -23,6 +23,9 @@ static int cs35l45_spi_probe(struct spi_device *spi) · 22 unmodified lines
2323 if (cs35l45 == NULL)
2424 return -ENOMEM;
2525
26+ spi->max_speed_hz = CS35L45_SPI_MAX_FREQ;
27+ spi_setup(spi);
28+
2629 spi_set_drvdata(spi, cs35l45);
2730 cs35l45->regmap = devm_regmap_init_spi(spi, &cs35l45_spi_regmap);
2831 if (IS_ERR(cs35l45->regmap)) {
@@ -32,6 +35,8 @@ static int cs35l45_spi_probe(struct spi_device *spi) · 3 unmodified lines
3235 }
3336
3437 cs35l45->dev = dev;
38+ cs35l45->irq = spi->irq;
39+ cs35l45->bus_type = CONTROL_BUS_SPI;
3540
3641 return cs35l45_probe(cs35l45);
3742 }
sound/soc/codecs/cs35l45-tables.c+133−2
@@ -43,6 +43,12 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, SND_SOC_CS35L45); · 42 unmodified lines
4343 static const struct reg_default cs35l45_defaults[] = {
4444 { CS35L45_BLOCK_ENABLES, 0x00003323 },
4545 { CS35L45_BLOCK_ENABLES2, 0x00000010 },
46+ { CS35L45_SYNC_GPIO1, 0x00000007 },
47+ { CS35L45_INTB_GPIO2_MCLK_REF, 0x00000005 },
48+ { CS35L45_GPIO3, 0x00000005 },
49+ { CS35L45_PWRMGT_CTL, 0x00000000 },
50+ { CS35L45_WAKESRC_CTL, 0x00000008 },
51+ { CS35L45_WKI2C_CTL, 0x00000030 },
4652 { CS35L45_REFCLK_INPUT, 0x00000510 },
4753 { CS35L45_GLOBAL_SAMPLE_RATE, 0x00000003 },
4854 { CS35L45_ASP_ENABLES1, 0x00000000 },
@@ -60,7 +66,53 @@ static const struct reg_default cs35l45_defaults[] = { · 11 unmodified lines
6066 { CS35L45_ASPTX3_INPUT, 0x00000020 },
6167 { CS35L45_ASPTX4_INPUT, 0x00000028 },
6268 { CS35L45_ASPTX5_INPUT, 0x00000048 },
69+ { CS35L45_DSP1_RX1_RATE, 0x00000001 },
70+ { CS35L45_DSP1_RX2_RATE, 0x00000001 },
71+ { CS35L45_DSP1_RX3_RATE, 0x00000001 },
72+ { CS35L45_DSP1_RX4_RATE, 0x00000001 },
73+ { CS35L45_DSP1_RX5_RATE, 0x00000001 },
74+ { CS35L45_DSP1_RX6_RATE, 0x00000001 },
75+ { CS35L45_DSP1_RX7_RATE, 0x00000001 },
76+ { CS35L45_DSP1_RX8_RATE, 0x00000001 },
77+ { CS35L45_DSP1_TX1_RATE, 0x00000001 },
78+ { CS35L45_DSP1_TX2_RATE, 0x00000001 },
79+ { CS35L45_DSP1_TX3_RATE, 0x00000001 },
80+ { CS35L45_DSP1_TX4_RATE, 0x00000001 },
81+ { CS35L45_DSP1_TX5_RATE, 0x00000001 },
82+ { CS35L45_DSP1_TX6_RATE, 0x00000001 },
83+ { CS35L45_DSP1_TX7_RATE, 0x00000001 },
84+ { CS35L45_DSP1_TX8_RATE, 0x00000001 },
85+ { CS35L45_DSP1RX1_INPUT, 0x00000008 },
86+ { CS35L45_DSP1RX2_INPUT, 0x00000009 },
87+ { CS35L45_DSP1RX3_INPUT, 0x00000018 },
88+ { CS35L45_DSP1RX4_INPUT, 0x00000019 },
89+ { CS35L45_DSP1RX5_INPUT, 0x00000020 },
90+ { CS35L45_DSP1RX6_INPUT, 0x00000028 },
91+ { CS35L45_DSP1RX7_INPUT, 0x0000003A },
92+ { CS35L45_DSP1RX8_INPUT, 0x00000028 },
6393 { CS35L45_AMP_PCM_CONTROL, 0x00100000 },
94+ { CS35L45_IRQ1_CFG, 0x00000000 },
95+ { CS35L45_IRQ1_MASK_1, 0xBFEFFFBF },
96+ { CS35L45_IRQ1_MASK_2, 0xFFFFFFFF },
97+ { CS35L45_IRQ1_MASK_3, 0xFFFF87FF },
98+ { CS35L45_IRQ1_MASK_4, 0xF8FFFFFF },
99+ { CS35L45_IRQ1_MASK_5, 0x0EF80000 },
100+ { CS35L45_IRQ1_MASK_6, 0x00000000 },
101+ { CS35L45_IRQ1_MASK_7, 0xFFFFFF78 },
102+ { CS35L45_IRQ1_MASK_8, 0x00003FFF },
103+ { CS35L45_IRQ1_MASK_9, 0x00000000 },
104+ { CS35L45_IRQ1_MASK_10, 0x00000000 },
105+ { CS35L45_IRQ1_MASK_11, 0x00000000 },
106+ { CS35L45_IRQ1_MASK_12, 0x00000000 },
107+ { CS35L45_IRQ1_MASK_13, 0x00000000 },
108+ { CS35L45_IRQ1_MASK_14, 0x00000001 },
109+ { CS35L45_IRQ1_MASK_15, 0x00000000 },
110+ { CS35L45_IRQ1_MASK_16, 0x00000000 },
111+ { CS35L45_IRQ1_MASK_17, 0x00000000 },
112+ { CS35L45_IRQ1_MASK_18, 0x3FE5D0FF },
113+ { CS35L45_GPIO1_CTRL1, 0x81000001 },
114+ { CS35L45_GPIO2_CTRL1, 0x81000001 },
115+ { CS35L45_GPIO3_CTRL1, 0x81000001 },
64116 };
65117
66118 static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
@@ -72,6 +124,13 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg) · 5 unmodified lines
72124 case CS35L45_BLOCK_ENABLES:
73125 case CS35L45_BLOCK_ENABLES2:
74126 case CS35L45_ERROR_RELEASE:
127+ case CS35L45_SYNC_GPIO1:
128+ case CS35L45_INTB_GPIO2_MCLK_REF:
129+ case CS35L45_GPIO3:
130+ case CS35L45_PWRMGT_CTL:
131+ case CS35L45_WAKESRC_CTL:
132+ case CS35L45_WKI2C_CTL:
133+ case CS35L45_PWRMGT_STS:
75134 case CS35L45_REFCLK_INPUT:
76135 case CS35L45_GLOBAL_SAMPLE_RATE:
77136 case CS35L45_ASP_ENABLES1:
@@ -89,9 +148,59 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg) · 11 unmodified lines
89148 case CS35L45_ASPTX3_INPUT:
90149 case CS35L45_ASPTX4_INPUT:
91150 case CS35L45_ASPTX5_INPUT:
151+ case CS35L45_DSP1RX1_INPUT:
152+ case CS35L45_DSP1RX2_INPUT:
153+ case CS35L45_DSP1RX3_INPUT:
154+ case CS35L45_DSP1RX4_INPUT:
155+ case CS35L45_DSP1RX5_INPUT:
156+ case CS35L45_DSP1RX6_INPUT:
157+ case CS35L45_DSP1RX7_INPUT:
158+ case CS35L45_DSP1RX8_INPUT:
92159 case CS35L45_AMP_PCM_CONTROL:
93160 case CS35L45_AMP_PCM_HPF_TST:
94− case CS35L45_IRQ1_EINT_4:
161+ case CS35L45_IRQ1_CFG:
162+ case CS35L45_IRQ1_STATUS:
163+ case CS35L45_IRQ1_EINT_1 ... CS35L45_IRQ1_EINT_18:
164+ case CS35L45_IRQ1_STS_1 ... CS35L45_IRQ1_STS_18:
165+ case CS35L45_IRQ1_MASK_1 ... CS35L45_IRQ1_MASK_18:
166+ case CS35L45_GPIO_STATUS1:
167+ case CS35L45_GPIO1_CTRL1:
168+ case CS35L45_GPIO2_CTRL1:
169+ case CS35L45_GPIO3_CTRL1:
170+ case CS35L45_DSP_MBOX_1:
171+ case CS35L45_DSP_MBOX_2:
172+ case CS35L45_DSP_VIRT1_MBOX_1 ... CS35L45_DSP_VIRT1_MBOX_4:
173+ case CS35L45_DSP_VIRT2_MBOX_1 ... CS35L45_DSP_VIRT2_MBOX_4:
174+ case CS35L45_DSP1_SYS_ID:
175+ case CS35L45_DSP1_CLOCK_FREQ:
176+ case CS35L45_DSP1_RX1_RATE:
177+ case CS35L45_DSP1_RX2_RATE:
178+ case CS35L45_DSP1_RX3_RATE:
179+ case CS35L45_DSP1_RX4_RATE:
180+ case CS35L45_DSP1_RX5_RATE:
181+ case CS35L45_DSP1_RX6_RATE:
182+ case CS35L45_DSP1_RX7_RATE:
183+ case CS35L45_DSP1_RX8_RATE:
184+ case CS35L45_DSP1_TX1_RATE:
185+ case CS35L45_DSP1_TX2_RATE:
186+ case CS35L45_DSP1_TX3_RATE:
187+ case CS35L45_DSP1_TX4_RATE:
188+ case CS35L45_DSP1_TX5_RATE:
189+ case CS35L45_DSP1_TX6_RATE:
190+ case CS35L45_DSP1_TX7_RATE:
191+ case CS35L45_DSP1_TX8_RATE:
192+ case CS35L45_DSP1_SCRATCH1:
193+ case CS35L45_DSP1_SCRATCH2:
194+ case CS35L45_DSP1_SCRATCH3:
195+ case CS35L45_DSP1_SCRATCH4:
196+ case CS35L45_DSP1_CCM_CORE_CONTROL:
197+ case CS35L45_DSP1_XMEM_PACK_0 ... CS35L45_DSP1_XMEM_PACK_4607:
198+ case CS35L45_DSP1_XMEM_UNPACK32_0 ... CS35L45_DSP1_XMEM_UNPACK32_3071:
199+ case CS35L45_DSP1_XMEM_UNPACK24_0 ... CS35L45_DSP1_XMEM_UNPACK24_6143:
200+ case CS35L45_DSP1_YMEM_PACK_0 ... CS35L45_DSP1_YMEM_PACK_1532:
201+ case CS35L45_DSP1_YMEM_UNPACK32_0 ... CS35L45_DSP1_YMEM_UNPACK32_1022:
202+ case CS35L45_DSP1_YMEM_UNPACK24_0 ... CS35L45_DSP1_YMEM_UNPACK24_2043:
203+ case CS35L45_DSP1_PMEM_0 ... CS35L45_DSP1_PMEM_3834:
95204 return true;
96205 default:
97206 return false;
@@ -106,7 +215,29 @@ static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg) · 8 unmodified lines
106215 case CS35L45_GLOBAL_ENABLES:
107216 case CS35L45_ERROR_RELEASE:
108217 case CS35L45_AMP_PCM_HPF_TST: /* not cachable */
109− case CS35L45_IRQ1_EINT_4:
218+ case CS35L45_PWRMGT_STS:
219+ case CS35L45_IRQ1_STATUS:
220+ case CS35L45_IRQ1_EINT_1 ... CS35L45_IRQ1_EINT_18:
221+ case CS35L45_IRQ1_STS_1 ... CS35L45_IRQ1_STS_18:
222+ case CS35L45_GPIO_STATUS1:
223+ case CS35L45_DSP_MBOX_1:
224+ case CS35L45_DSP_MBOX_2:
225+ case CS35L45_DSP_VIRT1_MBOX_1 ... CS35L45_DSP_VIRT1_MBOX_4:
226+ case CS35L45_DSP_VIRT2_MBOX_1 ... CS35L45_DSP_VIRT2_MBOX_4:
227+ case CS35L45_DSP1_SYS_ID:
228+ case CS35L45_DSP1_CLOCK_FREQ:
229+ case CS35L45_DSP1_SCRATCH1:
230+ case CS35L45_DSP1_SCRATCH2:
231+ case CS35L45_DSP1_SCRATCH3:
232+ case CS35L45_DSP1_SCRATCH4:
233+ case CS35L45_DSP1_CCM_CORE_CONTROL:
234+ case CS35L45_DSP1_XMEM_PACK_0 ... CS35L45_DSP1_XMEM_PACK_4607:
235+ case CS35L45_DSP1_XMEM_UNPACK32_0 ... CS35L45_DSP1_XMEM_UNPACK32_3071:
236+ case CS35L45_DSP1_XMEM_UNPACK24_0 ... CS35L45_DSP1_XMEM_UNPACK24_6143:
237+ case CS35L45_DSP1_YMEM_PACK_0 ... CS35L45_DSP1_YMEM_PACK_1532:
238+ case CS35L45_DSP1_YMEM_UNPACK32_0 ... CS35L45_DSP1_YMEM_UNPACK32_1022:
239+ case CS35L45_DSP1_YMEM_UNPACK24_0 ... CS35L45_DSP1_YMEM_UNPACK24_2043:
240+ case CS35L45_DSP1_PMEM_0 ... CS35L45_DSP1_PMEM_3834:
110241 return true;
111242 default:
112243 return false;
sound/soc/codecs/cs35l45.c+620−10
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/module.h>
1111 #include <linux/pm_runtime.h>
1212 #include <linux/property.h>
13+#include <linux/firmware.h>
1314 #include <linux/regulator/consumer.h>
1415 #include <sound/core.h>
1516 #include <sound/pcm.h>
@@ -19,6 +20,71 @@ · 3 unmodified lines
1920
2021 #include "cs35l45.h"
2122
23+static bool cs35l45_check_cspl_mbox_sts(const enum cs35l45_cspl_mboxcmd cmd,
24+ enum cs35l45_cspl_mboxstate sts)
25+{
26+ switch (cmd) {
27+ case CSPL_MBOX_CMD_NONE:
28+ case CSPL_MBOX_CMD_UNKNOWN_CMD:
29+ return true;
30+ case CSPL_MBOX_CMD_PAUSE:
31+ case CSPL_MBOX_CMD_OUT_OF_HIBERNATE:
32+ return (sts == CSPL_MBOX_STS_PAUSED);
33+ case CSPL_MBOX_CMD_RESUME:
34+ return (sts == CSPL_MBOX_STS_RUNNING);
35+ case CSPL_MBOX_CMD_REINIT:
36+ return (sts == CSPL_MBOX_STS_RUNNING);
37+ case CSPL_MBOX_CMD_STOP_PRE_REINIT:
38+ return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
39+ case CSPL_MBOX_CMD_HIBERNATE:
40+ return (sts == CSPL_MBOX_STS_HIBERNATE);
41+ default:
42+ return false;
43+ }
44+}
45+
46+static int cs35l45_set_cspl_mbox_cmd(struct cs35l45_private *cs35l45,
47+ struct regmap *regmap,
48+ const enum cs35l45_cspl_mboxcmd cmd)
49+{
50+ unsigned int sts = 0, i;
51+ int ret;
52+
53+ if (!cs35l45->dsp.cs_dsp.running) {
54+ dev_err(cs35l45->dev, "DSP not running\n");
55+ return -EPERM;
56+ }
57+
58+ // Set mailbox cmd
59+ ret = regmap_write(regmap, CS35L45_DSP_VIRT1_MBOX_1, cmd);
60+ if (ret < 0) {
61+ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
62+ dev_err(cs35l45->dev, "Failed to write MBOX: %d\n", ret);
63+ return ret;
64+ }
65+
66+ // Read mailbox status and verify it is appropriate for the given cmd
67+ for (i = 0; i < 5; i++) {
68+ usleep_range(1000, 1100);
69+
70+ ret = regmap_read(regmap, CS35L45_DSP_MBOX_2, &sts);
71+ if (ret < 0) {
72+ dev_err(cs35l45->dev, "Failed to read MBOX STS: %d\n", ret);
73+ continue;
74+ }
75+
76+ if (!cs35l45_check_cspl_mbox_sts(cmd, sts))
77+ dev_dbg(cs35l45->dev, "[%u] cmd %u returned invalid sts %u", i, cmd, sts);
78+ else
79+ return 0;
80+ }
81+
82+ if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE)
83+ dev_err(cs35l45->dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts);
84+
85+ return -ENOMSG;
86+}
87+
2288 static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,
2389 struct snd_kcontrol *kcontrol, int event)
2490 {
@@ -46,10 +112,68 @@ static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w, · 21 unmodified lines
46112 return 0;
47113 }
48114
115+static int cs35l45_dsp_preload_ev(struct snd_soc_dapm_widget *w,
116+ struct snd_kcontrol *kcontrol, int event)
117+{
118+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
119+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
120+ int ret;
121+
122+ switch (event) {
123+ case SND_SOC_DAPM_PRE_PMU:
124+ if (cs35l45->dsp.cs_dsp.booted)
125+ return 0;
126+
127+ return wm_adsp_early_event(w, kcontrol, event);
128+ case SND_SOC_DAPM_POST_PMU:
129+ if (cs35l45->dsp.cs_dsp.running)
130+ return 0;
131+
132+ regmap_set_bits(cs35l45->regmap, CS35L45_PWRMGT_CTL,
133+ CS35L45_MEM_RDY_MASK);
134+
135+ return wm_adsp_event(w, kcontrol, event);
136+ case SND_SOC_DAPM_PRE_PMD:
137+ if (cs35l45->dsp.preloaded)
138+ return 0;
139+
140+ if (cs35l45->dsp.cs_dsp.running) {
141+ ret = wm_adsp_event(w, kcontrol, event);
142+ if (ret)
143+ return ret;
144+ }
145+
146+ return wm_adsp_early_event(w, kcontrol, event);
147+ default:
148+ return 0;
149+ }
150+}
151+
152+static int cs35l45_dsp_audio_ev(struct snd_soc_dapm_widget *w,
153+ struct snd_kcontrol *kcontrol, int event)
154+{
155+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
156+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
157+
158+ switch (event) {
159+ case SND_SOC_DAPM_POST_PMU:
160+ return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
161+ CSPL_MBOX_CMD_RESUME);
162+ case SND_SOC_DAPM_PRE_PMD:
163+ return cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
164+ CSPL_MBOX_CMD_PAUSE);
165+ default:
166+ return 0;
167+ }
168+
169+ return 0;
170+}
171+
49172 static const char * const cs35l45_asp_tx_txt[] = {
50173 "Zero", "ASP_RX1", "ASP_RX2",
51174 "VMON", "IMON", "ERR_VOL",
52175 "VDD_BATTMON", "VDD_BSTMON",
176+ "DSP_TX1", "DSP_TX2",
53177 "Interpolator", "IL_TARGET",
54178 };
55179
@@ -57,6 +181,7 @@ static const unsigned int cs35l45_asp_tx_val[] = { · 1 unmodified line
57181 CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
58182 CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
59183 CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON,
184+ CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2,
60185 CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET,
61186 };
62187
@@ -78,12 +203,54 @@ static const struct soc_enum cs35l45_asp_tx_enums[] = { · 15 unmodified lines
78203 cs35l45_asp_tx_val),
79204 };
80205
206+static const char * const cs35l45_dsp_rx_txt[] = {
207+ "Zero", "ASP_RX1", "ASP_RX2",
208+ "VMON", "IMON", "ERR_VOL",
209+ "CLASSH_TGT", "VDD_BATTMON",
210+ "VDD_BSTMON", "TEMPMON",
211+};
212+
213+static const unsigned int cs35l45_dsp_rx_val[] = {
214+ CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
215+ CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
216+ CS35L45_PCM_SRC_CLASSH_TGT, CS35L45_PCM_SRC_VDD_BATTMON,
217+ CS35L45_PCM_SRC_VDD_BSTMON, CS35L45_PCM_SRC_TEMPMON,
218+};
219+
220+static const struct soc_enum cs35l45_dsp_rx_enums[] = {
221+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX1_INPUT, 0, CS35L45_PCM_SRC_MASK,
222+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
223+ cs35l45_dsp_rx_val),
224+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX2_INPUT, 0, CS35L45_PCM_SRC_MASK,
225+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
226+ cs35l45_dsp_rx_val),
227+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX3_INPUT, 0, CS35L45_PCM_SRC_MASK,
228+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
229+ cs35l45_dsp_rx_val),
230+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX4_INPUT, 0, CS35L45_PCM_SRC_MASK,
231+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
232+ cs35l45_dsp_rx_val),
233+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX5_INPUT, 0, CS35L45_PCM_SRC_MASK,
234+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
235+ cs35l45_dsp_rx_val),
236+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX6_INPUT, 0, CS35L45_PCM_SRC_MASK,
237+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
238+ cs35l45_dsp_rx_val),
239+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX7_INPUT, 0, CS35L45_PCM_SRC_MASK,
240+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
241+ cs35l45_dsp_rx_val),
242+ SOC_VALUE_ENUM_SINGLE(CS35L45_DSP1RX8_INPUT, 0, CS35L45_PCM_SRC_MASK,
243+ ARRAY_SIZE(cs35l45_dsp_rx_txt), cs35l45_dsp_rx_txt,
244+ cs35l45_dsp_rx_val),
245+};
246+
81247 static const char * const cs35l45_dac_txt[] = {
82− "Zero", "ASP_RX1", "ASP_RX2"
248+ "Zero", "ASP_RX1", "ASP_RX2", "DSP_TX1", "DSP_TX2"
83249 };
84250
85251 static const unsigned int cs35l45_dac_val[] = {
86− CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2
252+ CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
253+ CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2
87254 };
88255
89256 static const struct soc_enum cs35l45_dacpcm_enums[] = {
@@ -100,11 +267,29 @@ static const struct snd_kcontrol_new cs35l45_asp_muxes[] = { · 10 unmodified lines
100267 SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]),
101268 };
102269
270+static const struct snd_kcontrol_new cs35l45_dsp_muxes[] = {
271+ SOC_DAPM_ENUM("DSP_RX1 Source", cs35l45_dsp_rx_enums[0]),
272+ SOC_DAPM_ENUM("DSP_RX2 Source", cs35l45_dsp_rx_enums[1]),
273+ SOC_DAPM_ENUM("DSP_RX3 Source", cs35l45_dsp_rx_enums[2]),
274+ SOC_DAPM_ENUM("DSP_RX4 Source", cs35l45_dsp_rx_enums[3]),
275+ SOC_DAPM_ENUM("DSP_RX5 Source", cs35l45_dsp_rx_enums[4]),
276+ SOC_DAPM_ENUM("DSP_RX6 Source", cs35l45_dsp_rx_enums[5]),
277+ SOC_DAPM_ENUM("DSP_RX7 Source", cs35l45_dsp_rx_enums[6]),
278+ SOC_DAPM_ENUM("DSP_RX8 Source", cs35l45_dsp_rx_enums[7]),
279+};
280+
103281 static const struct snd_kcontrol_new cs35l45_dac_muxes[] = {
104282 SOC_DAPM_ENUM("DACPCM1 Source", cs35l45_dacpcm_enums[0]),
105283 };
106284
107285 static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {
286+ SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
287+ SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
288+ cs35l45_dsp_preload_ev,
289+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
290+ SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
291+ cs35l45_dsp_audio_ev,
292+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
108293 SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0,
109294 cs35l45_global_en_ev,
110295 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -139,6 +324,15 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { · 28 unmodified lines
139324 SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]),
140325 SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]),
141326
327+ SND_SOC_DAPM_MUX("DSP_RX1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[0]),
328+ SND_SOC_DAPM_MUX("DSP_RX2 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[1]),
329+ SND_SOC_DAPM_MUX("DSP_RX3 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[2]),
330+ SND_SOC_DAPM_MUX("DSP_RX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[3]),
331+ SND_SOC_DAPM_MUX("DSP_RX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[4]),
332+ SND_SOC_DAPM_MUX("DSP_RX6 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[5]),
333+ SND_SOC_DAPM_MUX("DSP_RX7 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[6]),
334+ SND_SOC_DAPM_MUX("DSP_RX8 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dsp_muxes[7]),
335+
142336 SND_SOC_DAPM_MUX("DACPCM1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]),
143337
144338 SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -149,6 +343,8 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { · 4 unmodified lines
149343 #define CS35L45_ASP_MUX_ROUTE(name) \
150344 { name" Source", "ASP_RX1", "ASP_RX1" }, \
151345 { name" Source", "ASP_RX2", "ASP_RX2" }, \
346+ { name" Source", "DSP_TX1", "DSP1" }, \
347+ { name" Source", "DSP_TX2", "DSP1" }, \
152348 { name" Source", "VMON", "VMON" }, \
153349 { name" Source", "IMON", "IMON" }, \
154350 { name" Source", "ERR_VOL", "ERR_VOL" }, \
@@ -157,10 +353,16 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { · 2 unmodified lines
157353 { name" Source", "Interpolator", "AMP_INTP" }, \
158354 { name" Source", "IL_TARGET", "IL_TARGET" }
159355
160−#define CS35L45_DAC_MUX_ROUTE(name) \
356+#define CS35L45_DSP_MUX_ROUTE(name) \
161357 { name" Source", "ASP_RX1", "ASP_RX1" }, \
162358 { name" Source", "ASP_RX2", "ASP_RX2" }
163359
360+#define CS35L45_DAC_MUX_ROUTE(name) \
361+ { name" Source", "ASP_RX1", "ASP_RX1" }, \
362+ { name" Source", "ASP_RX2", "ASP_RX2" }, \
363+ { name" Source", "DSP_TX1", "DSP1" }, \
364+ { name" Source", "DSP_TX2", "DSP1" }
365+
164366 static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {
165367 /* Feedback */
166368 { "VMON", NULL, "VMON_SRC" },
@@ -204,6 +406,27 @@ static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = { · 37 unmodified lines
204406 { "AMP", NULL, "DACPCM1 Source"},
205407 { "AMP", NULL, "GLOBAL_EN"},
206408
409+ CS35L45_DSP_MUX_ROUTE("DSP_RX1"),
410+ CS35L45_DSP_MUX_ROUTE("DSP_RX2"),
411+ CS35L45_DSP_MUX_ROUTE("DSP_RX3"),
412+ CS35L45_DSP_MUX_ROUTE("DSP_RX4"),
413+ CS35L45_DSP_MUX_ROUTE("DSP_RX5"),
414+ CS35L45_DSP_MUX_ROUTE("DSP_RX6"),
415+ CS35L45_DSP_MUX_ROUTE("DSP_RX7"),
416+ CS35L45_DSP_MUX_ROUTE("DSP_RX8"),
417+
418+ {"DSP1", NULL, "DSP_RX1 Source"},
419+ {"DSP1", NULL, "DSP_RX2 Source"},
420+ {"DSP1", NULL, "DSP_RX3 Source"},
421+ {"DSP1", NULL, "DSP_RX4 Source"},
422+ {"DSP1", NULL, "DSP_RX5 Source"},
423+ {"DSP1", NULL, "DSP_RX6 Source"},
424+ {"DSP1", NULL, "DSP_RX7 Source"},
425+ {"DSP1", NULL, "DSP_RX8 Source"},
426+
427+ {"DSP1 Preload", NULL, "DSP1 Preloader"},
428+ {"DSP1", NULL, "DSP1 Preloader"},
429+
207430 CS35L45_DAC_MUX_ROUTE("DACPCM1"),
208431
209432 { "SPK", NULL, "AMP"},
@@ -219,6 +442,8 @@ static const struct snd_kcontrol_new cs35l45_controls[] = { · 9 unmodified lines
219442 -409, 48,
220443 (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
221444 0, cs35l45_dig_pcm_vol_tlv),
445+ WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
446+ WM_ADSP_FW_CONTROL("DSP1", 0),
222447 };
223448
224449 static int cs35l45_set_pll(struct cs35l45_private *cs35l45, unsigned int freq)
@@ -489,7 +714,24 @@ static struct snd_soc_dai_driver cs35l45_dai[] = { · 264 unmodified lines
489714 },
490715 };
491716
717+static int cs35l45_component_probe(struct snd_soc_component *component)
718+{
719+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
720+
721+ return wm_adsp2_component_probe(&cs35l45->dsp, component);
722+}
723+
724+static void cs35l45_component_remove(struct snd_soc_component *component)
725+{
726+ struct cs35l45_private *cs35l45 = snd_soc_component_get_drvdata(component);
727+
728+ wm_adsp2_component_remove(&cs35l45->dsp, component);
729+}
730+
492731 static const struct snd_soc_component_driver cs35l45_component = {
732+ .probe = cs35l45_component_probe,
733+ .remove = cs35l45_component_remove,
734+
493735 .dapm_widgets = cs35l45_dapm_widgets,
494736 .num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets),
495737
@@ -504,11 +746,81 @@ static const struct snd_soc_component_driver cs35l45_component = { · 8 unmodified lines
504746 .endianness = 1,
505747 };
506748
749+static void cs35l45_setup_hibernate(struct cs35l45_private *cs35l45)
750+{
751+ unsigned int wksrc;
752+
753+ if (cs35l45->bus_type == CONTROL_BUS_I2C)
754+ wksrc = CS35L45_WKSRC_I2C;
755+ else
756+ wksrc = CS35L45_WKSRC_SPI;
757+
758+ regmap_update_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
759+ CS35L45_WKSRC_EN_MASK,
760+ wksrc << CS35L45_WKSRC_EN_SHIFT);
761+
762+ regmap_set_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL,
763+ CS35L45_UPDT_WKCTL_MASK);
764+
765+ regmap_update_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
766+ CS35L45_WKI2C_ADDR_MASK, cs35l45->i2c_addr);
767+
768+ regmap_set_bits(cs35l45->regmap, CS35L45_WKI2C_CTL,
769+ CS35L45_UPDT_WKI2C_MASK);
770+}
771+
772+static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45)
773+{
774+ dev_dbg(cs35l45->dev, "Enter hibernate\n");
775+
776+ cs35l45_setup_hibernate(cs35l45);
777+
778+ // Don't wait for ACK since bus activity would wake the device
779+ regmap_write(cs35l45->regmap, CS35L45_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE);
780+
781+ return 0;
782+}
783+
784+static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45)
785+{
786+ const int wake_retries = 20;
787+ const int sleep_retries = 5;
788+ int ret, i, j;
789+
790+ for (i = 0; i < sleep_retries; i++) {
791+ dev_dbg(cs35l45->dev, "Exit hibernate\n");
792+
793+ for (j = 0; j < wake_retries; j++) {
794+ ret = cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap,
795+ CSPL_MBOX_CMD_OUT_OF_HIBERNATE);
796+ if (!ret) {
797+ dev_dbg(cs35l45->dev, "Wake success at cycle: %d\n", j);
798+ return 0;
799+ }
800+ usleep_range(100, 200);
801+ }
802+
803+ dev_err(cs35l45->dev, "Wake failed, re-enter hibernate: %d\n", ret);
804+
805+ cs35l45_setup_hibernate(cs35l45);
806+ }
807+
808+ dev_err(cs35l45->dev, "Timed out waking device\n");
809+
810+ return -ETIMEDOUT;
811+}
812+
507813 static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
508814 {
509815 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
510816
817+ if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
818+ return 0;
819+
820+ cs35l45_enter_hibernate(cs35l45);
821+
511822 regcache_cache_only(cs35l45->regmap, true);
823+ regcache_mark_dirty(cs35l45->regmap);
512824
513825 dev_dbg(cs35l45->dev, "Runtime suspended\n");
514826
@@ -520,9 +832,17 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev) · 5 unmodified lines
520832 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
521833 int ret;
522834
835+ if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
836+ return 0;
837+
523838 dev_dbg(cs35l45->dev, "Runtime resume\n");
524839
525840 regcache_cache_only(cs35l45->regmap, false);
841+
842+ ret = cs35l45_exit_hibernate(cs35l45);
843+ if (ret)
844+ return ret;
845+
526846 ret = regcache_sync(cs35l45->regmap);
527847 if (ret != 0)
528848 dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret);
@@ -536,7 +856,66 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev) · 7 unmodified lines
536856
537857 static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
538858 {
859+ struct device_node *node = cs35l45->dev->of_node;
860+ unsigned int gpio_regs[] = {CS35L45_GPIO1_CTRL1, CS35L45_GPIO2_CTRL1,
861+ CS35L45_GPIO3_CTRL1};
862+ unsigned int pad_regs[] = {CS35L45_SYNC_GPIO1,
863+ CS35L45_INTB_GPIO2_MCLK_REF, CS35L45_GPIO3};
864+ struct device_node *child;
539865 unsigned int val;
866+ char of_name[32];
867+ int ret, i;
868+
869+ if (!node)
870+ return 0;
871+
872+ for (i = 0; i < CS35L45_NUM_GPIOS; i++) {
873+ sprintf(of_name, "cirrus,gpio-ctrl%d", i + 1);
874+ child = of_get_child_by_name(node, of_name);
875+ if (!child)
876+ continue;
877+
878+ ret = of_property_read_u32(child, "gpio-dir", &val);
879+ if (!ret)
880+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
881+ CS35L45_GPIO_DIR_MASK,
882+ val << CS35L45_GPIO_DIR_SHIFT);
883+
884+ ret = of_property_read_u32(child, "gpio-lvl", &val);
885+ if (!ret)
886+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
887+ CS35L45_GPIO_LVL_MASK,
888+ val << CS35L45_GPIO_LVL_SHIFT);
889+
890+ ret = of_property_read_u32(child, "gpio-op-cfg", &val);
891+ if (!ret)
892+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
893+ CS35L45_GPIO_OP_CFG_MASK,
894+ val << CS35L45_GPIO_OP_CFG_SHIFT);
895+
896+ ret = of_property_read_u32(child, "gpio-pol", &val);
897+ if (!ret)
898+ regmap_update_bits(cs35l45->regmap, gpio_regs[i],
899+ CS35L45_GPIO_POL_MASK,
900+ val << CS35L45_GPIO_POL_SHIFT);
901+
902+ ret = of_property_read_u32(child, "gpio-ctrl", &val);
903+ if (!ret)
904+ regmap_update_bits(cs35l45->regmap, pad_regs[i],
905+ CS35L45_GPIO_CTRL_MASK,
906+ val << CS35L45_GPIO_CTRL_SHIFT);
907+
908+ ret = of_property_read_u32(child, "gpio-invert", &val);
909+ if (!ret) {
910+ regmap_update_bits(cs35l45->regmap, pad_regs[i],
911+ CS35L45_GPIO_INVERT_MASK,
912+ val << CS35L45_GPIO_INVERT_SHIFT);
913+ if (i == 1)
914+ cs35l45->irq_invert = val;
915+ }
916+
917+ of_node_put(child);
918+ }
540919
541920 if (device_property_read_u32(cs35l45->dev,
542921 "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
@@ -548,6 +927,134 @@ static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45) · 5 unmodified lines
548927 return 0;
549928 }
550929
930+static int cs35l45_dsp_virt2_mbox3_irq_handle(struct cs35l45_private *cs35l45,
931+ const unsigned int cmd,
932+ unsigned int data)
933+{
934+ static char *speak_status = "Unknown";
935+
936+ switch (cmd) {
937+ case EVENT_SPEAKER_STATUS:
938+ switch (data) {
939+ case 1:
940+ speak_status = "All Clear";
941+ break;
942+ case 2:
943+ speak_status = "Open Circuit";
944+ break;
945+ case 4:
946+ speak_status = "Short Circuit";
947+ break;
948+ }
949+
950+ dev_info(cs35l45->dev, "MBOX event (SPEAKER_STATUS): %s\n",
951+ speak_status);
952+ break;
953+ case EVENT_BOOT_DONE:
954+ dev_dbg(cs35l45->dev, "MBOX event (BOOT_DONE)\n");
955+ break;
956+ default:
957+ dev_err(cs35l45->dev, "MBOX event not supported %u\n", cmd);
958+ return -EINVAL;
959+ }
960+
961+ return 0;
962+}
963+
964+static irqreturn_t cs35l45_dsp_virt2_mbox_cb(int irq, void *data)
965+{
966+ struct cs35l45_private *cs35l45 = data;
967+ unsigned int mbox_val;
968+ int ret = 0;
969+
970+ ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_3, &mbox_val);
971+ if (!ret && mbox_val)
972+ ret = cs35l45_dsp_virt2_mbox3_irq_handle(cs35l45, mbox_val & CS35L45_MBOX3_CMD_MASK,
973+ (mbox_val & CS35L45_MBOX3_DATA_MASK) >> CS35L45_MBOX3_DATA_SHIFT);
974+
975+ /* Handle DSP trace log IRQ */
976+ ret = regmap_read(cs35l45->regmap, CS35L45_DSP_VIRT2_MBOX_4, &mbox_val);
977+ if (!ret && mbox_val != 0) {
978+ dev_err(cs35l45->dev, "Spurious DSP MBOX4 IRQ\n");
979+ }
980+
981+ return IRQ_RETVAL(ret);
982+}
983+
984+static irqreturn_t cs35l45_pll_unlock(int irq, void *data)
985+{
986+ struct cs35l45_private *cs35l45 = data;
987+
988+ dev_dbg(cs35l45->dev, "PLL unlock detected!");
989+
990+ return IRQ_HANDLED;
991+}
992+
993+static irqreturn_t cs35l45_pll_lock(int irq, void *data)
994+{
995+ struct cs35l45_private *cs35l45 = data;
996+
997+ dev_dbg(cs35l45->dev, "PLL lock detected!");
998+
999+ return IRQ_HANDLED;
1000+}
1001+
1002+static irqreturn_t cs35l45_spk_safe_err(int irq, void *data);
1003+
1004+static const struct cs35l45_irq cs35l45_irqs[] = {
1005+ CS35L45_IRQ(AMP_SHORT_ERR, "Amplifier short error", cs35l45_spk_safe_err),
1006+ CS35L45_IRQ(UVLO_VDDBATT_ERR, "VDDBATT undervoltage error", cs35l45_spk_safe_err),
1007+ CS35L45_IRQ(BST_SHORT_ERR, "Boost inductor error", cs35l45_spk_safe_err),
1008+ CS35L45_IRQ(BST_UVP_ERR, "Boost undervoltage error", cs35l45_spk_safe_err),
1009+ CS35L45_IRQ(TEMP_ERR, "Overtemperature error", cs35l45_spk_safe_err),
1010+ CS35L45_IRQ(AMP_CAL_ERR, "Amplifier calibration error", cs35l45_spk_safe_err),
1011+ CS35L45_IRQ(UVLO_VDDLV_ERR, "LV threshold detector error", cs35l45_spk_safe_err),
1012+ CS35L45_IRQ(GLOBAL_ERROR, "Global error", cs35l45_spk_safe_err),
1013+ CS35L45_IRQ(DSP_WDT_EXPIRE, "DSP Watchdog Timer", cs35l45_spk_safe_err),
1014+ CS35L45_IRQ(PLL_UNLOCK_FLAG_RISE, "PLL unlock", cs35l45_pll_unlock),
1015+ CS35L45_IRQ(PLL_LOCK_FLAG, "PLL lock", cs35l45_pll_lock),
1016+ CS35L45_IRQ(DSP_VIRT2_MBOX, "DSP virtual MBOX 2 write flag", cs35l45_dsp_virt2_mbox_cb),
1017+};
1018+
1019+static irqreturn_t cs35l45_spk_safe_err(int irq, void *data)
1020+{
1021+ struct cs35l45_private *cs35l45 = data;
1022+ int i;
1023+
1024+ i = irq - regmap_irq_get_virq(cs35l45->irq_data, 0);
1025+
1026+ dev_err(cs35l45->dev, "%s condition detected!\n", cs35l45_irqs[i].name);
1027+
1028+ return IRQ_HANDLED;
1029+}
1030+
1031+static const struct regmap_irq cs35l45_reg_irqs[] = {
1032+ CS35L45_REG_IRQ(IRQ1_EINT_1, AMP_SHORT_ERR),
1033+ CS35L45_REG_IRQ(IRQ1_EINT_1, UVLO_VDDBATT_ERR),
1034+ CS35L45_REG_IRQ(IRQ1_EINT_1, BST_SHORT_ERR),
1035+ CS35L45_REG_IRQ(IRQ1_EINT_1, BST_UVP_ERR),
1036+ CS35L45_REG_IRQ(IRQ1_EINT_1, TEMP_ERR),
1037+ CS35L45_REG_IRQ(IRQ1_EINT_3, AMP_CAL_ERR),
1038+ CS35L45_REG_IRQ(IRQ1_EINT_18, UVLO_VDDLV_ERR),
1039+ CS35L45_REG_IRQ(IRQ1_EINT_18, GLOBAL_ERROR),
1040+ CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_WDT_EXPIRE),
1041+ CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_UNLOCK_FLAG_RISE),
1042+ CS35L45_REG_IRQ(IRQ1_EINT_3, PLL_LOCK_FLAG),
1043+ CS35L45_REG_IRQ(IRQ1_EINT_2, DSP_VIRT2_MBOX),
1044+};
1045+
1046+static const struct regmap_irq_chip cs35l45_regmap_irq_chip = {
1047+ .name = "cs35l45 IRQ1 Controller",
1048+ .main_status = CS35L45_IRQ1_STATUS,
1049+ .status_base = CS35L45_IRQ1_EINT_1,
1050+ .mask_base = CS35L45_IRQ1_MASK_1,
1051+ .ack_base = CS35L45_IRQ1_EINT_1,
1052+ .num_regs = 18,
1053+ .irqs = cs35l45_reg_irqs,
1054+ .num_irqs = ARRAY_SIZE(cs35l45_reg_irqs),
1055+ .runtime_pm = true,
1056+};
1057+
5511058 static int cs35l45_initialize(struct cs35l45_private *cs35l45)
5521059 {
5531060 struct device *dev = cs35l45->dev;
@@ -593,18 +1100,68 @@ static int cs35l45_initialize(struct cs35l45_private *cs35l45) · 39 unmodified lines
5931100 if (ret < 0)
5941101 return ret;
5951102
596− pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000);
597− pm_runtime_use_autosuspend(cs35l45->dev);
598− pm_runtime_set_active(cs35l45->dev);
599− pm_runtime_enable(cs35l45->dev);
600−
6011103 return 0;
6021104 }
6031105
1106+static const struct reg_sequence cs35l45_fs_errata_patch[] = {
1107+ {0x02B80080, 0x00000001},
1108+ {0x02B80088, 0x00000001},
1109+ {0x02B80090, 0x00000001},
1110+ {0x02B80098, 0x00000001},
1111+ {0x02B800A0, 0x00000001},
1112+ {0x02B800A8, 0x00000001},
1113+ {0x02B800B0, 0x00000001},
1114+ {0x02B800B8, 0x00000001},
1115+ {0x02B80280, 0x00000001},
1116+ {0x02B80288, 0x00000001},
1117+ {0x02B80290, 0x00000001},
1118+ {0x02B80298, 0x00000001},
1119+ {0x02B802A0, 0x00000001},
1120+ {0x02B802A8, 0x00000001},
1121+ {0x02B802B0, 0x00000001},
1122+ {0x02B802B8, 0x00000001},
1123+};
1124+
1125+static const struct cs_dsp_region cs35l45_dsp1_regions[] = {
1126+ { .type = WMFW_HALO_PM_PACKED, .base = CS35L45_DSP1_PMEM_0 },
1127+ { .type = WMFW_HALO_XM_PACKED, .base = CS35L45_DSP1_XMEM_PACK_0 },
1128+ { .type = WMFW_HALO_YM_PACKED, .base = CS35L45_DSP1_YMEM_PACK_0 },
1129+ {. type = WMFW_ADSP2_XM, .base = CS35L45_DSP1_XMEM_UNPACK24_0},
1130+ {. type = WMFW_ADSP2_YM, .base = CS35L45_DSP1_YMEM_UNPACK24_0},
1131+};
1132+
1133+static int cs35l45_dsp_init(struct cs35l45_private *cs35l45)
1134+{
1135+ struct wm_adsp *dsp = &cs35l45->dsp;
1136+ int ret;
1137+
1138+ dsp->part = "cs35l45";
1139+ dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
1140+ dsp->toggle_preload = true;
1141+ dsp->cs_dsp.num = 1;
1142+ dsp->cs_dsp.type = WMFW_HALO;
1143+ dsp->cs_dsp.rev = 0;
1144+ dsp->cs_dsp.dev = cs35l45->dev;
1145+ dsp->cs_dsp.regmap = cs35l45->regmap;
1146+ dsp->cs_dsp.base = CS35L45_DSP1_CLOCK_FREQ;
1147+ dsp->cs_dsp.base_sysinfo = CS35L45_DSP1_SYS_ID;
1148+ dsp->cs_dsp.mem = cs35l45_dsp1_regions;
1149+ dsp->cs_dsp.num_mems = ARRAY_SIZE(cs35l45_dsp1_regions);
1150+ dsp->cs_dsp.lock_regions = 0xFFFFFFFF;
1151+
1152+ ret = wm_halo_init(dsp);
1153+
1154+ regmap_multi_reg_write(cs35l45->regmap, cs35l45_fs_errata_patch,
1155+ ARRAY_SIZE(cs35l45_fs_errata_patch));
1156+
1157+ return ret;
1158+}
1159+
6041160 int cs35l45_probe(struct cs35l45_private *cs35l45)
6051161 {
6061162 struct device *dev = cs35l45->dev;
607− int ret;
1163+ unsigned long irq_pol = IRQF_ONESHOT | IRQF_SHARED;
1164+ int ret, i, irq;
6081165
6091166 cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
6101167 if (IS_ERR(cs35l45->vdd_batt))
@@ -649,14 +1206,63 @@ int cs35l45_probe(struct cs35l45_private *cs35l45) · 38 unmodified lines
6491206 if (ret < 0)
6501207 goto err_reset;
6511208
1209+ ret = cs35l45_dsp_init(cs35l45);
1210+ if (ret < 0)
1211+ goto err_reset;
1212+
1213+ pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000);
1214+ pm_runtime_use_autosuspend(cs35l45->dev);
1215+ pm_runtime_mark_last_busy(cs35l45->dev);
1216+ pm_runtime_set_active(cs35l45->dev);
1217+ pm_runtime_get_noresume(cs35l45->dev);
1218+ pm_runtime_enable(cs35l45->dev);
1219+
1220+ if (cs35l45->irq) {
1221+ if (cs35l45->irq_invert)
1222+ irq_pol |= IRQF_TRIGGER_HIGH;
1223+ else
1224+ irq_pol |= IRQF_TRIGGER_LOW;
1225+
1226+ ret = devm_regmap_add_irq_chip(dev, cs35l45->regmap, cs35l45->irq, irq_pol, 0,
1227+ &cs35l45_regmap_irq_chip, &cs35l45->irq_data);
1228+ if (ret) {
1229+ dev_err(dev, "Failed to register IRQ chip: %d\n", ret);
1230+ goto err_dsp;
1231+ }
1232+
1233+ for (i = 0; i < ARRAY_SIZE(cs35l45_irqs); i++) {
1234+ irq = regmap_irq_get_virq(cs35l45->irq_data, cs35l45_irqs[i].irq);
1235+ if (irq < 0) {
1236+ dev_err(dev, "Failed to get %s\n", cs35l45_irqs[i].name);
1237+ ret = irq;
1238+ goto err_dsp;
1239+ }
1240+
1241+ ret = devm_request_threaded_irq(dev, irq, NULL, cs35l45_irqs[i].handler,
1242+ irq_pol, cs35l45_irqs[i].name, cs35l45);
1243+ if (ret) {
1244+ dev_err(dev, "Failed to request IRQ %s: %d\n",
1245+ cs35l45_irqs[i].name, ret);
1246+ goto err_dsp;
1247+ }
1248+ }
1249+ }
1250+
6521251 ret = devm_snd_soc_register_component(dev, &cs35l45_component,
6531252 cs35l45_dai,
6541253 ARRAY_SIZE(cs35l45_dai));
6551254 if (ret < 0)
656− goto err_reset;
1255+ goto err_dsp;
1256+
1257+ pm_runtime_put_autosuspend(cs35l45->dev);
6571258
6581259 return 0;
6591260
1261+err_dsp:
1262+ pm_runtime_disable(cs35l45->dev);
1263+ pm_runtime_put_noidle(cs35l45->dev);
1264+ wm_adsp2_remove(&cs35l45->dsp);
1265+
6601266 err_reset:
6611267 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
6621268 err:
@@ -669,9 +1275,13 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); · 6 unmodified lines
6691275
6701276 void cs35l45_remove(struct cs35l45_private *cs35l45)
6711277 {
1278+ pm_runtime_get_sync(cs35l45->dev);
6721279 pm_runtime_disable(cs35l45->dev);
1280+ wm_adsp2_remove(&cs35l45->dsp);
6731281
6741282 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
1283+
1284+ pm_runtime_put_noidle(cs35l45->dev);
6751285 regulator_disable(cs35l45->vdd_a);
6761286 /* VDD_BATT must be the last to power-off */
6771287 regulator_disable(cs35l45->vdd_batt);
sound/soc/codecs/cs35l45.h+266−1
@@ -14,6 +14,8 @@ · 13 unmodified lines
1414 #include <linux/pm_runtime.h>
1515 #include <linux/regmap.h>
1616 #include <linux/regulator/consumer.h>
17+#include <dt-bindings/sound/cs35l45.h>
18+#include "wm_adsp.h"
1719
1820 #define CS35L45_DEVID 0x00000000
1921 #define CS35L45_REVID 0x00000004
@@ -24,6 +26,13 @@ · 4 unmodified lines
2426 #define CS35L45_BLOCK_ENABLES 0x00002018
2527 #define CS35L45_BLOCK_ENABLES2 0x0000201C
2628 #define CS35L45_ERROR_RELEASE 0x00002034
29+#define CS35L45_SYNC_GPIO1 0x00002430
30+#define CS35L45_INTB_GPIO2_MCLK_REF 0x00002434
31+#define CS35L45_GPIO3 0x00002438
32+#define CS35L45_PWRMGT_CTL 0x00002900
33+#define CS35L45_WAKESRC_CTL 0x00002904
34+#define CS35L45_WKI2C_CTL 0x00002908
35+#define CS35L45_PWRMGT_STS 0x0000290C
2736 #define CS35L45_REFCLK_INPUT 0x00002C04
2837 #define CS35L45_GLOBAL_SAMPLE_RATE 0x00002C0C
2938 #define CS35L45_BOOST_CCM_CFG 0x00003808
@@ -44,11 +53,105 @@ · 14 unmodified lines
4453 #define CS35L45_ASPTX3_INPUT 0x00004C28
4554 #define CS35L45_ASPTX4_INPUT 0x00004C2C
4655 #define CS35L45_ASPTX5_INPUT 0x00004C30
56+#define CS35L45_DSP1RX1_INPUT 0x00004C40
57+#define CS35L45_DSP1RX2_INPUT 0x00004C44
58+#define CS35L45_DSP1RX3_INPUT 0x00004C48
59+#define CS35L45_DSP1RX4_INPUT 0x00004C4C
60+#define CS35L45_DSP1RX5_INPUT 0x00004C50
61+#define CS35L45_DSP1RX6_INPUT 0x00004C54
62+#define CS35L45_DSP1RX7_INPUT 0x00004C58
63+#define CS35L45_DSP1RX8_INPUT 0x00004C5C
4764 #define CS35L45_LDPM_CONFIG 0x00006404
4865 #define CS35L45_AMP_PCM_CONTROL 0x00007000
4966 #define CS35L45_AMP_PCM_HPF_TST 0x00007004
67+#define CS35L45_IRQ1_CFG 0x0000E000
68+#define CS35L45_IRQ1_STATUS 0x0000E004
69+#define CS35L45_IRQ1_EINT_1 0x0000E010
70+#define CS35L45_IRQ1_EINT_2 0x0000E014
71+#define CS35L45_IRQ1_EINT_3 0x0000E018
5072 #define CS35L45_IRQ1_EINT_4 0x0000E01C
51−#define CS35L45_LASTREG 0x0000E01C
73+#define CS35L45_IRQ1_EINT_5 0x0000E020
74+#define CS35L45_IRQ1_EINT_7 0x0000E028
75+#define CS35L45_IRQ1_EINT_8 0x0000E02C
76+#define CS35L45_IRQ1_EINT_18 0x0000E054
77+#define CS35L45_IRQ1_STS_1 0x0000E090
78+#define CS35L45_IRQ1_STS_2 0x0000E094
79+#define CS35L45_IRQ1_STS_3 0x0000E098
80+#define CS35L45_IRQ1_STS_4 0x0000E09C
81+#define CS35L45_IRQ1_STS_5 0x0000E0A0
82+#define CS35L45_IRQ1_STS_7 0x0000E0A8
83+#define CS35L45_IRQ1_STS_8 0x0000E0AC
84+#define CS35L45_IRQ1_STS_18 0x0000E0D4
85+#define CS35L45_IRQ1_MASK_1 0x0000E110
86+#define CS35L45_IRQ1_MASK_2 0x0000E114
87+#define CS35L45_IRQ1_MASK_3 0x0000E118
88+#define CS35L45_IRQ1_MASK_4 0x0000E11C
89+#define CS35L45_IRQ1_MASK_5 0x0000E120
90+#define CS35L45_IRQ1_MASK_6 0x0000E124
91+#define CS35L45_IRQ1_MASK_7 0x0000E128
92+#define CS35L45_IRQ1_MASK_8 0x0000E12C
93+#define CS35L45_IRQ1_MASK_9 0x0000E130
94+#define CS35L45_IRQ1_MASK_10 0x0000E134
95+#define CS35L45_IRQ1_MASK_11 0x0000E138
96+#define CS35L45_IRQ1_MASK_12 0x0000E13C
97+#define CS35L45_IRQ1_MASK_13 0x0000E140
98+#define CS35L45_IRQ1_MASK_14 0x0000E144
99+#define CS35L45_IRQ1_MASK_15 0x0000E148
100+#define CS35L45_IRQ1_MASK_16 0x0000E14C
101+#define CS35L45_IRQ1_MASK_17 0x0000E150
102+#define CS35L45_IRQ1_MASK_18 0x0000E154
103+#define CS35L45_GPIO_STATUS1 0x0000F000
104+#define CS35L45_GPIO1_CTRL1 0x0000F008
105+#define CS35L45_GPIO2_CTRL1 0x0000F00C
106+#define CS35L45_GPIO3_CTRL1 0x0000F010
107+#define CS35L45_DSP_MBOX_1 0x00011000
108+#define CS35L45_DSP_MBOX_2 0x00011004
109+#define CS35L45_DSP_VIRT1_MBOX_1 0x00011020
110+#define CS35L45_DSP_VIRT1_MBOX_2 0x00011024
111+#define CS35L45_DSP_VIRT1_MBOX_3 0x00011028
112+#define CS35L45_DSP_VIRT1_MBOX_4 0x0001102C
113+#define CS35L45_DSP_VIRT2_MBOX_1 0x00011040
114+#define CS35L45_DSP_VIRT2_MBOX_2 0x00011044
115+#define CS35L45_DSP_VIRT2_MBOX_3 0x00011048
116+#define CS35L45_DSP_VIRT2_MBOX_4 0x0001104C
117+#define CS35L45_DSP1_XMEM_PACK_0 0x02000000
118+#define CS35L45_DSP1_XMEM_PACK_4607 0x020047FC
119+#define CS35L45_DSP1_XMEM_UNPACK32_0 0x02400000
120+#define CS35L45_DSP1_XMEM_UNPACK32_3071 0x02402FFC
121+#define CS35L45_DSP1_SYS_ID 0x025E0000
122+#define CS35L45_DSP1_XMEM_UNPACK24_0 0x02800000
123+#define CS35L45_DSP1_XMEM_UNPACK24_6143 0x02805FFC
124+#define CS35L45_DSP1_CLOCK_FREQ 0x02B80000
125+#define CS35L45_DSP1_RX1_RATE 0x02B80080
126+#define CS35L45_DSP1_RX2_RATE 0x02B80088
127+#define CS35L45_DSP1_RX3_RATE 0x02B80090
128+#define CS35L45_DSP1_RX4_RATE 0x02B80098
129+#define CS35L45_DSP1_RX5_RATE 0x02B800A0
130+#define CS35L45_DSP1_RX6_RATE 0x02B800A8
131+#define CS35L45_DSP1_RX7_RATE 0x02B800B0
132+#define CS35L45_DSP1_RX8_RATE 0x02B800B8
133+#define CS35L45_DSP1_TX1_RATE 0x02B80280
134+#define CS35L45_DSP1_TX2_RATE 0x02B80288
135+#define CS35L45_DSP1_TX3_RATE 0x02B80290
136+#define CS35L45_DSP1_TX4_RATE 0x02B80298
137+#define CS35L45_DSP1_TX5_RATE 0x02B802A0
138+#define CS35L45_DSP1_TX6_RATE 0x02B802A8
139+#define CS35L45_DSP1_TX7_RATE 0x02B802B0
140+#define CS35L45_DSP1_TX8_RATE 0x02B802B8
141+#define CS35L45_DSP1_SCRATCH1 0x02B805C0
142+#define CS35L45_DSP1_SCRATCH2 0x02B805C8
143+#define CS35L45_DSP1_SCRATCH3 0x02B805D0
144+#define CS35L45_DSP1_SCRATCH4 0x02B805D8
145+#define CS35L45_DSP1_CCM_CORE_CONTROL 0x02BC1000
146+#define CS35L45_DSP1_YMEM_PACK_0 0x02C00000
147+#define CS35L45_DSP1_YMEM_PACK_1532 0x02C017F0
148+#define CS35L45_DSP1_YMEM_UNPACK32_0 0x03000000
149+#define CS35L45_DSP1_YMEM_UNPACK32_1022 0x03000FF8
150+#define CS35L45_DSP1_YMEM_UNPACK24_0 0x03400000
151+#define CS35L45_DSP1_YMEM_UNPACK24_2043 0x03401FEC
152+#define CS35L45_DSP1_PMEM_0 0x03800000
153+#define CS35L45_DSP1_PMEM_3834 0x03803BE8
154+#define CS35L45_LASTREG 0x03C6EFE8
52155
53156 /* SFT_RESET */
54157 #define CS35L45_SOFT_RESET_TRIGGER 0x5A000000
@@ -70,9 +173,20 @@ · 15 unmodified lines
70173 /* BLOCK_ENABLES2 */
71174 #define CS35L45_ASP_EN_SHIFT 27
72175
176+#define CS35L45_MEM_RDY_SHIFT 1
177+#define CS35L45_MEM_RDY_MASK BIT(1)
178+
73179 /* ERROR_RELEASE */
74180 #define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11)
75181
182+/* CCM_CORE */
183+#define CS35L45_CCM_CORE_RESET_SHIFT 9
184+#define CS35L45_CCM_CORE_RESET_MASK BIT(9)
185+#define CS35L45_CCM_PM_REMAP_SHIFT 7
186+#define CS35L45_CCM_PM_REMAP_MASK BIT(7)
187+#define CS35L45_CCM_CORE_EN_SHIFT 0
188+#define CS35L45_CCM_CORE_EN_MASK BIT(0)
189+
76190 /* REFCLK_INPUT */
77191 #define CS35L45_PLL_FORCE_EN_SHIFT 16
78192 #define CS35L45_PLL_FORCE_EN_MASK BIT(16)
@@ -165,6 +279,56 @@ · 86 unmodified lines
165279 #define CS35L45_OTP_BOOT_DONE_STS_MASK BIT(1)
166280 #define CS35L45_OTP_BUSY_MASK BIT(0)
167281
282+/* GPIOX_CTRL1 */
283+#define CS35L45_GPIO_DIR_SHIFT 31
284+#define CS35L45_GPIO_DIR_MASK BIT(31)
285+#define CS35L45_GPIO_LVL_SHIFT 15
286+#define CS35L45_GPIO_LVL_MASK BIT(15)
287+#define CS35L45_GPIO_OP_CFG_SHIFT 14
288+#define CS35L45_GPIO_OP_CFG_MASK BIT(14)
289+#define CS35L45_GPIO_POL_SHIFT 12
290+#define CS35L45_GPIO_POL_MASK BIT(12)
291+
292+/* SYNC_GPIO1, INTB_GPIO2_MCLK_REF, GPIO3 */
293+#define CS35L45_GPIO_CTRL_SHIFT 20
294+#define CS35L45_GPIO_CTRL_MASK GENMASK(22, 20)
295+#define CS35L45_GPIO_INVERT_SHIFT 19
296+#define CS35L45_GPIO_INVERT_MASK BIT(19)
297+
298+/* CS35L45_IRQ1_EINT_1 */
299+#define CS35L45_BST_UVP_ERR_SHIFT 7
300+#define CS35L45_BST_UVP_ERR_MASK BIT(7)
301+#define CS35L45_BST_SHORT_ERR_SHIFT 8
302+#define CS35L45_BST_SHORT_ERR_MASK BIT(8)
303+#define CS35L45_TEMP_ERR_SHIFT 17
304+#define CS35L45_TEMP_ERR_MASK BIT(17)
305+#define CS35L45_MSM_GLOBAL_EN_ASSERT_SHIFT 22
306+#define CS35L45_MSM_GLOBAL_EN_ASSERT_MASK BIT(22)
307+#define CS35L45_UVLO_VDDBATT_ERR_SHIFT 29
308+#define CS35L45_UVLO_VDDBATT_ERR_MASK BIT(29)
309+#define CS35L45_AMP_SHORT_ERR_SHIFT 31
310+#define CS35L45_AMP_SHORT_ERR_MASK BIT(31)
311+
312+/* CS35L45_IRQ1_EINT_2 */
313+#define CS35L45_DSP_WDT_EXPIRE_SHIFT 4
314+#define CS35L45_DSP_WDT_EXPIRE_MASK BIT(4)
315+#define CS35L45_DSP_VIRT2_MBOX_SHIFT 21
316+#define CS35L45_DSP_VIRT2_MBOX_MASK BIT(21)
317+
318+/* CS35L45_IRQ1_EINT_3 */
319+#define CS35L45_PLL_LOCK_FLAG_SHIFT 1
320+#define CS35L45_PLL_LOCK_FLAG_MASK BIT(1)
321+#define CS35L45_PLL_UNLOCK_FLAG_RISE_SHIFT 4
322+#define CS35L45_PLL_UNLOCK_FLAG_RISE_MASK BIT(4)
323+#define CS35L45_AMP_CAL_ERR_SHIFT 25
324+#define CS35L45_AMP_CAL_ERR_MASK BIT(25)
325+
326+/* CS35L45_IRQ1_EINT_18 */
327+#define CS35L45_GLOBAL_ERROR_SHIFT 15
328+#define CS35L45_GLOBAL_ERROR_MASK BIT(15)
329+#define CS35L45_UVLO_VDDLV_ERR_SHIFT 16
330+#define CS35L45_UVLO_VDDLV_ERR_MASK BIT(16)
331+
168332 /* Mixer sources */
169333 #define CS35L45_PCM_SRC_MASK 0x7F
170334 #define CS35L45_PCM_SRC_ZERO 0x00
@@ -176,6 +340,8 @@ · 5 unmodified lines
176340 #define CS35L45_PCM_SRC_CLASSH_TGT 0x21
177341 #define CS35L45_PCM_SRC_VDD_BATTMON 0x28
178342 #define CS35L45_PCM_SRC_VDD_BSTMON 0x29
343+#define CS35L45_PCM_SRC_DSP_TX1 0x32
344+#define CS35L45_PCM_SRC_DSP_TX2 0x33
179345 #define CS35L45_PCM_SRC_TEMPMON 0x3A
180346 #define CS35L45_PCM_SRC_INTERPOLATOR 0x40
181347 #define CS35L45_PCM_SRC_IL_TARGET 0x48
@@ -185,6 +351,51 @@ · 3 unmodified lines
185351 #define CS35L45_POST_GLOBAL_EN_US 5000
186352 #define CS35L45_PRE_GLOBAL_DIS_US 3000
187353
354+/* WAKESRC_CTL */
355+#define CS35L45_WKSRC_SYNC_GPIO1 BIT(0)
356+#define CS35L45_WKSRC_INT_GPIO2 BIT(1)
357+#define CS35L45_WKSRC_GPIO3 BIT(2)
358+#define CS35L45_WKSRC_SPI BIT(3)
359+#define CS35L45_WKSRC_I2C BIT(4)
360+#define CS35L45_UPDT_WKCTL_SHIFT 15
361+#define CS35L45_UPDT_WKCTL_MASK BIT(15)
362+#define CS35L45_WKSRC_EN_SHIFT 8
363+#define CS35L45_WKSRC_EN_MASK GENMASK(12, 8)
364+#define CS35L45_WKSRC_POL_SHIFT 0
365+#define CS35L45_WKSRC_POL_MASK GENMASK(3, 0)
366+
367+/* WAKEI2C_CTL */
368+#define CS35L45_UPDT_WKI2C_SHIFT 15
369+#define CS35L45_UPDT_WKI2C_MASK BIT(15)
370+#define CS35L45_WKI2C_ADDR_SHIFT 0
371+#define CS35L45_WKI2C_ADDR_MASK GENMASK(6, 0)
372+
373+#define CS35L45_SPI_MAX_FREQ 4000000
374+
375+enum cs35l45_cspl_mboxstate {
376+ CSPL_MBOX_STS_RUNNING = 0,
377+ CSPL_MBOX_STS_PAUSED = 1,
378+ CSPL_MBOX_STS_RDY_FOR_REINIT = 2,
379+ CSPL_MBOX_STS_HIBERNATE = 3,
380+};
381+
382+enum cs35l45_cspl_mboxcmd {
383+ CSPL_MBOX_CMD_NONE = 0,
384+ CSPL_MBOX_CMD_PAUSE = 1,
385+ CSPL_MBOX_CMD_RESUME = 2,
386+ CSPL_MBOX_CMD_REINIT = 3,
387+ CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,
388+ CSPL_MBOX_CMD_HIBERNATE = 5,
389+ CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,
390+ CSPL_MBOX_CMD_UNKNOWN_CMD = -1,
391+ CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
392+};
393+
394+enum control_bus_type {
395+ CONTROL_BUS_I2C = 0,
396+ CONTROL_BUS_SPI = 1,
397+};
398+
188399 #define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
189400 SNDRV_PCM_FMTBIT_S24_3LE| \
190401 SNDRV_PCM_FMTBIT_S24_LE)
@@ -194,7 +405,56 @@ · 3 unmodified lines
194405 SNDRV_PCM_RATE_88200 | \
195406 SNDRV_PCM_RATE_96000)
196407
408+/*
409+ * IRQs
410+ */
411+#define CS35L45_IRQ(_irq, _name, _hand) \
412+ { \
413+ .irq = CS35L45_ ## _irq ## _IRQ,\
414+ .name = _name, \
415+ .handler = _hand, \
416+ }
417+
418+struct cs35l45_irq {
419+ int irq;
420+ const char *name;
421+ irqreturn_t (*handler)(int irq, void *data);
422+};
423+
424+#define CS35L45_REG_IRQ(_reg, _irq) \
425+ [CS35L45_ ## _irq ## _IRQ] = { \
426+ .reg_offset = (CS35L45_ ## _reg) - CS35L45_IRQ1_EINT_1, \
427+ .mask = CS35L45_ ## _irq ## _MASK \
428+ }
429+
430+enum cs35l45_irq_list {
431+ CS35L45_AMP_SHORT_ERR_IRQ,
432+ CS35L45_UVLO_VDDBATT_ERR_IRQ,
433+ CS35L45_BST_SHORT_ERR_IRQ,
434+ CS35L45_BST_UVP_ERR_IRQ,
435+ CS35L45_TEMP_ERR_IRQ,
436+ CS35L45_AMP_CAL_ERR_IRQ,
437+ CS35L45_UVLO_VDDLV_ERR_IRQ,
438+ CS35L45_GLOBAL_ERROR_IRQ,
439+ CS35L45_DSP_WDT_EXPIRE_IRQ,
440+ CS35L45_PLL_UNLOCK_FLAG_RISE_IRQ,
441+ CS35L45_PLL_LOCK_FLAG_IRQ,
442+ CS35L45_DSP_VIRT2_MBOX_IRQ,
443+ CS35L45_NUM_IRQ
444+};
445+
446+#define CS35L45_MBOX3_CMD_MASK 0xFF
447+#define CS35L45_MBOX3_CMD_SHIFT 0
448+#define CS35L45_MBOX3_DATA_MASK 0xFFFFFF00
449+#define CS35L45_MBOX3_DATA_SHIFT 8
450+
451+enum mbox3_events {
452+ EVENT_SPEAKER_STATUS = 0x66,
453+ EVENT_BOOT_DONE = 0x67,
454+};
455+
197456 struct cs35l45_private {
457+ struct wm_adsp dsp; /* needs to be first member */
198458 struct device *dev;
199459 struct regmap *regmap;
200460 struct gpio_desc *reset_gpio;
@@ -204,6 +464,11 @@ struct cs35l45_private { · 3 unmodified lines
204464 bool sysclk_set;
205465 u8 slot_width;
206466 u8 slot_count;
467+ int irq_invert;
468+ int irq;
469+ unsigned int i2c_addr;
470+ enum control_bus_type bus_type;
471+ struct regmap_irq_chip_data *irq_data;
207472 };
208473
209474 extern const struct dev_pm_ops cs35l45_pm_ops;
sound/soc/codecs/cs35l56-i2c.c+82−0
@@ -0,0 +1,82 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+//
3+// CS35L56 ALSA SoC audio driver I2C binding
4+//
5+// Copyright (C) 2023 Cirrus Logic, Inc. and
6+// Cirrus Logic International Semiconductor Ltd.
7+
8+#include <linux/acpi.h>
9+#include <linux/i2c.h>
10+#include <linux/module.h>
11+#include <linux/moduleparam.h>
12+#include <linux/regmap.h>
13+#include <linux/slab.h>
14+#include <linux/types.h>
15+
16+#include "cs35l56.h"
17+
18+static int cs35l56_i2c_probe(struct i2c_client *client)
19+{
20+ struct cs35l56_private *cs35l56;
21+ struct device *dev = &client->dev;
22+ const struct regmap_config *regmap_config = &cs35l56_regmap_i2c;
23+ int ret;
24+
25+ cs35l56 = devm_kzalloc(dev, sizeof(struct cs35l56_private), GFP_KERNEL);
26+ if (!cs35l56)
27+ return -ENOMEM;
28+
29+ cs35l56->dev = dev;
30+ cs35l56->can_hibernate = true;
31+
32+ i2c_set_clientdata(client, cs35l56);
33+ cs35l56->regmap = devm_regmap_init_i2c(client, regmap_config);
34+ if (IS_ERR(cs35l56->regmap)) {
35+ ret = PTR_ERR(cs35l56->regmap);
36+ return dev_err_probe(cs35l56->dev, ret, "Failed to allocate register map\n");
37+ }
38+
39+ ret = cs35l56_common_probe(cs35l56);
40+ if (ret != 0)
41+ return ret;
42+
43+ ret = cs35l56_init(cs35l56);
44+ if (ret == 0)
45+ ret = cs35l56_irq_request(cs35l56, client->irq);
46+ if (ret < 0)
47+ cs35l56_remove(cs35l56);
48+
49+ return ret;
50+}
51+
52+static void cs35l56_i2c_remove(struct i2c_client *client)
53+{
54+ struct cs35l56_private *cs35l56 = i2c_get_clientdata(client);
55+
56+ cs35l56_remove(cs35l56);
57+}
58+
59+static const struct i2c_device_id cs35l56_id_i2c[] = {
60+ { "cs35l56", 0 },
61+ {}
62+};
63+MODULE_DEVICE_TABLE(i2c, cs35l56_id_i2c);
64+
65+static struct i2c_driver cs35l56_i2c_driver = {
66+ .driver = {
67+ .name = "cs35l56",
68+ .pm = &cs35l56_pm_ops_i2c_spi,
69+ },
70+ .id_table = cs35l56_id_i2c,
71+ .probe_new = cs35l56_i2c_probe,
72+ .remove = cs35l56_i2c_remove,
73+};
74+
75+module_i2c_driver(cs35l56_i2c_driver);
76+
77+MODULE_DESCRIPTION("ASoC CS35L56 I2C driver");
78+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
79+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
80+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
81+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
82+MODULE_LICENSE("GPL");
sound/soc/codecs/cs35l56-sdw.c+566−0
@@ -0,0 +1,566 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+//
3+// CS35L56 ALSA SoC audio driver SoundWire binding
4+//
5+// Copyright (C) 2023 Cirrus Logic, Inc. and
6+// Cirrus Logic International Semiconductor Ltd.
7+
8+#include <linux/delay.h>
9+#include <linux/device.h>
10+#include <linux/err.h>
11+#include <linux/module.h>
12+#include <linux/pm_runtime.h>
13+#include <linux/regmap.h>
14+#include <linux/soundwire/sdw.h>
15+#include <linux/soundwire/sdw_registers.h>
16+#include <linux/soundwire/sdw_type.h>
17+#include <linux/swab.h>
18+#include <linux/types.h>
19+#include <linux/workqueue.h>
20+
21+#include "cs35l56.h"
22+
23+/* Register addresses are offset when sent over SoundWire */
24+#define CS35L56_SDW_ADDR_OFFSET 0x8000
25+
26+static int cs35l56_sdw_read_one(struct sdw_slave *peripheral, unsigned int reg, void *buf)
27+{
28+ int ret;
29+
30+ ret = sdw_nread_no_pm(peripheral, reg, 4, (u8 *)buf);
31+ if (ret != 0) {
32+ dev_err(&peripheral->dev, "Read failed @%#x:%d\n", reg, ret);
33+ return ret;
34+ }
35+
36+ swab32s((u32 *)buf);
37+
38+ return 0;
39+}
40+
41+static int cs35l56_sdw_read(void *context, const void *reg_buf,
42+ const size_t reg_size, void *val_buf,
43+ size_t val_size)
44+{
45+ struct sdw_slave *peripheral = context;
46+ u8 *buf8 = val_buf;
47+ unsigned int reg, bytes;
48+ int ret;
49+
50+ reg = le32_to_cpu(*(const __le32 *)reg_buf);
51+ reg += CS35L56_SDW_ADDR_OFFSET;
52+
53+ if (val_size == 4)
54+ return cs35l56_sdw_read_one(peripheral, reg, val_buf);
55+
56+ while (val_size) {
57+ bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR); /* to end of page */
58+ if (bytes > val_size)
59+ bytes = val_size;
60+
61+ ret = sdw_nread_no_pm(peripheral, reg, bytes, buf8);
62+ if (ret != 0) {
63+ dev_err(&peripheral->dev, "Read failed @%#x..%#x:%d\n",
64+ reg, reg + bytes - 1, ret);
65+ return ret;
66+ }
67+
68+ swab32_array((u32 *)buf8, bytes / 4);
69+ val_size -= bytes;
70+ reg += bytes;
71+ buf8 += bytes;
72+ }
73+
74+ return 0;
75+}
76+
77+static inline void cs35l56_swab_copy(void *dest, const void *src, size_t nbytes)
78+{
79+ u32 *dest32 = dest;
80+ const u32 *src32 = src;
81+
82+ for (; nbytes > 0; nbytes -= 4)
83+ *dest32++ = swab32(*src32++);
84+}
85+
86+static int cs35l56_sdw_write_one(struct sdw_slave *peripheral, unsigned int reg, const void *buf)
87+{
88+ u32 val_le = swab32(*(u32 *)buf);
89+ int ret;
90+
91+ ret = sdw_nwrite_no_pm(peripheral, reg, 4, (u8 *)&val_le);
92+ if (ret != 0) {
93+ dev_err(&peripheral->dev, "Write failed @%#x:%d\n", reg, ret);
94+ return ret;
95+ }
96+
97+ return 0;
98+}
99+
100+static int cs35l56_sdw_gather_write(void *context,
101+ const void *reg_buf, size_t reg_size,
102+ const void *val_buf, size_t val_size)
103+{
104+ struct sdw_slave *peripheral = context;
105+ const u8 *src_be = val_buf;
106+ u32 val_le_buf[64]; /* Define u32 so it is 32-bit aligned */
107+ unsigned int reg, bytes;
108+ int ret;
109+
110+ reg = le32_to_cpu(*(const __le32 *)reg_buf);
111+ reg += CS35L56_SDW_ADDR_OFFSET;
112+
113+ if (val_size == 4)
114+ return cs35l56_sdw_write_one(peripheral, reg, src_be);
115+
116+ while (val_size) {
117+ bytes = SDW_REG_NO_PAGE - (reg & SDW_REGADDR); /* to end of page */
118+ if (bytes > val_size)
119+ bytes = val_size;
120+ if (bytes > sizeof(val_le_buf))
121+ bytes = sizeof(val_le_buf);
122+
123+ cs35l56_swab_copy(val_le_buf, src_be, bytes);
124+
125+ ret = sdw_nwrite_no_pm(peripheral, reg, bytes, (u8 *)val_le_buf);
126+ if (ret != 0) {
127+ dev_err(&peripheral->dev, "Write failed @%#x..%#x:%d\n",
128+ reg, reg + bytes - 1, ret);
129+ return ret;
130+ }
131+
132+ val_size -= bytes;
133+ reg += bytes;
134+ src_be += bytes;
135+ }
136+
137+ return 0;
138+}
139+
140+static int cs35l56_sdw_write(void *context, const void *val_buf, size_t val_size)
141+{
142+ const u8 *src_buf = val_buf;
143+
144+ /* First word of val_buf contains the destination address */
145+ return cs35l56_sdw_gather_write(context, &src_buf[0], 4, &src_buf[4], val_size - 4);
146+}
147+
148+/*
149+ * Registers are big-endian on I2C and SPI but little-endian on SoundWire.
150+ * Exported firmware controls are big-endian on I2C/SPI but little-endian on
151+ * SoundWire. Firmware files are always big-endian and are opaque blobs.
152+ * Present a big-endian regmap and hide the endianness swap, so that the ALSA
153+ * byte controls always have the same byte order, and firmware file blobs
154+ * can be written verbatim.
155+ */
156+static const struct regmap_bus cs35l56_regmap_bus_sdw = {
157+ .read = cs35l56_sdw_read,
158+ .write = cs35l56_sdw_write,
159+ .gather_write = cs35l56_sdw_gather_write,
160+ .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
161+ .val_format_endian_default = REGMAP_ENDIAN_BIG,
162+};
163+
164+static void cs35l56_sdw_init(struct sdw_slave *peripheral)
165+{
166+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
167+ int ret;
168+
169+ pm_runtime_get_noresume(cs35l56->dev);
170+
171+ regcache_cache_only(cs35l56->regmap, false);
172+
173+ ret = cs35l56_init(cs35l56);
174+ if (ret < 0) {
175+ regcache_cache_only(cs35l56->regmap, true);
176+ goto out;
177+ }
178+
179+ /*
180+ * cs35l56_init can return with !init_done if it triggered
181+ * a soft reset.
182+ */
183+ if (cs35l56->init_done) {
184+ /* Enable SoundWire interrupts */
185+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1,
186+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
187+ }
188+
189+out:
190+ pm_runtime_mark_last_busy(cs35l56->dev);
191+ pm_runtime_put_autosuspend(cs35l56->dev);
192+}
193+
194+static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral,
195+ struct sdw_slave_intr_status *status)
196+{
197+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
198+
199+ /* SoundWire core holds our pm_runtime when calling this function. */
200+
201+ dev_dbg(cs35l56->dev, "int control_port=%#x\n", status->control_port);
202+
203+ if ((status->control_port & SDW_SCP_INT1_IMPL_DEF) == 0)
204+ return 0;
205+
206+ /*
207+ * Prevent bus manager suspending and possibly issuing a
208+ * bus-reset before the queued work has run.
209+ */
210+ pm_runtime_get_noresume(cs35l56->dev);
211+
212+ /*
213+ * Mask and clear until it has been handled. The read of GEN_INT_STAT_1
214+ * is required as per the SoundWire spec for interrupt status bits
215+ * to clear. GEN_INT_MASK_1 masks the _inputs_ to GEN_INT_STAT1.
216+ * None of the interrupts are time-critical so use the
217+ * power-efficient queue.
218+ */
219+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
220+ sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
221+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
222+ queue_work(system_power_efficient_wq, &cs35l56->sdw_irq_work);
223+
224+ return 0;
225+}
226+
227+static void cs35l56_sdw_irq_work(struct work_struct *work)
228+{
229+ struct cs35l56_private *cs35l56 = container_of(work,
230+ struct cs35l56_private,
231+ sdw_irq_work);
232+
233+ cs35l56_irq(-1, cs35l56);
234+
235+ /* unmask interrupts */
236+ if (!cs35l56->sdw_irq_no_unmask)
237+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
238+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
239+
240+ pm_runtime_put_autosuspend(cs35l56->dev);
241+}
242+
243+static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)
244+{
245+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
246+ struct sdw_slave_prop *prop = &peripheral->prop;
247+ struct sdw_dpn_prop *ports;
248+
249+ ports = devm_kcalloc(cs35l56->dev, 2, sizeof(*ports), GFP_KERNEL);
250+ if (!ports)
251+ return -ENOMEM;
252+
253+ prop->source_ports = BIT(CS35L56_SDW1_CAPTURE_PORT);
254+ prop->sink_ports = BIT(CS35L56_SDW1_PLAYBACK_PORT);
255+ prop->paging_support = true;
256+ prop->clk_stop_mode1 = false;
257+ prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
258+ prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY | SDW_SCP_INT1_IMPL_DEF;
259+
260+ /* DP1 - playback */
261+ ports[0].num = CS35L56_SDW1_PLAYBACK_PORT;
262+ ports[0].type = SDW_DPN_FULL;
263+ ports[0].ch_prep_timeout = 10;
264+ prop->sink_dpn_prop = &ports[0];
265+
266+ /* DP3 - capture */
267+ ports[1].num = CS35L56_SDW1_CAPTURE_PORT;
268+ ports[1].type = SDW_DPN_FULL;
269+ ports[1].ch_prep_timeout = 10;
270+ prop->src_dpn_prop = &ports[1];
271+
272+ return 0;
273+}
274+
275+static int cs35l56_sdw_update_status(struct sdw_slave *peripheral,
276+ enum sdw_slave_status status)
277+{
278+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
279+
280+ switch (status) {
281+ case SDW_SLAVE_ATTACHED:
282+ dev_dbg(cs35l56->dev, "%s: ATTACHED\n", __func__);
283+ if (cs35l56->sdw_attached)
284+ break;
285+
286+ if (!cs35l56->init_done || cs35l56->soft_resetting)
287+ cs35l56_sdw_init(peripheral);
288+
289+ cs35l56->sdw_attached = true;
290+ break;
291+ case SDW_SLAVE_UNATTACHED:
292+ dev_dbg(cs35l56->dev, "%s: UNATTACHED\n", __func__);
293+ cs35l56->sdw_attached = false;
294+ break;
295+ default:
296+ break;
297+ }
298+
299+ return 0;
300+}
301+
302+static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56,
303+ struct sdw_slave *peripheral)
304+{
305+ unsigned int curr_scale_reg, next_scale_reg;
306+ int curr_scale, next_scale, ret;
307+
308+ if (!cs35l56->init_done)
309+ return 0;
310+
311+ if (peripheral->bus->params.curr_bank) {
312+ curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1;
313+ next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0;
314+ } else {
315+ curr_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B0;
316+ next_scale_reg = SDW_SCP_BUSCLOCK_SCALE_B1;
317+ }
318+
319+ /*
320+ * Current clock scale value must be different to new value.
321+ * Modify current to guarantee this. If next still has the dummy
322+ * value we wrote when it was current, the core code has not set
323+ * a new scale so restore its original good value
324+ */
325+ curr_scale = sdw_read_no_pm(peripheral, curr_scale_reg);
326+ if (curr_scale < 0) {
327+ dev_err(cs35l56->dev, "Failed to read current clock scale: %d\n", curr_scale);
328+ return curr_scale;
329+ }
330+
331+ next_scale = sdw_read_no_pm(peripheral, next_scale_reg);
332+ if (next_scale < 0) {
333+ dev_err(cs35l56->dev, "Failed to read next clock scale: %d\n", next_scale);
334+ return next_scale;
335+ }
336+
337+ if (next_scale == CS35L56_SDW_INVALID_BUS_SCALE) {
338+ next_scale = cs35l56->old_sdw_clock_scale;
339+ ret = sdw_write_no_pm(peripheral, next_scale_reg, next_scale);
340+ if (ret < 0) {
341+ dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);
342+ return ret;
343+ }
344+ }
345+
346+ cs35l56->old_sdw_clock_scale = curr_scale;
347+ ret = sdw_write_no_pm(peripheral, curr_scale_reg, CS35L56_SDW_INVALID_BUS_SCALE);
348+ if (ret < 0) {
349+ dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);
350+ return ret;
351+ }
352+
353+ dev_dbg(cs35l56->dev, "Next bus scale: %#x\n", next_scale);
354+
355+ return 0;
356+}
357+
358+static int cs35l56_sdw_bus_config(struct sdw_slave *peripheral,
359+ struct sdw_bus_params *params)
360+{
361+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
362+ int sclk;
363+
364+ sclk = params->curr_dr_freq / 2;
365+ dev_dbg(cs35l56->dev, "%s: sclk=%u c=%u r=%u\n", __func__, sclk, params->col, params->row);
366+
367+ if (cs35l56->rev < 0xb0)
368+ return cs35l56_a1_kick_divider(cs35l56, peripheral);
369+
370+ return 0;
371+}
372+
373+static int __maybe_unused cs35l56_sdw_clk_stop(struct sdw_slave *peripheral,
374+ enum sdw_clk_stop_mode mode,
375+ enum sdw_clk_stop_type type)
376+{
377+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
378+
379+ dev_dbg(cs35l56->dev, "%s: mode:%d type:%d\n", __func__, mode, type);
380+
381+ return 0;
382+}
383+
384+static const struct sdw_slave_ops cs35l56_sdw_ops = {
385+ .read_prop = cs35l56_sdw_read_prop,
386+ .interrupt_callback = cs35l56_sdw_interrupt,
387+ .update_status = cs35l56_sdw_update_status,
388+ .bus_config = cs35l56_sdw_bus_config,
389+#ifdef DEBUG
390+ .clk_stop = cs35l56_sdw_clk_stop,
391+#endif
392+};
393+
394+static int __maybe_unused cs35l56_sdw_handle_unattach(struct cs35l56_private *cs35l56)
395+{
396+ struct sdw_slave *peripheral = cs35l56->sdw_peripheral;
397+
398+ if (peripheral->unattach_request) {
399+ /* Cannot access registers until bus is re-initialized. */
400+ dev_dbg(cs35l56->dev, "Wait for initialization_complete\n");
401+ if (!wait_for_completion_timeout(&peripheral->initialization_complete,
402+ msecs_to_jiffies(5000))) {
403+ dev_err(cs35l56->dev, "initialization_complete timed out\n");
404+ return -ETIMEDOUT;
405+ }
406+
407+ peripheral->unattach_request = 0;
408+
409+ /*
410+ * Don't call regcache_mark_dirty(), we can't be sure that the
411+ * Manager really did issue a Bus Reset.
412+ */
413+ }
414+
415+ return 0;
416+}
417+
418+static int __maybe_unused cs35l56_sdw_runtime_suspend(struct device *dev)
419+{
420+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
421+
422+ if (!cs35l56->init_done)
423+ return 0;
424+
425+ return cs35l56_runtime_suspend(dev);
426+}
427+
428+static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)
429+{
430+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
431+ int ret;
432+
433+ dev_dbg(dev, "Runtime resume\n");
434+
435+ if (!cs35l56->init_done)
436+ return 0;
437+
438+ ret = cs35l56_sdw_handle_unattach(cs35l56);
439+ if (ret < 0)
440+ return ret;
441+
442+ ret = cs35l56_runtime_resume_common(cs35l56);
443+ if (ret)
444+ return ret;
445+
446+ /* Re-enable SoundWire interrupts */
447+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
448+ CS35L56_SDW_INT_MASK_CODEC_IRQ);
449+
450+ return 0;
451+}
452+
453+static int __maybe_unused cs35l56_sdw_system_suspend(struct device *dev)
454+{
455+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
456+
457+ if (!cs35l56->init_done)
458+ return 0;
459+
460+ /*
461+ * Disable SoundWire interrupts.
462+ * Flush - don't cancel because that could leave an unbalanced pm_runtime_get.
463+ */
464+ cs35l56->sdw_irq_no_unmask = true;
465+ flush_work(&cs35l56->sdw_irq_work);
466+
467+ /* Mask interrupts and flush in case sdw_irq_work was queued again */
468+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
469+ sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1);
470+ sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
471+ flush_work(&cs35l56->sdw_irq_work);
472+
473+ return cs35l56_system_suspend(dev);
474+}
475+
476+static int __maybe_unused cs35l56_sdw_system_resume(struct device *dev)
477+{
478+ struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
479+
480+ cs35l56->sdw_irq_no_unmask = false;
481+ /* runtime_resume re-enables the interrupt */
482+
483+ return cs35l56_system_resume(dev);
484+}
485+
486+static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id)
487+{
488+ struct device *dev = &peripheral->dev;
489+ struct cs35l56_private *cs35l56;
490+ int ret;
491+
492+ cs35l56 = devm_kzalloc(dev, sizeof(*cs35l56), GFP_KERNEL);
493+ if (!cs35l56)
494+ return -ENOMEM;
495+
496+ cs35l56->dev = dev;
497+ cs35l56->sdw_peripheral = peripheral;
498+ INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);
499+
500+ dev_set_drvdata(dev, cs35l56);
501+
502+ cs35l56->regmap = devm_regmap_init(dev, &cs35l56_regmap_bus_sdw,
503+ peripheral, &cs35l56_regmap_sdw);
504+ if (IS_ERR(cs35l56->regmap)) {
505+ ret = PTR_ERR(cs35l56->regmap);
506+ return dev_err_probe(dev, ret, "Failed to allocate register map\n");
507+ }
508+
509+ /* Start in cache-only until device is enumerated */
510+ regcache_cache_only(cs35l56->regmap, true);
511+
512+ ret = cs35l56_common_probe(cs35l56);
513+ if (ret != 0)
514+ return ret;
515+
516+ return 0;
517+}
518+
519+static int cs35l56_sdw_remove(struct sdw_slave *peripheral)
520+{
521+ struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
522+
523+ /* Disable SoundWire interrupts */
524+ cs35l56->sdw_irq_no_unmask = true;
525+ cancel_work_sync(&cs35l56->sdw_irq_work);
526+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
527+ sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
528+ sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
529+
530+ cs35l56_remove(cs35l56);
531+
532+ return 0;
533+}
534+
535+static const struct dev_pm_ops cs35l56_sdw_pm = {
536+ SET_RUNTIME_PM_OPS(cs35l56_sdw_runtime_suspend, cs35l56_sdw_runtime_resume, NULL)
537+ SYSTEM_SLEEP_PM_OPS(cs35l56_sdw_system_suspend, cs35l56_sdw_system_resume)
538+ LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_system_suspend_late, cs35l56_system_resume_early)
539+ /* NOIRQ stage not needed, SoundWire doesn't use a hard IRQ */
540+};
541+
542+static const struct sdw_device_id cs35l56_sdw_id[] = {
543+ SDW_SLAVE_ENTRY(0x01FA, 0x3556, 0),
544+ {},
545+};
546+MODULE_DEVICE_TABLE(sdw, cs35l56_sdw_id);
547+
548+static struct sdw_driver cs35l56_sdw_driver = {
549+ .driver = {
550+ .name = "cs35l56",
551+ .pm = &cs35l56_sdw_pm,
552+ },
553+ .probe = cs35l56_sdw_probe,
554+ .remove = cs35l56_sdw_remove,
555+ .ops = &cs35l56_sdw_ops,
556+ .id_table = cs35l56_sdw_id,
557+};
558+
559+module_sdw_driver(cs35l56_sdw_driver);
560+
561+MODULE_DESCRIPTION("ASoC CS35L56 SoundWire driver");
562+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
563+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
564+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
565+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
566+MODULE_LICENSE("GPL");
sound/soc/codecs/cs35l56-shared.c+362−0
@@ -0,0 +1,362 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+//
3+// Components shared between ASoC and HDA CS35L56 drivers
4+//
5+// Copyright (C) 2023 Cirrus Logic, Inc. and
6+// Cirrus Logic International Semiconductor Ltd.
7+
8+#include <linux/regmap.h>
9+#include <linux/regulator/consumer.h>
10+#include <linux/types.h>
11+
12+#include "cs35l56.h"
13+
14+static const struct reg_default cs35l56_reg_defaults[] = {
15+ { CS35L56_ASP1_ENABLES1, 0x00000000 },
16+ { CS35L56_ASP1_CONTROL1, 0x00000028 },
17+ { CS35L56_ASP1_CONTROL2, 0x18180200 },
18+ { CS35L56_ASP1_CONTROL3, 0x00000002 },
19+ { CS35L56_ASP1_FRAME_CONTROL1, 0x03020100 },
20+ { CS35L56_ASP1_FRAME_CONTROL5, 0x00020100 },
21+ { CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
22+ { CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
23+ { CS35L56_ASP1TX1_INPUT, 0x00000018 },
24+ { CS35L56_ASP1TX2_INPUT, 0x00000019 },
25+ { CS35L56_ASP1TX3_INPUT, 0x00000020 },
26+ { CS35L56_ASP1TX4_INPUT, 0x00000028 },
27+ { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
28+ { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
29+ { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
30+ { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
31+ { CS35L56_IRQ1_CFG, 0x00000000 },
32+ { CS35L56_IRQ1_MASK_1, 0x83ffffff },
33+ { CS35L56_IRQ1_MASK_2, 0xffff7fff },
34+ { CS35L56_IRQ1_MASK_4, 0xe0ffffff },
35+ { CS35L56_IRQ1_MASK_8, 0xfc000fff },
36+ { CS35L56_IRQ1_MASK_18, 0x1f7df0ff },
37+ { CS35L56_IRQ1_MASK_20, 0x15c00000 },
38+ /* CS35L56_MAIN_RENDER_USER_MUTE - soft register, no default */
39+ /* CS35L56_MAIN_RENDER_USER_VOLUME - soft register, no default */
40+ /* CS35L56_MAIN_POSTURE_NUMBER - soft register, no default */
41+};
42+
43+static bool cs35l56_is_dsp_memory(unsigned int reg)
44+{
45+ switch (reg) {
46+ case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
47+ case CS35L56_DSP1_XMEM_UNPACKED32_0 ... CS35L56_DSP1_XMEM_UNPACKED32_4095:
48+ case CS35L56_DSP1_XMEM_UNPACKED24_0 ... CS35L56_DSP1_XMEM_UNPACKED24_8191:
49+ case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
50+ case CS35L56_DSP1_YMEM_UNPACKED32_0 ... CS35L56_DSP1_YMEM_UNPACKED32_3070:
51+ case CS35L56_DSP1_YMEM_UNPACKED24_0 ... CS35L56_DSP1_YMEM_UNPACKED24_6141:
52+ case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
53+ return true;
54+ default:
55+ return false;
56+ }
57+}
58+
59+static bool cs35l56_readable_reg(struct device *dev, unsigned int reg)
60+{
61+ switch (reg) {
62+ case CS35L56_DEVID:
63+ case CS35L56_REVID:
64+ case CS35L56_RELID:
65+ case CS35L56_OTPID:
66+ case CS35L56_SFT_RESET:
67+ case CS35L56_GLOBAL_ENABLES:
68+ case CS35L56_BLOCK_ENABLES:
69+ case CS35L56_BLOCK_ENABLES2:
70+ case CS35L56_REFCLK_INPUT:
71+ case CS35L56_GLOBAL_SAMPLE_RATE:
72+ case CS35L56_ASP1_ENABLES1:
73+ case CS35L56_ASP1_CONTROL1:
74+ case CS35L56_ASP1_CONTROL2:
75+ case CS35L56_ASP1_CONTROL3:
76+ case CS35L56_ASP1_FRAME_CONTROL1:
77+ case CS35L56_ASP1_FRAME_CONTROL5:
78+ case CS35L56_ASP1_DATA_CONTROL1:
79+ case CS35L56_ASP1_DATA_CONTROL5:
80+ case CS35L56_DACPCM1_INPUT:
81+ case CS35L56_DACPCM2_INPUT:
82+ case CS35L56_ASP1TX1_INPUT:
83+ case CS35L56_ASP1TX2_INPUT:
84+ case CS35L56_ASP1TX3_INPUT:
85+ case CS35L56_ASP1TX4_INPUT:
86+ case CS35L56_DSP1RX1_INPUT:
87+ case CS35L56_DSP1RX2_INPUT:
88+ case CS35L56_SWIRE_DP3_CH1_INPUT:
89+ case CS35L56_SWIRE_DP3_CH2_INPUT:
90+ case CS35L56_SWIRE_DP3_CH3_INPUT:
91+ case CS35L56_SWIRE_DP3_CH4_INPUT:
92+ case CS35L56_IRQ1_CFG:
93+ case CS35L56_IRQ1_STATUS:
94+ case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
95+ case CS35L56_IRQ1_EINT_18:
96+ case CS35L56_IRQ1_EINT_20:
97+ case CS35L56_IRQ1_MASK_1:
98+ case CS35L56_IRQ1_MASK_2:
99+ case CS35L56_IRQ1_MASK_4:
100+ case CS35L56_IRQ1_MASK_8:
101+ case CS35L56_IRQ1_MASK_18:
102+ case CS35L56_IRQ1_MASK_20:
103+ case CS35L56_DSP_VIRTUAL1_MBOX_1:
104+ case CS35L56_DSP_VIRTUAL1_MBOX_2:
105+ case CS35L56_DSP_VIRTUAL1_MBOX_3:
106+ case CS35L56_DSP_VIRTUAL1_MBOX_4:
107+ case CS35L56_DSP_VIRTUAL1_MBOX_5:
108+ case CS35L56_DSP_VIRTUAL1_MBOX_6:
109+ case CS35L56_DSP_VIRTUAL1_MBOX_7:
110+ case CS35L56_DSP_VIRTUAL1_MBOX_8:
111+ case CS35L56_DSP_RESTRICT_STS1:
112+ case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
113+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
114+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
115+ case CS35L56_DSP1_SCRATCH1:
116+ case CS35L56_DSP1_SCRATCH2:
117+ case CS35L56_DSP1_SCRATCH3:
118+ case CS35L56_DSP1_SCRATCH4:
119+ return true;
120+ default:
121+ return cs35l56_is_dsp_memory(reg);
122+ }
123+}
124+
125+static bool cs35l56_precious_reg(struct device *dev, unsigned int reg)
126+{
127+ switch (reg) {
128+ case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
129+ case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
130+ case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
131+ return true;
132+ default:
133+ return false;
134+ }
135+}
136+
137+static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
138+{
139+ switch (reg) {
140+ case CS35L56_DEVID:
141+ case CS35L56_REVID:
142+ case CS35L56_RELID:
143+ case CS35L56_OTPID:
144+ case CS35L56_SFT_RESET:
145+ case CS35L56_GLOBAL_ENABLES: /* owned by firmware */
146+ case CS35L56_BLOCK_ENABLES: /* owned by firmware */
147+ case CS35L56_BLOCK_ENABLES2: /* owned by firmware */
148+ case CS35L56_REFCLK_INPUT: /* owned by firmware */
149+ case CS35L56_GLOBAL_SAMPLE_RATE: /* owned by firmware */
150+ case CS35L56_DACPCM1_INPUT: /* owned by firmware */
151+ case CS35L56_DACPCM2_INPUT: /* owned by firmware */
152+ case CS35L56_DSP1RX1_INPUT: /* owned by firmware */
153+ case CS35L56_DSP1RX2_INPUT: /* owned by firmware */
154+ case CS35L56_IRQ1_STATUS:
155+ case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
156+ case CS35L56_IRQ1_EINT_18:
157+ case CS35L56_IRQ1_EINT_20:
158+ case CS35L56_DSP_VIRTUAL1_MBOX_1:
159+ case CS35L56_DSP_VIRTUAL1_MBOX_2:
160+ case CS35L56_DSP_VIRTUAL1_MBOX_3:
161+ case CS35L56_DSP_VIRTUAL1_MBOX_4:
162+ case CS35L56_DSP_VIRTUAL1_MBOX_5:
163+ case CS35L56_DSP_VIRTUAL1_MBOX_6:
164+ case CS35L56_DSP_VIRTUAL1_MBOX_7:
165+ case CS35L56_DSP_VIRTUAL1_MBOX_8:
166+ case CS35L56_DSP_RESTRICT_STS1:
167+ case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
168+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
169+ case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
170+ case CS35L56_DSP1_SCRATCH1:
171+ case CS35L56_DSP1_SCRATCH2:
172+ case CS35L56_DSP1_SCRATCH3:
173+ case CS35L56_DSP1_SCRATCH4:
174+ return true;
175+ case CS35L56_MAIN_RENDER_USER_MUTE:
176+ case CS35L56_MAIN_RENDER_USER_VOLUME:
177+ case CS35L56_MAIN_POSTURE_NUMBER:
178+ return false;
179+ default:
180+ return cs35l56_is_dsp_memory(reg);
181+ }
182+}
183+
184+static const u32 cs35l56_firmware_registers[] = {
185+ CS35L56_MAIN_RENDER_USER_MUTE,
186+ CS35L56_MAIN_RENDER_USER_VOLUME,
187+ CS35L56_MAIN_POSTURE_NUMBER,
188+};
189+
190+void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap)
191+{
192+ int i;
193+ unsigned int val;
194+
195+ for (i = 0; i < ARRAY_SIZE(cs35l56_firmware_registers); i++) {
196+ regmap_read(regmap, cs35l56_firmware_registers[i], &val);
197+ dev_dbg(dev, "%s: %d: %#x: %#x\n", __func__,
198+ i, cs35l56_firmware_registers[i], val);
199+ }
200+}
201+EXPORT_SYMBOL_NS_GPL(cs35l56_reread_firmware_registers, SND_SOC_CS35L56_SHARED);
202+
203+const struct cs_dsp_region cs35l56_dsp1_regions[] = {
204+ { .type = WMFW_HALO_PM_PACKED, .base = CS35L56_DSP1_PMEM_0 },
205+ { .type = WMFW_HALO_XM_PACKED, .base = CS35L56_DSP1_XMEM_PACKED_0 },
206+ { .type = WMFW_HALO_YM_PACKED, .base = CS35L56_DSP1_YMEM_PACKED_0 },
207+ { .type = WMFW_ADSP2_XM, .base = CS35L56_DSP1_XMEM_UNPACKED24_0 },
208+ { .type = WMFW_ADSP2_YM, .base = CS35L56_DSP1_YMEM_UNPACKED24_0 },
209+};
210+EXPORT_SYMBOL_NS_GPL(cs35l56_dsp1_regions, SND_SOC_CS35L56_SHARED);
211+
212+static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
213+ [0x0C] = 128000,
214+ [0x0F] = 256000,
215+ [0x11] = 384000,
216+ [0x12] = 512000,
217+ [0x15] = 768000,
218+ [0x17] = 1024000,
219+ [0x1A] = 1500000,
220+ [0x1B] = 1536000,
221+ [0x1C] = 2000000,
222+ [0x1D] = 2048000,
223+ [0x1E] = 2400000,
224+ [0x20] = 3000000,
225+ [0x21] = 3072000,
226+ [0x23] = 4000000,
227+ [0x24] = 4096000,
228+ [0x25] = 4800000,
229+ [0x27] = 6000000,
230+ [0x28] = 6144000,
231+ [0x29] = 6250000,
232+ [0x2A] = 6400000,
233+ [0x2E] = 8000000,
234+ [0x2F] = 8192000,
235+ [0x30] = 9600000,
236+ [0x32] = 12000000,
237+ [0x33] = 12288000,
238+ [0x37] = 13500000,
239+ [0x38] = 19200000,
240+ [0x39] = 22579200,
241+ [0x3B] = 24576000,
242+};
243+
244+int cs35l56_get_bclk_freq_id(unsigned int freq)
245+{
246+ int i;
247+
248+ if (freq == 0)
249+ return -EINVAL;
250+
251+ /* The BCLK frequency must be a valid PLL REFCLK */
252+ for (i = 0; i < ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table); ++i) {
253+ if (cs35l56_bclk_valid_for_pll_freq_table[i] == freq)
254+ return i;
255+ }
256+
257+ return -EINVAL;
258+}
259+EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED);
260+
261+static const char * const cs35l56_supplies[/* auto-sized */] = {
262+ "VDD_P",
263+ "VDD_IO",
264+ "VDD_A",
265+};
266+
267+void cs35l56_fill_supply_names(struct regulator_bulk_data *data)
268+{
269+ int i;
270+
271+ BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies) != CS35L56_NUM_BULK_SUPPLIES);
272+ for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++)
273+ data[i].supply = cs35l56_supplies[i];
274+}
275+EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED);
276+
277+const char * const cs35l56_tx_input_texts[] = {
278+ "None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
279+ "VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
280+ "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
281+ "INTERPOLATOR", "SDW1RX1", "SDW1RX2",
282+};
283+EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED);
284+
285+const unsigned int cs35l56_tx_input_values[] = {
286+ CS35L56_INPUT_SRC_NONE,
287+ CS35L56_INPUT_SRC_ASP1RX1,
288+ CS35L56_INPUT_SRC_ASP1RX2,
289+ CS35L56_INPUT_SRC_VMON,
290+ CS35L56_INPUT_SRC_IMON,
291+ CS35L56_INPUT_SRC_ERR_VOL,
292+ CS35L56_INPUT_SRC_CLASSH,
293+ CS35L56_INPUT_SRC_VDDBMON,
294+ CS35L56_INPUT_SRC_VBSTMON,
295+ CS35L56_INPUT_SRC_DSP1TX1,
296+ CS35L56_INPUT_SRC_DSP1TX2,
297+ CS35L56_INPUT_SRC_DSP1TX3,
298+ CS35L56_INPUT_SRC_DSP1TX4,
299+ CS35L56_INPUT_SRC_DSP1TX5,
300+ CS35L56_INPUT_SRC_DSP1TX6,
301+ CS35L56_INPUT_SRC_DSP1TX7,
302+ CS35L56_INPUT_SRC_DSP1TX8,
303+ CS35L56_INPUT_SRC_TEMPMON,
304+ CS35L56_INPUT_SRC_INTERPOLATOR,
305+ CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1,
306+ CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2,
307+};
308+EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED);
309+
310+struct regmap_config cs35l56_regmap_i2c = {
311+ .reg_bits = 32,
312+ .val_bits = 32,
313+ .reg_stride = 4,
314+ .reg_format_endian = REGMAP_ENDIAN_BIG,
315+ .val_format_endian = REGMAP_ENDIAN_BIG,
316+ .max_register = CS35L56_DSP1_PMEM_5114,
317+ .reg_defaults = cs35l56_reg_defaults,
318+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
319+ .volatile_reg = cs35l56_volatile_reg,
320+ .readable_reg = cs35l56_readable_reg,
321+ .precious_reg = cs35l56_precious_reg,
322+ .cache_type = REGCACHE_RBTREE,
323+};
324+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED);
325+
326+struct regmap_config cs35l56_regmap_spi = {
327+ .reg_bits = 32,
328+ .val_bits = 32,
329+ .pad_bits = 16,
330+ .reg_stride = 4,
331+ .reg_format_endian = REGMAP_ENDIAN_BIG,
332+ .val_format_endian = REGMAP_ENDIAN_BIG,
333+ .max_register = CS35L56_DSP1_PMEM_5114,
334+ .reg_defaults = cs35l56_reg_defaults,
335+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
336+ .volatile_reg = cs35l56_volatile_reg,
337+ .readable_reg = cs35l56_readable_reg,
338+ .precious_reg = cs35l56_precious_reg,
339+ .cache_type = REGCACHE_RBTREE,
340+};
341+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED);
342+
343+struct regmap_config cs35l56_regmap_sdw = {
344+ .reg_bits = 32,
345+ .val_bits = 32,
346+ .reg_stride = 4,
347+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
348+ .val_format_endian = REGMAP_ENDIAN_BIG,
349+ .max_register = CS35L56_DSP1_PMEM_5114,
350+ .reg_defaults = cs35l56_reg_defaults,
351+ .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
352+ .volatile_reg = cs35l56_volatile_reg,
353+ .readable_reg = cs35l56_readable_reg,
354+ .precious_reg = cs35l56_precious_reg,
355+ .cache_type = REGCACHE_RBTREE,
356+};
357+EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED);
358+
359+MODULE_DESCRIPTION("ASoC CS35L56 Shared");
360+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
361+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
362+MODULE_LICENSE("GPL");
sound/soc/codecs/cs35l56-spi.c+79−0
@@ -0,0 +1,79 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+//
3+// CS35L56 ALSA SoC audio driver SPI binding
4+//
5+// Copyright (C) 2023 Cirrus Logic, Inc. and
6+// Cirrus Logic International Semiconductor Ltd.
7+
8+#include <linux/acpi.h>
9+#include <linux/module.h>
10+#include <linux/moduleparam.h>
11+#include <linux/regmap.h>
12+#include <linux/spi/spi.h>
13+#include <linux/types.h>
14+
15+#include "cs35l56.h"
16+
17+static int cs35l56_spi_probe(struct spi_device *spi)
18+{
19+ const struct regmap_config *regmap_config = &cs35l56_regmap_spi;
20+ struct cs35l56_private *cs35l56;
21+ int ret;
22+
23+ cs35l56 = devm_kzalloc(&spi->dev, sizeof(struct cs35l56_private), GFP_KERNEL);
24+ if (!cs35l56)
25+ return -ENOMEM;
26+
27+ spi_set_drvdata(spi, cs35l56);
28+ cs35l56->regmap = devm_regmap_init_spi(spi, regmap_config);
29+ if (IS_ERR(cs35l56->regmap)) {
30+ ret = PTR_ERR(cs35l56->regmap);
31+ return dev_err_probe(&spi->dev, ret, "Failed to allocate register map\n");
32+ }
33+
34+ cs35l56->dev = &spi->dev;
35+
36+ ret = cs35l56_common_probe(cs35l56);
37+ if (ret != 0)
38+ return ret;
39+
40+ ret = cs35l56_init(cs35l56);
41+ if (ret == 0)
42+ ret = cs35l56_irq_request(cs35l56, spi->irq);
43+ if (ret < 0)
44+ cs35l56_remove(cs35l56);
45+
46+ return ret;
47+}
48+
49+static void cs35l56_spi_remove(struct spi_device *spi)
50+{
51+ struct cs35l56_private *cs35l56 = spi_get_drvdata(spi);
52+
53+ cs35l56_remove(cs35l56);
54+}
55+
56+static const struct spi_device_id cs35l56_id_spi[] = {
57+ { "cs35l56", 0 },
58+ {}
59+};
60+MODULE_DEVICE_TABLE(spi, cs35l56_id_spi);
61+
62+static struct spi_driver cs35l56_spi_driver = {
63+ .driver = {
64+ .name = "cs35l56",
65+ .pm = &cs35l56_pm_ops_i2c_spi,
66+ },
67+ .id_table = cs35l56_id_spi,
68+ .probe = cs35l56_spi_probe,
69+ .remove = cs35l56_spi_remove,
70+};
71+
72+module_spi_driver(cs35l56_spi_driver);
73+
74+MODULE_DESCRIPTION("ASoC CS35L56 SPI driver");
75+MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
76+MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
77+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
78+MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
79+MODULE_LICENSE("GPL");
sound/soc/codecs/cs35l56.c+1601−0
@@ -0,0 +1,1601 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+//
3+// Driver for Cirrus Logic CS35L56 smart amp
4+//
5+// Copyright (C) 2023 Cirrus Logic, Inc. and
6+// Cirrus Logic International Semiconductor Ltd.
7+
8+#include <linux/acpi.h>
9+#include <linux/completion.h>
10+#include <linux/debugfs.h>
11+#include <linux/delay.h>
12+#include <linux/err.h>
13+#include <linux/gpio/consumer.h>
14+#include <linux/interrupt.h>
15+#include <linux/math.h>
16+#include <linux/module.h>
17+#include <linux/pm.h>
18+#include <linux/pm_runtime.h>
19+#include <linux/regmap.h>
20+#include <linux/regulator/consumer.h>
21+#include <linux/slab.h>
22+#include <linux/soundwire/sdw.h>
23+#include <linux/types.h>
24+#include <linux/workqueue.h>
25+#include <sound/pcm.h>
26+#include <sound/pcm_params.h>
27+#include <sound/soc.h>
28+#include <sound/soc-dapm.h>
29+#include <sound/tlv.h>
30+
31+#include "wm_adsp.h"
32+#include "cs35l56.h"
33+
34+static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
35+ struct snd_kcontrol *kcontrol, int event);
36+
37+static int cs35l56_mbox_send(struct cs35l56_private *cs35l56, unsigned int command)
38+{
39+ unsigned int val;
40+ int ret;
41+
42+ regmap_write(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, command);
43+ ret = regmap_read_poll_timeout(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
44+ val, (val == 0),
45+ CS35L56_MBOX_POLL_US, CS35L56_MBOX_TIMEOUT_US);
46+ if (ret) {
47+ dev_warn(cs35l56->dev, "MBOX command %#x failed: %d\n", command, ret);
48+ return ret;
49+ }
50+
51+ return 0;
52+}
53+
54+static void cs35l56_wait_dsp_ready(struct cs35l56_private *cs35l56)
55+{
56+ /* Wait for patching to complete */
57+ flush_work(&cs35l56->dsp_work);
58+}
59+
60+static int cs35l56_dspwait_get_volsw(struct snd_kcontrol *kcontrol,
61+ struct snd_ctl_elem_value *ucontrol)
62+{
63+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
64+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
65+
66+ cs35l56_wait_dsp_ready(cs35l56);
67+ return snd_soc_get_volsw(kcontrol, ucontrol);
68+}
69+
70+static int cs35l56_dspwait_put_volsw(struct snd_kcontrol *kcontrol,
71+ struct snd_ctl_elem_value *ucontrol)
72+{
73+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
74+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
75+
76+ cs35l56_wait_dsp_ready(cs35l56);
77+ return snd_soc_put_volsw(kcontrol, ucontrol);
78+}
79+
80+static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
81+
82+static const struct snd_kcontrol_new cs35l56_controls[] = {
83+ SOC_SINGLE_EXT("Speaker Switch",
84+ CS35L56_MAIN_RENDER_USER_MUTE, 0, 1, 1,
85+ cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
86+ SOC_SINGLE_S_EXT_TLV("Speaker Volume",
87+ CS35L56_MAIN_RENDER_USER_VOLUME,
88+ 6, -400, 400, 9, 0,
89+ cs35l56_dspwait_get_volsw,
90+ cs35l56_dspwait_put_volsw,
91+ vol_tlv),
92+ SOC_SINGLE_EXT("Posture Number", CS35L56_MAIN_POSTURE_NUMBER,
93+ 0, 255, 0,
94+ cs35l56_dspwait_get_volsw, cs35l56_dspwait_put_volsw),
95+};
96+
97+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx1_enum,
98+ CS35L56_ASP1TX1_INPUT,
99+ 0, CS35L56_ASP_TXn_SRC_MASK,
100+ cs35l56_tx_input_texts,
101+ cs35l56_tx_input_values);
102+
103+static const struct snd_kcontrol_new asp1_tx1_mux =
104+ SOC_DAPM_ENUM("ASP1TX1 SRC", cs35l56_asp1tx1_enum);
105+
106+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx2_enum,
107+ CS35L56_ASP1TX2_INPUT,
108+ 0, CS35L56_ASP_TXn_SRC_MASK,
109+ cs35l56_tx_input_texts,
110+ cs35l56_tx_input_values);
111+
112+static const struct snd_kcontrol_new asp1_tx2_mux =
113+ SOC_DAPM_ENUM("ASP1TX2 SRC", cs35l56_asp1tx2_enum);
114+
115+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx3_enum,
116+ CS35L56_ASP1TX3_INPUT,
117+ 0, CS35L56_ASP_TXn_SRC_MASK,
118+ cs35l56_tx_input_texts,
119+ cs35l56_tx_input_values);
120+
121+static const struct snd_kcontrol_new asp1_tx3_mux =
122+ SOC_DAPM_ENUM("ASP1TX3 SRC", cs35l56_asp1tx3_enum);
123+
124+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_asp1tx4_enum,
125+ CS35L56_ASP1TX4_INPUT,
126+ 0, CS35L56_ASP_TXn_SRC_MASK,
127+ cs35l56_tx_input_texts,
128+ cs35l56_tx_input_values);
129+
130+static const struct snd_kcontrol_new asp1_tx4_mux =
131+ SOC_DAPM_ENUM("ASP1TX4 SRC", cs35l56_asp1tx4_enum);
132+
133+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx1_enum,
134+ CS35L56_SWIRE_DP3_CH1_INPUT,
135+ 0, CS35L56_SWIRETXn_SRC_MASK,
136+ cs35l56_tx_input_texts,
137+ cs35l56_tx_input_values);
138+
139+static const struct snd_kcontrol_new sdw1_tx1_mux =
140+ SOC_DAPM_ENUM("SDW1TX1 SRC", cs35l56_sdw1tx1_enum);
141+
142+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx2_enum,
143+ CS35L56_SWIRE_DP3_CH2_INPUT,
144+ 0, CS35L56_SWIRETXn_SRC_MASK,
145+ cs35l56_tx_input_texts,
146+ cs35l56_tx_input_values);
147+
148+static const struct snd_kcontrol_new sdw1_tx2_mux =
149+ SOC_DAPM_ENUM("SDW1TX2 SRC", cs35l56_sdw1tx2_enum);
150+
151+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx3_enum,
152+ CS35L56_SWIRE_DP3_CH3_INPUT,
153+ 0, CS35L56_SWIRETXn_SRC_MASK,
154+ cs35l56_tx_input_texts,
155+ cs35l56_tx_input_values);
156+
157+static const struct snd_kcontrol_new sdw1_tx3_mux =
158+ SOC_DAPM_ENUM("SDW1TX3 SRC", cs35l56_sdw1tx3_enum);
159+
160+static SOC_VALUE_ENUM_SINGLE_DECL(cs35l56_sdw1tx4_enum,
161+ CS35L56_SWIRE_DP3_CH4_INPUT,
162+ 0, CS35L56_SWIRETXn_SRC_MASK,
163+ cs35l56_tx_input_texts,
164+ cs35l56_tx_input_values);
165+
166+static const struct snd_kcontrol_new sdw1_tx4_mux =
167+ SOC_DAPM_ENUM("SDW1TX4 SRC", cs35l56_sdw1tx4_enum);
168+
169+static int cs35l56_play_event(struct snd_soc_dapm_widget *w,
170+ struct snd_kcontrol *kcontrol, int event)
171+{
172+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
173+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
174+ unsigned int val;
175+ int ret;
176+
177+ dev_dbg(cs35l56->dev, "play: %d\n", event);
178+
179+ switch (event) {
180+ case SND_SOC_DAPM_PRE_PMU:
181+ /* Don't wait for ACK, we check in POST_PMU that it completed */
182+ return regmap_write(cs35l56->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
183+ CS35L56_MBOX_CMD_AUDIO_PLAY);
184+ case SND_SOC_DAPM_POST_PMU:
185+ /* Wait for firmware to enter PS0 power state */
186+ ret = regmap_read_poll_timeout(cs35l56->regmap,
187+ CS35L56_TRANSDUCER_ACTUAL_PS,
188+ val, (val == CS35L56_PS0),
189+ CS35L56_PS0_POLL_US,
190+ CS35L56_PS0_TIMEOUT_US);
191+ if (ret)
192+ dev_err(cs35l56->dev, "PS0 wait failed: %d\n", ret);
193+ return ret;
194+ case SND_SOC_DAPM_POST_PMD:
195+ return cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_AUDIO_PAUSE);
196+ default:
197+ return 0;
198+ }
199+}
200+
201+static const struct snd_soc_dapm_widget cs35l56_dapm_widgets[] = {
202+ SND_SOC_DAPM_REGULATOR_SUPPLY("VDD_B", 0, 0),
203+ SND_SOC_DAPM_REGULATOR_SUPPLY("VDD_AMP", 0, 0),
204+
205+ SND_SOC_DAPM_SUPPLY("PLAY", SND_SOC_NOPM, 0, 0, cs35l56_play_event,
206+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
207+
208+ SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),
209+ SND_SOC_DAPM_OUTPUT("SPK"),
210+
211+ SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, cs35l56_dsp_event,
212+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
213+
214+ SND_SOC_DAPM_AIF_IN("ASP1RX1", NULL, 0, CS35L56_ASP1_ENABLES1,
215+ CS35L56_ASP_RX1_EN_SHIFT, 0),
216+ SND_SOC_DAPM_AIF_IN("ASP1RX2", NULL, 1, CS35L56_ASP1_ENABLES1,
217+ CS35L56_ASP_RX2_EN_SHIFT, 0),
218+ SND_SOC_DAPM_AIF_OUT("ASP1TX1", NULL, 0, CS35L56_ASP1_ENABLES1,
219+ CS35L56_ASP_TX1_EN_SHIFT, 0),
220+ SND_SOC_DAPM_AIF_OUT("ASP1TX2", NULL, 1, CS35L56_ASP1_ENABLES1,
221+ CS35L56_ASP_TX2_EN_SHIFT, 0),
222+ SND_SOC_DAPM_AIF_OUT("ASP1TX3", NULL, 2, CS35L56_ASP1_ENABLES1,
223+ CS35L56_ASP_TX3_EN_SHIFT, 0),
224+ SND_SOC_DAPM_AIF_OUT("ASP1TX4", NULL, 3, CS35L56_ASP1_ENABLES1,
225+ CS35L56_ASP_TX4_EN_SHIFT, 0),
226+
227+ SND_SOC_DAPM_MUX("ASP1 TX1 Source", SND_SOC_NOPM, 0, 0, &asp1_tx1_mux),
228+ SND_SOC_DAPM_MUX("ASP1 TX2 Source", SND_SOC_NOPM, 0, 0, &asp1_tx2_mux),
229+ SND_SOC_DAPM_MUX("ASP1 TX3 Source", SND_SOC_NOPM, 0, 0, &asp1_tx3_mux),
230+ SND_SOC_DAPM_MUX("ASP1 TX4 Source", SND_SOC_NOPM, 0, 0, &asp1_tx4_mux),
231+
232+ SND_SOC_DAPM_MUX("SDW1 TX1 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx1_mux),
233+ SND_SOC_DAPM_MUX("SDW1 TX2 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx2_mux),
234+ SND_SOC_DAPM_MUX("SDW1 TX3 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx3_mux),
235+ SND_SOC_DAPM_MUX("SDW1 TX4 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx4_mux),
236+
237+ SND_SOC_DAPM_SIGGEN("VMON ADC"),
238+ SND_SOC_DAPM_SIGGEN("IMON ADC"),
239+ SND_SOC_DAPM_SIGGEN("ERRVOL ADC"),
240+ SND_SOC_DAPM_SIGGEN("CLASSH ADC"),
241+ SND_SOC_DAPM_SIGGEN("VDDBMON ADC"),
242+ SND_SOC_DAPM_SIGGEN("VBSTMON ADC"),
243+ SND_SOC_DAPM_SIGGEN("TEMPMON ADC"),
244+};
245+
246+#define CS35L56_SRC_ROUTE(name) \
247+ { name" Source", "ASP1RX1", "ASP1RX1" }, \
248+ { name" Source", "ASP1RX2", "ASP1RX2" }, \
249+ { name" Source", "VMON", "VMON ADC" }, \
250+ { name" Source", "IMON", "IMON ADC" }, \
251+ { name" Source", "ERRVOL", "ERRVOL ADC" }, \
252+ { name" Source", "CLASSH", "CLASSH ADC" }, \
253+ { name" Source", "VDDBMON", "VDDBMON ADC" }, \
254+ { name" Source", "VBSTMON", "VBSTMON ADC" }, \
255+ { name" Source", "DSP1TX1", "DSP1" }, \
256+ { name" Source", "DSP1TX2", "DSP1" }, \
257+ { name" Source", "DSP1TX3", "DSP1" }, \
258+ { name" Source", "DSP1TX4", "DSP1" }, \
259+ { name" Source", "DSP1TX5", "DSP1" }, \
260+ { name" Source", "DSP1TX6", "DSP1" }, \
261+ { name" Source", "DSP1TX7", "DSP1" }, \
262+ { name" Source", "DSP1TX8", "DSP1" }, \
263+ { name" Source", "TEMPMON", "TEMPMON ADC" }, \
264+ { name" Source", "INTERPOLATOR", "AMP" }, \
265+ { name" Source", "SDW1RX1", "SDW1 Playback" }, \
266+ { name" Source", "SDW1RX2", "SDW1 Playback" },
267+
268+static const struct snd_soc_dapm_route cs35l56_audio_map[] = {
269+ { "AMP", NULL, "VDD_B" },
270+ { "AMP", NULL, "VDD_AMP" },
271+
272+ { "ASP1 Playback", NULL, "PLAY" },
273+ { "SDW1 Playback", NULL, "PLAY" },
274+
275+ { "ASP1RX1", NULL, "ASP1 Playback" },
276+ { "ASP1RX2", NULL, "ASP1 Playback" },
277+ { "DSP1", NULL, "ASP1RX1" },
278+ { "DSP1", NULL, "ASP1RX2" },
279+ { "DSP1", NULL, "SDW1 Playback" },
280+ { "AMP", NULL, "DSP1" },
281+ { "SPK", NULL, "AMP" },
282+
283+ CS35L56_SRC_ROUTE("ASP1 TX1")
284+ CS35L56_SRC_ROUTE("ASP1 TX2")
285+ CS35L56_SRC_ROUTE("ASP1 TX3")
286+ CS35L56_SRC_ROUTE("ASP1 TX4")
287+
288+ { "ASP1TX1", NULL, "ASP1 TX1 Source" },
289+ { "ASP1TX2", NULL, "ASP1 TX2 Source" },
290+ { "ASP1TX3", NULL, "ASP1 TX3 Source" },
291+ { "ASP1TX4", NULL, "ASP1 TX4 Source" },
292+ { "ASP1 Capture", NULL, "ASP1TX1" },
293+ { "ASP1 Capture", NULL, "ASP1TX2" },
294+ { "ASP1 Capture", NULL, "ASP1TX3" },
295+ { "ASP1 Capture", NULL, "ASP1TX4" },
296+
297+ CS35L56_SRC_ROUTE("SDW1 TX1")
298+ CS35L56_SRC_ROUTE("SDW1 TX2")
299+ CS35L56_SRC_ROUTE("SDW1 TX3")
300+ CS35L56_SRC_ROUTE("SDW1 TX4")
301+ { "SDW1 Capture", NULL, "SDW1 TX1 Source" },
302+ { "SDW1 Capture", NULL, "SDW1 TX2 Source" },
303+ { "SDW1 Capture", NULL, "SDW1 TX3 Source" },
304+ { "SDW1 Capture", NULL, "SDW1 TX4 Source" },
305+};
306+
307+static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
308+ struct snd_kcontrol *kcontrol, int event)
309+{
310+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
311+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
312+
313+ dev_dbg(cs35l56->dev, "%s: %d\n", __func__, event);
314+
315+ return wm_adsp_event(w, kcontrol, event);
316+}
317+
318+irqreturn_t cs35l56_irq(int irq, void *data)
319+{
320+ struct cs35l56_private *cs35l56 = data;
321+ unsigned int status1 = 0, status8 = 0, status20 = 0;
322+ unsigned int mask1, mask8, mask20;
323+ unsigned int val;
324+ int rv;
325+
326+ irqreturn_t ret = IRQ_NONE;
327+
328+ if (!cs35l56->init_done)
329+ return IRQ_NONE;
330+
331+ mutex_lock(&cs35l56->irq_lock);
332+
333+ rv = pm_runtime_resume_and_get(cs35l56->dev);
334+ if (rv < 0) {
335+ dev_err(cs35l56->dev, "irq: failed to get pm_runtime: %d\n", rv);
336+ goto err_unlock;
337+ }
338+
339+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_STATUS, &val);
340+ if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
341+ dev_dbg(cs35l56->dev, "Spurious IRQ: no pending interrupt\n");
342+ goto err;
343+ }
344+
345+ /* Ack interrupts */
346+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_1, &status1);
347+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_1, &mask1);
348+ status1 &= ~mask1;
349+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_EINT_1, status1);
350+
351+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_8, &status8);
352+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_8, &mask8);
353+ status8 &= ~mask8;
354+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_EINT_8, status8);
355+
356+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_EINT_20, &status20);
357+ regmap_read(cs35l56->regmap, CS35L56_IRQ1_MASK_20, &mask20);
358+ status20 &= ~mask20;
359+ /* We don't want EINT20 but they default to unmasked: force mask */
360+ regmap_write(cs35l56->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
361+
362+ dev_dbg(cs35l56->dev, "%s: %#x %#x\n", __func__, status1, status8);
363+
364+ /* Check to see if unmasked bits are active */
365+ if (!status1 && !status8 && !status20)
366+ goto err;
367+
368+ if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
369+ dev_crit(cs35l56->dev, "Amp short error\n");
370+
371+ if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
372+ dev_crit(cs35l56->dev, "Overtemp error\n");
373+
374+ ret = IRQ_HANDLED;
375+
376+err:
377+ pm_runtime_put(cs35l56->dev);
378+err_unlock:
379+ mutex_unlock(&cs35l56->irq_lock);
380+
381+ return ret;
382+}
383+EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_CORE);
384+
385+int cs35l56_irq_request(struct cs35l56_private *cs35l56, int irq)
386+{
387+ int ret;
388+
389+ if (!irq)
390+ return 0;
391+
392+ ret = devm_request_threaded_irq(cs35l56->dev, irq, NULL, cs35l56_irq,
393+ IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
394+ "cs35l56", cs35l56);
395+ if (!ret)
396+ cs35l56->irq = irq;
397+ else
398+ dev_err(cs35l56->dev, "Failed to get IRQ: %d\n", ret);
399+
400+ return ret;
401+}
402+EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_CORE);
403+
404+static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
405+{
406+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
407+ unsigned int val;
408+
409+ dev_dbg(cs35l56->dev, "%s: %#x\n", __func__, fmt);
410+
411+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
412+ case SND_SOC_DAIFMT_CBC_CFC:
413+ break;
414+ default:
415+ dev_err(cs35l56->dev, "Unsupported clock source mode\n");
416+ return -EINVAL;
417+ }
418+
419+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
420+ case SND_SOC_DAIFMT_DSP_A:
421+ val = CS35L56_ASP_FMT_DSP_A << CS35L56_ASP_FMT_SHIFT;
422+ cs35l56->tdm_mode = true;
423+ break;
424+ case SND_SOC_DAIFMT_I2S:
425+ val = CS35L56_ASP_FMT_I2S << CS35L56_ASP_FMT_SHIFT;
426+ cs35l56->tdm_mode = false;
427+ break;
428+ default:
429+ dev_err(cs35l56->dev, "Unsupported DAI format\n");
430+ return -EINVAL;
431+ }
432+
433+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
434+ case SND_SOC_DAIFMT_NB_IF:
435+ val |= CS35L56_ASP_FSYNC_INV_MASK;
436+ break;
437+ case SND_SOC_DAIFMT_IB_NF:
438+ val |= CS35L56_ASP_BCLK_INV_MASK;
439+ break;
440+ case SND_SOC_DAIFMT_IB_IF:
441+ val |= CS35L56_ASP_BCLK_INV_MASK | CS35L56_ASP_FSYNC_INV_MASK;
442+ break;
443+ case SND_SOC_DAIFMT_NB_NF:
444+ break;
445+ default:
446+ dev_err(cs35l56->dev, "Invalid clock invert\n");
447+ return -EINVAL;
448+ }
449+
450+ regmap_update_bits(cs35l56->regmap,
451+ CS35L56_ASP1_CONTROL2,
452+ CS35L56_ASP_FMT_MASK |
453+ CS35L56_ASP_BCLK_INV_MASK | CS35L56_ASP_FSYNC_INV_MASK,
454+ val);
455+
456+ /* Hi-Z DOUT in unused slots and when all TX are disabled */
457+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL3,
458+ CS35L56_ASP1_DOUT_HIZ_CTRL_MASK,
459+ CS35L56_ASP_UNUSED_HIZ_OFF_HIZ);
460+
461+ return 0;
462+}
463+
464+static void cs35l56_set_asp_slot_positions(struct cs35l56_private *cs35l56,
465+ unsigned int reg, unsigned long mask)
466+{
467+ unsigned int reg_val, channel_shift;
468+ int bit_num;
469+
470+ /* Init all slots to 63 */
471+ switch (reg) {
472+ case CS35L56_ASP1_FRAME_CONTROL1:
473+ reg_val = 0x3f3f3f3f;
474+ break;
475+ case CS35L56_ASP1_FRAME_CONTROL5:
476+ reg_val = 0x3f3f3f;
477+ break;
478+ }
479+
480+ /* Enable consecutive TX1..TXn for each of the slots set in mask */
481+ channel_shift = 0;
482+ for_each_set_bit(bit_num, &mask, 32) {
483+ reg_val &= ~(0x3f << channel_shift);
484+ reg_val |= bit_num << channel_shift;
485+ channel_shift += 8;
486+ }
487+
488+ regmap_write(cs35l56->regmap, reg, reg_val);
489+}
490+
491+static int cs35l56_asp_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
492+ unsigned int rx_mask, int slots, int slot_width)
493+{
494+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
495+
496+ if ((slots == 0) || (slot_width == 0)) {
497+ dev_dbg(cs35l56->dev, "tdm config cleared\n");
498+ cs35l56->asp_slot_width = 0;
499+ cs35l56->asp_slot_count = 0;
500+ return 0;
501+ }
502+
503+ if (slot_width > (CS35L56_ASP_RX_WIDTH_MASK >> CS35L56_ASP_RX_WIDTH_SHIFT)) {
504+ dev_err(cs35l56->dev, "tdm invalid slot width %d\n", slot_width);
505+ return -EINVAL;
506+ }
507+
508+ /* More than 32 slots would give an unsupportable BCLK frequency */
509+ if (slots > 32) {
510+ dev_err(cs35l56->dev, "tdm invalid slot count %d\n", slots);
511+ return -EINVAL;
512+ }
513+
514+ cs35l56->asp_slot_width = (u8)slot_width;
515+ cs35l56->asp_slot_count = (u8)slots;
516+
517+ // Note: rx/tx is from point of view of the CPU end
518+ if (tx_mask == 0)
519+ tx_mask = 0x3; // ASPRX1/RX2 in slots 0 and 1
520+
521+ if (rx_mask == 0)
522+ rx_mask = 0xf; // ASPTX1..TX4 in slots 0..3
523+
524+ cs35l56_set_asp_slot_positions(cs35l56, CS35L56_ASP1_FRAME_CONTROL1, rx_mask);
525+ cs35l56_set_asp_slot_positions(cs35l56, CS35L56_ASP1_FRAME_CONTROL5, tx_mask);
526+
527+ dev_dbg(cs35l56->dev, "tdm slot width: %u count: %u tx_mask: %#x rx_mask: %#x\n",
528+ cs35l56->asp_slot_width, cs35l56->asp_slot_count, tx_mask, rx_mask);
529+
530+ return 0;
531+}
532+
533+static int cs35l56_asp_dai_hw_params(struct snd_pcm_substream *substream,
534+ struct snd_pcm_hw_params *params,
535+ struct snd_soc_dai *dai)
536+{
537+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
538+ unsigned int rate = params_rate(params);
539+ u8 asp_width, asp_wl;
540+
541+ asp_wl = params_width(params);
542+ if (cs35l56->asp_slot_width)
543+ asp_width = cs35l56->asp_slot_width;
544+ else
545+ asp_width = asp_wl;
546+
547+ dev_dbg(cs35l56->dev, "%s: wl=%d, width=%d, rate=%d", __func__, asp_wl, asp_width, rate);
548+
549+ if (!cs35l56->sysclk_set) {
550+ unsigned int slots = cs35l56->asp_slot_count;
551+ unsigned int bclk_freq;
552+ int freq_id;
553+
554+ if (slots == 0) {
555+ slots = params_channels(params);
556+
557+ /* I2S always has an even number of slots */
558+ if (!cs35l56->tdm_mode)
559+ slots = round_up(slots, 2);
560+ }
561+
562+ bclk_freq = asp_width * slots * rate;
563+ freq_id = cs35l56_get_bclk_freq_id(bclk_freq);
564+ if (freq_id < 0) {
565+ dev_err(cs35l56->dev, "%s: Invalid BCLK %u\n", __func__, bclk_freq);
566+ return -EINVAL;
567+ }
568+
569+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL1,
570+ CS35L56_ASP_BCLK_FREQ_MASK,
571+ freq_id << CS35L56_ASP_BCLK_FREQ_SHIFT);
572+ }
573+
574+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
575+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL2,
576+ CS35L56_ASP_RX_WIDTH_MASK, asp_width <<
577+ CS35L56_ASP_RX_WIDTH_SHIFT);
578+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_DATA_CONTROL5,
579+ CS35L56_ASP_RX_WL_MASK, asp_wl);
580+ } else {
581+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL2,
582+ CS35L56_ASP_TX_WIDTH_MASK, asp_width <<
583+ CS35L56_ASP_TX_WIDTH_SHIFT);
584+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_DATA_CONTROL1,
585+ CS35L56_ASP_TX_WL_MASK, asp_wl);
586+ }
587+
588+ return 0;
589+}
590+
591+static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai,
592+ int clk_id, unsigned int freq, int dir)
593+{
594+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
595+ int freq_id;
596+
597+ if (freq == 0) {
598+ cs35l56->sysclk_set = false;
599+ return 0;
600+ }
601+
602+ freq_id = cs35l56_get_bclk_freq_id(freq);
603+ if (freq_id < 0)
604+ return freq_id;
605+
606+ regmap_update_bits(cs35l56->regmap, CS35L56_ASP1_CONTROL1,
607+ CS35L56_ASP_BCLK_FREQ_MASK,
608+ freq_id << CS35L56_ASP_BCLK_FREQ_SHIFT);
609+ cs35l56->sysclk_set = true;
610+
611+ return 0;
612+}
613+
614+static const struct snd_soc_dai_ops cs35l56_ops = {
615+ .set_fmt = cs35l56_asp_dai_set_fmt,
616+ .set_tdm_slot = cs35l56_asp_dai_set_tdm_slot,
617+ .hw_params = cs35l56_asp_dai_hw_params,
618+ .set_sysclk = cs35l56_asp_dai_set_sysclk,
619+};
620+
621+static void cs35l56_sdw_dai_shutdown(struct snd_pcm_substream *substream,
622+ struct snd_soc_dai *dai)
623+{
624+ snd_soc_dai_set_dma_data(dai, substream, NULL);
625+}
626+
627+static int cs35l56_sdw_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
628+ unsigned int rx_mask, int slots, int slot_width)
629+{
630+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
631+
632+ /* rx/tx are from point of view of the CPU end so opposite to our rx/tx */
633+ cs35l56->rx_mask = tx_mask;
634+ cs35l56->tx_mask = rx_mask;
635+
636+ return 0;
637+}
638+
639+static int cs35l56_sdw_dai_hw_params(struct snd_pcm_substream *substream,
640+ struct snd_pcm_hw_params *params,
641+ struct snd_soc_dai *dai)
642+{
643+ struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
644+ struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
645+ struct sdw_stream_config sconfig;
646+ struct sdw_port_config pconfig;
647+ int ret;
648+
649+ dev_dbg(cs35l56->dev, "%s: rate %d\n", __func__, params_rate(params));
650+
651+ if (!cs35l56->init_done)
652+ return -ENODEV;
653+
654+ if (!sdw_stream)
655+ return -EINVAL;
656+
657+ memset(&sconfig, 0, sizeof(sconfig));
658+ memset(&pconfig, 0, sizeof(pconfig));
659+
660+ sconfig.frame_rate = params_rate(params);
661+ sconfig.bps = snd_pcm_format_width(params_format(params));
662+
663+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
664+ sconfig.direction = SDW_DATA_DIR_RX;
665+ pconfig.num = CS35L56_SDW1_PLAYBACK_PORT;
666+ pconfig.ch_mask = cs35l56->rx_mask;
667+ } else {
668+ sconfig.direction = SDW_DATA_DIR_TX;
669+ pconfig.num = CS35L56_SDW1_CAPTURE_PORT;
670+ pconfig.ch_mask = cs35l56->tx_mask;

931 more lines aren’t shown here.

sound/soc/codecs/cs35l56.h+81−0

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

sound/soc/codecs/cs4271-i2c.c+0−1

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

sound/soc/codecs/cs4271-spi.c+0−1

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

sound/soc/codecs/cs4271.c+2−2

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

sound/soc/codecs/cs42l42-sdw.c+0−3

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

sound/soc/codecs/cs47l15.c+2−4

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

sound/soc/codecs/cs47l24.c+2−4

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

sound/soc/codecs/cs47l35.c+2−4

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

sound/soc/codecs/cs47l85.c+2−4

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

sound/soc/codecs/cs47l90.c+2−4

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

sound/soc/codecs/cs47l92.c+2−4

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

sound/soc/codecs/da7218.c+3−7

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

sound/soc/codecs/da7219-aad.c+29−31

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

sound/soc/codecs/da7219-aad.h+2−3

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

sound/soc/codecs/es8316.c+18−15

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

sound/soc/codecs/inno_rk3036.c+2−4

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

sound/soc/codecs/lpass-macro-common.c+1−1

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

sound/soc/codecs/lpass-macro-common.h+3−0

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

sound/soc/codecs/lpass-rx-macro.c+30−12

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

sound/soc/codecs/lpass-tx-macro.c+29−12

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

sound/soc/codecs/lpass-va-macro.c+2−4

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

sound/soc/codecs/lpass-wsa-macro.c+31−12

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

sound/soc/codecs/max98363.c+464−0

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

sound/soc/codecs/max98363.h+36−0

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

sound/soc/codecs/max98373-sdw.c+7−27

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

sound/soc/codecs/max9867.c+17−2

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

sound/soc/codecs/msm8916-wcd-analog.c+2−4

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

sound/soc/codecs/msm8916-wcd-digital.c+2−4

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

sound/soc/codecs/mt6358.c+1−1

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

sound/soc/codecs/mt6359.c+1−1

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

sound/soc/codecs/nau8821.c+96−0

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

sound/soc/codecs/nau8821.h+23−0

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

sound/soc/codecs/nau8825.c+7−1

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

sound/soc/codecs/nau8825.h+1−0

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

sound/soc/codecs/pcm179x-spi.c+1−1

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

sound/soc/codecs/rk817_codec.c+2−4

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

sound/soc/codecs/rt1019.c+1−1

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

sound/soc/codecs/rt1308-sdw.c+7−23

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

sound/soc/codecs/rt1308-sdw.h+0−4

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

sound/soc/codecs/rt1316-sdw.c+7−23

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

sound/soc/codecs/rt1316-sdw.h+0−4

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

sound/soc/codecs/rt1318-sdw.c+7−23

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

sound/soc/codecs/rt1318-sdw.h+0−4

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

sound/soc/codecs/rt5682-sdw.c+7−27

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

sound/soc/codecs/rt700.c+7−23

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

sound/soc/codecs/rt700.h+0−4

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

sound/soc/codecs/rt711-sdca.c+7−23

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

sound/soc/codecs/rt711-sdca.h+0−4

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

sound/soc/codecs/rt711.c+7−23

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

sound/soc/codecs/rt711.h+0−4

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

sound/soc/codecs/rt712-sdca-dmic.c+983−0

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

sound/soc/codecs/rt712-sdca-dmic.h+108−0

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

sound/soc/codecs/rt712-sdca.c+7−23

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

sound/soc/codecs/rt712-sdca.h+0−4

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

sound/soc/codecs/rt715-sdca.c+7−23

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

sound/soc/codecs/rt715-sdca.h+0−4

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

sound/soc/codecs/rt715.c+7−23

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

sound/soc/codecs/rt715.h+0−4

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

sound/soc/codecs/sdw-mockup.c+6−28

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

sound/soc/codecs/sma1303.c+1−1

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

sound/soc/codecs/src4xxx-i2c.c+1−1

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

sound/soc/codecs/ssm2602.c+12−3

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

sound/soc/codecs/sta32x.c+18−21

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

sound/soc/codecs/sta350.c+28−35

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

sound/soc/codecs/tas5086.c+1−1

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

sound/soc/codecs/tas571x.c+59−0

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

sound/soc/codecs/tas5720.c+2−1

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

sound/soc/codecs/wcd9335.c+11−16

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

sound/soc/codecs/wcd934x.c+10−15

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

sound/soc/codecs/wcd938x.c+12−21

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

sound/soc/codecs/wm5102.c+2−4

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

sound/soc/codecs/wm5110.c+2−4

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

sound/soc/codecs/wm8903.c+0−1

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

sound/soc/codecs/wm8994.c+2−4

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

sound/soc/codecs/wm8997.c+2−4

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

sound/soc/codecs/wm8998.c+2−4

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

sound/soc/codecs/wm_adsp.c+48−15

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

sound/soc/codecs/wm_adsp.h+3−0

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

sound/soc/codecs/zl38060.c+1−1

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

sound/soc/dwc/dwc-i2s.c+2−3

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

sound/soc/fsl/Kconfig+9−0

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

sound/soc/fsl/Makefile+2−0

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

sound/soc/fsl/eukrea-tlv320.c+2−4

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

sound/soc/fsl/fsl-asoc-card.c+6−3

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

sound/soc/fsl/fsl_asrc.c+2−4

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

sound/soc/fsl/fsl_aud2htx.c+2−4

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

sound/soc/fsl/fsl_audmix.c+2−4

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

sound/soc/fsl/fsl_dma.c+2−4

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

sound/soc/fsl/fsl_easrc.c+2−4

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

sound/soc/fsl/fsl_esai.c+2−4

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

sound/soc/fsl/fsl_mqs.c+7−13

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

sound/soc/fsl/fsl_qmc_audio.c+735−0

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

sound/soc/fsl/fsl_rpmsg.c+2−4

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

sound/soc/fsl/fsl_sai.c+8−10

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

sound/soc/fsl/fsl_spdif.c+2−4

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

sound/soc/fsl/fsl_ssi.c+3−5

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

sound/soc/fsl/fsl_xcvr.c+2−3

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

sound/soc/fsl/imx-audmix.c+11−11

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

sound/soc/fsl/imx-audmux.c+2−4

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

sound/soc/fsl/imx-card.c+1−1

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

sound/soc/fsl/imx-es8328.c+7−4

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

sound/soc/fsl/imx-pcm-rpmsg.c+2−4

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

sound/soc/fsl/imx-sgtl5000.c+2−4

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

sound/soc/fsl/imx-spdif.c+7−4

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

sound/soc/fsl/mpc5200_psc_ac97.c+2−3

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

sound/soc/fsl/mpc5200_psc_i2s.c+2−3

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

sound/soc/fsl/mpc8610_hpcd.c+2−4

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

sound/soc/fsl/p1022_ds.c+2−4

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

sound/soc/fsl/p1022_rdk.c+2−4

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

sound/soc/fsl/pcm030-audio-fabric.c+2−4

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

sound/soc/generic/audio-graph-card.c+13−2

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

sound/soc/generic/audio-graph-card2-custom-sample.c+3−0

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

sound/soc/generic/audio-graph-card2.c+20−3

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

sound/soc/generic/simple-card-utils.c+22−13

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

sound/soc/generic/simple-card.c+22−1

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

sound/soc/generic/test-component.c+2−4

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

sound/soc/img/img-i2s-in.c+2−4

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

sound/soc/img/img-i2s-out.c+2−4

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

sound/soc/img/img-parallel-out.c+2−4

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

sound/soc/img/img-spdif-in.c+2−4

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

sound/soc/img/img-spdif-out.c+2−4

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

sound/soc/img/pistachio-internal-dac.c+2−4

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

sound/soc/intel/atom/sst-mfld-platform-pcm.c+2−3

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

sound/soc/intel/atom/sst/sst_acpi.c+2−3

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

sound/soc/intel/avs/boards/hdaudio.c+4−6

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

sound/soc/intel/avs/path.c+1−1

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

sound/soc/intel/boards/bytcht_es8316.c+2−3

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

sound/soc/intel/boards/bytcr_rt5640.c+2−3

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

sound/soc/intel/boards/bytcr_rt5651.c+2−3

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

sound/soc/intel/boards/bytcr_wm5102.c+2−3

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

sound/soc/intel/boards/cht_bsw_max98090_ti.c+2−4

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

sound/soc/intel/boards/sof_cirrus_common.c+6−1

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

sound/soc/intel/boards/sof_es8336.c+2−4

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

sound/soc/intel/boards/sof_pcm512x.c+2−4

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

sound/soc/intel/boards/sof_rt5682.c+23−5

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

sound/soc/intel/boards/sof_sdw.c+121−66

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

sound/soc/intel/boards/sof_sdw_common.h+0−3

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

sound/soc/intel/boards/sof_sdw_max98373.c+11−11

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

sound/soc/intel/boards/sof_wm8804.c+2−3

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

sound/soc/intel/catpt/device.c+2−4

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

sound/soc/intel/common/soc-acpi-intel-rpl-match.c+33−1

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

sound/soc/intel/skylake/skl-ssp-clk.c+2−4

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

sound/soc/kirkwood/kirkwood-i2s.c+2−4

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

sound/soc/mediatek/common/mtk-btcvsd.c+2−3

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

sound/soc/mediatek/common/mtk-soundcard-driver.c+9−3

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

sound/soc/mediatek/mt2701/mt2701-afe-pcm.c+2−4

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

sound/soc/mediatek/mt6797/mt6797-afe-pcm.c+2−4

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

sound/soc/mediatek/mt8173/mt8173-afe-pcm.c+2−3

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

sound/soc/mediatek/mt8183/mt8183-afe-pcm.c+2−4

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

sound/soc/mediatek/mt8186/mt8186-afe-gpio.c+14−14

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

sound/soc/mediatek/mt8186/mt8186-dai-adda.c+2−2

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

sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c+1−1

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

sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c+3−3

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

sound/soc/mediatek/mt8188/mt8188-afe-pcm.c+2−4

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

sound/soc/mediatek/mt8192/mt8192-afe-clk.c+0−4

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

sound/soc/mediatek/mt8192/mt8192-afe-pcm.c+3−8

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

sound/soc/mediatek/mt8192/mt8192-dai-tdm.c+13−15

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

sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c+5−7

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

sound/soc/mediatek/mt8195/mt8195-afe-pcm.c+2−3

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

sound/soc/mediatek/mt8195/mt8195-dai-adda.c+11−6

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

sound/soc/mediatek/mt8195/mt8195-dai-etdm.c+154−23

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

sound/soc/mediatek/mt8195/mt8195-dai-pcm.c+20−6

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

sound/soc/mediatek/mt8195/mt8195-mt6359.c+1−1

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

sound/soc/meson/aiu.c+2−4

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

sound/soc/meson/axg-card.c+2−1

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

sound/soc/meson/axg-tdm-interface.c+4−9

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

sound/soc/meson/gx-card.c+2−1

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

sound/soc/meson/meson-codec-glue.c+3−2

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

sound/soc/mxs/mxs-sgtl5000.c+3−5

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

sound/soc/pxa/mmp-sspa.c+3−4

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

sound/soc/pxa/pxa2xx-ac97.c+2−3

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

sound/soc/qcom/common.c+15−2

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

sound/soc/qcom/qdsp6/q6apm-lpass-dais.c+3−0

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

sound/soc/qcom/qdsp6/q6apm.c+1−1

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

sound/soc/qcom/qdsp6/q6routing.c+2−4

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

sound/soc/qcom/sdw.c+2−5

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

sound/soc/rockchip/rockchip_i2s.c+3−4

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

sound/soc/rockchip/rockchip_pdm.c+2−4

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

sound/soc/rockchip/rockchip_rt5645.c+2−4

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

sound/soc/rockchip/rockchip_spdif.c+2−4

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

sound/soc/samsung/aries_wm8994.c+4−2

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

sound/soc/samsung/arndale.c+2−3

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

sound/soc/samsung/bells.c+14−7

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

sound/soc/samsung/i2s.c+4−6

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

sound/soc/samsung/littlemill.c+2−1

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

sound/soc/samsung/lowland.c+2−1

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

sound/soc/samsung/odroid.c+2−4

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

sound/soc/samsung/pcm.c+2−4

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

sound/soc/samsung/snow.c+2−4

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

sound/soc/samsung/spdif.c+2−4

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

sound/soc/samsung/speyside.c+2−1

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

sound/soc/sh/fsi.c+3−5

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

sound/soc/sh/hac.c+2−3

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

sound/soc/sh/rcar/core.c+2−4

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

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

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

sound/soc/sh/rz-ssi.c+46−23

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

sound/soc/sh/siu_dai.c+2−3

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

sound/soc/soc-component.c+6−6

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

sound/soc/soc-compress.c+33−37

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

sound/soc/soc-core.c+25−27

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

sound/soc/soc-dai.c+3−0

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

sound/soc/soc-dapm.c+171−153

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

sound/soc/soc-jack.c+1−0

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

sound/soc/soc-pcm.c+11−26

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

sound/soc/soc-topology.c+7−3

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

sound/soc/sof/amd/acp-common.c+1−16

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

sound/soc/sof/amd/acp-pcm.c+34−0

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

sound/soc/sof/amd/acp.c+29−16

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

sound/soc/sof/amd/acp.h+4−3

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

sound/soc/sof/amd/pci-rmb.c+2−89

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

sound/soc/sof/amd/pci-rn.c+2−89

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

sound/soc/sof/amd/rembrandt.c+0−4

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

sound/soc/sof/amd/renoir.c+0−3

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

sound/soc/sof/compress.c+2−6

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

sound/soc/sof/core.c+26−5

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

sound/soc/sof/debug.c+1−0

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

sound/soc/sof/intel/Kconfig+7−0

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

sound/soc/sof/intel/Makefile+4−1

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

sound/soc/sof/intel/apl.c+4−0

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

sound/soc/sof/intel/cnl.c+4−0

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

sound/soc/sof/intel/hda-common-ops.c+0−1

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

sound/soc/sof/intel/hda-ctrl.c+6−3

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

sound/soc/sof/intel/hda-dai-ops.c+390−0

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

sound/soc/sof/intel/hda-dai.c+180−518

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

sound/soc/sof/intel/hda-dsp.c+66−35

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

sound/soc/sof/intel/hda-ipc.c+3−0

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

sound/soc/sof/intel/hda-loader.c+5−4

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

sound/soc/sof/intel/hda-mlink.c+799−23

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

sound/soc/sof/intel/hda-pcm.c+17−7

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

sound/soc/sof/intel/hda-stream.c+59−34

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

sound/soc/sof/intel/hda.c+118−115

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

sound/soc/sof/intel/hda.h+42−27

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

sound/soc/sof/intel/icl.c+4−0

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

sound/soc/sof/intel/mtl.c+23−3

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

sound/soc/sof/intel/pci-apl.c+2−0

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

sound/soc/sof/intel/pci-cnl.c+3−0

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

sound/soc/sof/intel/pci-icl.c+2−0

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

sound/soc/sof/intel/pci-mtl.c+1−0

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

sound/soc/sof/intel/pci-skl.c+2−0

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

sound/soc/sof/intel/pci-tgl.c+8−0

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

sound/soc/sof/intel/tgl.c+4−0

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

sound/soc/sof/ipc3-control.c+28−62

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

sound/soc/sof/ipc3-dtrace.c+4−8

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

sound/soc/sof/ipc3-pcm.c+3−4

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

sound/soc/sof/ipc3-topology.c+10−23

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

sound/soc/sof/ipc3.c+3−9

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

sound/soc/sof/ipc4-control.c+252−5

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

sound/soc/sof/ipc4-mtrace.c+21−0

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

sound/soc/sof/ipc4-pcm.c+176−10

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

sound/soc/sof/ipc4-topology.c+890−324

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

sound/soc/sof/ipc4-topology.h+77−12

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

sound/soc/sof/loader.c+2−2

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

sound/soc/sof/pcm.c+48−15

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

sound/soc/sof/pm.c+5−0

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

sound/soc/sof/sof-audio.c+75−10

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

sound/soc/sof/sof-audio.h+31−18

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

sound/soc/sof/sof-client-ipc-flood-test.c+1−2

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

sound/soc/sof/sof-client-probes-ipc3.c+4−8

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

sound/soc/sof/sof-client-probes-ipc4.c+2−2

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

sound/soc/sof/sof-client.c+3−0

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

sound/soc/sof/sof-client.h+4−0

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

sound/soc/sof/sof-priv.h+21−0

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

sound/soc/sof/topology.c+218−84

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

sound/soc/sprd/sprd-mcdt.c+2−4

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

sound/soc/stm/stm32_adfsdm.c+2−4

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

sound/soc/stm/stm32_i2s.c+3−5

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

sound/soc/stm/stm32_sai_sub.c+4−6

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

sound/soc/stm/stm32_spdifrx.c+2−4

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

sound/soc/sunxi/sun4i-codec.c+2−4

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

sound/soc/sunxi/sun4i-i2s.c+2−4

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

sound/soc/sunxi/sun4i-spdif.c+2−4

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

sound/soc/sunxi/sun50i-dmic.c+2−4

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

sound/soc/sunxi/sun8i-codec.c+2−4

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

sound/soc/tegra/Kconfig+18−0

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

sound/soc/tegra/tegra186_asrc.c+2−4

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

sound/soc/tegra/tegra186_dspk.c+2−4

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

sound/soc/tegra/tegra20_ac97.c+4−5

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

sound/soc/tegra/tegra20_i2s.c+2−4

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

sound/soc/tegra/tegra210_admaif.c+2−4

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

sound/soc/tegra/tegra210_adx.c+2−4

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

sound/soc/tegra/tegra210_ahub.c+2−4

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

sound/soc/tegra/tegra210_amx.c+2−4

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

sound/soc/tegra/tegra210_dmic.c+2−4

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

sound/soc/tegra/tegra210_i2s.c+2−4

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

sound/soc/tegra/tegra210_mixer.c+2−4

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

sound/soc/tegra/tegra210_mvc.c+2−4

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

sound/soc/tegra/tegra210_ope.c+2−4

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

sound/soc/tegra/tegra210_sfc.c+2−4

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

sound/soc/tegra/tegra30_ahub.c+2−4

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

sound/soc/tegra/tegra30_i2s.c+2−4

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

sound/soc/tegra/tegra_asoc_machine.c+122−5

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

sound/soc/ti/ams-delta.c+2−3

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

sound/soc/ti/davinci-i2s.c+2−4

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

sound/soc/ti/davinci-mcasp.c+2−4

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

sound/soc/ti/omap-hdmi.c+3−7

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

sound/soc/ti/omap-mcbsp.c+2−4

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

sound/soc/uniphier/evea.c+2−4

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

sound/soc/ux500/mop500.c+2−4

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

sound/soc/ux500/ux500_msp_dai.c+2−4

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

sound/soc/xilinx/xlnx_formatter_pcm.c+2−3

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

sound/soc/xilinx/xlnx_spdif.c+2−3

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

sound/soc/xtensa/xtfpga-i2s.c+2−3

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

sound/sparc/cs4231.c+2−4

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

sound/sparc/dbri.c+2−4

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

sound/usb/card.c+0−1

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

sound/usb/endpoint.c+4−17

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

sound/usb/helper.c+0−1

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

sound/usb/usbaudio.h+2−0

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

tools/testing/selftests/alsa/mixer-test.c+59−7

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

tools/testing/selftests/alsa/pcm-test.c+17−6

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