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
7title: PowerQUICC CPM QUICC Multichannel Controller (QMC)
8
9maintainers:
10 - Herve Codina <herve.codina@bootlin.com>
11
12description:
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
16properties:
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
62patternProperties:
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
108required:
109 - compatible
110 - reg
111 - reg-names
112 - interrupts
113 - fsl,tsa-serial
114 - '#address-cells'
115 - '#size-cells'
116
117additionalProperties: false
118
119examples:
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
7title: PowerQUICC CPM Time-slot assigner (TSA) controller
8
9maintainers:
10 - Herve Codina <herve.codina@bootlin.com>
11
12description:
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
17properties:
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
41patternProperties:
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
163required:
164 - compatible
165 - reg
166 - reg-names
167 - '#address-cells'
168 - '#size-cells'
169
170additionalProperties: false
171
172examples:
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
32 maxItems: 132 maxItems: 1
33 33
34 clock-names:34 clock-names:
35 const: "mclk"35 const: mclk
36 36
37 powerdown-gpios:37 powerdown-gpios:
38 description: GPIO used for hardware power-down.38 description: GPIO used for hardware power-down.
Documentation/devicetree/bindings/sound/adi,adau17x1.txt+0−32
@@ -1,32 +0,0 @@
1Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781
2
3Required properties:
4
5 - compatible: Should contain one of the following:
6 "adi,adau1361"
7 "adi,adau1461"
8 "adi,adau1761"
9 "adi,adau1961"
10 "adi,adau1381"
11 "adi,adau1781"
12
13 - reg: The i2c address. Value depends on the state of ADDR0
14 and ADDR1, as wired in hardware.
15
16Optional 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
21Examples:
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
7title: Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781 Codec
8
9maintainers:
10 - Lars-Peter Clausen <lars@metafoo.de>
11
12properties:
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
35required:
36 - compatible
37 - reg
38
39additionalProperties: false
40
41examples:
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
7title: Analog Devices MAX98363 SoundWire Amplifier
8
9maintainers:
10 - Ryan Lee <ryans.lee@analog.com>
11
12description:
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
20allOf:
21 - $ref: dai-common.yaml#
22
23properties:
24 compatible:
25 const: sdw3019f836300
26
27 reg:
28 maxItems: 1
29
30 '#sound-dai-cells':
31 const: 0
32
33required:
34 - compatible
35 - reg
36 - "#sound-dai-cells"
37
38unevaluatedProperties: false
39
40examples:
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
41 41
42 adi,vmon-slot-no:42 adi,vmon-slot-no:
43 description: slot number of the voltage sense monitor43 description: slot number of the voltage sense monitor
44 $ref: "/schemas/types.yaml#/definitions/uint32"44 $ref: /schemas/types.yaml#/definitions/uint32
45 minimum: 045 minimum: 0
46 maximum: 1546 maximum: 15
47 default: 047 default: 0
48 48
49 adi,imon-slot-no:49 adi,imon-slot-no:
50 description: slot number of the current sense monitor50 description: slot number of the current sense monitor
51 $ref: "/schemas/types.yaml#/definitions/uint32"51 $ref: /schemas/types.yaml#/definitions/uint32
52 minimum: 052 minimum: 0
53 maximum: 1553 maximum: 15
54 default: 154 default: 1
55 55
56 adi,spkfb-slot-no:56 adi,spkfb-slot-no:
57 description: slot number of speaker DSP monitor57 description: slot number of speaker DSP monitor
58 $ref: "/schemas/types.yaml#/definitions/uint32"58 $ref: /schemas/types.yaml#/definitions/uint32
59 minimum: 059 minimum: 0
60 maximum: 1560 maximum: 15
61 default: 261 default: 2
@@ -64,7 +64,7 @@ properties: · 2 unmodified lines
64 description:64 description:
65 Selects the PCM data input channel that is routed to the speaker65 Selects the PCM data input channel that is routed to the speaker
66 audio processing bypass path.66 audio processing bypass path.
67 $ref: "/schemas/types.yaml#/definitions/uint32"67 $ref: /schemas/types.yaml#/definitions/uint32
68 minimum: 068 minimum: 0
69 maximum: 1569 maximum: 15
70 default: 070 default: 0
Documentation/devicetree/bindings/sound/ak4458.txt+0−28
@@ -1,28 +0,0 @@
1AK4458 audio DAC
2
3This device supports I2C mode.
4
5Required properties:
6
7- compatible : "asahi-kasei,ak4458" or "asahi-kasei,ak4497"
8- reg : The I2C address of the device for I2C
9
10Optional 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
19Example:
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 @@
1AK5558 8 channel differential 32-bit delta-sigma ADC
2
3This device supports I2C mode only.
4
5Required properties:
6
7- compatible : "asahi-kasei,ak5558" or "asahi-kasei,ak5552".
8- reg : The I2C address of the device.
9
10Optional 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
16Example:
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 @@
1ALC5632 audio CODEC
2
3This device supports I2C only.
4
5Required 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
16Pins 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
35Example:
36
37alc5632: 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
7title: AK4458 audio DAC
8
9maintainers:
10 - Shengjiu Wang <shengjiu.wang@nxp.com>
11
12properties:
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
44required:
45 - compatible
46 - reg
47
48allOf:
49 - if:
50 properties:
51 compatible:
52 contains:
53 const: asahi-kasei,ak4458
54
55 then:
56 properties:
57 dsd-path: false
58
59additionalProperties: false
60
61examples:
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
7title: AK5558 8 channel differential 32-bit delta-sigma ADC
8
9maintainers:
10 - Junichi Wakasugi <wakasugi.jb@om.asahi-kasei.co.jp>
11 - Mihai Serban <mihai.serban@nxp.com>
12
13properties:
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
31required:
32 - compatible
33 - reg
34
35additionalProperties: false
36
37examples:
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
16 $ref: /schemas/graph.yaml#/$defs/port-base16 $ref: /schemas/graph.yaml#/$defs/port-base
17 properties:17 properties:
18 convert-rate:18 convert-rate:
19 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"19 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
20 convert-channels:20 convert-channels:
21 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"21 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
22 convert-sample-format:22 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
24 mclk-fs:24 mclk-fs:
25 $ref: "simple-card.yaml#/definitions/mclk-fs"25 $ref: simple-card.yaml#/definitions/mclk-fs
26 26
27 endpoint-base:27 endpoint-base:
28 $ref: /schemas/graph.yaml#/$defs/endpoint-base28 $ref: /schemas/graph.yaml#/$defs/endpoint-base
29 properties:29 properties:
30 mclk-fs:30 mclk-fs:
31 $ref: "simple-card.yaml#/definitions/mclk-fs"31 $ref: simple-card.yaml#/definitions/mclk-fs
32 frame-inversion:32 frame-inversion:
33 description: dai-link uses frame clock inversion33 description: dai-link uses frame clock inversion
34 $ref: /schemas/types.yaml#/definitions/flag34 $ref: /schemas/types.yaml#/definitions/flag
@@ -49,11 +49,11 @@ definitions: · 14 unmodified lines
49 description: Indicates system clock49 description: Indicates system clock
50 $ref: /schemas/types.yaml#/definitions/phandle50 $ref: /schemas/types.yaml#/definitions/phandle
51 system-clock-frequency:51 system-clock-frequency:
52 $ref: "simple-card.yaml#/definitions/system-clock-frequency"52 $ref: simple-card.yaml#/definitions/system-clock-frequency
53 system-clock-direction-out:53 system-clock-direction-out:
54 $ref: "simple-card.yaml#/definitions/system-clock-direction-out"54 $ref: simple-card.yaml#/definitions/system-clock-direction-out
55 system-clock-fixed:55 system-clock-fixed:
56 $ref: "simple-card.yaml#/definitions/system-clock-fixed"56 $ref: simple-card.yaml#/definitions/system-clock-fixed
57 57
58 dai-format:58 dai-format:
59 description: audio format.59 description: audio format.
@@ -69,11 +69,11 @@ definitions: · 9 unmodified lines
69 - msb69 - msb
70 - lsb70 - lsb
71 convert-rate:71 convert-rate:
72 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"72 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
73 convert-channels:73 convert-channels:
74 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"74 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
75 convert-sample-format:75 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
77 77
78 dai-tdm-slot-num:78 dai-tdm-slot-num:
79 description: Number of slots in use.79 description: Number of slots in use.
Documentation/devicetree/bindings/sound/audio-graph.yaml+4−4
@@ -15,7 +15,7 @@ properties: · 14 unmodified lines
15 label:15 label:
16 maxItems: 116 maxItems: 1
17 prefix:17 prefix:
18 description: "device name prefix"18 description: device name prefix
19 $ref: /schemas/types.yaml#/definitions/string19 $ref: /schemas/types.yaml#/definitions/string
20 routing:20 routing:
21 description: |21 description: |
@@ -27,11 +27,11 @@ properties: · 5 unmodified lines
27 description: User specified audio sound widgets.27 description: User specified audio sound widgets.
28 $ref: /schemas/types.yaml#/definitions/non-unique-string-array28 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
29 convert-rate:29 convert-rate:
30 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"30 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-sample-rate
31 convert-channels:31 convert-channels:
32 $ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"32 $ref: /schemas/sound/dai-params.yaml#/$defs/dai-channels
33 convert-sample-format:33 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
35 35
36 pa-gpios:36 pa-gpios:
37 maxItems: 137 maxItems: 1
Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml+9−1
@@ -85,11 +85,19 @@ properties: · 84 unmodified lines
85 boost-cap-microfarad.85 boost-cap-microfarad.
86 External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to86 External Boost must have GPIO1 as GPIO output. GPIO1 will be set high to
87 enable boost voltage.87 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.
88 0 = Internal Boost94 0 = Internal Boost
89 1 = External Boost95 1 = External Boost
96 2 = Shared Boost Active
97 3 = Shared Boost Passive
90 $ref: /schemas/types.yaml#/definitions/uint3298 $ref: /schemas/types.yaml#/definitions/uint32
91 minimum: 099 minimum: 0
92 maximum: 1100 maximum: 3
93 101
94 cirrus,gpio1-polarity-invert:102 cirrus,gpio1-polarity-invert:
95 description:103 description:
Documentation/devicetree/bindings/sound/cirrus,cs35l45.yaml+79−1
@@ -45,11 +45,79 @@ properties: · 44 unmodified lines
45 Audio serial port SDOUT Hi-Z control. Sets the Hi-Z45 Audio serial port SDOUT Hi-Z control. Sets the Hi-Z
46 configuration for SDOUT pin of amplifier. Logical OR of46 configuration for SDOUT pin of amplifier. Logical OR of
47 CS35L45_ASP_TX_HIZ_xxx values.47 CS35L45_ASP_TX_HIZ_xxx values.
48 $ref: "/schemas/types.yaml#/definitions/uint32"48 $ref: /schemas/types.yaml#/definitions/uint32
49 minimum: 049 minimum: 0
50 maximum: 350 maximum: 3
51 default: 251 default: 2
52 52
53patternProperties:
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
53required:121required:
54 - compatible122 - compatible
55 - reg123 - reg
@@ -74,5 +142,15 @@ examples: · 18 unmodified lines
74 reset-gpios = <&gpio 110 0>;142 reset-gpios = <&gpio 110 0>;
75 cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |143 cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
76 CS35L45_ASP_TX_HIZ_DISABLED)>;144 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 };
77 };155 };
78 };156 };
Documentation/devicetree/bindings/sound/cirrus,cs42l42.yaml+6−6
@@ -68,7 +68,7 @@ properties: · 67 unmodified lines
68 This is "normal tip sense (TS)" in the datasheet.68 This is "normal tip sense (TS)" in the datasheet.
69 69
70 The CS42L42_TS_INV_* defines are available for this.70 The CS42L42_TS_INV_* defines are available for this.
71 $ref: "/schemas/types.yaml#/definitions/uint32"71 $ref: /schemas/types.yaml#/definitions/uint32
72 minimum: 072 minimum: 0
73 maximum: 173 maximum: 1
74 74
@@ -87,7 +87,7 @@ properties: · 12 unmodified lines
87 7 - 1.5s87 7 - 1.5s
88 88
89 The CS42L42_TS_DBNCE_* defines are available for this.89 The CS42L42_TS_DBNCE_* defines are available for this.
90 $ref: "/schemas/types.yaml#/definitions/uint32"90 $ref: /schemas/types.yaml#/definitions/uint32
91 minimum: 091 minimum: 0
92 maximum: 792 maximum: 7
93 93
@@ -106,7 +106,7 @@ properties: · 12 unmodified lines
106 7 - 1.5s106 7 - 1.5s
107 107
108 The CS42L42_TS_DBNCE_* defines are available for this.108 The CS42L42_TS_DBNCE_* defines are available for this.
109 $ref: "/schemas/types.yaml#/definitions/uint32"109 $ref: /schemas/types.yaml#/definitions/uint32
110 minimum: 0110 minimum: 0
111 maximum: 7111 maximum: 7
112 112
@@ -120,7 +120,7 @@ properties: · 7 unmodified lines
120 120
121 0ms - 200ms,121 0ms - 200ms,
122 Default = 100ms122 Default = 100ms
123 $ref: "/schemas/types.yaml#/definitions/uint32"123 $ref: /schemas/types.yaml#/definitions/uint32
124 minimum: 0124 minimum: 0
125 maximum: 200125 maximum: 200
126 126
@@ -133,7 +133,7 @@ properties: · 6 unmodified lines
133 133
134 0ms - 20ms,134 0ms - 20ms,
135 Default = 10ms135 Default = 10ms
136 $ref: "/schemas/types.yaml#/definitions/uint32"136 $ref: /schemas/types.yaml#/definitions/uint32
137 minimum: 0137 minimum: 0
138 maximum: 20138 maximum: 20
139 139
@@ -169,7 +169,7 @@ properties: · 29 unmodified lines
169 3 - Slowest169 3 - Slowest
170 170
171 The CS42L42_HSBIAS_RAMP_* defines are available for this.171 The CS42L42_HSBIAS_RAMP_* defines are available for this.
172 $ref: "/schemas/types.yaml#/definitions/uint32"172 $ref: /schemas/types.yaml#/definitions/uint32
173 minimum: 0173 minimum: 0
174 maximum: 3174 maximum: 3
175 175
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
7title: Cirrus EP93xx I2S Controller
8
9description: |
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
14maintainers:
15 - Alexander Sverdlin <alexander.sverdlin@gmail.com>
16
17allOf:
18 - $ref: dai-common.yaml#
19
20properties:
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
43required:
44 - compatible
45 - '#sound-dai-cells'
46 - reg
47 - clocks
48 - clock-names
49
50additionalProperties: false
51
52examples:
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
28 items:28 items:
29 - const: mclk29 - const: mclk
30 30
31 port:
32 $ref: audio-graph-port.yaml#
33 unevaluatedProperties: false
34
31 "#sound-dai-cells":35 "#sound-dai-cells":
32 const: 036 const: 0
33 37
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
7title: QMC audio
8
9maintainers:
10 - Herve Codina <herve.codina@bootlin.com>
11
12description: |
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
17allOf:
18 - $ref: dai-common.yaml#
19
20properties:
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
31patternProperties:
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
58required:
59 - compatible
60 - '#address-cells'
61 - '#size-cells'
62 - '#sound-dai-cells'
63
64additionalProperties: false
65
66examples:
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 @@
1max98371 codec
2
3This device supports I2C mode only.
4
5Required properties:
6
7- compatible : "maxim,max98371"
8- reg : The chip select number on the I2C bus
9
10Example:
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 @@
1max9867 codec
2
3This device supports I2C mode only.
4
5Required properties:
6
7- compatible : "maxim,max9867"
8- reg : The chip select number on the I2C bus
9
10Example:
11
12&i2c {
13 max9867: max9867@18 {
14 compatible = "maxim,max9867";
15 reg = <0x18>;
16 };
17};
Documentation/devicetree/bindings/sound/maxim,max9759.txt+0−18
@@ -1,18 +0,0 @@
1Maxim MAX9759 Speaker Amplifier
2===============================
3
4Required 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
10Example:
11
12max9759: 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
7title: Maxim MAX9759 Speaker Amplifier
8
9maintainers:
10 - Otabek Nazrullaev <otabeknazrullaev1998@gmail.com>
11
12properties:
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
28required:
29 - compatible
30 - shutdown-gpios
31 - mute-gpios
32 - gain-gpios
33
34additionalProperties: false
35
36examples:
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
7title: Maxim MAX98371 audio codec
8
9maintainers:
10 - anish kumar <yesanishhere@gmail.com>
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: maxim,max98371
18
19 '#sound-dai-cells':
20 const: 0
21
22 reg:
23 maxItems: 1
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: Maxim Integrated MAX9867 CODEC
8
9description: |
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
21maintainers:
22 - Ladislav Michl <ladis@linux-mips.org>
23
24allOf:
25 - $ref: dai-common.yaml#
26
27properties:
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
41required:
42 - compatible
43 - reg
44 - clocks
45
46additionalProperties: false
47
48examples:
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
26 const: audiosys26 const: audiosys
27 27
28 mediatek,apmixedsys:28 mediatek,apmixedsys:
29 $ref: "/schemas/types.yaml#/definitions/phandle"29 $ref: /schemas/types.yaml#/definitions/phandle
30 description: The phandle of the mediatek apmixedsys controller30 description: The phandle of the mediatek apmixedsys controller
31 31
32 mediatek,infracfg:32 mediatek,infracfg:
33 $ref: "/schemas/types.yaml#/definitions/phandle"33 $ref: /schemas/types.yaml#/definitions/phandle
34 description: The phandle of the mediatek infracfg controller34 description: The phandle of the mediatek infracfg controller
35 35
36 mediatek,topckgen:36 mediatek,topckgen:
37 $ref: "/schemas/types.yaml#/definitions/phandle"37 $ref: /schemas/types.yaml#/definitions/phandle
38 description: The phandle of the mediatek topckgen controller38 description: The phandle of the mediatek topckgen controller
39 39
40 clocks:40 clocks:
Documentation/devicetree/bindings/sound/mt8186-mt6366-da7219-max98357.yaml+1−1
@@ -18,7 +18,7 @@ properties: · 17 unmodified lines
18 - mediatek,mt8186-mt6366-da7219-max98357-sound18 - mediatek,mt8186-mt6366-da7219-max98357-sound
19 19
20 mediatek,platform:20 mediatek,platform:
21 $ref: "/schemas/types.yaml#/definitions/phandle"21 $ref: /schemas/types.yaml#/definitions/phandle
22 description: The phandle of MT8186 ASoC platform.22 description: The phandle of MT8186 ASoC platform.
23 23
24 headset-codec:24 headset-codec:
Documentation/devicetree/bindings/sound/mt8186-mt6366-rt1019-rt5682s.yaml+1−1
@@ -19,7 +19,7 @@ properties: · 18 unmodified lines
19 - mediatek,mt8186-mt6366-rt5682s-max98360-sound19 - mediatek,mt8186-mt6366-rt5682s-max98360-sound
20 20
21 mediatek,platform:21 mediatek,platform:
22 $ref: "/schemas/types.yaml#/definitions/phandle"22 $ref: /schemas/types.yaml#/definitions/phandle
23 description: The phandle of MT8186 ASoC platform.23 description: The phandle of MT8186 ASoC platform.
24 24
25 dmic-gpios:25 dmic-gpios:
Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml+3−3
@@ -24,15 +24,15 @@ properties: · 23 unmodified lines
24 const: audiosys24 const: audiosys
25 25
26 mediatek,apmixedsys:26 mediatek,apmixedsys:
27 $ref: "/schemas/types.yaml#/definitions/phandle"27 $ref: /schemas/types.yaml#/definitions/phandle
28 description: The phandle of the mediatek apmixedsys controller28 description: The phandle of the mediatek apmixedsys controller
29 29
30 mediatek,infracfg:30 mediatek,infracfg:
31 $ref: "/schemas/types.yaml#/definitions/phandle"31 $ref: /schemas/types.yaml#/definitions/phandle
32 description: The phandle of the mediatek infracfg controller32 description: The phandle of the mediatek infracfg controller
33 33
34 mediatek,topckgen:34 mediatek,topckgen:
35 $ref: "/schemas/types.yaml#/definitions/phandle"35 $ref: /schemas/types.yaml#/definitions/phandle
36 description: The phandle of the mediatek topckgen controller36 description: The phandle of the mediatek topckgen controller
37 37
38 power-domains:38 power-domains:
Documentation/devicetree/bindings/sound/mt8192-mt6359-rt1015-rt5682.yaml+2−2
@@ -21,11 +21,11 @@ properties: · 20 unmodified lines
21 - mediatek,mt8192_mt6359_rt1015p_rt5682s21 - mediatek,mt8192_mt6359_rt1015p_rt5682s
22 22
23 mediatek,platform:23 mediatek,platform:
24 $ref: "/schemas/types.yaml#/definitions/phandle"24 $ref: /schemas/types.yaml#/definitions/phandle
25 description: The phandle of MT8192 ASoC platform.25 description: The phandle of MT8192 ASoC platform.
26 26
27 mediatek,hdmi-codec:27 mediatek,hdmi-codec:
28 $ref: "/schemas/types.yaml#/definitions/phandle"28 $ref: /schemas/types.yaml#/definitions/phandle
29 description: The phandle of HDMI codec.29 description: The phandle of HDMI codec.
30 30
31 headset-codec:31 headset-codec:
Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml+1−1
@@ -32,7 +32,7 @@ properties: · 31 unmodified lines
32 See ../reserved-memory/reserved-memory.txt for details.32 See ../reserved-memory/reserved-memory.txt for details.
33 33
34 mediatek,topckgen:34 mediatek,topckgen:
35 $ref: "/schemas/types.yaml#/definitions/phandle"35 $ref: /schemas/types.yaml#/definitions/phandle
36 description: The phandle of the mediatek topckgen controller36 description: The phandle of the mediatek topckgen controller
37 37
38 power-domains:38 power-domains:
Documentation/devicetree/bindings/sound/mt8195-mt6359.yaml+4−4
@@ -24,19 +24,19 @@ properties: · 23 unmodified lines
24 description: User specified audio sound card name24 description: User specified audio sound card name
25 25
26 mediatek,platform:26 mediatek,platform:
27 $ref: "/schemas/types.yaml#/definitions/phandle"27 $ref: /schemas/types.yaml#/definitions/phandle
28 description: The phandle of MT8195 ASoC platform.28 description: The phandle of MT8195 ASoC platform.
29 29
30 mediatek,dptx-codec:30 mediatek,dptx-codec:
31 $ref: "/schemas/types.yaml#/definitions/phandle"31 $ref: /schemas/types.yaml#/definitions/phandle
32 description: The phandle of MT8195 Display Port Tx codec node.32 description: The phandle of MT8195 Display Port Tx codec node.
33 33
34 mediatek,hdmi-codec:34 mediatek,hdmi-codec:
35 $ref: "/schemas/types.yaml#/definitions/phandle"35 $ref: /schemas/types.yaml#/definitions/phandle
36 description: The phandle of MT8195 HDMI codec node.36 description: The phandle of MT8195 HDMI codec node.
37 37
38 mediatek,adsp:38 mediatek,adsp:
39 $ref: "/schemas/types.yaml#/definitions/phandle"39 $ref: /schemas/types.yaml#/definitions/phandle
40 description: The phandle of MT8195 ADSP platform.40 description: The phandle of MT8195 ADSP platform.
41 41
42 mediatek,dai-link:42 mediatek,dai-link:
Documentation/devicetree/bindings/sound/nau8825.txt+3−0
@@ -74,6 +74,9 @@ Optional properties: · 73 unmodified lines
74 - nuvoton,adcout-drive-strong: make the drive strength of ADCOUT IO PIN strong if set.74 - nuvoton,adcout-drive-strong: make the drive strength of ADCOUT IO PIN strong if set.
75 Otherwise, the drive keeps normal strength.75 Otherwise, the drive keeps normal strength.
76 76
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
77 - clocks: list of phandle and clock specifier pairs according to common clock bindings for the80 - clocks: list of phandle and clock specifier pairs according to common clock bindings for the
78 clocks described in clock-names81 clocks described in clock-names
79 - clock-names: should include "mclk" for the MCLK master clock82 - 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
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headset Stereophone"34 - Headset Stereophone
35 - "Int Spk"35 - Int Spk
36 - "Headset Mic"36 - Headset Mic
37 - "Digital Mic"37 - Digital Mic
38 38
39 # CODEC Pins39 # CODEC Pins
40 - SPKOUT40 - SPKOUT
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-common.yaml+4−0
@@ -80,4 +80,8 @@ properties: · 79 unmodified lines
80 type: boolean80 type: boolean
81 description: The Mic Jack represents state of the headset microphone pin81 description: The Mic Jack represents state of the headset microphone pin
82 82
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
83additionalProperties: true87additionalProperties: 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
7title: NVIDIA Tegra audio complex with MAX9808x CODEC
8
9maintainers:
10 - Jon Hunter <jonathanh@nvidia.com>
11 - Thierry Reding <thierry.reding@gmail.com>
12
13allOf:
14 - $ref: nvidia,tegra-audio-common.yaml#
15
16properties:
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
60unevaluatedProperties: false
61
62examples:
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
38 items:38 items:
39 enum:39 enum:
40 # Board Connectors40 # Board Connectors
41 - "Headphones"41 - Headphones
42 - "Speakers"42 - Speakers
43 - "Mic Jack"43 - Mic Jack
44 - "Int Mic"44 - Int Mic
45 45
46 # CODEC Pins46 # CODEC Pins
47 - MIC147 - 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
7title: NVIDIA Tegra audio complex with RT5631 CODEC
8
9maintainers:
10 - Jon Hunter <jonathanh@nvidia.com>
11 - Thierry Reding <thierry.reding@gmail.com>
12
13allOf:
14 - $ref: nvidia,tegra-audio-common.yaml#
15
16properties:
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
58unevaluatedProperties: false
59
60examples:
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
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headphones"34 - Headphones
35 - "Speakers"35 - Speakers
36 - "Mic Jack"36 - Mic Jack
37 37
38 # CODEC Pins38 # CODEC Pins
39 - DMIC139 - DMIC1
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5677.yaml+13−13
@@ -31,11 +31,11 @@ properties: · 30 unmodified lines
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headphone"34 - Headphone
35 - "Speaker"35 - Speaker
36 - "Headset Mic"36 - Headset Mic
37 - "Internal Mic 1"37 - Internal Mic 1
38 - "Internal Mic 2"38 - Internal Mic 2
39 39
40 # CODEC Pins40 # CODEC Pins
41 - IN1P41 - IN1P
@@ -47,14 +47,14 @@ properties: · 5 unmodified lines
47 - DMIC247 - DMIC2
48 - DMIC348 - DMIC3
49 - DMIC449 - DMIC4
50 - "DMIC L1"50 - DMIC L1
51 - "DMIC L2"51 - DMIC L2
52 - "DMIC L3"52 - DMIC L3
53 - "DMIC L4"53 - DMIC L4
54 - "DMIC R1"54 - DMIC R1
55 - "DMIC R2"55 - DMIC R2
56 - "DMIC R3"56 - DMIC R3
57 - "DMIC R4"57 - DMIC R4
58 - LOUT158 - LOUT1
59 - LOUT259 - LOUT2
60 - LOUT360 - LOUT3
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-sgtl5000.yaml+3−3
@@ -31,9 +31,9 @@ properties: · 30 unmodified lines
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headphone Jack"34 - Headphone Jack
35 - "Line In Jack"35 - Line In Jack
36 - "Mic Jack"36 - Mic Jack
37 37
38 # CODEC Pins38 # CODEC Pins
39 - HP_OUT39 - HP_OUT
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.yaml+3−3
@@ -31,8 +31,8 @@ properties: · 30 unmodified lines
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headphone Jack"34 - Headphone Jack
35 - "Mic Jack"35 - Mic Jack
36 36
37 # CODEC Pins37 # CODEC Pins
38 - LOUT138 - LOUT1
@@ -53,7 +53,7 @@ properties: · 14 unmodified lines
53 - MIC153 - MIC1
54 - MIC2N54 - MIC2N
55 - MIC255 - MIC2
56 - "Mic Bias"56 - Mic Bias
57 57
58required:58required:
59 - nvidia,i2s-controller59 - nvidia,i2s-controller
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.yaml+4−4
@@ -35,10 +35,10 @@ properties: · 34 unmodified lines
35 items:35 items:
36 enum:36 enum:
37 # Board Connectors37 # Board Connectors
38 - "Headphone Jack"38 - Headphone Jack
39 - "Int Spk"39 - Int Spk
40 - "Mic Jack"40 - Mic Jack
41 - "Int Mic"41 - Int Mic
42 42
43 # CODEC Pins43 # CODEC Pins
44 - IN1L44 - IN1L
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.yaml+4−4
@@ -31,9 +31,9 @@ properties: · 30 unmodified lines
31 items:31 items:
32 enum:32 enum:
33 # Board Connectors33 # Board Connectors
34 - "Headphone"34 - Headphone
35 - "LineIn"35 - LineIn
36 - "Mic"36 - Mic
37 37
38 # CODEC Pins38 # CODEC Pins
39 - MONOOUT39 - MONOOUT
@@ -48,7 +48,7 @@ properties: · 8 unmodified lines
48 - PCBEEP48 - PCBEEP
49 - MIC149 - MIC1
50 - MIC250 - MIC2
51 - "Mic Bias"51 - Mic Bias
52 52
53required:53required:
54 - nvidia,ac97-controller54 - 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
9maintainers:9maintainers:
10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
11 11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:12properties:
16 compatible:13 compatible:
17 enum:14 enum:
18 - qcom,sc7280-lpass-rx-macro15 - qcom,sc7280-lpass-rx-macro
19 - qcom,sm8250-lpass-rx-macro16 - qcom,sm8250-lpass-rx-macro
20 - qcom,sm8450-lpass-rx-macro17 - qcom,sm8450-lpass-rx-macro
18 - qcom,sm8550-lpass-rx-macro
21 - qcom,sc8280xp-lpass-rx-macro19 - qcom,sc8280xp-lpass-rx-macro
22 20
23 reg:21 reg:
@@ -30,20 +28,12 @@ properties: · 6 unmodified lines
30 const: 028 const: 0
31 29
32 clocks:30 clocks:
31 minItems: 3
33 maxItems: 532 maxItems: 5
34 33
35 clock-names:34 clock-names:
36 oneOf:35 minItems: 3
37 - items: # for ADSP based platforms36 maxItems: 5
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
47 37
48 clock-output-names:38 clock-output-names:
49 maxItems: 139 maxItems: 1
@@ -61,6 +51,65 @@ required: · 11 unmodified lines
61 - reg51 - reg
62 - "#sound-dai-cells"52 - "#sound-dai-cells"
63 53
54allOf:
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
64unevaluatedProperties: false113unevaluatedProperties: false
65 114
66examples:115examples:
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
9maintainers:9maintainers:
10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
11 11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:12properties:
16 compatible:13 compatible:
17 enum:14 enum:
18 - qcom,sc7280-lpass-tx-macro15 - qcom,sc7280-lpass-tx-macro
19 - qcom,sm8250-lpass-tx-macro16 - qcom,sm8250-lpass-tx-macro
20 - qcom,sm8450-lpass-tx-macro17 - qcom,sm8450-lpass-tx-macro
18 - qcom,sm8550-lpass-tx-macro
21 - qcom,sc8280xp-lpass-tx-macro19 - qcom,sc8280xp-lpass-tx-macro
22 20
23 reg:21 reg:
@@ -30,22 +28,12 @@ properties: · 6 unmodified lines
30 const: 028 const: 0
31 29
32 clocks:30 clocks:
33 oneOf:31 minItems: 3
34 - maxItems: 332 maxItems: 5
35 - maxItems: 5
36 33
37 clock-names:34 clock-names:
38 oneOf:35 minItems: 3
39 - items: # for ADSP based platforms36 maxItems: 5
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
49 37
50 clock-output-names:38 clock-output-names:
51 maxItems: 139 maxItems: 1
@@ -67,6 +55,65 @@ required: · 15 unmodified lines
67 - reg55 - reg
68 - "#sound-dai-cells"56 - "#sound-dai-cells"
69 57
58allOf:
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
70unevaluatedProperties: false117unevaluatedProperties: false
71 118
72examples:119examples:
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
9maintainers:9maintainers:
10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
11 11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:12properties:
16 compatible:13 compatible:
17 enum:14 enum:
18 - qcom,sc7280-lpass-va-macro15 - qcom,sc7280-lpass-va-macro
19 - qcom,sm8250-lpass-va-macro16 - qcom,sm8250-lpass-va-macro
20 - qcom,sm8450-lpass-va-macro17 - qcom,sm8450-lpass-va-macro
18 - qcom,sm8550-lpass-va-macro
21 - qcom,sc8280xp-lpass-va-macro19 - qcom,sc8280xp-lpass-va-macro
22 20
23 reg:21 reg:
@@ -30,16 +28,12 @@ properties: · 6 unmodified lines
30 const: 028 const: 0
31 29
32 clocks:30 clocks:
33 maxItems: 331 minItems: 1
32 maxItems: 4
34 33
35 clock-names:34 clock-names:
36 oneOf:35 minItems: 1
37 - items: # for ADSP based platforms36 maxItems: 4
38 - const: mclk
39 - const: macro
40 - const: dcodec
41 - items: # for ADSP bypass based platforms
42 - const: mclk
43 37
44 clock-output-names:38 clock-output-names:
45 maxItems: 139 maxItems: 1
@@ -63,6 +57,76 @@ required: · 17 unmodified lines
63 - compatible57 - compatible
64 - reg58 - reg
65 - "#sound-dai-cells"59 - "#sound-dai-cells"
60 - clock-names
61 - clocks
62
63allOf:
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
66 130
67unevaluatedProperties: false131unevaluatedProperties: false
68 132
Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml+21−2
@@ -15,6 +15,7 @@ properties: · 14 unmodified lines
15 - qcom,sc7280-lpass-wsa-macro15 - qcom,sc7280-lpass-wsa-macro
16 - qcom,sm8250-lpass-wsa-macro16 - qcom,sm8250-lpass-wsa-macro
17 - qcom,sm8450-lpass-wsa-macro17 - qcom,sm8450-lpass-wsa-macro
18 - qcom,sm8550-lpass-wsa-macro
18 - qcom,sc8280xp-lpass-wsa-macro19 - qcom,sc8280xp-lpass-wsa-macro
19 20
20 reg:21 reg:
@@ -27,11 +28,11 @@ properties: · 6 unmodified lines
27 const: 028 const: 0
28 29
29 clocks:30 clocks:
30 minItems: 531 minItems: 4
31 maxItems: 632 maxItems: 6
32 33
33 clock-names:34 clock-names:
34 minItems: 535 minItems: 4
35 maxItems: 636 maxItems: 6
36 37
37 clock-output-names:38 clock-output-names:
@@ -62,6 +63,7 @@ allOf: · 24 unmodified lines
62 then:63 then:
63 properties:64 properties:
64 clocks:65 clocks:
66 minItems: 5
65 maxItems: 567 maxItems: 5
66 clock-names:68 clock-names:
67 items:69 items:
@@ -89,6 +91,23 @@ allOf: · 21 unmodified lines
89 - const: va91 - const: va
90 - const: fsgen92 - const: fsgen
91 93
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
92unevaluatedProperties: false111unevaluatedProperties: false
93 112
94examples:113examples:
Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml+1−1
@@ -56,7 +56,7 @@ patternProperties: · 55 unmodified lines
56 Compress offload dai.56 Compress offload dai.
57 57
58 dependencies:58 dependencies:
59 is-compress-dai: ["direction"]59 is-compress-dai: [ direction ]
60 60
61 required:61 required:
62 - reg62 - reg
Documentation/devicetree/bindings/sound/qcom,wcd9335.txt+0−123
@@ -1,123 +0,0 @@
1QCOM WCD9335 Codec
2
3Qualcomm WCD9335 Codec is a standalone Hi-Fi audio codec IC, supports
4Qualcomm Technologies, Inc. (QTI) multimedia solutions, including
5the MSM8996, MSM8976, and MSM8956 chipsets. It has in-built
6Soundwire controller, interrupt mux. It supports both I2S/I2C and
7SLIMbus audio interfaces.
8
9Required 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
107audio-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
7title: Qualcomm WCD9335 Audio Codec
8
9maintainers:
10 - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
11
12description:
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
17properties:
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
76required:
77 - compatible
78 - reg
79
80allOf:
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
120additionalProperties: false
121
122examples:
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
152 - reg152 - reg
153 153
154allOf:154allOf:
155 - $ref: dai-common.yaml#
155 - if:156 - if:
156 required:157 required:
157 - slim-ifc-dev158 - 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
7title: ALC5632 audio CODEC
8
9description: |
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
28maintainers:
29 - Leon Romanovsky <leon@leon.nu>
30
31properties:
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
43required:
44 - compatible
45 - reg
46 - '#gpio-cells'
47 - gpio-controller
48
49additionalProperties: false
50
51examples:
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
101 101
102 clock-names:102 clock-names:
103 description: List of necessary clock names.103 description: List of necessary clock names.
104 minItems: 1104 # details are defined below
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)$'
115 105
116 ports:106 ports:
117 $ref: audio-graph-port.yaml#/definitions/port-base107 $ref: audio-graph-port.yaml#/definitions/port-base
@@ -155,7 +145,7 @@ properties: · 37 unmodified lines
155 dmas:145 dmas:
156 maxItems: 1146 maxItems: 1
157 dma-names:147 dma-names:
158 const: "tx"148 const: tx
159 required:149 required:
160 - dmas150 - dmas
161 - dma-names151 - dma-names
@@ -288,6 +278,11 @@ required: · 126 unmodified lines
288 278
289allOf:279allOf:
290 - $ref: dai-common.yaml#280 - $ref: dai-common.yaml#
281
282 # --------------------
283 # reg/reg-names
284 # --------------------
285 # for Gen1
291 - if:286 - if:
292 properties:287 properties:
293 compatible:288 compatible:
@@ -303,7 +298,15 @@ allOf: · 9 unmodified lines
303 - scu298 - scu
304 - ssi299 - ssi
305 - adg300 - 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:
307 properties:310 properties:
308 reg:311 reg:
309 minItems: 5312 minItems: 5
@@ -315,35 +318,87 @@ allOf: · 5 unmodified lines
315 - ssiu318 - ssiu
316 - ssi319 - ssi
317 - audmapp320 - 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)$'
318 370
319unevaluatedProperties: false371unevaluatedProperties: false
320 372
321examples:373examples:
322 - |374 - |
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>
323 rcar_sound: sound@ec500000 {378 rcar_sound: sound@ec500000 {
324 #sound-dai-cells = <1>;379 #sound-dai-cells = <1>;
325 compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";380 compatible = "renesas,rcar_sound-r8a7790", "renesas,rcar_sound-gen2";
326 reg = <0xec500000 0x1000>, /* SCU */381 reg = <0xec500000 0x1000>, /* SCU */
327 <0xec5a0000 0x100>, /* ADG */382 <0xec5a0000 0x100>, /* ADG */
328 <0xec540000 0x1000>, /* SSIU */383 <0xec540000 0x1000>, /* SSIU */
329 <0xec541000 0x1280>, /* SSI */384 <0xec541000 0x280>, /* SSI */
330 <0xec740000 0x200>; /* Audio DMAC peri peri*/385 <0xec740000 0x200>; /* Audio DMAC peri peri*/
331 reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";386 reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
332 387
333 clocks = <&mstp10_clks 1005>, /* SSI-ALL */388 clocks = <&cpg CPG_MOD 1005>, /* SSI-ALL */
334 <&mstp10_clks 1006>, <&mstp10_clks 1007>, /* SSI9, SSI8 */389 <&cpg CPG_MOD 1006>, <&cpg CPG_MOD 1007>, /* SSI9, SSI8 */
335 <&mstp10_clks 1008>, <&mstp10_clks 1009>, /* SSI7, SSI6 */390 <&cpg CPG_MOD 1008>, <&cpg CPG_MOD 1009>, /* SSI7, SSI6 */
336 <&mstp10_clks 1010>, <&mstp10_clks 1011>, /* SSI5, SSI4 */391 <&cpg CPG_MOD 1010>, <&cpg CPG_MOD 1011>, /* SSI5, SSI4 */
337 <&mstp10_clks 1012>, <&mstp10_clks 1013>, /* SSI3, SSI2 */392 <&cpg CPG_MOD 1012>, <&cpg CPG_MOD 1013>, /* SSI3, SSI2 */
338 <&mstp10_clks 1014>, <&mstp10_clks 1015>, /* SSI1, SSI0 */393 <&cpg CPG_MOD 1014>, <&cpg CPG_MOD 1015>, /* SSI1, SSI0 */
339 <&mstp10_clks 1022>, <&mstp10_clks 1023>, /* SRC9, SRC8 */394 <&cpg CPG_MOD 1022>, <&cpg CPG_MOD 1023>, /* SRC9, SRC8 */
340 <&mstp10_clks 1024>, <&mstp10_clks 1025>, /* SRC7, SRC6 */395 <&cpg CPG_MOD 1024>, <&cpg CPG_MOD 1025>, /* SRC7, SRC6 */
341 <&mstp10_clks 1026>, <&mstp10_clks 1027>, /* SRC5, SRC4 */396 <&cpg CPG_MOD 1026>, <&cpg CPG_MOD 1027>, /* SRC5, SRC4 */
342 <&mstp10_clks 1028>, <&mstp10_clks 1029>, /* SRC3, SRC2 */397 <&cpg CPG_MOD 1028>, <&cpg CPG_MOD 1029>, /* SRC3, SRC2 */
343 <&mstp10_clks 1030>, <&mstp10_clks 1031>, /* SRC1, SRC0 */398 <&cpg CPG_MOD 1030>, <&cpg CPG_MOD 1031>, /* SRC1, SRC0 */
344 <&mstp10_clks 1020>, <&mstp10_clks 1021>, /* MIX1, MIX0 */399 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, /* MIX1, MIX0 */
345 <&mstp10_clks 1020>, <&mstp10_clks 1021>, /* CTU1, CTU0 */400 <&cpg CPG_MOD 1020>, <&cpg CPG_MOD 1021>, /* CTU1, CTU0 */
346 <&mstp10_clks 1019>, <&mstp10_clks 1018>, /* DVC0, DVC1 */401 <&cpg CPG_MOD 1019>, <&cpg CPG_MOD 1018>, /* DVC0, DVC1 */
347 <&audio_clk_a>, <&audio_clk_b>, /* CLKA, CLKB */402 <&audio_clk_a>, <&audio_clk_b>, /* CLKA, CLKB */
348 <&audio_clk_c>, <&audio_clk_i>; /* CLKC, CLKI */403 <&audio_clk_c>, <&audio_clk_i>; /* CLKC, CLKI */
349 404
@@ -364,6 +419,17 @@ examples: · 14 unmodified lines
364 "clk_a", "clk_b",419 "clk_a", "clk_b",
365 "clk_c", "clk_i";420 "clk_c", "clk_i";
366 421
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
367 rcar_sound,dvc {433 rcar_sound,dvc {
368 dvc0: dvc-0 {434 dvc0: dvc-0 {
369 dmas = <&audma0 0xbc>;435 dmas = <&audma0 0xbc>;
@@ -396,7 +462,7 @@ examples: · 26 unmodified lines
396 status = "disabled";462 status = "disabled";
397 };463 };
398 src1: src-1 {464 src1: src-1 {
399 interrupts = <0 353 0>;465 interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
400 dmas = <&audma0 0x87>, <&audma1 0x9c>;466 dmas = <&audma0 0x87>, <&audma1 0x9c>;
401 dma-names = "rx", "tx";467 dma-names = "rx", "tx";
402 };468 };
@@ -417,12 +483,12 @@ examples: · 14 unmodified lines
417 483
418 rcar_sound,ssi {484 rcar_sound,ssi {
419 ssi0: ssi-0 {485 ssi0: ssi-0 {
420 interrupts = <0 370 1>;486 interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
421 dmas = <&audma0 0x01>, <&audma1 0x02>;487 dmas = <&audma0 0x01>, <&audma1 0x02>;
422 dma-names = "rx", "tx";488 dma-names = "rx", "tx";
423 };489 };
424 ssi1: ssi-1 {490 ssi1: ssi-1 {
425 interrupts = <0 371 1>;491 interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
426 dmas = <&audma0 0x03>, <&audma1 0x04>;492 dmas = <&audma0 0x03>, <&audma1 0x04>;
427 dma-names = "rx", "tx";493 dma-names = "rx", "tx";
428 };494 };
@@ -464,7 +530,6 @@ examples: · 35 unmodified lines
464 };530 };
465 };531 };
466 532
467
468 /* assume audio-graph */533 /* assume audio-graph */
469 codec {534 codec {
470 port {535 port {
Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml+12−9
@@ -25,14 +25,18 @@ properties: · 24 unmodified lines
25 maxItems: 125 maxItems: 1
26 26
27 interrupts:27 interrupts:
28 maxItems: 428 minItems: 2
29 maxItems: 3
29 30
30 interrupt-names:31 interrupt-names:
31 items:32 oneOf:
32 - const: int_req33 - items:
33 - const: dma_rx34 - const: int_req
34 - const: dma_tx35 - const: dma_rx
35 - const: dma_rt36 - const: dma_tx
37 - items:
38 - const: int_req
39 - const: dma_rt
36 40
37 clocks:41 clocks:
38 maxItems: 442 maxItems: 4
@@ -106,9 +110,8 @@ examples: · 67 unmodified lines
106 reg = <0x10049c00 0x400>;110 reg = <0x10049c00 0x400>;
107 interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,111 interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
108 <GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,112 <GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
109 <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,113 <GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
110 <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;114 interrupt-names = "int_req", "dma_rx", "dma_tx";
111 interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
112 clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,115 clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
113 <&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,116 <&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
114 <&audio_clk1>,117 <&audio_clk1>,
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml+7−0
@@ -86,6 +86,13 @@ properties: · 85 unmodified lines
86 - tx-m86 - tx-m
87 - rx-m87 - rx-m
88 88
89 port:
90 $ref: audio-graph-port.yaml#
91 unevaluatedProperties: false
92
93 power-domains:
94 maxItems: 1
95
89 rockchip,grf:96 rockchip,grf:
90 $ref: /schemas/types.yaml#/definitions/phandle97 $ref: /schemas/types.yaml#/definitions/phandle
91 description:98 description:
Documentation/devicetree/bindings/sound/rockchip-i2s.yaml+5−0
@@ -34,6 +34,7 @@ properties: · 33 unmodified lines
34 - rockchip,rk3366-i2s34 - rockchip,rk3366-i2s
35 - rockchip,rk3368-i2s35 - rockchip,rk3368-i2s
36 - rockchip,rk3399-i2s36 - rockchip,rk3399-i2s
37 - rockchip,rk3588-i2s
37 - rockchip,rv1126-i2s38 - rockchip,rv1126-i2s
38 - const: rockchip,rk3066-i2s39 - const: rockchip,rk3066-i2s
39 40
@@ -82,6 +83,10 @@ properties: · 42 unmodified lines
82 resets:83 resets:
83 maxItems: 284 maxItems: 2
84 85
86 port:
87 $ref: audio-graph-port.yaml#
88 unevaluatedProperties: false
89
85 rockchip,capture-channels:90 rockchip,capture-channels:
86 $ref: /schemas/types.yaml#/definitions/uint3291 $ref: /schemas/types.yaml#/definitions/uint32
87 default: 292 default: 2
Documentation/devicetree/bindings/sound/sgtl5000.yaml+3−3
@@ -50,7 +50,7 @@ properties: · 49 unmodified lines
50 description: The bias voltage to be used in mVolts. The voltage can take50 description: The bias voltage to be used in mVolts. The voltage can take
51 values from 1.25V to 3V by 250mV steps. If this node is not mentioned51 values from 1.25V to 3V by 250mV steps. If this node is not mentioned
52 or the value is unknown, then the value is set to 1.25V.52 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
54 enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ]54 enum: [ 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000 ]
55 55
56 lrclk-strength:56 lrclk-strength:
@@ -63,7 +63,7 @@ properties: · 6 unmodified lines
63 1 = 1.66 mA 2.87 mA 4.02 mA63 1 = 1.66 mA 2.87 mA 4.02 mA
64 2 = 3.33 mA 5.74 mA 8.03 mA64 2 = 3.33 mA 5.74 mA 8.03 mA
65 3 = 4.99 mA 8.61 mA 12.05 mA65 3 = 4.99 mA 8.61 mA 12.05 mA
66 $ref: "/schemas/types.yaml#/definitions/uint32"66 $ref: /schemas/types.yaml#/definitions/uint32
67 enum: [ 0, 1, 2, 3 ]67 enum: [ 0, 1, 2, 3 ]
68 68
69 sclk-strength:69 sclk-strength:
@@ -76,7 +76,7 @@ properties: · 6 unmodified lines
76 1 = 1.66 mA 2.87 mA 4.02 mA76 1 = 1.66 mA 2.87 mA 4.02 mA
77 2 = 3.33 mA 5.74 mA 8.03 mA77 2 = 3.33 mA 5.74 mA 8.03 mA
78 3 = 4.99 mA 8.61 mA 12.05 mA78 3 = 4.99 mA 8.61 mA 12.05 mA
79 $ref: "/schemas/types.yaml#/definitions/uint32"79 $ref: /schemas/types.yaml#/definitions/uint32
80 enum: [ 0, 1, 2, 3 ]80 enum: [ 0, 1, 2, 3 ]
81 81
82 port:82 port:
Documentation/devicetree/bindings/sound/simple-card.yaml+1−1
@@ -78,7 +78,7 @@ definitions: · 77 unmodified lines
78 $ref: /schemas/types.yaml#/definitions/uint3278 $ref: /schemas/types.yaml#/definitions/uint32
79 79
80 prefix:80 prefix:
81 description: "device name prefix"81 description: device name prefix
82 $ref: /schemas/types.yaml#/definitions/string82 $ref: /schemas/types.yaml#/definitions/string
83 83
84 label:84 label:
Documentation/devicetree/bindings/sound/socionext,uniphier-aio.yaml+1−1
@@ -42,7 +42,7 @@ properties: · 41 unmodified lines
42 Specifies a phandle to soc-glue, which is used for changing mode of S/PDIF42 Specifies a phandle to soc-glue, which is used for changing mode of S/PDIF
43 signal pin to output from Hi-Z. This property is optional if you use I2S43 signal pin to output from Hi-Z. This property is optional if you use I2S
44 signal pins only.44 signal pins only.
45 $ref: "/schemas/types.yaml#/definitions/phandle"45 $ref: /schemas/types.yaml#/definitions/phandle
46 46
47 "#sound-dai-cells":47 "#sound-dai-cells":
48 const: 148 const: 1
Documentation/devicetree/bindings/sound/tas571x.txt+1−0
@@ -12,6 +12,7 @@ Required properties: · 11 unmodified lines
12 - "ti,tas5717",12 - "ti,tas5717",
13 - "ti,tas5719",13 - "ti,tas5719",
14 - "ti,tas5721"14 - "ti,tas5721"
15 - "ti,tas5733"
15- reg: The I2C address of the device16- reg: The I2C address of the device
16- #sound-dai-cells: must be equal to 017- #sound-dai-cells: must be equal to 0
17 18
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
7title: WM8510 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: wlf,wm8510
18
19 reg:
20 maxItems: 1
21
22 "#sound-dai-cells":
23 const: 0
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: WM8523 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: wlf,wm8523
18
19 reg:
20 maxItems: 1
21
22 "#sound-dai-cells":
23 const: 0
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: Wolfson WM8524 24-bit 192KHz Stereo DAC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
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
27required:
28 - compatible
29 - wlf,mute-gpios
30
31unevaluatedProperties: false
32
33examples:
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
7title: WM8580 and WM8581 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
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
27required:
28 - compatible
29 - reg
30
31unevaluatedProperties: false
32
33examples:
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
7title: WM8711 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: wlf,wm8711
18
19 reg:
20 maxItems: 1
21
22 "#sound-dai-cells":
23 const: 0
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: WM8728 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: wlf,wm8728
18
19 reg:
20 maxItems: 1
21
22 "#sound-dai-cells":
23 const: 0
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: WM8737 audio CODEC
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: wlf,wm8737
18
19 reg:
20 maxItems: 1
21
22 "#sound-dai-cells":
23 const: 0
24
25required:
26 - compatible
27 - reg
28
29unevaluatedProperties: false
30
31examples:
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
7title: WM8753 audio CODEC
8
9description: |
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
31maintainers:
32 - patches@opensource.cirrus.com
33
34allOf:
35 - $ref: dai-common.yaml#
36
37properties:
38 compatible:
39 const: wlf,wm8753
40
41 reg:
42 maxItems: 1
43
44 "#sound-dai-cells":
45 const: 0
46
47required:
48 - compatible
49 - reg
50
51unevaluatedProperties: false
52
53examples:
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
7title: Wolfson WM8960 audio codec
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12properties:
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
63required:
64 - compatible
65 - reg
66
67allOf:
68 - $ref: dai-common.yaml#
69
70unevaluatedProperties: false
71
72examples:
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
7title: Wolfson WM1811/WM8994/WM8958 audio codecs
8
9maintainers:
10 - Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
11 - patches@opensource.cirrus.com
12
13description: |
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
22properties:
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
134required:
135 - compatible
136 - reg
137 - AVDD2-supply
138 - CPVDD-supply
139 - SPKVDD1-supply
140 - SPKVDD2-supply
141
142allOf:
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
166unevaluatedProperties: false
167
168examples:
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 @@
1WM8510 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
13Example:
14
15wm8510: codec@1a {
16 compatible = "wlf,wm8510";
17 reg = <0x1a>;
18};
Documentation/devicetree/bindings/sound/wm8523.txt+0−16
@@ -1,16 +0,0 @@
1WM8523 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8523"
8
9 - reg : the I2C address of the device.
10
11Example:
12
13wm8523: codec@1a {
14 compatible = "wlf,wm8523";
15 reg = <0x1a>;
16};
Documentation/devicetree/bindings/sound/wm8524.txt+0−16
@@ -1,16 +0,0 @@
1WM8524 audio CODEC
2
3This device does not use I2C or SPI but a simple Hardware Control Interface.
4
5Required properties:
6
7 - compatible : "wlf,wm8524"
8
9 - wlf,mute-gpios: a GPIO spec for the MUTE pin.
10
11Example:
12
13wm8524: 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 @@
1WM8580 and WM8581 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8580", "wlf,wm8581"
8
9 - reg : the I2C address of the device.
10
11Example:
12
13wm8580: codec@1a {
14 compatible = "wlf,wm8580";
15 reg = <0x1a>;
16};
Documentation/devicetree/bindings/sound/wm8711.txt+0−18
@@ -1,18 +0,0 @@
1WM8711 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
13Example:
14
15wm8711: codec@1a {
16 compatible = "wlf,wm8711";
17 reg = <0x1a>;
18};
Documentation/devicetree/bindings/sound/wm8728.txt+0−18
@@ -1,18 +0,0 @@
1WM8728 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
13Example:
14
15wm8728: codec@1a {
16 compatible = "wlf,wm8728";
17 reg = <0x1a>;
18};
Documentation/devicetree/bindings/sound/wm8737.txt+0−18
@@ -1,18 +0,0 @@
1WM8737 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
13Example:
14
15wm8737: codec@1a {
16 compatible = "wlf,wm8737";
17 reg = <0x1a>;
18};
Documentation/devicetree/bindings/sound/wm8753.txt+0−40
@@ -1,40 +0,0 @@
1WM8753 audio CODEC
2
3This device supports both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
13Pins 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
35Example:
36
37wm8753: codec@1a {
38 compatible = "wlf,wm8753";
39 reg = <0x1a>;
40};
Documentation/devicetree/bindings/sound/wm8960.txt+0−42
@@ -1,42 +0,0 @@
1WM8960 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8960"
8
9 - reg : the I2C address of the device.
10
11Optional 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
35Example:
36
37wm8960: 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 @@
1WM1811/WM8994/WM8958 audio CODEC
2
3These devices support both I2C and SPI (configured with pin strapping
4on the board).
5
6Required 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
27Optional 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
71Pins 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
94Example:
95
96wm8994: 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
723 723
724* Sound Blaster Live!724* Sound Blaster Live!
725* Sound Blaster PCI 512725* Sound Blaster PCI 512
726* Emu APS (partially supported)
727* Sound Blaster Audigy726* Sound Blaster Audigy
728 727* E-MU APS (partially supported)
728* E-MU DAS
729
729extin730extin
730 bitmap of available external inputs for FX8010 (see below)731 bitmap of available external inputs for FX8010 (see below)
731extout732extout
Documentation/sound/cards/audigy-mixer.rst+15−12
@@ -19,9 +19,9 @@ Digital mixer controls · 18 unmodified lines
19These controls are built using the DSP instructions. They offer extended19These controls are built using the DSP instructions. They offer extended
20functionality. Only the default built-in code in the ALSA driver is described20functionality. Only the default built-in code in the ALSA driver is described
21here. Note that the controls work as attenuators: the maximum value is the 21here. Note that the controls work as attenuators: the maximum value is the
22neutral position leaving the signal unchanged. Note that if the same destination 22neutral position leaving the signal unchanged. Note that if the same destination
23is mentioned in multiple controls, the signal is accumulated and can be wrapped 23is mentioned in multiple controls, the signal is accumulated and can be clipped
24(set to maximal or minimal value without checking of overflow).24(set to maximal or minimal value without checking for overflow).
25 25
26 26
27Explanation of used abbreviations:27Explanation of used abbreviations:
@@ -32,17 +32,17 @@ ADC · 4 unmodified lines
32 analog to digital converter32 analog to digital converter
33I2S33I2S
34 one-way three wire serial bus for digital sound by Philips Semiconductors34 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)
36LFE36LFE
37 low frequency effects (subwoofer signal)37 low frequency effects (used as subwoofer signal)
38AC9738AC97
39 a chip containing an analog mixer, DAC and ADC converters39 a chip containing an analog mixer, D/A and A/D converters
40IEC95840IEC958
41 S/PDIF41 S/PDIF
42FX-bus42FX-bus
43 the EMU10K2 chip has an effect bus containing 64 accumulators.43 the EMU10K2 chip has an effect bus containing 64 accumulators.
44 Each of the synthesizer voices can feed its output to these accumulators44 Each of the synthesizer voices can feed its output to these accumulators
45 and the DSP microcontroller can operate with the resulting sum.45 and the DSP microcontroller can operate with the resulting sum.
46 46
47name='PCM Front Playback Volume',index=047name='PCM Front Playback Volume',index=0
48----------------------------------------48----------------------------------------
@@ -218,8 +218,8 @@ LFE outputs. · 169 unmodified lines
218name='IEC958 Optical Raw Playback Switch',index=0218name='IEC958 Optical Raw Playback Switch',index=0
219-------------------------------------------------219-------------------------------------------------
220If this switch is on, then the samples for the IEC958 (S/PDIF) digital220If this switch is on, then the samples for the IEC958 (S/PDIF) digital
221output are taken only from the raw FX8010 PCM, otherwise standard front221output are taken only from the raw iec958 ALSA PCM device (which uses
222PCM samples are taken.222accumulators 20 and 21 for left and right PCM by default).
223 223
224 224
225PCM stream related controls225PCM stream related controls
@@ -237,8 +237,8 @@ as follows: · 11 unmodified lines
237 237
238name='EMU10K1 PCM Send Routing',index 0-31238name='EMU10K1 PCM Send Routing',index 0-31
239------------------------------------------239------------------------------------------
240This control specifies the destination - FX-bus accumulators. There 24240This control specifies the destination - FX-bus accumulators. There are 24
241values with this mapping:241values in this mapping:
242 242
243* 0 - mono, A destination (FX-bus 0-63), default 0243* 0 - mono, A destination (FX-bus 0-63), default 0
244* 1 - mono, B destination (FX-bus 0-63), default 1244* 1 - mono, B destination (FX-bus 0-63), default 1
@@ -306,6 +306,9 @@ MANUALS/PATENTS · 61 unmodified lines
306ftp://opensource.creative.com/pub/doc306ftp://opensource.creative.com/pub/doc
307-------------------------------------307-------------------------------------
308 308
309Note that the site is defunct, but the documents are available
310from various other locations.
311
309LM4545.pdf312LM4545.pdf
310 AC97 Codec313 AC97 Codec
311 314
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
15IEC958 (S/PDIF) raw PCM15IEC958 (S/PDIF) raw PCM
16=======================16=======================
17 17
18This PCM device (it's the 4th PCM device (index 3!) and first subdevice18This PCM device (it's the 3rd PCM device (index 2!) and first subdevice
19(index 0) for a given card) allows to forward 48kHz, stereo, 16-bit19(index 0) for a given card) allows to forward 48kHz, stereo, 16-bit
20little endian streams without any modifications to the digital output20little endian streams without any modifications to the digital output
21(coaxial or optical). The universal interface allows the creation of up21(coaxial or optical). The universal interface allows the creation of up
@@ -33,9 +33,9 @@ Digital mixer controls · 11 unmodified lines
33These controls are built using the DSP instructions. They offer extended33These controls are built using the DSP instructions. They offer extended
34functionality. Only the default built-in code in the ALSA driver is described34functionality. Only the default built-in code in the ALSA driver is described
35here. Note that the controls work as attenuators: the maximum value is the 35here. Note that the controls work as attenuators: the maximum value is the
36neutral position leaving the signal unchanged. Note that if the same destination 36neutral position leaving the signal unchanged. Note that if the same destination
37is mentioned in multiple controls, the signal is accumulated and can be wrapped 37is mentioned in multiple controls, the signal is accumulated and can be clipped
38(set to maximal or minimal value without checking of overflow).38(set to maximal or minimal value without checking for overflow).
39 39
40 40
41Explanation of used abbreviations:41Explanation of used abbreviations:
@@ -46,11 +46,11 @@ ADC · 4 unmodified lines
46 analog to digital converter46 analog to digital converter
47I2S47I2S
48 one-way three wire serial bus for digital sound by Philips Semiconductors48 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)
50LFE50LFE
51 low frequency effects (subwoofer signal)51 low frequency effects (used as subwoofer signal)
52AC9752AC97
53 a chip containing an analog mixer, DAC and ADC converters53 a chip containing an analog mixer, D/A and A/D converters
54IEC95854IEC958
55 S/PDIF55 S/PDIF
56FX-bus56FX-bus
@@ -313,6 +313,9 @@ MANUALS/PATENTS · 256 unmodified lines
313ftp://opensource.creative.com/pub/doc313ftp://opensource.creative.com/pub/doc
314-------------------------------------314-------------------------------------
315 315
316Note that the site is defunct, but the documents are available
317from various other locations.
318
316LM4545.pdf319LM4545.pdf
317 AC97 Codec320 AC97 Codec
318m2049.pdf321m2049.pdf
Documentation/sound/hd-audio/index.rst+1−0
@@ -9,3 +9,4 @@ HD-Audio · 8 unmodified lines
9 controls9 controls
10 dp-mst10 dp-mst
11 realtek-pc-beep11 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================================================
5HDAudio multi-link extensions on Intel platforms
6================================================
7
8:Copyright: |copy| 2023 Intel Corporation
9
10This file documents the 'multi-link structure' introduced in 2015 with
11the Skylake processor and recently extended in newer Intel platforms
12
13HDaudio existing link mapping (2015 addition in SkyLake)
14========================================================
15
16External HDAudio codecs are handled with link #0, while iDISP codec
17for HDMI/DisplayPort is handled with link #1.
18
19The only change to the 2015 definitions is the declaration of the
20LCAP.ALT=0x0 - since the ALT bit was previously reserved, this is a
21backwards-compatible change.
22
23LCTL.SPA and LCTL.CPA are automatically set when exiting reset. They
24are only used in existing drivers when the SCF value needs to be
25corrected.
26
27Basic 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
80SoundWire HDaudio extended link mapping
81=======================================
82
83A SoundWire extended link is identified when LCAP.ALT=1 and
84LEPTR.ID=0.
85
86DMA control uses the existing LOSIDV register.
87
88Changes include additional descriptions for enumeration that were not
89present 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
100Extended 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
172DMIC HDaudio extended link mapping
173==================================
174
175A DMIC extended link is identified when LCAP.ALT=1 and
176LEPTR.ID=0xC1 are set.
177
178DMA control uses the existing LOSIDV register
179
180Changes include additional descriptions for enumeration that were not
181present 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
191Extended 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
243SSP HDaudio extended link mapping
244=================================
245
246A DMIC extended link is identified when LCAP.ALT=1 and
247LEPTR.ID=0xC0 are set.
248
249DMA control uses the existing LOSIDV register
250
251Changes include additional descriptions for enumeration and control that were not
252present 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
256with LCTL.OFLEN
257- move of SHIM and SSP IP registers to different offsets, with no
258change in functionality. The LEPTR.PTR value is an offset from the ML
259address, with a default value of 0x28000.
260
261Extended 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
19low-level driver implementation details. It only describes the standard19low-level driver implementation details. It only describes the standard
20way to write a PCI sound driver on ALSA.20way to write a PCI sound driver on ALSA.
21 21
22This document is still a draft version. Any feedback and corrections,
23please!!
24
25File Tree Structure22File Tree Structure
26===================23===================
27 24
28General25General
29-------26-------
30 27
31The file tree structure of ALSA driver is depicted below.28The file tree structure of ALSA driver is depicted below::
32
33::
34 29
35 sound30 sound
36 /core31 /core
@@ -68,8 +63,8 @@ kernel config. · 31 unmodified lines
68core/oss63core/oss
69~~~~~~~~64~~~~~~~~
70 65
71The codes for PCM and mixer OSS emulation modules are stored in this66The code for OSS PCM and mixer emulation modules is stored in this
72directory. The rawmidi OSS emulation is included in the ALSA rawmidi67directory. The OSS rawmidi emulation is included in the ALSA rawmidi
73code since it's quite small. The sequencer code is stored in68code since it's quite small. The sequencer code is stored in
74``core/seq/oss`` directory (see `below <core/seq/oss_>`__).69``core/seq/oss`` directory (see `below <core/seq/oss_>`__).
75 70
@@ -78,19 +73,19 @@ core/seq · 2 unmodified lines
78 73
79This directory and its sub-directories are for the ALSA sequencer. This74This directory and its sub-directories are for the ALSA sequencer. This
80directory contains the sequencer core and primary sequencer modules such75directory contains the sequencer core and primary sequencer modules such
81like snd-seq-midi, snd-seq-virmidi, etc. They are compiled only when76as snd-seq-midi, snd-seq-virmidi, etc. They are compiled only when
82``CONFIG_SND_SEQUENCER`` is set in the kernel config.77``CONFIG_SND_SEQUENCER`` is set in the kernel config.
83 78
84core/seq/oss79core/seq/oss
85~~~~~~~~~~~~80~~~~~~~~~~~~
86 81
87This contains the OSS sequencer emulation codes.82This contains the OSS sequencer emulation code.
88 83
89include directory84include directory
90-----------------85-----------------
91 86
92This is the place for the public header files of ALSA drivers, which are87This is the place for the public header files of ALSA drivers, which are
93to be exported to user-space, or included by several files at different88to be exported to user-space, or included by several files in different
94directories. Basically, the private header files should not be placed in89directories. Basically, the private header files should not be placed in
95this directory, but you may still find files there, due to historical90this directory, but you may still find files there, due to historical
96reasons :)91reasons :)
@@ -100,7 +95,7 @@ drivers directory · 3 unmodified lines
100 95
101This directory contains code shared among different drivers on different96This directory contains code shared among different drivers on different
102architectures. They are hence supposed not to be architecture-specific.97architectures. They are hence supposed not to be architecture-specific.
103For example, the dummy pcm driver and the serial MIDI driver are found98For example, the dummy PCM driver and the serial MIDI driver are found
104in this directory. In the sub-directories, there is code for components99in this directory. In the sub-directories, there is code for components
105which are independent from bus and cpu architectures.100which are independent from bus and cpu architectures.
106 101
@@ -156,8 +151,8 @@ these architectures. · 49 unmodified lines
156usb directory151usb directory
157-------------152-------------
158 153
159This directory contains the USB-audio driver. In the latest version, the154This directory contains the USB-audio driver.
160USB MIDI driver is integrated in the usb-audio driver.155The USB MIDI driver is integrated in the usb-audio driver.
161 156
162pcmcia directory157pcmcia directory
163----------------158----------------
@@ -175,9 +170,9 @@ layer including ASoC core, codec and machine drivers. · 11 unmodified lines
175oss directory170oss directory
176-------------171-------------
177 172
178Here contains OSS/Lite codes.173This contains OSS/Lite code.
179All codes have been deprecated except for dmasound on m68k as of174At the time of writing, all code has been removed except for dmasound
180writing this.175on m68k.
181 176
182 177
183Basic Flow for PCI Drivers178Basic Flow for PCI Drivers
@@ -341,7 +336,7 @@ to details explained in the following section. · 157 unmodified lines
341 336
342 error:337 error:
343 snd_card_free(card);338 snd_card_free(card);
344 return err;339 return err;
345 }340 }
346 341
347 /* destructor -- see the "Destructor" sub-section */342 /* destructor -- see the "Destructor" sub-section */
@@ -381,7 +376,7 @@ where ``enable[dev]`` is the module option. · 33 unmodified lines
381 376
382Each time the ``probe`` callback is called, check the availability of377Each time the ``probe`` callback is called, check the availability of
383the device. If not available, simply increment the device index and378the device. If not available, simply increment the device index and
384returns. dev will be incremented also later (`step 7379return. dev will be incremented also later (`step 7
385<7) Set the PCI driver data and return zero._>`__).380<7) Set the PCI driver data and return zero._>`__).
386 381
3872) Create a card instance3822) Create a card instance
@@ -402,9 +397,7 @@ Components`_. · 14 unmodified lines
4023) Create a main component3973) Create a main component
403~~~~~~~~~~~~~~~~~~~~~~~~~~398~~~~~~~~~~~~~~~~~~~~~~~~~~
404 399
405In this part, the PCI resources are allocated.400In this part, the PCI resources are allocated::
406
407::
408 401
409 struct mychip *chip;402 struct mychip *chip;
410 ....403 ....
@@ -417,13 +410,11 @@ Management`_. · 6 unmodified lines
417 410
418When something goes wrong, the probe function needs to deal with the411When something goes wrong, the probe function needs to deal with the
419error. In this example, we have a single error handling path placed412error. In this example, we have a single error handling path placed
420at the end of the function.413at the end of the function::
421
422::
423 414
424 error:415 error:
425 snd_card_free(card);416 snd_card_free(card);
426 return err;417 return err;
427 418
428Since each component can be properly freed, the single419Since each component can be properly freed, the single
429:c:func:`snd_card_free()` call should suffice in most cases.420: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
483Destructor474Destructor
484----------475----------
485 476
486The destructor, remove callback, simply releases the card instance. Then477The destructor, the remove callback, simply releases the card instance.
487the ALSA middle layer will release all the attached components478Then the ALSA middle layer will release all the attached components
488automatically.479automatically.
489 480
490It would be typically just calling :c:func:`snd_card_free()`:481It would be typically just calling :c:func:`snd_card_free()`::
491
492::
493 482
494 static void snd_mychip_remove(struct pci_dev *pci)483 static void snd_mychip_remove(struct pci_dev *pci)
495 {484 {
@@ -504,9 +493,7 @@ Header Files · 8 unmodified lines
504------------493------------
505 494
506For the above example, at least the following include files are495For the above example, at least the following include files are
507necessary.496necessary::
508
509::
510 497
511 #include <linux/init.h>498 #include <linux/init.h>
512 #include <linux/pci.h>499 #include <linux/pci.h>
@@ -544,9 +531,7 @@ list on the card record is used to manage the correct release of · 31 unmodified lines
544resources at destruction.531resources at destruction.
545 532
546As mentioned above, to create a card instance, call533As mentioned above, to create a card instance, call
547:c:func:`snd_card_new()`.534:c:func:`snd_card_new()`::
548
549::
550 535
551 struct snd_card *card;536 struct snd_card *card;
552 int err;537 int err;
@@ -572,10 +557,8 @@ struct snd_device object. A component · 19 unmodified lines
572can be a PCM instance, a control interface, a raw MIDI interface, etc.557can be a PCM instance, a control interface, a raw MIDI interface, etc.
573Each such instance has one component entry.558Each such instance has one component entry.
574 559
575A component can be created via :c:func:`snd_device_new()`560A component can be created via the :c:func:`snd_device_new()`
576function.561function::
577
578::
579 562
580 snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);563 snd_device_new(card, SNDRV_DEV_XXX, chip, &ops);
581 564
@@ -591,7 +574,7 @@ allocated manually beforehand, and its pointer is passed as the · 9 unmodified lines
591argument. This pointer (``chip`` in the above example) is used as the574argument. This pointer (``chip`` in the above example) is used as the
592identifier for the instance.575identifier for the instance.
593 576
594Each pre-defined ALSA component such as ac97 and pcm calls577Each pre-defined ALSA component such as AC97 and PCM calls
595:c:func:`snd_device_new()` inside its constructor. The destructor578:c:func:`snd_device_new()` inside its constructor. The destructor
596for each component is defined in the callback pointers. Hence, you don't579for each component is defined in the callback pointers. Hence, you don't
597need to take care of calling a destructor for such a component.580need to take care of calling a destructor for such a component.
@@ -605,9 +588,7 @@ Chip-Specific Data · 7 unmodified lines
605------------------588------------------
606 589
607Chip-specific information, e.g. the I/O port address, its resource590Chip-specific information, e.g. the I/O port address, its resource
608pointer, or the irq number, is stored in the chip-specific record.591pointer, or the irq number, is stored in the chip-specific record::
609
610::
611 592
612 struct mychip {593 struct mychip {
613 ....594 ....
@@ -620,9 +601,7 @@ In general, there are two ways of allocating the chip record. · 6 unmodified lines
620~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~601~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
621 602
622As mentioned above, you can pass the extra-data-length to the 5th603As mentioned above, you can pass the extra-data-length to the 5th
623argument of :c:func:`snd_card_new()`, i.e.604argument of :c:func:`snd_card_new()`, e.g.::
624
625::
626 605
627 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,606 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
628 sizeof(struct mychip), &card);607 sizeof(struct mychip), &card);
@@ -642,9 +621,7 @@ released together with the card instance. · 13 unmodified lines
642~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~621~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
643 622
644After allocating a card instance via :c:func:`snd_card_new()`623After allocating a card instance via :c:func:`snd_card_new()`
645(with ``0`` on the 4th arg), call :c:func:`kzalloc()`.624(with ``0`` on the 4th arg), call :c:func:`kzalloc()`::
646
647::
648 625
649 struct snd_card *card;626 struct snd_card *card;
650 struct mychip *chip;627 struct mychip *chip;
@@ -663,16 +640,12 @@ The chip record should have the field to hold the card pointer at least, · 12 unmodified lines
663 };640 };
664 641
665 642
666Then, set the card pointer in the returned chip instance.643Then, set the card pointer in the returned chip instance::
667
668::
669 644
670 chip->card = card;645 chip->card = card;
671 646
672Next, initialize the fields, and register this chip record as a647Next, initialize the fields, and register this chip record as a
673low-level device with a specified ``ops``,648low-level device with a specified ``ops``::
674
675::
676 649
677 static const struct snd_device_ops ops = {650 static const struct snd_device_ops ops = {
678 .dev_free = snd_mychip_dev_free,651 .dev_free = snd_mychip_dev_free,
@@ -681,9 +654,7 @@ low-level device with a specified ``ops``, · 2 unmodified lines
681 snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);654 snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
682 655
683:c:func:`snd_mychip_dev_free()` is the device-destructor656:c:func:`snd_mychip_dev_free()` is the device-destructor
684function, which will call the real destructor.657function, which will call the real destructor::
685
686::
687 658
688 static int snd_mychip_dev_free(struct snd_device *device)659 static int snd_mychip_dev_free(struct snd_device *device)
689 {660 {
@@ -692,10 +663,10 @@ function, which will call the real destructor. · 2 unmodified lines
692 663
693where :c:func:`snd_mychip_free()` is the real destructor.664where :c:func:`snd_mychip_free()` is the real destructor.
694 665
695The demerit of this method is the obviously more amount of codes.666The demerit of this method is the obviously larger amount of code.
696The merit is, however, you can trigger the own callback at registering667The merit is, however, that you can trigger your own callback at
697and disconnecting the card via setting in snd_device_ops.668registering and disconnecting the card via a setting in snd_device_ops.
698About the registering and disconnecting the card, see the subsections669About registering and disconnecting the card, see the subsections
699below.670below.
700 671
701 672
@@ -724,9 +695,7 @@ Full Code Example · 22 unmodified lines
724-----------------695-----------------
725 696
726In this section, we'll complete the chip-specific constructor,697In this section, we'll complete the chip-specific constructor,
727destructor and PCI entries. Example code is shown first, below.698destructor and PCI entries. Example code is shown first, below::
728
729::
730 699
731 struct mychip {700 struct mychip {
732 struct snd_card *card;701 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
866accessed I/O range. In some cases, you might need to call835accessed I/O range. In some cases, you might need to call
867:c:func:`pci_set_master()` function, too.836:c:func:`pci_set_master()` function, too.
868 837
869Suppose the 28bit mask, and the code to be added would be like:838Suppose a 28bit mask, the code to be added would look like::
870
871::
872 839
873 err = pci_enable_device(pci);840 err = pci_enable_device(pci);
874 if (err < 0)841 if (err < 0)
@@ -890,9 +857,7 @@ function (see below). · 15 unmodified lines
890 857
891Now assume that the PCI device has an I/O port with 8 bytes and an858Now assume that the PCI device has an I/O port with 8 bytes and an
892interrupt. Then struct mychip will have the859interrupt. Then struct mychip will have the
893following fields:860following fields::
894
895::
896 861
897 struct mychip {862 struct mychip {
898 struct snd_card *card;863 struct snd_card *card;
@@ -905,14 +870,12 @@ following fields: · 6 unmodified lines
905For an I/O port (and also a memory region), you need to have the870For an I/O port (and also a memory region), you need to have the
906resource pointer for the standard resource management. For an irq, you871resource pointer for the standard resource management. For an irq, you
907have to keep only the irq number (integer). But you need to initialize872have to keep only the irq number (integer). But you need to initialize
908this number as -1 before actual allocation, since irq 0 is valid. The873this number to -1 before actual allocation, since irq 0 is valid. The
909port address and its resource pointer can be initialized as null by874port address and its resource pointer can be initialized as null by
910:c:func:`kzalloc()` automatically, so you don't have to take care of875:c:func:`kzalloc()` automatically, so you don't have to take care of
911resetting them.876resetting them.
912 877
913The allocation of an I/O port is done like this:878The allocation of an I/O port is done like this::
914
915::
916 879
917 err = pci_request_regions(pci, "My Chip");880 err = pci_request_regions(pci, "My Chip");
918 if (err < 0) { 881 if (err < 0) {
@@ -928,9 +891,7 @@ The returned value, ``chip->res_port``, is allocated via · 9 unmodified lines
928must be released via :c:func:`kfree()`, but there is a problem with891must be released via :c:func:`kfree()`, but there is a problem with
929this. This issue will be explained later.892this. This issue will be explained later.
930 893
931The allocation of an interrupt source is done like this:894The allocation of an interrupt source is done like this::
932
933::
934 895
935 if (request_irq(pci->irq, snd_mychip_interrupt,896 if (request_irq(pci->irq, snd_mychip_interrupt,
936 IRQF_SHARED, KBUILD_MODNAME, chip)) {897 IRQF_SHARED, KBUILD_MODNAME, chip)) {
@@ -954,9 +915,7 @@ used for that, but you can use what you like, too. · 17 unmodified lines
954 915
955I won't give details about the interrupt handler at this point, but at916I won't give details about the interrupt handler at this point, but at
956least its appearance can be explained now. The interrupt handler looks917least its appearance can be explained now. The interrupt handler looks
957usually like the following:918usually as follows::
958
959::
960 919
961 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)920 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
962 {921 {
@@ -966,13 +925,12 @@ usually like the following: · 3 unmodified lines
966 }925 }
967 926
968After requesting the IRQ, you can passed it to ``card->sync_irq``927After requesting the IRQ, you can passed it to ``card->sync_irq``
969field:928field::
970::
971 929
972 card->irq = chip->irq;930 card->irq = chip->irq;
973 931
974This allows PCM core automatically performing932This allows the PCM core to automatically call
975:c:func:`synchronize_irq()` at the necessary timing like ``hw_free``.933:c:func:`synchronize_irq()` at the right time, like before ``hw_free``.
976See the later section `sync_stop callback`_ for details.934See the later section `sync_stop callback`_ for details.
977 935
978Now let's write the corresponding destructor for the resources above.936Now 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
981so the disabling code is not written here.939so the disabling code is not written here.
982 940
983To release the resources, the “check-and-release” method is a safer way.941To release the resources, the “check-and-release” method is a safer way.
984For the interrupt, do like this:942For the interrupt, do like this::
985
986::
987 943
988 if (chip->irq >= 0)944 if (chip->irq >= 0)
989 free_irq(chip->irq, chip);945 free_irq(chip->irq, chip);
@@ -997,9 +953,7 @@ When you requested I/O ports or memory regions via · 7 unmodified lines
997:c:func:`pci_request_regions()` like in this example, release the953:c:func:`pci_request_regions()` like in this example, release the
998resource(s) using the corresponding function,954resource(s) using the corresponding function,
999:c:func:`pci_release_region()` or955:c:func:`pci_release_region()` or
1000:c:func:`pci_release_regions()`.956:c:func:`pci_release_regions()`::
1001
1002::
1003 957
1004 pci_release_regions(chip->pci);958 pci_release_regions(chip->pci);
1005 959
@@ -1007,39 +961,32 @@ When you requested manually via :c:func:`request_region()` or · 1 unmodified line
1007:c:func:`request_mem_region()`, you can release it via961:c:func:`request_mem_region()`, you can release it via
1008:c:func:`release_resource()`. Suppose that you keep the resource962:c:func:`release_resource()`. Suppose that you keep the resource
1009pointer returned from :c:func:`request_region()` in963pointer returned from :c:func:`request_region()` in
1010chip->res_port, the release procedure looks like:964chip->res_port, the release procedure looks like::
1011
1012::
1013 965
1014 release_and_free_resource(chip->res_port);966 release_and_free_resource(chip->res_port);
1015 967
1016Don't forget to call :c:func:`pci_disable_device()` before the968Don't forget to call :c:func:`pci_disable_device()` before the
1017end.969end.
1018 970
1019And finally, release the chip-specific record.971And finally, release the chip-specific record::
1020
1021::
1022 972
1023 kfree(chip);973 kfree(chip);
1024 974
1025We didn't implement the hardware disabling part in the above. If you975We didn't implement the hardware disabling part above. If you
1026need to do this, please note that the destructor may be called even976need to do this, please note that the destructor may be called even
1027before the initialization of the chip is completed. It would be better977before the initialization of the chip is completed. It would be better
1028to have a flag to skip hardware disabling if the hardware was not978to have a flag to skip hardware disabling if the hardware was not
1029initialized yet.979initialized yet.
1030 980
1031When the chip-data is assigned to the card using981When the chip-data is assigned to the card using
1032:c:func:`snd_device_new()` with ``SNDRV_DEV_LOWLELVEL`` , its982:c:func:`snd_device_new()` with ``SNDRV_DEV_LOWLELVEL``, its
1033destructor is called at the last. That is, it is assured that all other983destructor is called last. That is, it is assured that all other
1034components like PCMs and controls have already been released. You don't984components like PCMs and controls have already been released. You don't
1035have to stop PCMs, etc. explicitly, but just call low-level hardware985have to stop PCMs, etc. explicitly, but just call low-level hardware
1036stopping.986stopping.
1037 987
1038The management of a memory-mapped region is almost as same as the988The management of a memory-mapped region is almost as same as the
1039management of an I/O port. You'll need three fields like the989management of an I/O port. You'll need two fields as follows::
1040following:
1041
1042::
1043 990
1044 struct mychip {991 struct mychip {
1045 ....992 ....
@@ -1047,9 +994,7 @@ following: · 1 unmodified line
1047 void __iomem *iobase_virt;994 void __iomem *iobase_virt;
1048 };995 };
1049 996
1050and the allocation would be like below:997and the allocation would look like below::
1051
1052::
1053 998
1054 err = pci_request_regions(pci, "My Chip");999 err = pci_request_regions(pci, "My Chip");
1055 if (err < 0) {1000 if (err < 0) {
@@ -1060,9 +1005,7 @@ and the allocation would be like below: · 4 unmodified lines
1060 chip->iobase_virt = ioremap(chip->iobase_phys,1005 chip->iobase_virt = ioremap(chip->iobase_phys,
1061 pci_resource_len(pci, 0));1006 pci_resource_len(pci, 0));
1062 1007
1063and the corresponding destructor would be:1008and the corresponding destructor would be::
1064
1065::
1066 1009
1067 static int snd_mychip_free(struct mychip *chip)1010 static int snd_mychip_free(struct mychip *chip)
1068 {1011 {
@@ -1075,9 +1018,7 @@ and the corresponding destructor would be: · 6 unmodified lines
1075 }1018 }
1076 1019
1077Of course, a modern way with :c:func:`pci_iomap()` will make things a1020Of course, a modern way with :c:func:`pci_iomap()` will make things a
1078bit easier, too.1021bit easier, too::
1079
1080::
1081 1022
1082 err = pci_request_regions(pci, "My Chip");1023 err = pci_request_regions(pci, "My Chip");
1083 if (err < 0) {1024 if (err < 0) {
@@ -1097,9 +1038,7 @@ struct pci_device_id table for · 13 unmodified lines
1097this chipset. It's a table of PCI vendor/device ID number, and some1038this chipset. It's a table of PCI vendor/device ID number, and some
1098masks.1039masks.
1099 1040
1100For example,1041For example::
1101
1102::
1103 1042
1104 static struct pci_device_id snd_mychip_ids[] = {1043 static struct pci_device_id snd_mychip_ids[] = {
1105 { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,1044 { 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
1120all-zero entry.1059all-zero entry.
1121 1060
1122Then, prepare the struct pci_driver1061Then, prepare the struct pci_driver
1123record:1062record::
1124
1125::
1126 1063
1127 static struct pci_driver driver = {1064 static struct pci_driver driver = {
1128 .name = KBUILD_MODNAME,1065 .name = KBUILD_MODNAME,
@@ -1133,11 +1070,9 @@ record: · 4 unmodified lines
1133 1070
1134The ``probe`` and ``remove`` functions have already been defined in1071The ``probe`` and ``remove`` functions have already been defined in
1135the previous sections. The ``name`` field is the name string of this1072the previous sections. The ``name`` field is the name string of this
1136device. Note that you must not use a slash “/” in this string.1073device. Note that you must not use slashes (“/”) in this string.
1137
1138And at last, the module entries:
1139 1074
1140::1075And at last, the module entries::
1141 1076
1142 static int __init alsa_card_mychip_init(void)1077 static int __init alsa_card_mychip_init(void)
1143 {1078 {
@@ -1167,22 +1102,22 @@ The PCM middle layer of ALSA is quite powerful and it is only necessary · 23 unmodified lines
1167for each driver to implement the low-level functions to access its1102for each driver to implement the low-level functions to access its
1168hardware.1103hardware.
1169 1104
1170For accessing to the PCM layer, you need to include ``<sound/pcm.h>``1105To access the PCM layer, you need to include ``<sound/pcm.h>``
1171first. In addition, ``<sound/pcm_params.h>`` might be needed if you1106first. In addition, ``<sound/pcm_params.h>`` might be needed if you
1172access to some functions related with hw_param.1107access some functions related with hw_param.
1173 1108
1174Each card device can have up to four pcm instances. A pcm instance1109Each card device can have up to four PCM instances. A PCM instance
1175corresponds to a pcm device file. The limitation of number of instances1110corresponds to a PCM device file. The limitation of number of instances
1176comes only from the available bit size of the Linux's device numbers.1111comes only from the available bit size of Linux' device numbers.
1177Once when 64bit device number is used, we'll have more pcm instances1112Once 64bit device numbers are used, we'll have more PCM instances
1178available.1113available.
1179 1114
1180A pcm instance consists of pcm playback and capture streams, and each1115A PCM instance consists of PCM playback and capture streams, and each
1181pcm stream consists of one or more pcm substreams. Some soundcards1116PCM stream consists of one or more PCM substreams. Some soundcards
1182support multiple playback functions. For example, emu10k1 has a PCM1117support multiple playback functions. For example, emu10k1 has a PCM
1183playback of 32 stereo substreams. In this case, at each open, a free1118playback of 32 stereo substreams. In this case, at each open, a free
1184substream is (usually) automatically chosen and opened. Meanwhile, when1119substream is (usually) automatically chosen and opened. Meanwhile, when
1185only one substream exists and it was already opened, the successful open1120only one substream exists and it was already opened, a subsequent open
1186will either block or error with ``EAGAIN`` according to the file open1121will either block or error with ``EAGAIN`` according to the file open
1187mode. But you don't have to care about such details in your driver. The1122mode. But you don't have to care about such details in your driver. The
1188PCM middle layer will take care of such work.1123PCM middle layer will take care of such work.
@@ -1191,9 +1126,7 @@ Full Code Example · 2 unmodified lines
1191-----------------1126-----------------
1192 1127
1193The example code below does not include any hardware access routines but1128The example code below does not include any hardware access routines but
1194shows only the skeleton, how to build up the PCM interfaces.1129shows only the skeleton, how to build up the PCM interfaces::
1195
1196::
1197 1130
1198 #include <sound/pcm.h>1131 #include <sound/pcm.h>
1199 ....1132 ....
@@ -1399,10 +1332,8 @@ shows only the skeleton, how to build up the PCM interfaces. · 199 unmodified lines
1399PCM Constructor1332PCM Constructor
1400---------------1333---------------
1401 1334
1402A pcm instance is allocated by the :c:func:`snd_pcm_new()`1335A PCM instance is allocated by the :c:func:`snd_pcm_new()`
1403function. It would be better to create a constructor for pcm, namely,1336function. It would be better to create a constructor for the PCM, namely::
1404
1405::
1406 1337
1407 static int snd_mychip_new_pcm(struct mychip *chip)1338 static int snd_mychip_new_pcm(struct mychip *chip)
1408 {1339 {
@@ -1415,16 +1346,16 @@ function. It would be better to create a constructor for pcm, namely, · 6 unmodified lines
1415 pcm->private_data = chip;1346 pcm->private_data = chip;
1416 strcpy(pcm->name, "My Chip");1347 strcpy(pcm->name, "My Chip");
1417 chip->pcm = pcm;1348 chip->pcm = pcm;
1418 ....1349 ...
1419 return 0;1350 return 0;
1420 }1351 }
1421 1352
1422The :c:func:`snd_pcm_new()` function takes four arguments. The1353The :c:func:`snd_pcm_new()` function takes six arguments. The
1423first argument is the card pointer to which this pcm is assigned, and1354first argument is the card pointer to which this PCM is assigned, and
1424the second is the ID string.1355the second is the ID string.
1425 1356
1426The third argument (``index``, 0 in the above) is the index of this new1357The third argument (``index``, 0 in the above) is the index of this new
1427pcm. It begins from zero. If you create more than one pcm instances,1358PCM. It begins from zero. If you create more than one PCM instances,
1428specify the different numbers in this argument. For example, ``index =1359specify the different numbers in this argument. For example, ``index =
14291`` for the second PCM device.13601`` for the second PCM device.
1430 1361
@@ -1437,26 +1368,20 @@ If a chip supports multiple playbacks or captures, you can specify more · 6 unmodified lines
1437numbers, but they must be handled properly in open/close, etc.1368numbers, but they must be handled properly in open/close, etc.
1438callbacks. When you need to know which substream you are referring to,1369callbacks. When you need to know which substream you are referring to,
1439then it can be obtained from struct snd_pcm_substream data passed to each1370then it can be obtained from struct snd_pcm_substream data passed to each
1440callback as follows:1371callback as follows::
1441
1442::
1443 1372
1444 struct snd_pcm_substream *substream;1373 struct snd_pcm_substream *substream;
1445 int index = substream->number;1374 int index = substream->number;
1446 1375
1447 1376
1448After the pcm is created, you need to set operators for each pcm stream.1377After the PCM is created, you need to set operators for each PCM stream::
1449
1450::
1451 1378
1452 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,1379 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1453 &snd_mychip_playback_ops);1380 &snd_mychip_playback_ops);
1454 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,1381 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1455 &snd_mychip_capture_ops);1382 &snd_mychip_capture_ops);
1456 1383
1457The operators are defined typically like this:1384The operators are defined typically like this::
1458
1459::
1460 1385
1461 static struct snd_pcm_ops snd_mychip_playback_ops = {1386 static struct snd_pcm_ops snd_mychip_playback_ops = {
1462 .open = snd_mychip_pcm_open,1387 .open = snd_mychip_pcm_open,
@@ -1472,25 +1397,21 @@ All the callbacks are described in the Operators_ subsection. · 9 unmodified lines
1472 1397
1473After setting the operators, you probably will want to pre-allocate the1398After setting the operators, you probably will want to pre-allocate the
1474buffer and set up the managed allocation mode.1399buffer and set up the managed allocation mode.
1475For that, simply call the following:1400For that, simply call the following::
1476
1477::
1478 1401
1479 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,1402 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
1480 &chip->pci->dev,1403 &chip->pci->dev,
1481 64*1024, 64*1024);1404 64*1024, 64*1024);
1482 1405
1483It will allocate a buffer up to 64kB as default. Buffer management1406It will allocate a buffer up to 64kB by default. Buffer management
1484details will be described in the later section `Buffer and Memory1407details will be described in the later section `Buffer and Memory
1485Management`_.1408Management`_.
1486 1409
1487Additionally, you can set some extra information for this pcm in1410Additionally, you can set some extra information for this PCM in
1488``pcm->info_flags``. The available values are defined as1411``pcm->info_flags``. The available values are defined as
1489``SNDRV_PCM_INFO_XXX`` in ``<sound/asound.h>``, which is used for the1412``SNDRV_PCM_INFO_XXX`` in ``<sound/asound.h>``, which is used for the
1490hardware definition (described later). When your soundchip supports only1413hardware definition (described later). When your soundchip supports only
1491half-duplex, specify like this:1414half-duplex, specify it like this::
1492
1493::
1494 1415
1495 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;1416 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
1496 1417
@@ -1498,15 +1419,13 @@ half-duplex, specify like this: · 1 unmodified line
1498... And the Destructor?1419... And the Destructor?
1499-----------------------1420-----------------------
1500 1421
1501The destructor for a pcm instance is not always necessary. Since the pcm1422The destructor for a PCM instance is not always necessary. Since the PCM
1502device will be released by the middle layer code automatically, you1423device will be released by the middle layer code automatically, you
1503don't have to call the destructor explicitly.1424don't have to call the destructor explicitly.
1504 1425
1505The destructor would be necessary if you created special records1426The destructor would be necessary if you created special records
1506internally and needed to release them. In such a case, set the1427internally and needed to release them. In such a case, set the
1507destructor function to ``pcm->private_free``:1428destructor function to ``pcm->private_free``::
1508
1509::
1510 1429
1511 static void mychip_pcm_free(struct snd_pcm *pcm)1430 static void mychip_pcm_free(struct snd_pcm *pcm)
1512 {1431 {
@@ -1537,13 +1456,11 @@ Runtime Pointer - The Chest of PCM Information · 24 unmodified lines
1537When the PCM substream is opened, a PCM runtime instance is allocated1456When the PCM substream is opened, a PCM runtime instance is allocated
1538and assigned to the substream. This pointer is accessible via1457and assigned to the substream. This pointer is accessible via
1539``substream->runtime``. This runtime pointer holds most information you1458``substream->runtime``. This runtime pointer holds most information you
1540need to control the PCM: the copy of hw_params and sw_params1459need to control the PCM: a copy of hw_params and sw_params
1541configurations, the buffer pointers, mmap records, spinlocks, etc.1460configurations, the buffer pointers, mmap records, spinlocks, etc.
1542 1461
1543The definition of runtime instance is found in ``<sound/pcm.h>``. Here1462The definition of runtime instance is found in ``<sound/pcm.h>``. Here
1544are the contents of this file:1463is the relevant part of this file::
1545
1546::
1547 1464
1548 struct _snd_pcm_runtime {1465 struct _snd_pcm_runtime {
1549 /* -- Status -- */1466 /* -- Status -- */
@@ -1577,14 +1494,19 @@ are the contents of this file: · 27 unmodified lines
1577 unsigned int period_step;1494 unsigned int period_step;
1578 unsigned int sleep_min; /* min ticks to sleep */1495 unsigned int sleep_min; /* min ticks to sleep */
1579 snd_pcm_uframes_t start_threshold;1496 snd_pcm_uframes_t start_threshold;
1580 snd_pcm_uframes_t stop_threshold;1497 /*
1581 snd_pcm_uframes_t silence_threshold; /* Silence filling happens when1498 * The following two thresholds alleviate playback buffer underruns; when
1582 noise is nearest than this */1499 * hw_avail drops below the threshold, the respective action is triggered:
1583 snd_pcm_uframes_t silence_size; /* Silence filling size */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 */
1584 snd_pcm_uframes_t boundary; /* pointers wrap point */1505 snd_pcm_uframes_t boundary; /* pointers wrap point */
1585 1506
1586 snd_pcm_uframes_t silenced_start;1507 /* internal data of auto-silencer */
1587 snd_pcm_uframes_t silenced_size;1508 snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
1509 snd_pcm_uframes_t silence_filled; /* size filled with silence */
1588 1510
1589 snd_pcm_sync_id_t sync; /* hardware synchronization ID */1511 snd_pcm_sync_id_t sync; /* hardware synchronization ID */
1590 1512
@@ -1638,14 +1560,12 @@ Hardware Description · 47 unmodified lines
1638 1560
1639The hardware descriptor (struct snd_pcm_hardware) contains the definitions of1561The hardware descriptor (struct snd_pcm_hardware) contains the definitions of
1640the fundamental hardware configuration. Above all, you'll need to define this1562the fundamental hardware configuration. Above all, you'll need to define this
1641in the `PCM open callback`_. Note that the runtime instance holds the copy of1563in the `PCM open callback`_. Note that the runtime instance holds a copy of
1642the descriptor, not the pointer to the existing descriptor. That is,1564the descriptor, not a pointer to the existing descriptor. That is,
1643in the open callback, you can modify the copied descriptor1565in the open callback, you can modify the copied descriptor
1644(``runtime->hw``) as you need. For example, if the maximum number of1566(``runtime->hw``) as you need. For example, if the maximum number of
1645channels is 1 only on some chip models, you can still use the same1567channels is 1 only on some chip models, you can still use the same
1646hardware descriptor and change the channels_max later:1568hardware descriptor and change the channels_max later::
1647
1648::
1649 1569
1650 struct snd_pcm_runtime *runtime = substream->runtime;1570 struct snd_pcm_runtime *runtime = substream->runtime;
1651 ...1571 ...
@@ -1653,9 +1573,7 @@ hardware descriptor and change the channels_max later: · 1 unmodified line
1653 if (chip->model == VERY_OLD_ONE)1573 if (chip->model == VERY_OLD_ONE)
1654 runtime->hw.channels_max = 1;1574 runtime->hw.channels_max = 1;
1655 1575
1656Typically, you'll have a hardware descriptor as below:1576Typically, you'll have a hardware descriptor as below::
1657
1658::
1659 1577
1660 static struct snd_pcm_hardware snd_mychip_playback_hw = {1578 static struct snd_pcm_hardware snd_mychip_playback_hw = {
1661 .info = (SNDRV_PCM_INFO_MMAP |1579 .info = (SNDRV_PCM_INFO_MMAP |
@@ -1676,51 +1594,51 @@ Typically, you'll have a hardware descriptor as below: · 14 unmodified lines
1676 };1594 };
1677 1595
1678- The ``info`` field contains the type and capabilities of this1596- The ``info`` field contains the type and capabilities of this
1679 pcm. The bit flags are defined in ``<sound/asound.h>`` as1597 PCM. The bit flags are defined in ``<sound/asound.h>`` as
1680 ``SNDRV_PCM_INFO_XXX``. Here, at least, you have to specify whether1598 ``SNDRV_PCM_INFO_XXX``. Here, at least, you have to specify whether
1681 the mmap is supported and which interleaved format is1599 mmap is supported and which interleaving formats are
1682 supported. When the hardware supports mmap, add the1600 supported. When the hardware supports mmap, add the
1683 ``SNDRV_PCM_INFO_MMAP`` flag here. When the hardware supports the1601 ``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
1685 ``SNDRV_PCM_INFO_INTERLEAVED`` or ``SNDRV_PCM_INFO_NONINTERLEAVED``1603 ``SNDRV_PCM_INFO_INTERLEAVED`` or ``SNDRV_PCM_INFO_NONINTERLEAVED``
1686 flag must be set, respectively. If both are supported, you can set1604 flag must be set, respectively. If both are supported, you can set
1687 both, too.1605 both, too.
1688 1606
1689 In the above example, ``MMAP_VALID`` and ``BLOCK_TRANSFER`` are1607 In the above example, ``MMAP_VALID`` and ``BLOCK_TRANSFER`` are
1690 specified for the OSS mmap mode. Usually both are set. Of course,1608 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.
1692 1610
1693 The other possible flags are ``SNDRV_PCM_INFO_PAUSE`` and1611 The other possible flags are ``SNDRV_PCM_INFO_PAUSE`` and
1694 ``SNDRV_PCM_INFO_RESUME``. The ``PAUSE`` bit means that the pcm1612 ``SNDRV_PCM_INFO_RESUME``. The ``PAUSE`` bit means that the PCM
1695 supports the “pause” operation, while the ``RESUME`` bit means that1613 supports the “pause” operation, while the ``RESUME`` bit means that
1696 the pcm supports the full “suspend/resume” operation. If the1614 the PCM supports the full “suspend/resume” operation. If the
1697 ``PAUSE`` flag is set, the ``trigger`` callback below must handle1615 ``PAUSE`` flag is set, the ``trigger`` callback below must handle
1698 the corresponding (pause push/release) commands. The suspend/resume1616 the corresponding (pause push/release) commands. The suspend/resume
1699 trigger commands can be defined even without the ``RESUME``1617 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.
1701 1619
1702 When the PCM substreams can be synchronized (typically,1620 When the PCM substreams can be synchronized (typically,
1703 synchronized start/stop of a playback and a capture streams), you1621 synchronized start/stop of a playback and a capture stream), you
1704 can give ``SNDRV_PCM_INFO_SYNC_START``, too. In this case, you'll1622 can give ``SNDRV_PCM_INFO_SYNC_START``, too. In this case, you'll
1705 need to check the linked-list of PCM substreams in the trigger1623 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.
1707 1625
1708- ``formats`` field contains the bit-flags of supported formats1626- The ``formats`` field contains the bit-flags of supported formats
1709 (``SNDRV_PCM_FMTBIT_XXX``). If the hardware supports more than one1627 (``SNDRV_PCM_FMTBIT_XXX``). If the hardware supports more than one
1710 format, give all or'ed bits. In the example above, the signed 16bit1628 format, give all or'ed bits. In the example above, the signed 16bit
1711 little-endian format is specified.1629 little-endian format is specified.
1712 1630
1713- ``rates`` field contains the bit-flags of supported rates1631- The ``rates`` field contains the bit-flags of supported rates
1714 (``SNDRV_PCM_RATE_XXX``). When the chip supports continuous rates,1632 (``SNDRV_PCM_RATE_XXX``). When the chip supports continuous rates,
1715 pass ``CONTINUOUS`` bit additionally. The pre-defined rate bits are1633 pass the ``CONTINUOUS`` bit additionally. The pre-defined rate bits
1716 provided only for typical rates. If your chip supports1634 are provided only for typical rates. If your chip supports
1717 unconventional rates, you need to add the ``KNOT`` bit and set up1635 unconventional rates, you need to add the ``KNOT`` bit and set up
1718 the hardware constraint manually (explained later).1636 the hardware constraint manually (explained later).
1719 1637
1720- ``rate_min`` and ``rate_max`` define the minimum and maximum sample1638- ``rate_min`` and ``rate_max`` define the minimum and maximum sample
1721 rate. This should correspond somehow to ``rates`` bits.1639 rate. This should correspond somehow to ``rates`` bits.
1722 1640
1723- ``channels_min`` and ``channels_max`` define, as you might already1641- ``channels_min`` and ``channels_max`` define, as you might have already
1724 expected, the minimum and maximum number of channels.1642 expected, the minimum and maximum number of channels.
1725 1643
1726- ``buffer_bytes_max`` defines the maximum buffer size in1644- ``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
1732 number of periods in the buffer.1650 number of periods in the buffer.
1733 1651
1734 The “period” is a term that corresponds to a fragment in the OSS1652 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 is1653 world. The period defines the point at which a PCM interrupt is
1736 generated. This size strongly depends on the hardware. Generally,1654 generated. This point strongly depends on the hardware. Generally,
1737 the smaller period size will give you more interrupts, that is,1655 a smaller period size will give you more interrupts, which results
1738 more controls. In the case of capture, this size defines the input1656 in being able to fill/drain the buffer more timely. In the case of
1739 latency. On the other hand, the whole buffer size defines the1657 capture, this size defines the input latency. On the other hand,
1740 output latency for the playback direction.1658 the whole buffer size defines the output latency for the playback
1659 direction.
1741 1660
1742- There is also a field ``fifo_size``. This specifies the size of the1661- 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 nor1662 hardware FIFO, but currently it is neither used by the drivers nor
1744 in the alsa-lib. So, you can ignore this field.1663 in the alsa-lib. So, you can ignore this field.
1745 1664
1746PCM Configurations1665PCM Configurations
@@ -1759,34 +1678,32 @@ One thing to be noted is that the configured buffer and period sizes · 12 unmodified lines
1759are stored in “frames” in the runtime. In the ALSA world, ``1 frame =1678are stored in “frames” in the runtime. In the ALSA world, ``1 frame =
1760channels \* samples-size``. For conversion between frames and bytes,1679channels \* samples-size``. For conversion between frames and bytes,
1761you can use the :c:func:`frames_to_bytes()` and1680you can use the :c:func:`frames_to_bytes()` and
1762:c:func:`bytes_to_frames()` helper functions.1681:c:func:`bytes_to_frames()` helper functions::
1763
1764::
1765 1682
1766 period_bytes = frames_to_bytes(runtime, runtime->period_size);1683 period_bytes = frames_to_bytes(runtime, runtime->period_size);
1767 1684
1768Also, many software parameters (sw_params) are stored in frames, too.1685Also, many software parameters (sw_params) are stored in frames, too.
1769Please check the type of the field. ``snd_pcm_uframes_t`` is for the1686Please check the type of the field. ``snd_pcm_uframes_t`` is for
1770frames as unsigned integer while ``snd_pcm_sframes_t`` is for the1687frames as unsigned integer while ``snd_pcm_sframes_t`` is for
1771frames as signed integer.1688frames as signed integer.
1772 1689
1773DMA Buffer Information1690DMA Buffer Information
1774~~~~~~~~~~~~~~~~~~~~~~1691~~~~~~~~~~~~~~~~~~~~~~
1775 1692
1776The DMA buffer is defined by the following four fields, ``dma_area``,1693The DMA buffer is defined by the following four fields: ``dma_area``,
1777``dma_addr``, ``dma_bytes`` and ``dma_private``. The ``dma_area``1694``dma_addr``, ``dma_bytes`` and ``dma_private``. ``dma_area``
1778holds the buffer pointer (the logical address). You can call1695holds the buffer pointer (the logical address). You can call
1779:c:func:`memcpy()` from/to this pointer. Meanwhile, ``dma_addr`` holds1696:c:func:`memcpy()` from/to this pointer. Meanwhile, ``dma_addr`` holds
1780the physical address of the buffer. This field is specified only when1697the physical address of the buffer. This field is specified only when
1781the buffer is a linear buffer. ``dma_bytes`` holds the size of buffer1698the buffer is a linear buffer. ``dma_bytes`` holds the size of the
1782in bytes. ``dma_private`` is used for the ALSA DMA allocator.1699buffer in bytes. ``dma_private`` is used for the ALSA DMA allocator.
1783 1700
1784If you use either the managed buffer allocation mode or the standard1701If you use either the managed buffer allocation mode or the standard
1785API function :c:func:`snd_pcm_lib_malloc_pages()` for allocating the buffer,1702API function :c:func:`snd_pcm_lib_malloc_pages()` for allocating the buffer,
1786these fields are set by the ALSA middle layer, and you should *not*1703these fields are set by the ALSA middle layer, and you should *not*
1787change them by yourself. You can read them but not write them. On the1704change them by yourself. You can read them but not write them. On the
1788other hand, if you want to allocate the buffer by yourself, you'll1705other hand, if you want to allocate the buffer by yourself, you'll
1789need to manage it in hw_params callback. At least, ``dma_bytes`` is1706need to manage it in the hw_params callback. At least, ``dma_bytes`` is
1790mandatory. ``dma_area`` is necessary when the buffer is mmapped. If1707mandatory. ``dma_area`` is necessary when the buffer is mmapped. If
1791your driver doesn't support mmap, this field is not1708your driver doesn't support mmap, this field is not
1792necessary. ``dma_addr`` is also optional. You can use dma_private as1709necessary. ``dma_addr`` is also optional. You can use dma_private as
@@ -1796,13 +1713,13 @@ Running Status · 3 unmodified lines
1796~~~~~~~~~~~~~~1713~~~~~~~~~~~~~~
1797 1714
1798The running status can be referred via ``runtime->status``. This is1715The running status can be referred via ``runtime->status``. This is
1799the pointer to the struct snd_pcm_mmap_status record.1716a pointer to a struct snd_pcm_mmap_status record.
1800For example, you can get the current1717For example, you can get the current
1801DMA hardware pointer via ``runtime->status->hw_ptr``.1718DMA hardware pointer via ``runtime->status->hw_ptr``.
1802 1719
1803The DMA application pointer can be referred via ``runtime->control``,1720The DMA application pointer can be referred via ``runtime->control``,
1804which points to the struct snd_pcm_mmap_control record.1721which points to a struct snd_pcm_mmap_control record.
1805However, accessing directly to this value is not recommended.1722However, accessing this value directly is not recommended.
1806 1723
1807Private Data1724Private Data
1808~~~~~~~~~~~~1725~~~~~~~~~~~~
@@ -1811,11 +1728,10 @@ You can allocate a record for the substream and store it in · 2 unmodified lines
1811``runtime->private_data``. Usually, this is done in the `PCM open1728``runtime->private_data``. Usually, this is done in the `PCM open
1812callback`_. Don't mix this with ``pcm->private_data``. The1729callback`_. Don't mix this with ``pcm->private_data``. The
1813``pcm->private_data`` usually points to the chip instance assigned1730``pcm->private_data`` usually points to the chip instance assigned
1814statically at the creation of PCM, while the ``runtime->private_data``1731statically at creation time of the PCM device, while
1815points to a dynamic data structure created at the PCM open1732``runtime->private_data``
1816callback.1733points to a dynamic data structure created in the PCM open
1817 1734callback::
1818::
1819 1735
1820 static int snd_xxx_open(struct snd_pcm_substream *substream)1736 static int snd_xxx_open(struct snd_pcm_substream *substream)
1821 {1737 {
@@ -1832,20 +1748,18 @@ The allocated object must be released in the `close callback`_. · 10 unmodified lines
1832Operators1748Operators
1833---------1749---------
1834 1750
1835OK, now let me give details about each pcm callback (``ops``). In1751OK, now let me give details about each PCM callback (``ops``). In
1836general, every callback must return 0 if successful, or a negative1752general, every callback must return 0 if successful, or a negative
1837error number such as ``-EINVAL``. To choose an appropriate error1753error number such as ``-EINVAL``. To choose an appropriate error
1838number, it is advised to check what value other parts of the kernel1754number, it is advised to check what value other parts of the kernel
1839return when the same kind of request fails.1755return when the same kind of request fails.
1840 1756
1841The callback function takes at least the argument with1757Each callback function takes at least one argument containing a
1842struct snd_pcm_substream pointer. To retrieve the chip1758struct snd_pcm_substream pointer. To retrieve the chip
1843record from the given substream instance, you can use the following1759record from the given substream instance, you can use the following
1844macro.1760macro::
1845
1846::
1847 1761
1848 int xxx() {1762 int xxx(...) {
1849 struct mychip *chip = snd_pcm_substream_chip(substream);1763 struct mychip *chip = snd_pcm_substream_chip(substream);
1850 ....1764 ....
1851 }1765 }
@@ -1864,12 +1778,10 @@ PCM open callback · 12 unmodified lines
1864 1778
1865 static int snd_xxx_open(struct snd_pcm_substream *substream);1779 static int snd_xxx_open(struct snd_pcm_substream *substream);
1866 1780
1867This is called when a pcm substream is opened.1781This is called when a PCM substream is opened.
1868 1782
1869At least, here you have to initialize the ``runtime->hw``1783At least, here you have to initialize the ``runtime->hw``
1870record. Typically, this is done by like this:1784record. Typically, this is done like this::
1871
1872::
1873 1785
1874 static int snd_xxx_open(struct snd_pcm_substream *substream)1786 static int snd_xxx_open(struct snd_pcm_substream *substream)
1875 {1787 {
@@ -1883,7 +1795,7 @@ record. Typically, this is done by like this: · 7 unmodified lines
1883where ``snd_mychip_playback_hw`` is the pre-defined hardware1795where ``snd_mychip_playback_hw`` is the pre-defined hardware
1884description.1796description.
1885 1797
1886You can allocate a private data in this callback, as described in1798You can allocate private data in this callback, as described in the
1887`Private Data`_ section.1799`Private Data`_ section.
1888 1800
1889If the hardware configuration needs more constraints, set the hardware1801If the hardware configuration needs more constraints, set the hardware
@@ -1897,12 +1809,10 @@ close callback · 7 unmodified lines
1897 static int snd_xxx_close(struct snd_pcm_substream *substream);1809 static int snd_xxx_close(struct snd_pcm_substream *substream);
1898 1810
1899 1811
1900Obviously, this is called when a pcm substream is closed.1812Obviously, this is called when a PCM substream is closed.
1901
1902Any private instance for a pcm substream allocated in the ``open``
1903callback will be released here.
1904 1813
1905::1814Any private instance for a PCM substream allocated in the ``open``
1815callback will be released here::
1906 1816
1907 static int snd_xxx_close(struct snd_pcm_substream *substream)1817 static int snd_xxx_close(struct snd_pcm_substream *substream)
1908 {1818 {
@@ -1914,9 +1824,9 @@ callback will be released here. · 5 unmodified lines
1914ioctl callback1824ioctl callback
1915~~~~~~~~~~~~~~1825~~~~~~~~~~~~~~
1916 1826
1917This is used for any special call to pcm ioctls. But usually you can1827This is used for any special call to PCM ioctls. But usually you can
1918leave it as NULL, then PCM core calls the generic ioctl callback1828leave it NULL, then the PCM core calls the generic ioctl callback
1919function :c:func:`snd_pcm_lib_ioctl()`. If you need to deal with the1829function :c:func:`snd_pcm_lib_ioctl()`. If you need to deal with a
1920unique setup of channel info or reset procedure, you can pass your own1830unique setup of channel info or reset procedure, you can pass your own
1921callback function here.1831callback function here.
1922 1832
@@ -1928,22 +1838,20 @@ hw_params callback · 5 unmodified lines
1928 static int snd_xxx_hw_params(struct snd_pcm_substream *substream,1838 static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
1929 struct snd_pcm_hw_params *hw_params);1839 struct snd_pcm_hw_params *hw_params);
1930 1840
1931This is called when the hardware parameter (``hw_params``) is set up1841This is called when the hardware parameters (``hw_params``) are set up
1932by the application, that is, once when the buffer size, the period1842by the application, that is, once when the buffer size, the period
1933size, the format, etc. are defined for the pcm substream.1843size, the format, etc. are defined for the PCM substream.
1934 1844
1935Many hardware setups should be done in this callback, including the1845Many hardware setups should be done in this callback, including the
1936allocation of buffers.1846allocation of buffers.
1937 1847
1938Parameters to be initialized are retrieved by1848Parameters to be initialized are retrieved by the
1939:c:func:`params_xxx()` macros.1849:c:func:`params_xxx()` macros.
1940 1850
1941When you set up the managed buffer allocation mode for the substream,1851When you choose managed buffer allocation mode for the substream,
1942a buffer is already allocated before this callback gets1852a buffer is already allocated before this callback gets
1943called. Alternatively, you can call a helper function below for1853called. Alternatively, you can call a helper function below for
1944allocating the buffer, too.1854allocating the buffer::
1945
1946::
1947 1855
1948 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));1856 snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1949 1857
@@ -1951,8 +1859,8 @@ allocating the buffer, too. · 1 unmodified line
1951DMA buffers have been pre-allocated. See the section `Buffer Types`_1859DMA buffers have been pre-allocated. See the section `Buffer Types`_
1952for more details.1860for more details.
1953 1861
1954Note that this and ``prepare`` callbacks may be called multiple times1862Note that this one and the ``prepare`` callback may be called multiple
1955per initialization. For example, the OSS emulation may call these1863times per initialization. For example, the OSS emulation may call these
1956callbacks at each change via its ioctl.1864callbacks at each change via its ioctl.
1957 1865
1958Thus, you need to be careful not to allocate the same buffers many1866Thus, 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
1960above many times is OK. It will release the previous buffer1868above many times is OK. It will release the previous buffer
1961automatically when it was already allocated.1869automatically when it was already allocated.
1962 1870
1963Another note is that this callback is non-atomic (schedulable) as1871Another note is that this callback is non-atomic (schedulable) by
1964default, i.e. when no ``nonatomic`` flag set. This is important,1872default, i.e. when no ``nonatomic`` flag set. This is important,
1965because the ``trigger`` callback is atomic (non-schedulable). That is,1873because the ``trigger`` callback is atomic (non-schedulable). That is,
1966mutexes or any schedule-related functions are not available in1874mutexes or any schedule-related functions are not available in the
1967``trigger`` callback. Please see the subsection Atomicity_ for1875``trigger`` callback. Please see the subsection Atomicity_ for
1968details.1876details.
1969 1877
@@ -1979,16 +1887,14 @@ This is called to release the resources allocated via · 9 unmodified lines
1979 1887
1980This function is always called before the close callback is called.1888This function is always called before the close callback is called.
1981Also, the callback may be called multiple times, too. Keep track1889Also, the callback may be called multiple times, too. Keep track
1982whether the resource was already released.1890whether each resource was already released.
1983 1891
1984When you have set up the managed buffer allocation mode for the PCM1892When you have chosen managed buffer allocation mode for the PCM
1985substream, the allocated PCM buffer will be automatically released1893substream, the allocated PCM buffer will be automatically released
1986after this callback gets called. Otherwise you'll have to release the1894after this callback gets called. Otherwise you'll have to release the
1987buffer manually. Typically, when the buffer was allocated from the1895buffer manually. Typically, when the buffer was allocated from the
1988pre-allocated pool, you can use the standard API function1896pre-allocated pool, you can use the standard API function
1989:c:func:`snd_pcm_lib_malloc_pages()` like:1897:c:func:`snd_pcm_lib_malloc_pages()` like::
1990
1991::
1992 1898
1993 snd_pcm_lib_free_pages(substream);1899 snd_pcm_lib_free_pages(substream);
1994 1900
@@ -1999,13 +1905,13 @@ prepare callback · 4 unmodified lines
1999 1905
2000 static int snd_xxx_prepare(struct snd_pcm_substream *substream);1906 static int snd_xxx_prepare(struct snd_pcm_substream *substream);
2001 1907
2002This callback is called when the pcm is “prepared”. You can set the1908This callback is called when the PCM is “prepared”. You can set the
2003format type, sample rate, etc. here. The difference from ``hw_params``1909format type, sample rate, etc. here. The difference from ``hw_params``
2004is that the ``prepare`` callback will be called each time1910is that the ``prepare`` callback will be called each time
2005:c:func:`snd_pcm_prepare()` is called, i.e. when recovering after1911:c:func:`snd_pcm_prepare()` is called, i.e. when recovering after
2006underruns, etc.1912underruns, etc.
2007 1913
2008Note that this callback is now non-atomic. You can use1914Note that this callback is non-atomic. You can use
2009schedule-related functions safely in this callback.1915schedule-related functions safely in this callback.
2010 1916
2011In this and the following callbacks, you can refer to the values via1917In this and the following callbacks, you can refer to the values via
@@ -2026,13 +1932,11 @@ trigger callback · 14 unmodified lines
2026 1932
2027 static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);1933 static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
2028 1934
2029This is called when the pcm is started, stopped or paused.1935This is called when the PCM is started, stopped or paused.
2030
2031Which action is specified in the second argument,
2032``SNDRV_PCM_TRIGGER_XXX`` in ``<sound/pcm.h>``. At least, the ``START``
2033and ``STOP`` commands must be defined in this callback.
2034 1936
2035::1937The action is specified in the second argument, ``SNDRV_PCM_TRIGGER_XXX``
1938defined in ``<sound/pcm.h>``. At least, the ``START``
1939and ``STOP`` commands must be defined in this callback::
2036 1940
2037 switch (cmd) {1941 switch (cmd) {
2038 case SNDRV_PCM_TRIGGER_START:1942 case SNDRV_PCM_TRIGGER_START:
@@ -2045,23 +1949,23 @@ and ``STOP`` commands must be defined in this callback. · 6 unmodified lines
2045 return -EINVAL;1949 return -EINVAL;
2046 }1950 }
2047 1951
2048When the pcm supports the pause operation (given in the info field of1952When the PCM supports the pause operation (given in the info field of
2049the hardware table), the ``PAUSE_PUSH`` and ``PAUSE_RELEASE`` commands1953the hardware table), the ``PAUSE_PUSH`` and ``PAUSE_RELEASE`` commands
2050must be handled here, too. The former is the command to pause the pcm,1954must be handled here, too. The former is the command to pause the PCM,
2051and the latter to restart the pcm again.1955and the latter to restart the PCM again.
2052 1956
2053When the pcm supports the suspend/resume operation, regardless of full1957When the PCM supports the suspend/resume operation, regardless of full
2054or partial suspend/resume support, the ``SUSPEND`` and ``RESUME``1958or partial suspend/resume support, the ``SUSPEND`` and ``RESUME``
2055commands must be handled, too. These commands are issued when the1959commands must be handled, too. These commands are issued when the
2056power-management status is changed. Obviously, the ``SUSPEND`` and1960power-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,
2058they are identical to the ``STOP`` and ``START`` commands, respectively.1962they are identical to the ``STOP`` and ``START`` commands, respectively.
2059See the `Power Management`_ section for details.1963See the `Power Management`_ section for details.
2060 1964
2061As mentioned, this callback is atomic as default unless ``nonatomic``1965As mentioned, this callback is atomic by default unless the ``nonatomic``
2062flag set, and you cannot call functions which may sleep. The1966flag set, and you cannot call functions which may sleep. The
2063``trigger`` callback should be as minimal as possible, just really1967``trigger`` callback should be as minimal as possible, just really
2064triggering the DMA. The other stuff should be initialized1968triggering the DMA. The other stuff should be initialized in
2065``hw_params`` and ``prepare`` callbacks properly beforehand.1969``hw_params`` and ``prepare`` callbacks properly beforehand.
2066 1970
2067sync_stop callback1971sync_stop callback
@@ -2072,22 +1976,22 @@ sync_stop callback · 4 unmodified lines
2072 static int snd_xxx_sync_stop(struct snd_pcm_substream *substream);1976 static int snd_xxx_sync_stop(struct snd_pcm_substream *substream);
2073 1977
2074This callback is optional, and NULL can be passed. It's called after1978This callback is optional, and NULL can be passed. It's called after
2075the PCM core stops the stream and changes the stream state1979the PCM core stops the stream, before it changes the stream state via
2076``prepare``, ``hw_params`` or ``hw_free``.1980``prepare``, ``hw_params`` or ``hw_free``.
2077Since the IRQ handler might be still pending, we need to wait until1981Since the IRQ handler might be still pending, we need to wait until
2078the pending task finishes before moving to the next step; otherwise it1982the pending task finishes before moving to the next step; otherwise it
2079might lead to a crash due to resource conflicts or access to the freed1983might lead to a crash due to resource conflicts or access to freed
2080resources. A typical behavior is to call a synchronization function1984resources. A typical behavior is to call a synchronization function
2081like :c:func:`synchronize_irq()` here.1985like :c:func:`synchronize_irq()` here.
2082 1986
2083For majority of drivers that need only a call of1987For the majority of drivers that need only a call of
2084:c:func:`synchronize_irq()`, there is a simpler setup, too.1988:c:func:`synchronize_irq()`, there is a simpler setup, too.
2085While keeping NULL to ``sync_stop`` PCM callback, the driver can set1989While keeping the ``sync_stop`` PCM callback NULL, the driver can set
2086``card->sync_irq`` field to store the valid interrupt number after1990the ``card->sync_irq`` field to the returned interrupt number after
2087requesting an IRQ, instead. Then PCM core will look call1991requesting an IRQ, instead. Then PCM core will call
2088:c:func:`synchronize_irq()` with the given IRQ appropriately.1992:c:func:`synchronize_irq()` with the given IRQ appropriately.
2089 1993
2090If the IRQ handler is released at the card destructor, you don't need1994If the IRQ handler is released by the card destructor, you don't need
2091to clear ``card->sync_irq``, as the card itself is being released.1995to clear ``card->sync_irq``, as the card itself is being released.
2092So, usually you'll need to add just a single line for assigning1996So, usually you'll need to add just a single line for assigning
2093``card->sync_irq`` in the driver code unless the driver re-acquires1997``card->sync_irq`` in the driver code unless the driver re-acquires
@@ -2103,30 +2007,30 @@ pointer callback · 9 unmodified lines
2103 static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)2007 static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
2104 2008
2105This callback is called when the PCM middle layer inquires the current2009This callback is called when the PCM middle layer inquires the current
2106hardware position on the buffer. The position must be returned in2010hardware position in the buffer. The position must be returned in
2107frames, ranging from 0 to ``buffer_size - 1``. 2011frames, ranging from 0 to ``buffer_size - 1``.
2108 2012
2109This is called usually from the buffer-update routine in the pcm2013This is usually called from the buffer-update routine in the PCM
2110middle layer, which is invoked when :c:func:`snd_pcm_period_elapsed()`2014middle layer, which is invoked when :c:func:`snd_pcm_period_elapsed()`
2111is called in the interrupt routine. Then the pcm middle layer updates2015is called by the interrupt routine. Then the PCM middle layer updates
2112the position and calculates the available space, and wakes up the2016the position and calculates the available space, and wakes up the
2113sleeping poll threads, etc.2017sleeping poll threads, etc.
2114 2018
2115This callback is also atomic as default.2019This callback is also atomic by default.
2116 2020
2117copy_user, copy_kernel and fill_silence ops2021copy_user, copy_kernel and fill_silence ops
2118~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2022~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2119 2023
2120These callbacks are not mandatory, and can be omitted in most cases.2024These callbacks are not mandatory, and can be omitted in most cases.
2121These callbacks are used when the hardware buffer cannot be in the2025These callbacks are used when the hardware buffer cannot be in the
2122normal memory space. Some chips have their own buffer on the hardware2026normal memory space. Some chips have their own buffer in the hardware
2123which is not mappable. In such a case, you have to transfer the data2027which is not mappable. In such a case, you have to transfer the data
2124manually from the memory buffer to the hardware buffer. Or, if the2028manually from the memory buffer to the hardware buffer. Or, if the
2125buffer is non-contiguous on both physical and virtual memory spaces,2029buffer is non-contiguous on both physical and virtual memory spaces,
2126these callbacks must be defined, too.2030these callbacks must be defined, too.
2127 2031
2128If these two callbacks are defined, copy and set-silence operations2032If these two callbacks are defined, copy and set-silence operations
2129are done by them. The detailed will be described in the later section2033are done by them. The details will be described in the later section
2130`Buffer and Memory Management`_.2034`Buffer and Memory Management`_.
2131 2035
2132ack callback2036ack callback
@@ -2137,7 +2041,11 @@ This callback is also not mandatory. This callback is called when the · 4 unmodified lines
2137emu10k1-fx and cs46xx need to track the current ``appl_ptr`` for the2041emu10k1-fx and cs46xx need to track the current ``appl_ptr`` for the
2138internal buffer, and this callback is useful only for such a purpose.2042internal buffer, and this callback is useful only for such a purpose.
2139 2043
2140This callback is atomic as default.2044The callback function may return 0 or a negative error. When the
2045return value is ``-EPIPE``, PCM core treats that as a buffer XRUN,
2046and changes the state to ``SNDRV_PCM_STATE_XRUN`` automatically.
2047
2048This callback is atomic by default.
2141 2049
2142page callback2050page callback
2143~~~~~~~~~~~~~2051~~~~~~~~~~~~~
@@ -2145,16 +2053,15 @@ page callback · 1 unmodified line
2145This callback is optional too. The mmap calls this callback to get the2053This callback is optional too. The mmap calls this callback to get the
2146page fault address.2054page fault address.
2147 2055
2148Since the recent changes, you need no special callback any longer for2056You need no special callback for the standard SG-buffer or vmalloc-
2149the standard SG-buffer or vmalloc-buffer. Hence this callback should2057buffer. Hence this callback should be rarely used.
2150be rarely used.
2151 2058
2152mmap calllback2059mmap callback
2153~~~~~~~~~~~~~~2060~~~~~~~~~~~~~
2154 2061
2155This is another optional callback for controlling mmap behavior.2062This is another optional callback for controlling mmap behavior.
2156Once when defined, PCM core calls this callback when a page is2063When defined, the PCM core calls this callback when a page is
2157memory-mapped instead of dealing via the standard helper.2064memory-mapped, instead of using the standard helper.
2158If you need special handling (due to some architecture or2065If you need special handling (due to some architecture or
2159device-specific issues), implement everything here as you like.2066device-specific issues), implement everything here as you like.
2160 2067
@@ -2162,13 +2069,14 @@ device-specific issues), implement everything here as you like. · 1 unmodified line
2162PCM Interrupt Handler2069PCM Interrupt Handler
2163---------------------2070---------------------
2164 2071
2165The rest of pcm stuff is the PCM interrupt handler. The role of PCM2072The remainder of the PCM stuff is the PCM interrupt handler. The role
2073of the PCM
2166interrupt handler in the sound driver is to update the buffer position2074interrupt handler in the sound driver is to update the buffer position
2167and to tell the PCM middle layer when the buffer position goes across2075and to tell the PCM middle layer when the buffer position goes across
2168the prescribed period size. To inform this, call the2076the specified period boundary. To inform about this, call the
2169:c:func:`snd_pcm_period_elapsed()` function.2077:c:func:`snd_pcm_period_elapsed()` function.
2170 2078
2171There are several types of sound chips to generate the interrupts.2079There are several ways sound chips can generate interrupts.
2172 2080
2173Interrupts at the period (fragment) boundary2081Interrupts at the period (fragment) boundary
2174~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2082~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2184,14 +2092,12 @@ chip record to hold the current running substream pointer, and set the · 9 unmodified lines
2184pointer value at ``open`` callback (and reset at ``close`` callback).2092pointer value at ``open`` callback (and reset at ``close`` callback).
2185 2093
2186If you acquire a spinlock in the interrupt handler, and the lock is used2094If you acquire a spinlock in the interrupt handler, and the lock is used
2187in other pcm callbacks, too, then you have to release the lock before2095in other PCM callbacks, too, then you have to release the lock before
2188calling :c:func:`snd_pcm_period_elapsed()`, because2096calling :c:func:`snd_pcm_period_elapsed()`, because
2189:c:func:`snd_pcm_period_elapsed()` calls other pcm callbacks2097:c:func:`snd_pcm_period_elapsed()` calls other PCM callbacks
2190inside.2098inside.
2191 2099
2192Typical code would be like:2100Typical code would look like::
2193
2194::
2195 2101
2196 2102
2197 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)2103 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)
@@ -2211,6 +2117,12 @@ Typical code would be like: · 13 unmodified lines
2211 return IRQ_HANDLED;2117 return IRQ_HANDLED;
2212 }2118 }
2213 2119
2120Also, when the device can detect a buffer underrun/overrun, the driver
2121can notify the XRUN status to the PCM core by calling
2122:c:func:`snd_pcm_stop_xrun()`. This function stops the stream and sets
2123the PCM state to ``SNDRV_PCM_STATE_XRUN``. Note that it must be called
2124outside the PCM stream lock, hence it can't be called from the atomic
2125callback.
2214 2126
2215 2127
2216High frequency timer interrupts2128High frequency timer interrupts
@@ -2223,9 +2135,7 @@ position and accumulate the processed sample length at each interrupt. · 6 unmodified lines
2223When the accumulated size exceeds the period size, call2135When the accumulated size exceeds the period size, call
2224:c:func:`snd_pcm_period_elapsed()` and reset the accumulator.2136:c:func:`snd_pcm_period_elapsed()` and reset the accumulator.
2225 2137
2226Typical code would be like the following.2138Typical code would look as follows::
2227
2228::
2229 2139
2230 2140
2231 static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id)2141 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
2270On calling :c:func:`snd_pcm_period_elapsed()`2180On calling :c:func:`snd_pcm_period_elapsed()`
2271~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2272 2182
2273In both cases, even if more than one period are elapsed, you don't have2183In both cases, even if more than one period has elapsed, you don't have
2274to call :c:func:`snd_pcm_period_elapsed()` many times. Call only2184to call :c:func:`snd_pcm_period_elapsed()` many times. Call only
2275once. And the pcm layer will check the current hardware pointer and2185once. And the PCM layer will check the current hardware pointer and
2276update to the latest status.2186update to the latest status.
2277 2187
2278Atomicity2188Atomicity
@@ -2283,15 +2193,16 @@ kernel programming are race conditions. In the Linux kernel, they are · 4 unmodified lines
2283usually avoided via spin-locks, mutexes or semaphores. In general, if a2193usually avoided via spin-locks, mutexes or semaphores. In general, if a
2284race condition can happen in an interrupt handler, it has to be managed2194race condition can happen in an interrupt handler, it has to be managed
2285atomically, and you have to use a spinlock to protect the critical2195atomically, and you have to use a spinlock to protect the critical
2286session. If the critical section is not in interrupt handler code and if2196section. If the critical section is not in interrupt handler code and if
2287taking a relatively long time to execute is acceptable, you should use2197taking a relatively long time to execute is acceptable, you should use
2288mutexes or semaphores instead.2198mutexes or semaphores instead.
2289 2199
2290As already seen, some pcm callbacks are atomic and some are not. For2200As already seen, some PCM callbacks are atomic and some are not. For
2291example, the ``hw_params`` callback is non-atomic, while ``trigger``2201example, the ``hw_params`` callback is non-atomic, while the ``trigger``
2292callback is atomic. This means, the latter is called already in a2202callback is atomic. This means, the latter is called already in a
2293spinlock held by the PCM middle layer. Please take this atomicity into2203spinlock held by the PCM middle layer, the PCM stream lock. Please
2294account when you choose a locking scheme in the callbacks.2204take this atomicity into account when you choose a locking scheme in
2205the callbacks.
2295 2206
2296In the atomic callbacks, you cannot use functions which may call2207In the atomic callbacks, you cannot use functions which may call
2297:c:func:`schedule()` or go to :c:func:`sleep()`. Semaphores and2208: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
2302All three atomic callbacks (trigger, pointer, and ack) are called with2213All three atomic callbacks (trigger, pointer, and ack) are called with
2303local interrupts disabled.2214local interrupts disabled.
2304 2215
2305The recent changes in PCM core code, however, allow all PCM operations2216However, it is possible to request all PCM operations to be non-atomic.
2306to be non-atomic. This assumes that the all caller sides are in2217This assumes that all call sites are in
2307non-atomic contexts. For example, the function2218non-atomic contexts. For example, the function
2308:c:func:`snd_pcm_period_elapsed()` is called typically from the2219:c:func:`snd_pcm_period_elapsed()` is called typically from the
2309interrupt handler. But, if you set up the driver to use a threaded2220interrupt handler. But, if you set up the driver to use a threaded
2310interrupt handler, this call can be in non-atomic context, too. In such2221interrupt handler, this call can be in non-atomic context, too. In such
2311a case, you can set ``nonatomic`` filed of struct snd_pcm object2222a case, you can set the ``nonatomic`` field of the struct snd_pcm object
2312after creating it. When this flag is set, mutex and rwsem are used internally2223after creating it. When this flag is set, mutex and rwsem are used internally
2313in the PCM core instead of spin and rwlocks, so that you can call all PCM2224in the PCM core instead of spin and rwlocks, so that you can call all PCM
2314functions safely in a non-atomic2225functions safely in a non-atomic
2315context.2226context.
2316 2227
2228Also, in some cases, you might need to call
2229:c:func:`snd_pcm_period_elapsed()` in the atomic context (e.g. the
2230period gets elapsed during ``ack`` or other callback). There is a
2231variant that can be called inside the PCM stream lock
2232:c:func:`snd_pcm_period_elapsed_under_stream_lock()` for that purpose,
2233too.
2234
2317Constraints2235Constraints
2318-----------2236-----------
2319 2237
2320If your chip supports unconventional sample rates, or only the limited2238Due to physical limitations, hardware is not infinitely configurable.
2321samples, you need to set a constraint for the condition.2239These limitations are expressed by setting constraints.
2322 2240
2323For example, in order to restrict the sample rates in the some supported2241For example, in order to restrict the sample rates to some supported
2324values, use :c:func:`snd_pcm_hw_constraint_list()`. You need to2242values, use :c:func:`snd_pcm_hw_constraint_list()`. You need to
2325call this function in the open callback.2243call this function in the open callback::
2326
2327::
2328 2244
2329 static unsigned int rates[] =2245 static unsigned int rates[] =
2330 {4000, 10000, 22050, 44100};2246 {4000, 10000, 22050, 44100};
@@ -2346,16 +2262,12 @@ call this function in the open callback. · 15 unmodified lines
2346 ....2262 ....
2347 }2263 }
2348 2264
2349
2350
2351There are many different constraints. Look at ``sound/pcm.h`` for a2265There are many different constraints. Look at ``sound/pcm.h`` for a
2352complete list. You can even define your own constraint rules. For2266complete list. You can even define your own constraint rules. For
2353example, let's suppose my_chip can manage a substream of 1 channel if2267example, let's suppose my_chip can manage a substream of 1 channel if
2354and only if the format is ``S16_LE``, otherwise it supports any format2268and only if the format is ``S16_LE``, otherwise it supports any format
2355specified in struct snd_pcm_hardware> (or in any other2269specified in struct snd_pcm_hardware (or in any other
2356constraint_list). You can build a rule like this:2270constraint_list). You can build a rule like this::
2357
2358::
2359 2271
2360 static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,2272 static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
2361 struct snd_pcm_hw_rule *rule)2273 struct snd_pcm_hw_rule *rule)
@@ -2375,9 +2287,7 @@ constraint_list). You can build a rule like this: · 13 unmodified lines
2375 }2287 }
2376 2288
2377 2289
2378Then you need to call this function to add your rule:2290Then you need to call this function to add your rule::
2379
2380::
2381 2291
2382 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,2292 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
2383 hw_rule_channels_by_format, NULL,2293 hw_rule_channels_by_format, NULL,
@@ -2386,9 +2296,7 @@ Then you need to call this function to add your rule: · 2 unmodified lines
2386The rule function is called when an application sets the PCM format, and2296The rule function is called when an application sets the PCM format, and
2387it refines the number of channels accordingly. But an application may2297it refines the number of channels accordingly. But an application may
2388set the number of channels before setting the format. Thus you also need2298set the number of channels before setting the format. Thus you also need
2389to define the inverse rule:2299to define the inverse rule::
2390
2391::
2392 2300
2393 static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,2301 static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
2394 struct snd_pcm_hw_rule *rule)2302 struct snd_pcm_hw_rule *rule)
@@ -2407,16 +2315,14 @@ to define the inverse rule: · 12 unmodified lines
2407 }2315 }
2408 2316
2409 2317
2410... and in the open callback:2318... and in the open callback::
2411
2412::
2413 2319
2414 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,2320 snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
2415 hw_rule_format_by_channels, NULL,2321 hw_rule_format_by_channels, NULL,
2416 SNDRV_PCM_HW_PARAM_CHANNELS, -1);2322 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
2417 2323
2418One typical usage of the hw constraints is to align the buffer size2324One typical usage of the hw constraints is to align the buffer size
2419with the period size. As default, ALSA PCM core doesn't enforce the2325with the period size. By default, ALSA PCM core doesn't enforce the
2420buffer size to be aligned with the period size. For example, it'd be2326buffer size to be aligned with the period size. For example, it'd be
2421possible to have a combination like 256 period bytes with 999 buffer2327possible to have a combination like 256 period bytes with 999 buffer
2422bytes.2328bytes.
@@ -2424,9 +2330,7 @@ bytes. · 1 unmodified line
2424Many device chips, however, require the buffer to be a multiple of2330Many device chips, however, require the buffer to be a multiple of
2425periods. In such a case, call2331periods. In such a case, call
2426:c:func:`snd_pcm_hw_constraint_integer()` for2332:c:func:`snd_pcm_hw_constraint_integer()` for
2427``SNDRV_PCM_HW_PARAM_PERIODS``.2333``SNDRV_PCM_HW_PARAM_PERIODS``::
2428
2429::
2430 2334
2431 snd_pcm_hw_constraint_integer(substream->runtime,2335 snd_pcm_hw_constraint_integer(substream->runtime,
2432 SNDRV_PCM_HW_PARAM_PERIODS);2336 SNDRV_PCM_HW_PARAM_PERIODS);
@@ -2434,7 +2338,7 @@ periods. In such a case, call · 1 unmodified line
2434This assures that the number of periods is integer, hence the buffer2338This assures that the number of periods is integer, hence the buffer
2435size is aligned with the period size.2339size is aligned with the period size.
2436 2340
2437The hw constraint is a very much powerful mechanism to define the2341The hw constraint is a very powerful mechanism to define the
2438preferred PCM configuration, and there are relevant helpers.2342preferred PCM configuration, and there are relevant helpers.
2439I won't give more details here, rather I would like to say, “Luke, use2343I won't give more details here, rather I would like to say, “Luke, use
2440the source.”2344the source.”
@@ -2461,9 +2365,7 @@ Definition of Controls · 20 unmodified lines
2461 2365
2462To create a new control, you need to define the following three2366To create a new control, you need to define the following three
2463callbacks: ``info``, ``get`` and ``put``. Then, define a2367callbacks: ``info``, ``get`` and ``put``. Then, define a
2464struct snd_kcontrol_new record, such as:2368struct snd_kcontrol_new record, such as::
2465
2466::
2467 2369
2468 2370
2469 static struct snd_kcontrol_new my_control = {2371 static struct snd_kcontrol_new my_control = {
@@ -2506,7 +2408,7 @@ The ``private_value`` field contains an arbitrary long integer value · 36 unmodified lines
2506for this record. When using the generic ``info``, ``get`` and ``put``2408for this record. When using the generic ``info``, ``get`` and ``put``
2507callbacks, you can pass a value through this field. If several small2409callbacks, you can pass a value through this field. If several small
2508numbers are necessary, you can combine them in bitwise. Or, it's2410numbers are necessary, you can combine them in bitwise. Or, it's
2509possible to give a pointer (casted to unsigned long) of some record to2411possible to store a pointer (casted to unsigned long) of some record in
2510this field, too. 2412this field, too.
2511 2413
2512The ``tlv`` field can be used to provide metadata about the control;2414The ``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
2573given control. The default access type is2475given control. The default access type is
2574``SNDRV_CTL_ELEM_ACCESS_READWRITE``, which means both read and write are2476``SNDRV_CTL_ELEM_ACCESS_READWRITE``, which means both read and write are
2575allowed to this control. When the access flag is omitted (i.e. = 0), it2477allowed to this control. When the access flag is omitted (i.e. = 0), it
2576is considered as ``READWRITE`` access as default.2478is considered as ``READWRITE`` access by default.
2577 2479
2578When the control is read-only, pass ``SNDRV_CTL_ELEM_ACCESS_READ``2480When the control is read-only, pass ``SNDRV_CTL_ELEM_ACCESS_READ``
2579instead. In this case, you don't have to define the ``put`` callback.2481instead. 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
2586changed without `Change notification`_. Applications should poll such2488changed without `Change notification`_. Applications should poll such
2587a control constantly.2489a control constantly.
2588 2490
2589When the control is inactive, set the ``INACTIVE`` flag, too. There are2491When the control may be updated, but currently has no effect on anything,
2590``LOCK`` and ``OWNER`` flags to change the write permissions.2492setting the ``INACTIVE`` flag may be appropriate. For example, PCM
2493controls should be inactive while no PCM device is open.
2494
2495There are ``LOCK`` and ``OWNER`` flags to change the write permissions.
2591 2496
2592Control Callbacks2497Control Callbacks
2593-----------------2498-----------------
@@ -2598,9 +2503,7 @@ info callback · 4 unmodified lines
2598The ``info`` callback is used to get detailed information on this2503The ``info`` callback is used to get detailed information on this
2599control. This must store the values of the given2504control. This must store the values of the given
2600struct snd_ctl_elem_info object. For example,2505struct snd_ctl_elem_info object. For example,
2601for a boolean control with a single element:2506for a boolean control with a single element::
2602
2603::
2604 2507
2605 2508
2606 static int snd_myctl_mono_info(struct snd_kcontrol *kcontrol,2509 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
2619``BOOLEAN``, ``INTEGER``, ``ENUMERATED``, ``BYTES``, ``IEC958`` and2522``BOOLEAN``, ``INTEGER``, ``ENUMERATED``, ``BYTES``, ``IEC958`` and
2620``INTEGER64``. The ``count`` field specifies the number of elements in2523``INTEGER64``. The ``count`` field specifies the number of elements in
2621this control. For example, a stereo volume would have count = 2. The2524this control. For example, a stereo volume would have count = 2. The
2622``value`` field is a union, and the values stored are depending on the2525``value`` field is a union, and the values stored depend on the
2623type. The boolean and integer types are identical.2526type. The boolean and integer types are identical.
2624 2527
2625The enumerated type is a bit different from others. You'll need to set2528The enumerated type is a bit different from the others. You'll need to
2626the string for the currently given item index.2529set the string for the selectec item index::
2627
2628::
2629 2530
2630 static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,2531 static int snd_myctl_enum_info(struct snd_kcontrol *kcontrol,
2631 struct snd_ctl_elem_info *uinfo)2532 struct snd_ctl_elem_info *uinfo)
@@ -2670,13 +2571,10 @@ stereo channel boolean item. · 38 unmodified lines
2670get callback2571get callback
2671~~~~~~~~~~~~2572~~~~~~~~~~~~
2672 2573
2673This callback is used to read the current value of the control and to2574This callback is used to read the current value of the control, so it
2674return to user-space.2575can be returned to user-space.
2675
2676For example,
2677
2678::
2679 2576
2577For example::
2680 2578
2681 static int snd_myctl_get(struct snd_kcontrol *kcontrol,2579 static int snd_myctl_get(struct snd_kcontrol *kcontrol,
2682 struct snd_ctl_elem_value *ucontrol)2580 struct snd_ctl_elem_value *ucontrol)
@@ -2691,15 +2589,11 @@ For example, · 8 unmodified lines
2691The ``value`` field depends on the type of control as well as on the2589The ``value`` field depends on the type of control as well as on the
2692info callback. For example, the sb driver uses this field to store the2590info callback. For example, the sb driver uses this field to store the
2693register offset, the bit-shift and the bit-mask. The ``private_value``2591register offset, the bit-shift and the bit-mask. The ``private_value``
2694field is set as follows:2592field is set as follows::
2695
2696::
2697 2593
2698 .private_value = reg | (shift << 16) | (mask << 24)2594 .private_value = reg | (shift << 16) | (mask << 24)
2699 2595
2700and is retrieved in callbacks like2596and is retrieved in callbacks like::
2701
2702::
2703 2597
2704 static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,2598 static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
2705 struct snd_ctl_elem_value *ucontrol)2599 struct snd_ctl_elem_value *ucontrol)
@@ -2711,19 +2605,16 @@ and is retrieved in callbacks like · 5 unmodified lines
2711 }2605 }
2712 2606
2713In the ``get`` callback, you have to fill all the elements if the2607In the ``get`` callback, you have to fill all the elements if the
2714control has more than one elements, i.e. ``count > 1``. In the example2608control has more than one element, i.e. ``count > 1``. In the example
2715above, we filled only one element (``value.integer.value[0]``) since2609above, we filled only one element (``value.integer.value[0]``) since
2716it's assumed as ``count = 1``.2610``count = 1`` is assumed.
2717 2611
2718put callback2612put callback
2719~~~~~~~~~~~~2613~~~~~~~~~~~~
2720 2614
2721This callback is used to write a value from user-space.2615This callback is used to write a value coming from user-space.
2722
2723For example,
2724
2725::
2726 2616
2617For example::
2727 2618
2728 static int snd_myctl_put(struct snd_kcontrol *kcontrol,2619 static int snd_myctl_put(struct snd_kcontrol *kcontrol,
2729 struct snd_ctl_elem_value *ucontrol)2620 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
2746return a negative error code as usual.2637return a negative error code as usual.
2747 2638
2748As in the ``get`` callback, when the control has more than one2639As in the ``get`` callback, when the control has more than one
2749elements, all elements must be evaluated in this callback, too.2640element, all elements must be evaluated in this callback, too.
2750 2641
2751Callbacks are not atomic2642Callbacks are not atomic
2752~~~~~~~~~~~~~~~~~~~~~~~~2643~~~~~~~~~~~~~~~~~~~~~~~~
2753 2644
2754All these three callbacks are basically not atomic.2645All these three callbacks are not-atomic.
2755 2646
2756Control Constructor2647Control Constructor
2757-------------------2648-------------------
@@ -2760,9 +2651,7 @@ When everything is ready, finally we can create a new control. To create · 2 unmodified lines
2760a control, there are two functions to be called,2651a control, there are two functions to be called,
2761:c:func:`snd_ctl_new1()` and :c:func:`snd_ctl_add()`.2652:c:func:`snd_ctl_new1()` and :c:func:`snd_ctl_add()`.
2762 2653
2763In the simplest way, you can do like this:2654In the simplest way, you can do it like this::
2764
2765::
2766 2655
2767 err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));2656 err = snd_ctl_add(card, snd_ctl_new1(&my_control, chip));
2768 if (err < 0)2657 if (err < 0)
@@ -2780,9 +2669,7 @@ Change Notification · 11 unmodified lines
2780-------------------2669-------------------
2781 2670
2782If you need to change and update a control in the interrupt routine, you2671If you need to change and update a control in the interrupt routine, you
2783can call :c:func:`snd_ctl_notify()`. For example,2672can call :c:func:`snd_ctl_notify()`. For example::
2784
2785::
2786 2673
2787 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);2674 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, id_pointer);
2788 2675
@@ -2796,13 +2683,11 @@ for hardware volume interrupts. · 7 unmodified lines
2796Metadata2683Metadata
2797--------2684--------
2798 2685
2799To provide information about the dB values of a mixer control, use on of2686To provide information about the dB values of a mixer control, use one of
2800the ``DECLARE_TLV_xxx`` macros from ``<sound/tlv.h>`` to define a2687the ``DECLARE_TLV_xxx`` macros from ``<sound/tlv.h>`` to define a
2801variable containing this information, set the ``tlv.p`` field to point to2688variable containing this information, set the ``tlv.p`` field to point to
2802this variable, and include the ``SNDRV_CTL_ELEM_ACCESS_TLV_READ`` flag2689this variable, and include the ``SNDRV_CTL_ELEM_ACCESS_TLV_READ`` flag
2803in the ``access`` field; like this:2690in the ``access`` field; like this::
2804
2805::
2806 2691
2807 static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);2692 static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
2808 2693
@@ -2892,9 +2777,7 @@ AC97 Constructor · 83 unmodified lines
2892----------------2777----------------
2893 2778
2894To create an ac97 instance, first call :c:func:`snd_ac97_bus()`2779To create an ac97 instance, first call :c:func:`snd_ac97_bus()`
2895with an ``ac97_bus_ops_t`` record with callback functions.2780with an ``ac97_bus_ops_t`` record with callback functions::
2896
2897::
2898 2781
2899 struct snd_ac97_bus *bus;2782 struct snd_ac97_bus *bus;
2900 static struct snd_ac97_bus_ops ops = {2783 static struct snd_ac97_bus_ops ops = {
@@ -2906,10 +2789,8 @@ with an ``ac97_bus_ops_t`` record with callback functions. · 5 unmodified lines
2906 2789
2907The bus record is shared among all belonging ac97 instances.2790The bus record is shared among all belonging ac97 instances.
2908 2791
2909And then call :c:func:`snd_ac97_mixer()` with an struct snd_ac97_template2792And then call :c:func:`snd_ac97_mixer()` with a struct snd_ac97_template
2910record together with the bus pointer created above.2793record together with the bus pointer created above::
2911
2912::
2913 2794
2914 struct snd_ac97_template ac97;2795 struct snd_ac97_template ac97;
2915 int err;2796 int err;
@@ -2934,9 +2815,7 @@ correspond to the functions for read and write accesses to the · 18 unmodified lines
2934hardware low-level codes.2815hardware low-level codes.
2935 2816
2936The ``read`` callback returns the register value specified in the2817The ``read`` callback returns the register value specified in the
2937argument.2818argument::
2938
2939::
2940 2819
2941 static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,2820 static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
2942 unsigned short reg)2821 unsigned short reg)
@@ -2949,9 +2828,7 @@ argument. · 6 unmodified lines
2949Here, the chip can be cast from ``ac97->private_data``.2828Here, the chip can be cast from ``ac97->private_data``.
2950 2829
2951Meanwhile, the ``write`` callback is used to set the register2830Meanwhile, the ``write`` callback is used to set the register
2952value2831value::
2953
2954::
2955 2832
2956 static void snd_mychip_ac97_write(struct snd_ac97 *ac97,2833 static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
2957 unsigned short reg, unsigned short val)2834 unsigned short reg, unsigned short val)
@@ -2984,32 +2861,24 @@ Both :c:func:`snd_ac97_write()` and · 26 unmodified lines
2984the given register (``AC97_XXX``). The difference between them is that2861the given register (``AC97_XXX``). The difference between them is that
2985:c:func:`snd_ac97_update()` doesn't write a value if the given2862:c:func:`snd_ac97_update()` doesn't write a value if the given
2986value has been already set, while :c:func:`snd_ac97_write()`2863value has been already set, while :c:func:`snd_ac97_write()`
2987always rewrites the value.2864always rewrites the value::
2988
2989::
2990 2865
2991 snd_ac97_write(ac97, AC97_MASTER, 0x8080);2866 snd_ac97_write(ac97, AC97_MASTER, 0x8080);
2992 snd_ac97_update(ac97, AC97_MASTER, 0x8080);2867 snd_ac97_update(ac97, AC97_MASTER, 0x8080);
2993 2868
2994:c:func:`snd_ac97_read()` is used to read the value of the given2869:c:func:`snd_ac97_read()` is used to read the value of the given
2995register. For example,2870register. For example::
2996
2997::
2998 2871
2999 value = snd_ac97_read(ac97, AC97_MASTER);2872 value = snd_ac97_read(ac97, AC97_MASTER);
3000 2873
3001:c:func:`snd_ac97_update_bits()` is used to update some bits in2874:c:func:`snd_ac97_update_bits()` is used to update some bits in
3002the given register.2875the given register::
3003
3004::
3005 2876
3006 snd_ac97_update_bits(ac97, reg, mask, value);2877 snd_ac97_update_bits(ac97, reg, mask, value);
3007 2878
3008Also, there is a function to change the sample rate (of a given register2879Also, there is a function to change the sample rate (of a given register
3009such as ``AC97_PCM_FRONT_DAC_RATE``) when VRA or DRA is supported by the2880such as ``AC97_PCM_FRONT_DAC_RATE``) when VRA or DRA is supported by the
3010codec: :c:func:`snd_ac97_set_rate()`.2881codec: :c:func:`snd_ac97_set_rate()`::
3011
3012::
3013 2882
3014 snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);2883 snd_ac97_set_rate(ac97, AC97_PCM_FRONT_DAC_RATE, 44100);
3015 2884
@@ -3064,9 +2933,7 @@ mpu401 stuff. For example, emu10k1 has its own mpu401 routines. · 48 unmodified lines
3064MIDI Constructor2933MIDI Constructor
3065----------------2934----------------
3066 2935
3067To create a rawmidi object, call :c:func:`snd_mpu401_uart_new()`.2936To create a rawmidi object, call :c:func:`snd_mpu401_uart_new()`::
3068
3069::
3070 2937
3071 struct snd_rawmidi *rmidi;2938 struct snd_rawmidi *rmidi;
3072 snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,2939 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
3111field of struct snd_mpu401 manually afterward.2978field of struct snd_mpu401 manually afterward.
3112However, struct snd_mpu401 pointer is2979However, struct snd_mpu401 pointer is
3113not returned explicitly by :c:func:`snd_mpu401_uart_new()`. You2980not returned explicitly by :c:func:`snd_mpu401_uart_new()`. You
3114need to cast ``rmidi->private_data`` to struct snd_mpu401 explicitly,2981need to cast ``rmidi->private_data`` to struct snd_mpu401 explicitly::
3115
3116::
3117 2982
3118 struct snd_mpu401 *mpu;2983 struct snd_mpu401 *mpu;
3119 mpu = rmidi->private_data;2984 mpu = rmidi->private_data;
3120 2985
3121and reset the ``cport`` as you like:2986and reset the ``cport`` as you like::
3122
3123::
3124 2987
3125 mpu->cport = my_own_control_port;2988 mpu->cport = my_own_control_port;
3126 2989
@@ -3144,9 +3007,7 @@ occurred. · 17 unmodified lines
3144 3007
3145In this case, you need to pass the private_data of the returned rawmidi3008In this case, you need to pass the private_data of the returned rawmidi
3146object from :c:func:`snd_mpu401_uart_new()` as the second3009object from :c:func:`snd_mpu401_uart_new()` as the second
3147argument of :c:func:`snd_mpu401_uart_interrupt()`.3010argument of :c:func:`snd_mpu401_uart_interrupt()`::
3148
3149::
3150 3011
3151 snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);3012 snd_mpu401_uart_interrupt(irq, rmidi->private_data, regs);
3152 3013
@@ -3170,9 +3031,7 @@ RawMIDI Constructor · 17 unmodified lines
3170-------------------3031-------------------
3171 3032
3172To create a rawmidi device, call the :c:func:`snd_rawmidi_new()`3033To create a rawmidi device, call the :c:func:`snd_rawmidi_new()`
3173function:3034function::
3174
3175::
3176 3035
3177 struct snd_rawmidi *rmidi;3036 struct snd_rawmidi *rmidi;
3178 err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);3037 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
3202 3061
3203After the rawmidi device is created, you need to set the operators3062After the rawmidi device is created, you need to set the operators
3204(callbacks) for each substream. There are helper functions to set the3063(callbacks) for each substream. There are helper functions to set the
3205operators for all the substreams of a device:3064operators for all the substreams of a device::
3206
3207::
3208 3065
3209 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);3066 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mymidi_output_ops);
3210 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);3067 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mymidi_input_ops);
3211 3068
3212The operators are usually defined like this:3069The operators are usually defined like this::
3213
3214::
3215 3070
3216 static struct snd_rawmidi_ops snd_mymidi_output_ops = {3071 static struct snd_rawmidi_ops snd_mymidi_output_ops = {
3217 .open = snd_mymidi_output_open,3072 .open = snd_mymidi_output_open,
@@ -3222,9 +3077,7 @@ The operators are usually defined like this: · 4 unmodified lines
3222These callbacks are explained in the `RawMIDI Callbacks`_ section.3077These callbacks are explained in the `RawMIDI Callbacks`_ section.
3223 3078
3224If there are more than one substream, you should give a unique name to3079If there are more than one substream, you should give a unique name to
3225each of them:3080each of them::
3226
3227::
3228 3081
3229 struct snd_rawmidi_substream *substream;3082 struct snd_rawmidi_substream *substream;
3230 list_for_each_entry(substream,3083 list_for_each_entry(substream,
@@ -3242,9 +3095,7 @@ device can be accessed as ``substream->rmidi->private_data``. · 11 unmodified lines
3242 3095
3243If there is more than one port, your callbacks can determine the port3096If there is more than one port, your callbacks can determine the port
3244index from the struct snd_rawmidi_substream data passed to each3097index from the struct snd_rawmidi_substream data passed to each
3245callback:3098callback::
3246
3247::
3248 3099
3249 struct snd_rawmidi_substream *substream;3100 struct snd_rawmidi_substream *substream;
3250 int index = substream->number;3101 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
3289requested when there are no more data in the buffer. After the data have3140requested when there are no more data in the buffer. After the data have
3290been transmitted successfully, call3141been transmitted successfully, call
3291:c:func:`snd_rawmidi_transmit_ack()` to remove the data from the3142:c:func:`snd_rawmidi_transmit_ack()` to remove the data from the
3292substream buffer:3143substream buffer::
3293
3294::
3295 3144
3296 unsigned char data;3145 unsigned char data;
3297 while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {3146 while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
@@ -3303,9 +3152,7 @@ substream buffer: · 5 unmodified lines
3303 3152
3304If you know beforehand that the hardware will accept data, you can use3153If you know beforehand that the hardware will accept data, you can use
3305the :c:func:`snd_rawmidi_transmit()` function which reads some3154the :c:func:`snd_rawmidi_transmit()` function which reads some
3306data and removes them from the buffer at once:3155data and removes them from the buffer at once::
3307
3308::
3309 3156
3310 while (snd_mychip_transmit_possible()) {3157 while (snd_mychip_transmit_possible()) {
3311 unsigned char data;3158 unsigned char data;
@@ -3340,9 +3187,7 @@ The ``trigger`` callback must not sleep; the actual reading of data · 28 unmodified lines
3340from the device is usually done in an interrupt handler.3187from the device is usually done in an interrupt handler.
3341 3188
3342When data reception is enabled, your interrupt handler should call3189When data reception is enabled, your interrupt handler should call
3343:c:func:`snd_rawmidi_receive()` for all received data:3190:c:func:`snd_rawmidi_receive()` for all received data::
3344
3345::
3346 3191
3347 void snd_mychip_midi_interrupt(...)3192 void snd_mychip_midi_interrupt(...)
3348 {3193 {
@@ -3388,9 +3233,7 @@ whereas in OSS compatible mode, FM registers can be accessed with the · 39 unmodified lines
3388OSS direct-FM compatible API in ``/dev/dmfmX`` device.3233OSS direct-FM compatible API in ``/dev/dmfmX`` device.
3389 3234
3390To create the OPL3 component, you have two functions to call. The first3235To create the OPL3 component, you have two functions to call. The first
3391one is a constructor for the ``opl3_t`` instance.3236one is a constructor for the ``opl3_t`` instance::
3392
3393::
3394 3237
3395 struct snd_opl3 *opl3;3238 struct snd_opl3 *opl3;
3396 snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,3239 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
3408 3251
3409When the accessing the hardware requires special method instead of the3252When the accessing the hardware requires special method instead of the
3410standard I/O access, you can create opl3 instance separately with3253standard I/O access, you can create opl3 instance separately with
3411:c:func:`snd_opl3_new()`.3254:c:func:`snd_opl3_new()`::
3412
3413::
3414 3255
3415 struct snd_opl3 *opl3;3256 struct snd_opl3 *opl3;
3416 snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);3257 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
3427it internally.3268it internally.
3428 3269
3429If the opl3 instance is created successfully, then create a hwdep device3270If the opl3 instance is created successfully, then create a hwdep device
3430for this opl3.3271for this opl3::
3431
3432::
3433 3272
3434 struct snd_hwdep *opl3hwdep;3273 struct snd_hwdep *opl3hwdep;
3435 snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);3274 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
3451``isa/sb/sb16_csp.c``.3290``isa/sb/sb16_csp.c``.
3452 3291
3453The creation of the ``hwdep`` instance is done via3292The creation of the ``hwdep`` instance is done via
3454:c:func:`snd_hwdep_new()`.3293:c:func:`snd_hwdep_new()`::
3455
3456::
3457 3294
3458 struct snd_hwdep *hw;3295 struct snd_hwdep *hw;
3459 snd_hwdep_new(card, "My HWDEP", 0, &hw);3296 snd_hwdep_new(card, "My HWDEP", 0, &hw);
@@ -3461,18 +3298,14 @@ The creation of the ``hwdep`` instance is done via · 1 unmodified line
3461where the third argument is the index number.3298where the third argument is the index number.
3462 3299
3463You can then pass any pointer value to the ``private_data``. If you3300You can then pass any pointer value to the ``private_data``. If you
3464assign a private data, you should define the destructor, too. The3301assign private data, you should define a destructor, too. The
3465destructor function is set in the ``private_free`` field.3302destructor function is set in the ``private_free`` field::
3466
3467::
3468 3303
3469 struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);3304 struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
3470 hw->private_data = p;3305 hw->private_data = p;
3471 hw->private_free = mydata_free;3306 hw->private_free = mydata_free;
3472 3307
3473and the implementation of the destructor would be:3308and the implementation of the destructor would be::
3474
3475::
3476 3309
3477 static void mydata_free(struct snd_hwdep *hw)3310 static void mydata_free(struct snd_hwdep *hw)
3478 {3311 {
@@ -3482,9 +3315,7 @@ and the implementation of the destructor would be: · 3 unmodified lines
3482 3315
3483The arbitrary file operations can be defined for this instance. The file3316The arbitrary file operations can be defined for this instance. The file
3484operators are defined in the ``ops`` table. For example, assume that3317operators are defined in the ``ops`` table. For example, assume that
3485this chip needs an ioctl.3318this chip needs an ioctl::
3486
3487::
3488 3319
3489 hw->ops.open = mydata_open;3320 hw->ops.open = mydata_open;
3490 hw->ops.ioctl = mydata_ioctl;3321 hw->ops.ioctl = mydata_ioctl;
@@ -3534,31 +3365,30 @@ Buffer Types · 43 unmodified lines
3534 3365
3535ALSA provides several different buffer allocation functions depending on3366ALSA provides several different buffer allocation functions depending on
3536the bus and the architecture. All these have a consistent API. The3367the bus and the architecture. All these have a consistent API. The
3537allocation of physically-contiguous pages is done via3368allocation of physically-contiguous pages is done via the
3538:c:func:`snd_malloc_xxx_pages()` function, where xxx is the bus3369:c:func:`snd_malloc_xxx_pages()` function, where xxx is the bus
3539type.3370type.
3540 3371
3541The allocation of pages with fallback is3372The allocation of pages with fallback is done via
3542:c:func:`snd_malloc_xxx_pages_fallback()`. This function tries3373:c:func:`snd_dma_alloc_pages_fallback()`. This function tries
3543to allocate the specified pages but if the pages are not available, it3374to allocate the specified number of pages, but if not enough pages are
3544tries to reduce the page sizes until enough space is found.3375available, it tries to reduce the request size until enough space
3376is found, down to one page.
3545 3377
3546The release the pages, call :c:func:`snd_free_xxx_pages()`3378To release the pages, call the :c:func:`snd_dma_free_pages()`
3547function.3379function.
3548 3380
3549Usually, ALSA drivers try to allocate and reserve a large contiguous3381Usually, ALSA drivers try to allocate and reserve a large contiguous
3550physical space at the time the module is loaded for the later use. This3382physical space at the time the module is loaded for later use. This
3551is called “pre-allocation”. As already written, you can call the3383is called “pre-allocation”. As already written, you can call the
3552following function at pcm instance construction time (in the case of PCI3384following function at PCM instance construction time (in the case of PCI
3553bus).3385bus)::
3554
3555::
3556 3386
3557 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,3387 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
3558 &pci->dev, size, max);3388 &pci->dev, size, max);
3559 3389
3560where ``size`` is the byte size to be pre-allocated and the ``max`` is3390where ``size`` is the byte size to be pre-allocated and ``max`` is
3561the maximum size to be changed via the ``prealloc`` proc file. The3391the maximum size settable via the ``prealloc`` proc file. The
3562allocator will try to get an area as large as possible within the3392allocator will try to get an area as large as possible within the
3563given size.3393given size.
3564 3394
@@ -3567,10 +3397,10 @@ dependent on the bus. For normal devices, pass the device pointer · 2 unmodified lines
3567(typically identical as ``card->dev``) to the third argument with3397(typically identical as ``card->dev``) to the third argument with
3568``SNDRV_DMA_TYPE_DEV`` type.3398``SNDRV_DMA_TYPE_DEV`` type.
3569 3399
3570For the continuous buffer unrelated to the3400A continuous buffer unrelated to the
3571bus can be pre-allocated with ``SNDRV_DMA_TYPE_CONTINUOUS`` type.3401bus can be pre-allocated with ``SNDRV_DMA_TYPE_CONTINUOUS`` type.
3572You can pass NULL to the device pointer in that case, which is the3402You can pass NULL to the device pointer in that case, which is the
3573default mode implying to allocate with ``GFP_KERNEL`` flag.3403default mode implying to allocate with the ``GFP_KERNEL`` flag.
3574If you need a restricted (lower) address, set up the coherent DMA mask3404If you need a restricted (lower) address, set up the coherent DMA mask
3575bits for the device, and pass the device pointer, like the normal3405bits for the device, and pass the device pointer, like the normal
3576device memory allocations. For this type, it's still allowed to pass3406device 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
3580device pointer (see the `Non-Contiguous Buffers`_ section).3410device pointer (see the `Non-Contiguous Buffers`_ section).
3581 3411
3582Once the buffer is pre-allocated, you can use the allocator in the3412Once the buffer is pre-allocated, you can use the allocator in the
3583``hw_params`` callback:3413``hw_params`` callback::
3584
3585::
3586 3414
3587 snd_pcm_lib_malloc_pages(substream, size);3415 snd_pcm_lib_malloc_pages(substream, size);
3588 3416
3589Note that you have to pre-allocate to use this function.3417Note that you have to pre-allocate to use this function.
3590 3418
3591Most of drivers use, though, rather the newly introduced "managed3419But most drivers use the "managed buffer allocation mode" instead
3592buffer allocation mode" instead of the manual allocation or release.3420of manual allocation and release.
3593This is done by calling :c:func:`snd_pcm_set_managed_buffer_all()`3421This is done by calling :c:func:`snd_pcm_set_managed_buffer_all()`
3594instead of :c:func:`snd_pcm_lib_preallocate_pages_for_all()`.3422instead of :c:func:`snd_pcm_lib_preallocate_pages_for_all()`::
3595
3596::
3597 3423
3598 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,3424 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
3599 &pci->dev, size, max);3425 &pci->dev, size, max);
3600 3426
3601where passed arguments are identical in both functions.3427where the passed arguments are identical for both functions.
3602The difference in the managed mode is that PCM core will call3428The difference in the managed mode is that PCM core will call
3603:c:func:`snd_pcm_lib_malloc_pages()` internally already before calling3429:c:func:`snd_pcm_lib_malloc_pages()` internally already before calling
3604the PCM ``hw_params`` callback, and call :c:func:`snd_pcm_lib_free_pages()`3430the PCM ``hw_params`` callback, and call :c:func:`snd_pcm_lib_free_pages()`
3605after the PCM ``hw_free`` callback automatically. So the driver3431after the PCM ``hw_free`` callback automatically. So the driver
3606doesn't have to call these functions explicitly in its callback any3432doesn't have to call these functions explicitly in its callback any
3607longer. This made many driver code having NULL ``hw_params`` and3433longer. This allows many drivers to have NULL ``hw_params`` and
3608``hw_free`` entries.3434``hw_free`` entries.
3609 3435
3610External Hardware Buffers3436External Hardware Buffers
3611-------------------------3437-------------------------
3612 3438
3613Some chips have their own hardware buffers and the DMA transfer from the3439Some chips have their own hardware buffers and DMA transfer from the
3614host memory is not available. In such a case, you need to either 1)3440host memory is not available. In such a case, you need to either 1)
3615copy/set the audio data directly to the external hardware buffer, or 2)3441copy/set the audio data directly to the external hardware buffer, or 2)
3616make an intermediate buffer and copy/set the data from it to the3442make 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
3618 3444
3619The first case works fine if the external hardware buffer is large3445The first case works fine if the external hardware buffer is large
3620enough. This method doesn't need any extra buffers and thus is more3446enough. This method doesn't need any extra buffers and thus is more
3621effective. You need to define the ``copy_user`` and ``copy_kernel``3447efficient. You need to define the ``copy_user`` and ``copy_kernel``
3622callbacks for the data transfer, in addition to ``fill_silence``3448callbacks for the data transfer, in addition to the ``fill_silence``
3623callback for playback. However, there is a drawback: it cannot be3449callback for playback. However, there is a drawback: it cannot be
3624mmapped. The examples are GUS's GF1 PCM or emu8000's wavetable PCM.3450mmapped. The examples are GUS's GF1 PCM or emu8000's wavetable PCM.
3625 3451
@@ -3633,16 +3459,14 @@ buffer instead of the host memory. In this case, mmap is available only · 7 unmodified lines
3633on certain architectures like the Intel one. In non-mmap mode, the data3459on certain architectures like the Intel one. In non-mmap mode, the data
3634cannot be transferred as in the normal way. Thus you need to define the3460cannot be transferred as in the normal way. Thus you need to define the
3635``copy_user``, ``copy_kernel`` and ``fill_silence`` callbacks as well,3461``copy_user``, ``copy_kernel`` and ``fill_silence`` callbacks as well,
3636as in the cases above. The examples are found in ``rme32.c`` and3462as in the cases above. Examples are found in ``rme32.c`` and
3637``rme96.c``.3463``rme96.c``.
3638 3464
3639The implementation of the ``copy_user``, ``copy_kernel`` and3465The implementation of the ``copy_user``, ``copy_kernel`` and
3640``silence`` callbacks depends upon whether the hardware supports3466``silence`` callbacks depends upon whether the hardware supports
3641interleaved or non-interleaved samples. The ``copy_user`` callback is3467interleaved or non-interleaved samples. The ``copy_user`` callback is
3642defined like below, a bit differently depending whether the direction3468defined like below, a bit differently depending on whether the direction
3643is playback or capture:3469is playback or capture::
3644
3645::
3646 3470
3647 static int playback_copy_user(struct snd_pcm_substream *substream,3471 static int playback_copy_user(struct snd_pcm_substream *substream,
3648 int channel, unsigned long pos,3472 int channel, unsigned long pos,
@@ -3652,8 +3476,7 @@ is playback or capture: · 3 unmodified lines
3652 void __user *dst, unsigned long count);3476 void __user *dst, unsigned long count);
3653 3477
3654In the case of interleaved samples, the second argument (``channel``) is3478In the case of interleaved samples, the second argument (``channel``) is
3655not used. The third argument (``pos``) points the current position3479not used. The third argument (``pos``) specifies the position in bytes.
3656offset in bytes.
3657 3480
3658The meaning of the fourth argument is different between playback and3481The meaning of the fourth argument is different between playback and
3659capture. For playback, it holds the source data pointer, and for3482capture. 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
3664What you have to do in this callback is again different between playback3487What you have to do in this callback is again different between playback
3665and capture directions. In the playback case, you copy the given amount3488and capture directions. In the playback case, you copy the given amount
3666of data (``count``) at the specified pointer (``src``) to the specified3489of data (``count``) at the specified pointer (``src``) to the specified
3667offset (``pos``) on the hardware buffer. When coded like memcpy-like3490offset (``pos``) in the hardware buffer. When coded like memcpy-like
3668way, the copy would be like:3491way, the copy would look like::
3669
3670::
3671 3492
3672 my_memcpy_from_user(my_buffer + pos, src, count);3493 my_memcpy_from_user(my_buffer + pos, src, count);
3673 3494
3674For the capture direction, you copy the given amount of data (``count``)3495For the capture direction, you copy the given amount of data (``count``)
3675at the specified offset (``pos``) on the hardware buffer to the3496at the specified offset (``pos``) in the hardware buffer to the
3676specified pointer (``dst``).3497specified pointer (``dst``)::
3677
3678::
3679 3498
3680 my_memcpy_to_user(dst, my_buffer + pos, count);3499 my_memcpy_to_user(dst, my_buffer + pos, count);
3681 3500
3682Here the functions are named as ``from_user`` and ``to_user`` because3501Here the functions are named ``from_user`` and ``to_user`` because
3683it's the user-space buffer that is passed to these callbacks. That3502it's the user-space buffer that is passed to these callbacks. That
3684is, the callback is supposed to copy from/to the user-space data3503is, the callback is supposed to copy data from/to the user-space
3685directly to/from the hardware buffer.3504directly to/from the hardware buffer.
3686 3505
3687Careful readers might notice that these callbacks receive the3506Careful readers might notice that these callbacks receive the
3688arguments in bytes, not in frames like other callbacks. It's because3507arguments in bytes, not in frames like other callbacks. It's because
3689it would make coding easier like the examples above, and also it makes3508this makes coding easier like in the examples above, and also it makes
3690easier to unify both the interleaved and non-interleaved cases, as3509it easier to unify both the interleaved and non-interleaved cases, as
3691explained in the following.3510explained below.
3692 3511
3693In the case of non-interleaved samples, the implementation will be a bit3512In the case of non-interleaved samples, the implementation will be a bit
3694more complicated. The callback is called for each channel, passed by3513more complicated. The callback is called for each channel, passed in
3695the second argument, so totally it's called for N-channels times per3514the second argument, so in total it's called N times per transfer.
3696transfer.
3697
3698The meaning of other arguments are almost same as the interleaved
3699case. The callback is supposed to copy the data from/to the given
3700user-space buffer, but only for the given channel. For the detailed
3701implementations, please check ``isa/gus/gus_pcm.c`` or
3702"pci/rme9652/rme9652.c" as examples.
3703 3515
3704The above callbacks are the copy from/to the user-space buffer. There3516The meaning of the other arguments are almost the same as in the
3705are some cases where we want copy from/to the kernel-space buffer3517interleaved case. The callback is supposed to copy the data from/to
3706instead. In such a case, ``copy_kernel`` callback is called. It'd3518the given user-space buffer, but only for the given channel. For
3707look like:3519details, please check ``isa/gus/gus_pcm.c`` or ``pci/rme9652/rme9652.c``
3520as examples.
3708 3521
3709::3522The above callbacks are the copies from/to the user-space buffer. There
3523are some cases where we want to copy from/to the kernel-space buffer
3524instead. In such a case, the ``copy_kernel`` callback is called. It'd
3525look like::
3710 3526
3711 static int playback_copy_kernel(struct snd_pcm_substream *substream,3527 static int playback_copy_kernel(struct snd_pcm_substream *substream,
3712 int channel, unsigned long pos,3528 int channel, unsigned long pos,
@@ -3716,19 +3532,15 @@ look like: · 3 unmodified lines
3716 void *dst, unsigned long count);3532 void *dst, unsigned long count);
3717 3533
3718As found easily, the only difference is that the buffer pointer is3534As found easily, the only difference is that the buffer pointer is
3719without ``__user`` prefix; that is, a kernel-buffer pointer is passed3535without a ``__user`` prefix; that is, a kernel-buffer pointer is passed
3720in the fourth argument. Correspondingly, the implementation would be3536in the fourth argument. Correspondingly, the implementation would be
3721a version without the user-copy, such as:3537a version without the user-copy, such as::
3722
3723::
3724 3538
3725 my_memcpy(my_buffer + pos, src, count);3539 my_memcpy(my_buffer + pos, src, count);
3726 3540
3727Usually for the playback, another callback ``fill_silence`` is3541Usually for the playback, another callback ``fill_silence`` is
3728defined. It's implemented in a similar way as the copy callbacks3542defined. It's implemented in a similar way as the copy callbacks
3729above:3543above::
3730
3731::
3732 3544
3733 static int silence(struct snd_pcm_substream *substream, int channel,3545 static int silence(struct snd_pcm_substream *substream, int channel,
3734 unsigned long pos, unsigned long count);3546 unsigned long pos, unsigned long count);
@@ -3736,54 +3548,47 @@ above: · 1 unmodified line
3736The meanings of arguments are the same as in the ``copy_user`` and3548The meanings of arguments are the same as in the ``copy_user`` and
3737``copy_kernel`` callbacks, although there is no buffer pointer3549``copy_kernel`` callbacks, although there is no buffer pointer
3738argument. In the case of interleaved samples, the channel argument has3550argument. In the case of interleaved samples, the channel argument has
3739no meaning, as well as on ``copy_*`` callbacks.3551no meaning, as for the ``copy_*`` callbacks.
3740 3552
3741The role of ``fill_silence`` callback is to set the given amount3553The role of the ``fill_silence`` callback is to set the given amount
3742(``count``) of silence data at the specified offset (``pos``) on the3554(``count``) of silence data at the specified offset (``pos``) in the
3743hardware buffer. Suppose that the data format is signed (that is, the3555hardware buffer. Suppose that the data format is signed (that is, the
3744silent-data is 0), and the implementation using a memset-like function3556silent-data is 0), and the implementation using a memset-like function
3745would be like: 3557would look like::
3746
3747::
3748 3558
3749 my_memset(my_buffer + pos, 0, count);3559 my_memset(my_buffer + pos, 0, count);
3750 3560
3751In the case of non-interleaved samples, again, the implementation3561In the case of non-interleaved samples, again, the implementation
3752becomes a bit more complicated, as it's called N-times per transfer3562becomes a bit more complicated, as it's called N times per transfer
3753for each channel. See, for example, ``isa/gus/gus_pcm.c``.3563for each channel. See, for example, ``isa/gus/gus_pcm.c``.
3754 3564
3755Non-Contiguous Buffers3565Non-Contiguous Buffers
3756----------------------3566----------------------
3757 3567
3758If your hardware supports the page table as in emu10k1 or the buffer3568If your hardware supports a page table as in emu10k1 or buffer
3759descriptors as in via82xx, you can use the scatter-gather (SG) DMA. ALSA3569descriptors as in via82xx, you can use scatter-gather (SG) DMA. ALSA
3760provides an interface for handling SG-buffers. The API is provided in3570provides an interface for handling SG-buffers. The API is provided in
3761``<sound/pcm.h>``.3571``<sound/pcm.h>``.
3762 3572
3763For creating the SG-buffer handler, call3573For creating the SG-buffer handler, call
3764:c:func:`snd_pcm_set_managed_buffer()` or3574:c:func:`snd_pcm_set_managed_buffer()` or
3765:c:func:`snd_pcm_set_managed_buffer_all()` with3575:c:func:`snd_pcm_set_managed_buffer_all()` with
3766``SNDRV_DMA_TYPE_DEV_SG`` in the PCM constructor like other PCI3576``SNDRV_DMA_TYPE_DEV_SG`` in the PCM constructor like for other PCI
3767pre-allocator. You need to pass ``&pci->dev``, where pci is3577pre-allocations. You need to pass ``&pci->dev``, where pci is
3768the struct pci_dev pointer of the chip as3578the struct pci_dev pointer of the chip as well::
3769well.
3770
3771::
3772 3579
3773 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,3580 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
3774 &pci->dev, size, max);3581 &pci->dev, size, max);
3775 3582
3776The ``struct snd_sg_buf`` instance is created as3583The ``struct snd_sg_buf`` instance is created as
3777``substream->dma_private`` in turn. You can cast the pointer like:3584``substream->dma_private`` in turn. You can cast the pointer like::
3778
3779::
3780 3585
3781 struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;3586 struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
3782 3587
3783Then in :c:func:`snd_pcm_lib_malloc_pages()` call, the common SG-buffer3588Then in the :c:func:`snd_pcm_lib_malloc_pages()` call, the common SG-buffer
3784handler will allocate the non-contiguous kernel pages of the given size3589handler will allocate the non-contiguous kernel pages of the given size
3785and map them onto the virtually contiguous memory. The virtual pointer3590and map them as virtually contiguous memory. The virtual pointer
3786is addressed in runtime->dma_area. The physical address3591is addressed via runtime->dma_area. The physical address
3787(``runtime->dma_addr``) is set to zero, because the buffer is3592(``runtime->dma_addr``) is set to zero, because the buffer is
3788physically non-contiguous. The physical address table is set up in3593physically non-contiguous. The physical address table is set up in
3789``sgbuf->table``. You can get the physical address at a certain offset3594``sgbuf->table``. You can get the physical address at a certain offset
@@ -3796,22 +3601,20 @@ Vmalloc'ed Buffers · 6 unmodified lines
3796------------------3601------------------
3797 3602
3798It's possible to use a buffer allocated via :c:func:`vmalloc()`, for3603It's possible to use a buffer allocated via :c:func:`vmalloc()`, for
3799example, for an intermediate buffer. In the recent version of kernel,3604example, for an intermediate buffer.
3800you can simply allocate it via standard3605You can simply allocate it via the standard
3801:c:func:`snd_pcm_lib_malloc_pages()` and co after setting up the3606:c:func:`snd_pcm_lib_malloc_pages()` and co. after setting up the
3802buffer preallocation with ``SNDRV_DMA_TYPE_VMALLOC`` type.3607buffer preallocation with ``SNDRV_DMA_TYPE_VMALLOC`` type::
3803
3804::
3805 3608
3806 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,3609 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC,
3807 NULL, 0, 0);3610 NULL, 0, 0);
3808 3611
3809The NULL is passed to the device pointer argument, which indicates3612NULL is passed as the device pointer argument, which indicates
3810that the default pages (GFP_KERNEL and GFP_HIGHMEM) will be3613that default pages (GFP_KERNEL and GFP_HIGHMEM) will be
3811allocated.3614allocated.
3812 3615
3813Also, note that zero is passed to both the size and the max size3616Also, note that zero is passed as both the size and the max size
3814arguments here. Since each vmalloc call should succeed at any time,3617argument here. Since each vmalloc call should succeed at any time,
3815we don't need to pre-allocate the buffers like other continuous3618we don't need to pre-allocate the buffers like other continuous
3816pages.3619pages.
3817 3620
@@ -3823,9 +3626,7 @@ useful for debugging. I recommend you set up proc files if you write a · 5 unmodified lines
3823driver and want to get a running status or register dumps. The API is3626driver and want to get a running status or register dumps. The API is
3824found in ``<sound/info.h>``.3627found in ``<sound/info.h>``.
3825 3628
3826To create a proc file, call :c:func:`snd_card_proc_new()`.3629To create a proc file, call :c:func:`snd_card_proc_new()`::
3827
3828::
3829 3630
3830 struct snd_info_entry *entry;3631 struct snd_info_entry *entry;
3831 int err = snd_card_proc_new(card, "my-file", &entry);3632 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
3841When the creation is successful, the function stores a new instance in3642When the creation is successful, the function stores a new instance in
3842the pointer given in the third argument. It is initialized as a text3643the pointer given in the third argument. It is initialized as a text
3843proc file for read only. To use this proc file as a read-only text file3644proc file for read only. To use this proc file as a read-only text file
3844as it is, set the read callback with a private data via3645as-is, set the read callback with private data via
3845:c:func:`snd_info_set_text_ops()`.3646:c:func:`snd_info_set_text_ops()`::
3846
3847::
3848 3647
3849 snd_info_set_text_ops(entry, chip, my_proc_read);3648 snd_info_set_text_ops(entry, chip, my_proc_read);
3850 3649
3851where the second argument (``chip``) is the private data to be used in3650where the second argument (``chip``) is the private data to be used in
3852the callbacks. The third parameter specifies the read buffer size and3651the callback. The third parameter specifies the read buffer size and
3853the fourth (``my_proc_read``) is the callback function, which is3652the fourth (``my_proc_read``) is the callback function, which is
3854defined like3653defined like::
3855
3856::
3857 3654
3858 static void my_proc_read(struct snd_info_entry *entry,3655 static void my_proc_read(struct snd_info_entry *entry,
3859 struct snd_info_buffer *buffer);3656 struct snd_info_buffer *buffer);
3860 3657
3861In the read callback, use :c:func:`snd_iprintf()` for output3658In the read callback, use :c:func:`snd_iprintf()` for output
3862strings, which works just like normal :c:func:`printf()`. For3659strings, which works just like normal :c:func:`printf()`. For
3863example,3660example::
3864
3865::
3866 3661
3867 static void my_proc_read(struct snd_info_entry *entry,3662 static void my_proc_read(struct snd_info_entry *entry,
3868 struct snd_info_buffer *buffer)3663 struct snd_info_buffer *buffer)
@@ -3873,28 +3668,22 @@ example, · 4 unmodified lines
3873 snd_iprintf(buffer, "Port = %ld\n", chip->port);3668 snd_iprintf(buffer, "Port = %ld\n", chip->port);
3874 }3669 }
3875 3670
3876The file permissions can be changed afterwards. As default, it's set as3671The file permissions can be changed afterwards. By default, they are
3877read only for all users. If you want to add write permission for the3672read only for all users. If you want to add write permission for the
3878user (root as default), do as follows:3673user (root by default), do as follows::
3879
3880::
3881 3674
3882 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;3675 entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
3883 3676
3884and set the write buffer size and the callback3677and set the write buffer size and the callback::
3885
3886::
3887 3678
3888 entry->c.text.write = my_proc_write;3679 entry->c.text.write = my_proc_write;
3889 3680
3890For the write callback, you can use :c:func:`snd_info_get_line()`3681In the write callback, you can use :c:func:`snd_info_get_line()`
3891to get a text line, and :c:func:`snd_info_get_str()` to retrieve3682to get a text line, and :c:func:`snd_info_get_str()` to retrieve
3892a string from the line. Some examples are found in3683a string from the line. Some examples are found in
3893``core/oss/mixer_oss.c``, core/oss/and ``pcm_oss.c``.3684``core/oss/mixer_oss.c``, core/oss/and ``pcm_oss.c``.
3894 3685
3895For a raw-data proc-file, set the attributes as follows:3686For a raw-data proc-file, set the attributes as follows::
3896
3897::
3898 3687
3899 static const struct snd_info_entry_ops my_file_io_ops = {3688 static const struct snd_info_entry_ops my_file_io_ops = {
3900 .read = my_file_io_read,3689 .read = my_file_io_read,
@@ -3906,14 +3695,13 @@ For a raw-data proc-file, set the attributes as follows: · 5 unmodified lines
3906 entry->size = 4096;3695 entry->size = 4096;
3907 entry->mode = S_IFREG | S_IRUGO;3696 entry->mode = S_IFREG | S_IRUGO;
3908 3697
3909For the raw data, ``size`` field must be set properly. This specifies3698For raw data, ``size`` field must be set properly. This specifies
3910the maximum size of the proc file access.3699the maximum size of the proc file access.
3911 3700
3912The read/write callbacks of raw mode are more direct than the text mode.3701The read/write callbacks of raw mode are more direct than the text mode.
3913You need to use a low-level I/O functions such as3702You 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.3703:c:func:`copy_from_user()` and :c:func:`copy_to_user()` to transfer the
3915 3704data::
3916::
3917 3705
3918 static ssize_t my_file_io_read(struct snd_info_entry *entry,3706 static ssize_t my_file_io_read(struct snd_info_entry *entry,
3919 void *file_private_data,3707 void *file_private_data,
@@ -3938,12 +3726,11 @@ Power Management · 18 unmodified lines
3938If the chip is supposed to work with suspend/resume functions, you need3726If the chip is supposed to work with suspend/resume functions, you need
3939to add power-management code to the driver. The additional code for3727to add power-management code to the driver. The additional code for
3940power-management should be ifdef-ed with ``CONFIG_PM``, or annotated3728power-management should be ifdef-ed with ``CONFIG_PM``, or annotated
3941with __maybe_unused attribute; otherwise the compiler will complain3729with __maybe_unused attribute; otherwise the compiler will complain.
3942you.
3943 3730
3944If the driver *fully* supports suspend/resume that is, the device can be3731If the driver *fully* supports suspend/resume that is, the device can be
3945properly resumed to its state when suspend was called, you can set the3732properly 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 is3733``SNDRV_PCM_INFO_RESUME`` flag in the PCM info field. Usually, this is
3947possible when the registers of the chip can be safely saved and restored3734possible when the registers of the chip can be safely saved and restored
3948to RAM. If this is set, the trigger callback is called with3735to RAM. If this is set, the trigger callback is called with
3949``SNDRV_PCM_TRIGGER_RESUME`` after the resume callback completes.3736``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
3953callbacks. In such a case, applications would reset the status by3740callbacks. In such a case, applications would reset the status by
3954calling :c:func:`snd_pcm_prepare()` and restart the stream3741calling :c:func:`snd_pcm_prepare()` and restart the stream
3955appropriately. Hence, you can define suspend/resume callbacks below but3742appropriately. Hence, you can define suspend/resume callbacks below but
3956don't set ``SNDRV_PCM_INFO_RESUME`` info flag to the PCM.3743don't set the ``SNDRV_PCM_INFO_RESUME`` info flag to the PCM.
3957 3744
3958Note that the trigger with SUSPEND can always be called when3745Note that the trigger with SUSPEND can always be called when
3959:c:func:`snd_pcm_suspend_all()` is called, regardless of the3746: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
3963callback when no ``SNDRV_PCM_INFO_RESUME`` flag is set. But, it's better3750callback when no ``SNDRV_PCM_INFO_RESUME`` flag is set. But, it's better
3964to keep it for compatibility reasons.)3751to keep it for compatibility reasons.)
3965 3752
3966In the earlier version of ALSA drivers, a common power-management layer3753The driver needs to define the
3967was provided, but it has been removed. The driver needs to define the
3968suspend/resume hooks according to the bus the device is connected to. In3754suspend/resume hooks according to the bus the device is connected to. In
3969the case of PCI drivers, the callbacks look like below:3755the case of PCI drivers, the callbacks look like below::
3970
3971::
3972 3756
3973 static int __maybe_unused snd_my_suspend(struct device *dev)3757 static int __maybe_unused snd_my_suspend(struct device *dev)
3974 {3758 {
@@ -3981,7 +3765,7 @@ the case of PCI drivers, the callbacks look like below: · 6 unmodified lines
3981 return 0;3765 return 0;
3982 }3766 }
3983 3767
3984The scheme of the real suspend job is as follows.3768The scheme of the real suspend job is as follows:
3985 3769
39861. Retrieve the card and the chip data.37701. Retrieve the card and the chip data.
3987 3771
@@ -3995,9 +3779,7 @@ The scheme of the real suspend job is as follows. · 7 unmodified lines
3995 3779
39965. Stop the hardware if necessary.37805. Stop the hardware if necessary.
3997 3781
3998A typical code would be like:3782Typical code would look like::
3999
4000::
4001 3783
4002 static int __maybe_unused mychip_suspend(struct device *dev)3784 static int __maybe_unused mychip_suspend(struct device *dev)
4003 {3785 {
@@ -4016,7 +3798,7 @@ A typical code would be like: · 12 unmodified lines
4016 }3798 }
4017 3799
4018 3800
4019The scheme of the real resume job is as follows.3801The scheme of the real resume job is as follows:
4020 3802
40211. Retrieve the card and the chip data.38031. Retrieve the card and the chip data.
4022 3804
@@ -4024,16 +3806,14 @@ The scheme of the real resume job is as follows. · 1 unmodified line
4024 3806
40253. Restore the saved registers if necessary.38073. Restore the saved registers if necessary.
4026 3808
40274. Resume the mixer, e.g. calling :c:func:`snd_ac97_resume()`.38094. Resume the mixer, e.g. by calling :c:func:`snd_ac97_resume()`.
4028 3810
40295. Restart the hardware (if any).38115. Restart the hardware (if any).
4030 3812
40316. Call :c:func:`snd_power_change_state()` with38136. Call :c:func:`snd_power_change_state()` with
4032 ``SNDRV_CTL_POWER_D0`` to notify the processes.3814 ``SNDRV_CTL_POWER_D0`` to notify the processes.
4033 3815
4034A typical code would be like:3816Typical code would look like::
4035
4036::
4037 3817
4038 static int __maybe_unused mychip_resume(struct pci_dev *pci)3818 static int __maybe_unused mychip_resume(struct pci_dev *pci)
4039 {3819 {
@@ -4060,9 +3840,7 @@ been already suspended via its own PM ops calling · 20 unmodified lines
4060OK, we have all callbacks now. Let's set them up. In the initialization3840OK, we have all callbacks now. Let's set them up. In the initialization
4061of the card, make sure that you can get the chip data from the card3841of the card, make sure that you can get the chip data from the card
4062instance, typically via ``private_data`` field, in case you created the3842instance, typically via ``private_data`` field, in case you created the
4063chip data individually.3843chip data individually::
4064
4065::
4066 3844
4067 static int snd_mychip_probe(struct pci_dev *pci,3845 static int snd_mychip_probe(struct pci_dev *pci,
4068 const struct pci_device_id *pci_id)3846 const struct pci_device_id *pci_id)
@@ -4082,9 +3860,7 @@ chip data individually. · 13 unmodified lines
4082 }3860 }
4083 3861
4084When you created the chip data with :c:func:`snd_card_new()`, it's3862When you created the chip data with :c:func:`snd_card_new()`, it's
4085anyway accessible via ``private_data`` field.3863anyway accessible via ``private_data`` field::
4086
4087::
4088 3864
4089 static int snd_mychip_probe(struct pci_dev *pci,3865 static int snd_mychip_probe(struct pci_dev *pci,
4090 const struct pci_device_id *pci_id)3866 const struct pci_device_id *pci_id)
@@ -4101,14 +3877,12 @@ anyway accessible via ``private_data`` field. · 10 unmodified lines
4101 ....3877 ....
4102 }3878 }
4103 3879
4104If you need a space to save the registers, allocate the buffer for it3880If you need space to save the registers, allocate the buffer for it
4105here, too, since it would be fatal if you cannot allocate a memory in3881here, too, since it would be fatal if you cannot allocate a memory in
4106the suspend phase. The allocated buffer should be released in the3882the suspend phase. The allocated buffer should be released in the
4107corresponding destructor.3883corresponding destructor.
4108 3884
4109And next, set suspend/resume callbacks to the pci_driver.3885And next, set suspend/resume callbacks to the pci_driver::
4110
4111::
4112 3886
4113 static SIMPLE_DEV_PM_OPS(snd_my_pm_ops, mychip_suspend, mychip_resume);3887 static SIMPLE_DEV_PM_OPS(snd_my_pm_ops, mychip_suspend, mychip_resume);
4114 3888
@@ -4128,9 +3902,7 @@ have the ``index``, ``id`` and ``enable`` options. · 13 unmodified lines
4128 3902
4129If the module supports multiple cards (usually up to 8 = ``SNDRV_CARDS``3903If the module supports multiple cards (usually up to 8 = ``SNDRV_CARDS``
4130cards), they should be arrays. The default initial values are defined3904cards), they should be arrays. The default initial values are defined
4131already as constants for easier programming:3905already as constants for easier programming::
4132
4133::
4134 3906
4135 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;3907 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
4136 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;3908 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -4144,9 +3916,7 @@ The module parameters must be declared with the standard · 7 unmodified lines
4144``module_param()``, ``module_param_array()`` and3916``module_param()``, ``module_param_array()`` and
4145:c:func:`MODULE_PARM_DESC()` macros.3917:c:func:`MODULE_PARM_DESC()` macros.
4146 3918
4147The typical coding would be like below:3919Typical code would look as below::
4148
4149::
4150 3920
4151 #define CARD_NAME "My Chip"3921 #define CARD_NAME "My Chip"
4152 3922
@@ -4159,9 +3929,7 @@ The typical coding would be like below: · 6 unmodified lines
4159 3929
4160Also, don't forget to define the module description and the license.3930Also, don't forget to define the module description and the license.
4161Especially, the recent modprobe requires to define the3931Especially, the recent modprobe requires to define the
4162module license as GPL, etc., otherwise the system is shown as “tainted”.3932module license as GPL, etc., otherwise the system is shown as “tainted”::
4163
4164::
4165 3933
4166 MODULE_DESCRIPTION("Sound driver for My Chip");3934 MODULE_DESCRIPTION("Sound driver for My Chip");
4167 MODULE_LICENSE("GPL");3935 MODULE_LICENSE("GPL");
@@ -4224,32 +3992,36 @@ Driver with A Single Source File · 56 unmodified lines
4224 3992
42251. Modify sound/pci/Makefile39931. Modify sound/pci/Makefile
4226 3994
4227 Suppose you have a file xyz.c. Add the following two lines3995 Suppose you have a file xyz.c. Add the following two lines::
4228
4229::
4230 3996
4231 snd-xyz-objs := xyz.o3997 snd-xyz-objs := xyz.o
4232 obj-$(CONFIG_SND_XYZ) += snd-xyz.o3998 obj-$(CONFIG_SND_XYZ) += snd-xyz.o
4233 3999
42342. Create the Kconfig entry40002. Create the Kconfig entry
4235 4001
4236 Add the new entry of Kconfig for your xyz driver. config SND_XYZ4002 Add the new entry of Kconfig for your xyz driver::
4237 tristate "Foobar XYZ" depends on SND select SND_PCM help Say Y here4003
4238 to include support for Foobar XYZ soundcard. To compile this driver4004 config SND_XYZ
4239 as a module, choose M here: the module will be called snd-xyz. the4005 tristate "Foobar XYZ"
4240 line, select SND_PCM, specifies that the driver xyz supports PCM. In4006 depends on SND
4241 addition to SND_PCM, the following components are supported for4007 select SND_PCM
4242 select command: SND_RAWMIDI, SND_TIMER, SND_HWDEP,4008 help
4243 SND_MPU401_UART, SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB,4009 Say Y here to include support for Foobar XYZ soundcard.
4244 SND_AC97_CODEC. Add the select command for each supported4010 To compile this driver as a module, choose M here:
4245 component.4011 the module will be called snd-xyz.
4012
4013The line ``select SND_PCM`` specifies that the driver xyz supports PCM.
4014In addition to SND_PCM, the following components are supported for
4015select command: SND_RAWMIDI, SND_TIMER, SND_HWDEP, SND_MPU401_UART,
4016SND_OPL3_LIB, SND_OPL4_LIB, SND_VX_LIB, SND_AC97_CODEC.
4017Add the select command for each supported component.
4246 4018
4247 Note that some selections imply the lowlevel selections. For example,4019Note that some selections imply the lowlevel selections. For example,
4248 PCM includes TIMER, MPU401_UART includes RAWMIDI, AC97_CODEC4020PCM includes TIMER, MPU401_UART includes RAWMIDI, AC97_CODEC
4249 includes PCM, and OPL3_LIB includes HWDEP. You don't need to give4021includes PCM, and OPL3_LIB includes HWDEP. You don't need to give
4250 the lowlevel selections again.4022the lowlevel selections again.
4251 4023
4252 For the details of Kconfig script, refer to the kbuild documentation.4024For the details of Kconfig script, refer to the kbuild documentation.
4253 4025
4254Drivers with Several Source Files4026Drivers with Several Source Files
4255---------------------------------4027---------------------------------
@@ -4258,16 +4030,12 @@ Suppose that the driver snd-xyz have several source files. They are · 2 unmodified lines
4258located in the new subdirectory, sound/pci/xyz.4030located in the new subdirectory, sound/pci/xyz.
4259 4031
42601. Add a new directory (``sound/pci/xyz``) in ``sound/pci/Makefile``40321. Add a new directory (``sound/pci/xyz``) in ``sound/pci/Makefile``
4261 as below4033 as below::
4262
4263::
4264 4034
4265 obj-$(CONFIG_SND) += sound/pci/xyz/4035 obj-$(CONFIG_SND) += sound/pci/xyz/
4266 4036
4267 4037
42682. Under the directory ``sound/pci/xyz``, create a Makefile40382. Under the directory ``sound/pci/xyz``, create a Makefile::
4269
4270::
4271 4039
4272 snd-xyz-objs := xyz.o abc.o def.o4040 snd-xyz-objs := xyz.o abc.o def.o
4273 obj-$(CONFIG_SND_XYZ) += snd-xyz.o4041 obj-$(CONFIG_SND_XYZ) += snd-xyz.o
MAINTAINERS+34−2
@@ -2075,6 +2075,7 @@ M: Alexander Sverdlin <alexander.sverdlin@gmail.com> · 2074 unmodified lines
2075L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)2075L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
2076S: Maintained2076S: Maintained
2077F: Documentation/devicetree/bindings/iio/adc/cirrus,ep9301-adc.yaml2077F: Documentation/devicetree/bindings/iio/adc/cirrus,ep9301-adc.yaml
2078F: Documentation/devicetree/bindings/sound/cirrus,ep9301-*
2078F: arch/arm/boot/compressed/misc-ep93xx.h2079F: arch/arm/boot/compressed/misc-ep93xx.h
2079F: arch/arm/mach-ep93xx/2080F: arch/arm/mach-ep93xx/
2080F: drivers/iio/adc/ep93xx_adc.c2081F: drivers/iio/adc/ep93xx_adc.c
@@ -4922,6 +4923,7 @@ L: patches@opensource.cirrus.com · 2841 unmodified lines
4922S: Maintained4923S: Maintained
4923F: Documentation/devicetree/bindings/sound/cirrus,cs*4924F: Documentation/devicetree/bindings/sound/cirrus,cs*
4924F: include/dt-bindings/sound/cs*4925F: include/dt-bindings/sound/cs*
4926F: include/sound/cs*
4925F: sound/pci/hda/cs*4927F: sound/pci/hda/cs*
4926F: sound/pci/hda/hda_cs_dsp_ctl.*4928F: sound/pci/hda/hda_cs_dsp_ctl.*
4927F: sound/soc/codecs/cs*4929F: sound/soc/codecs/cs*
@@ -8282,6 +8284,23 @@ S: Maintained · 3354 unmodified lines
8282F: drivers/soc/fsl/qe/8284F: drivers/soc/fsl/qe/
8283F: include/soc/fsl/qe/8285F: include/soc/fsl/qe/
8284 8286
8287FREESCALE QUICC ENGINE QMC DRIVER
8288M: Herve Codina <herve.codina@bootlin.com>
8289L: linuxppc-dev@lists.ozlabs.org
8290S: Maintained
8291F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
8292F: drivers/soc/fsl/qe/qmc.c
8293F: include/soc/fsl/qe/qmc.h
8294
8295FREESCALE QUICC ENGINE TSA DRIVER
8296M: Herve Codina <herve.codina@bootlin.com>
8297L: linuxppc-dev@lists.ozlabs.org
8298S: Maintained
8299F: Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-tsa.yaml
8300F: drivers/soc/fsl/qe/tsa.c
8301F: drivers/soc/fsl/qe/tsa.h
8302F: include/dt-bindings/soc/cpm1-fsl,tsa.h
8303
8285FREESCALE QUICC ENGINE UCC ETHERNET DRIVER8304FREESCALE QUICC ENGINE UCC ETHERNET DRIVER
8286M: Li Yang <leoyang.li@nxp.com>8305M: Li Yang <leoyang.li@nxp.com>
8287L: netdev@vger.kernel.org8306L: netdev@vger.kernel.org
@@ -8333,6 +8352,14 @@ F: sound/soc/fsl/fsl* · 45 unmodified lines
8333F: sound/soc/fsl/imx*8352F: sound/soc/fsl/imx*
8334F: sound/soc/fsl/mpc8610_hpcd.c8353F: sound/soc/fsl/mpc8610_hpcd.c
8335 8354
8355FREESCALE SOC SOUND QMC DRIVER
8356M: Herve Codina <herve.codina@bootlin.com>
8357L: alsa-devel@alsa-project.org (moderated for non-subscribers)
8358L: linuxppc-dev@lists.ozlabs.org
8359S: Maintained
8360F: Documentation/devicetree/bindings/sound/fsl,qmc-audio.yaml
8361F: sound/soc/fsl/fsl_qmc_audio.c
8362
8336FREESCALE USB PERIPHERAL DRIVERS8363FREESCALE USB PERIPHERAL DRIVERS
8337M: Li Yang <leoyang.li@nxp.com>8364M: Li Yang <leoyang.li@nxp.com>
8338L: linux-usb@vger.kernel.org8365L: linux-usb@vger.kernel.org
@@ -13651,9 +13678,13 @@ F: Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml · 5312 unmodified lines
13651F: drivers/spi/spi-at91-usart.c13678F: drivers/spi/spi-at91-usart.c
13652 13679
13653MICROCHIP AUDIO ASOC DRIVERS13680MICROCHIP AUDIO ASOC DRIVERS
13654M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>13681M: Claudiu Beznea <claudiu.beznea@microchip.com>
13655L: alsa-devel@alsa-project.org (moderated for non-subscribers)13682L: alsa-devel@alsa-project.org (moderated for non-subscribers)
13656S: Supported13683S: Supported
13684F: Documentation/devicetree/bindings/sound/atmel*
13685F: Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt
13686F: Documentation/devicetree/bindings/sound/microchip,sama7g5-*
13687F: Documentation/devicetree/bindings/sound/mikroe,mikroe-proto.txt
13657F: sound/soc/atmel13688F: sound/soc/atmel
13658 13689
13659MICROCHIP CSI2DC DRIVER13690MICROCHIP CSI2DC DRIVER
@@ -13826,9 +13857,10 @@ S: Supported · 166 unmodified lines
13826F: drivers/spi/spi-atmel.*13857F: drivers/spi/spi-atmel.*
13827 13858
13828MICROCHIP SSC DRIVER13859MICROCHIP SSC DRIVER
13829M: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>13860M: Claudiu Beznea <claudiu.beznea@microchip.com>
13830L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)13861L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
13831S: Supported13862S: Supported
13863F: Documentation/devicetree/bindings/misc/atmel-ssc.txt
13832F: drivers/misc/atmel-ssc.c13864F: drivers/misc/atmel-ssc.c
13833F: include/linux/atmel-ssc.h13865F: include/linux/atmel-ssc.h
13834 13866
arch/powerpc/platforms/8xx/cpm1.c+1−1
@@ -94,7 +94,7 @@ int cpm_command(u32 command, u8 opcode) · 93 unmodified lines
94 int i, ret;94 int i, ret;
95 unsigned long flags;95 unsigned long flags;
96 96
97 if (command & 0xffffff0f)97 if (command & 0xffffff03)
98 return -EINVAL;98 return -EINVAL;
99 99
100 spin_lock_irqsave(&cmd_lock, flags);100 spin_lock_irqsave(&cmd_lock, flags);
drivers/firmware/cirrus/cs_dsp.c+47−1
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/delay.h>14#include <linux/delay.h>
15#include <linux/module.h>15#include <linux/module.h>
16#include <linux/moduleparam.h>16#include <linux/moduleparam.h>
17#include <linux/seq_file.h>
17#include <linux/slab.h>18#include <linux/slab.h>
18#include <linux/vmalloc.h>19#include <linux/vmalloc.h>
19 20
@@ -301,6 +302,7 @@ struct cs_dsp_ops { · 281 unmodified lines
301static const struct cs_dsp_ops cs_dsp_adsp1_ops;302static const struct cs_dsp_ops cs_dsp_adsp1_ops;
302static const struct cs_dsp_ops cs_dsp_adsp2_ops[];303static const struct cs_dsp_ops cs_dsp_adsp2_ops[];
303static const struct cs_dsp_ops cs_dsp_halo_ops;304static const struct cs_dsp_ops cs_dsp_halo_ops;
305static const struct cs_dsp_ops cs_dsp_halo_ao_ops;
304 306
305struct cs_dsp_buf {307struct cs_dsp_buf {
306 struct list_head list;308 struct list_head list;
@@ -456,6 +458,33 @@ static const struct { · 149 unmodified lines
456 },458 },
457};459};
458 460
461static int cs_dsp_coeff_base_reg(struct cs_dsp_coeff_ctl *ctl, unsigned int *reg,
462 unsigned int off);
463
464static 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}
486DEFINE_SHOW_ATTRIBUTE(cs_dsp_debugfs_read_controls);
487
459/**488/**
460 * cs_dsp_init_debugfs() - Create and populate DSP representation in debugfs489 * cs_dsp_init_debugfs() - Create and populate DSP representation in debugfs
461 * @dsp: pointer to DSP structure490 * @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
478 debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root,507 debugfs_create_file(cs_dsp_debugfs_fops[i].name, 0444, root,
479 dsp, &cs_dsp_debugfs_fops[i].fops);508 dsp, &cs_dsp_debugfs_fops[i].fops);
480 509
510 debugfs_create_file("controls", 0444, root, dsp,
511 &cs_dsp_debugfs_read_controls_fops);
512
481 dsp->debugfs_root = root;513 dsp->debugfs_root = root;
482}514}
483EXPORT_SYMBOL_NS_GPL(cs_dsp_init_debugfs, FW_CS_DSP);515EXPORT_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
1300 int regions = 0;1332 int regions = 0;
1301 int ret, offset, type;1333 int ret, offset, type;
1302 1334
1335 if (!firmware)
1336 return 0;
1337
1303 ret = -EINVAL;1338 ret = -EINVAL;
1304 1339
1305 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);1340 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
2821 */2856 */
2822int cs_dsp_halo_init(struct cs_dsp *dsp)2857int cs_dsp_halo_init(struct cs_dsp *dsp)
2823{2858{
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;
2825 2863
2826 return cs_dsp_common_init(dsp);2864 return cs_dsp_common_init(dsp);
2827}2865}
@@ -3187,6 +3225,14 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { · 359 unmodified lines
3187 .stop_core = cs_dsp_halo_stop_core,3225 .stop_core = cs_dsp_halo_stop_core,
3188};3226};
3189 3227
3228static 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
3190/**3236/**
3191 * cs_dsp_chunk_write() - Format data to a DSP memory chunk3237 * cs_dsp_chunk_write() - Format data to a DSP memory chunk
3192 * @ch: Pointer to the chunk structure3238 * @ch: Pointer to the chunk structure
drivers/soc/fsl/qe/Kconfig+23−0
@@ -33,6 +33,29 @@ config UCC · 32 unmodified lines
33 bool33 bool
34 default y if UCC_FAST || UCC_SLOW34 default y if UCC_FAST || UCC_SLOW
35 35
36config 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
47config 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
36config QE_TDM59config QE_TDM
37 bool60 bool
38 default y if FSL_UCC_HDLC61 default y if FSL_UCC_HDLC
drivers/soc/fsl/qe/Makefile+2−0
@@ -4,6 +4,8 @@ · 3 unmodified lines
4#4#
5obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o5obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_common.o qe_ic.o qe_io.o
6obj-$(CONFIG_CPM) += qe_common.o6obj-$(CONFIG_CPM) += qe_common.o
7obj-$(CONFIG_CPM_TSA) += tsa.o
8obj-$(CONFIG_CPM_QMC) += qmc.o
7obj-$(CONFIG_UCC) += ucc.o9obj-$(CONFIG_UCC) += ucc.o
8obj-$(CONFIG_UCC_SLOW) += ucc_slow.o10obj-$(CONFIG_UCC_SLOW) += ucc_slow.o
9obj-$(CONFIG_UCC_FAST) += ucc_fast.o11obj-$(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
166struct 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
174struct 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
203struct 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
221static inline void qmc_write16(void *__iomem addr, u16 val)
222{
223 iowrite16be(val, addr);
224}
225
226static inline u16 qmc_read16(void *__iomem addr)
227{
228 return ioread16be(addr);
229}
230
231static inline void qmc_setbits16(void *__iomem addr, u16 set)
232{
233 qmc_write16(addr, qmc_read16(addr) | set);
234}
235
236static inline void qmc_clrbits16(void *__iomem addr, u16 clr)
237{
238 qmc_write16(addr, qmc_read16(addr) & ~clr);
239}
240
241static inline void qmc_write32(void *__iomem addr, u32 val)
242{
243 iowrite32be(val, addr);
244}
245
246static inline u32 qmc_read32(void *__iomem addr)
247{
248 return ioread32be(addr);
249}
250
251static inline void qmc_setbits32(void *__iomem addr, u32 set)
252{
253 qmc_write32(addr, qmc_read32(addr) | set);
254}
255
256
257int 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}
277EXPORT_SYMBOL(qmc_chan_get_info);
278
279int 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}
314EXPORT_SYMBOL(qmc_chan_set_param);
315
316int 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
365end:
366 spin_unlock_irqrestore(&chan->tx_lock, flags);
367 return ret;
368}
369EXPORT_SYMBOL(qmc_chan_write_submit);
370
371static 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
419end:
420 spin_unlock_irqrestore(&chan->tx_lock, flags);
421}
422
423int 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;
480end:
481 spin_unlock_irqrestore(&chan->rx_lock, flags);
482 return ret;
483}
484EXPORT_SYMBOL(qmc_chan_read_submit);
485
486static 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
538end:
539 spin_unlock_irqrestore(&chan->rx_lock, flags);
540}
541
542static 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
547static 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
564end:
565 spin_unlock_irqrestore(&chan->rx_lock, flags);
566 return ret;
567}
568
569static 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
586end:
587 spin_unlock_irqrestore(&chan->tx_lock, flags);
588 return ret;
589}
590
591int 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}
609EXPORT_SYMBOL(qmc_chan_stop);
610
611static 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
630static 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
650int 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}
660EXPORT_SYMBOL(qmc_chan_start);
661
662static 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
693static 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
729int 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}
739EXPORT_SYMBOL(qmc_chan_reset);
740
741static 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
808static 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
819static 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
898static 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
940static 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
998static 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
1017static 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
1051static 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
1128static 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
1142static 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
1169static 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
1187static 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
1237int_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
1246static 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
1270static 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
1410err_disable_intr:
1411 qmc_write16(qmc->scc_regs + SCC_SCCM, 0);
1412
1413err_tsa_serial_disconnect:
1414 tsa_serial_disconnect(qmc->tsa_serial);
1415 return ret;
1416}
1417
1418static 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
1434static const struct of_device_id qmc_id_table[] = {
1435 { .compatible = "fsl,cpm1-scc-qmc" },
1436 {} /* sentinel */
1437};
1438MODULE_DEVICE_TABLE(of, qmc_id_table);
1439
1440static 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};
1448module_platform_driver(qmc_driver);
1449
1450struct 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}
1497EXPORT_SYMBOL(qmc_chan_get_byphandle);
1498
1499void qmc_chan_put(struct qmc_chan *chan)
1500{
1501 put_device(chan->qmc->dev);
1502}
1503EXPORT_SYMBOL(qmc_chan_put);
1504
1505static 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
1512struct 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}
1533EXPORT_SYMBOL(devm_qmc_chan_get_byphandle);
1534
1535MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
1536MODULE_DESCRIPTION("CPM QMC driver");
1537MODULE_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
100struct tsa_entries_area {
101 void *__iomem entries_start;
102 void *__iomem entries_next;
103 void *__iomem last_entry;
104};
105
106struct 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
118struct 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
132static 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
138static inline void tsa_write32(void *__iomem addr, u32 val)
139{
140 iowrite32be(val, addr);
141}
142
143static inline void tsa_write8(void *__iomem addr, u32 val)
144{
145 iowrite8(val, addr);
146}
147
148static inline u32 tsa_read32(void *__iomem addr)
149{
150 return ioread32be(addr);
151}
152
153static inline void tsa_clrbits32(void *__iomem addr, u32 clr)
154{
155 tsa_write32(addr, tsa_read32(addr) & ~clr);
156}
157
158static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set)
159{
160 tsa_write32(addr, (tsa_read32(addr) & ~clr) | set);
161}
162
163int 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}
194EXPORT_SYMBOL(tsa_serial_connect);
195
196int 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}
223EXPORT_SYMBOL(tsa_serial_disconnect);
224
225int 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}
230EXPORT_SYMBOL(tsa_serial_get_info);
231
232static 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
284static 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
299static 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
313static 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
356static 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
428static 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
435static 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
442static 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
612err:
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
634static 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
643static 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
709static 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
735static const struct of_device_id tsa_id_table[] = {
736 { .compatible = "fsl,cpm1-tsa" },
737 {} /* sentinel */
738};
739MODULE_DEVICE_TABLE(of, tsa_id_table);
740
741static 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};
749module_platform_driver(tsa_driver);
750
751struct 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}
804EXPORT_SYMBOL(tsa_serial_get_byphandle);
805
806void 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}
812EXPORT_SYMBOL(tsa_serial_put);
813
814static 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
821struct 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}
842EXPORT_SYMBOL(devm_tsa_serial_get_byphandle);
843
844MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
845MODULE_DESCRIPTION("CPM TSA driver");
846MODULE_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
14struct device_node;
15struct device;
16struct tsa_serial;
17
18struct tsa_serial *tsa_serial_get_byphandle(struct device_node *np,
19 const char *phandle_name);
20void tsa_serial_put(struct tsa_serial *tsa_serial);
21struct 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 */
26int tsa_serial_connect(struct tsa_serial *tsa_serial);
27int tsa_serial_disconnect(struct tsa_serial *tsa_serial);
28
29/* Cell information */
30struct 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 */
40int 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
17#define CS35L45_ASP_TX_HIZ_UNUSED 0x117#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
18#define CS35L45_ASP_TX_HIZ_DISABLED 0x218#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
19 19
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
20#endif /* DT_CS35L45_H */77#endif /* DT_CS35L45_H */
include/linux/firmware/cirrus/cs_dsp.h+1−0
@@ -156,6 +156,7 @@ struct cs_dsp { · 155 unmodified lines
156 unsigned int sysclk_reg;156 unsigned int sysclk_reg;
157 unsigned int sysclk_mask;157 unsigned int sysclk_mask;
158 unsigned int sysclk_shift;158 unsigned int sysclk_shift;
159 bool no_core_startstop;
159 160
160 struct list_head alg_regions;161 struct list_head alg_regions;
161 162
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
14struct device_node;
15struct device;
16struct qmc_chan;
17
18struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name);
19void qmc_chan_put(struct qmc_chan *chan);
20struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, struct device_node *np,
21 const char *phandle_name);
22
23enum qmc_mode {
24 QMC_TRANSPARENT,
25 QMC_HDLC,
26};
27
28struct 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
38int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info);
39
40struct 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
54int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param);
55
56int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
57 void (*complete)(void *context), void *context);
58
59int 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
67int qmc_chan_start(struct qmc_chan *chan, int direction);
68int qmc_chan_stop(struct qmc_chan *chan, int direction);
69int 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
335#ifdef CONFIG_PM335#ifdef CONFIG_PM
336void snd_ac97_suspend(struct snd_ac97 *ac97);336void snd_ac97_suspend(struct snd_ac97 *ac97);
337void snd_ac97_resume(struct snd_ac97 *ac97);337void snd_ac97_resume(struct snd_ac97 *ac97);
338#else
339static inline void snd_ac97_suspend(struct snd_ac97 *ac97) {}
340static inline void snd_ac97_resume(struct snd_ac97 *ac97) {}
338#endif341#endif
339int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,342int snd_ac97_reset(struct snd_ac97 *ac97, bool try_warm, unsigned int id,
340 unsigned int id_mask);343 unsigned int id_mask);
include/sound/cs35l41.h+12−1
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#define __CS35L41_H11#define __CS35L41_H
12 12
13#include <linux/regmap.h>13#include <linux/regmap.h>
14#include <linux/completion.h>
14#include <linux/firmware/cirrus/cs_dsp.h>15#include <linux/firmware/cirrus/cs_dsp.h>
15 16
16#define CS35L41_FIRSTREG 0x0000000017#define CS35L41_FIRSTREG 0x00000000
@@ -677,6 +678,7 @@ · 660 unmodified lines
677 678
678#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F679#define CS35L36_PUP_DONE_IRQ_UNMASK 0x5F
679#define CS35L36_PUP_DONE_IRQ_MASK 0xBF680#define CS35L36_PUP_DONE_IRQ_MASK 0xBF
681#define CS35L41_SYNC_EN_MASK BIT(8)
680 682
681#define CS35L41_AMP_SHORT_ERR 0x80000000683#define CS35L41_AMP_SHORT_ERR 0x80000000
682#define CS35L41_BST_SHORT_ERR 0x0100684#define CS35L41_BST_SHORT_ERR 0x0100
@@ -686,6 +688,7 @@ · 3 unmodified lines
686#define CS35L41_BST_DCM_UVP_ERR 0x80688#define CS35L41_BST_DCM_UVP_ERR 0x80
687#define CS35L41_OTP_BOOT_DONE 0x02689#define CS35L41_OTP_BOOT_DONE 0x02
688#define CS35L41_PLL_UNLOCK 0x10690#define CS35L41_PLL_UNLOCK 0x10
691#define CS35L41_PLL_LOCK BIT(1)
689#define CS35L41_OTP_BOOT_ERR 0x80000000692#define CS35L41_OTP_BOOT_ERR 0x80000000
690 693
691#define CS35L41_AMP_SHORT_ERR_RLS 0x02694#define CS35L41_AMP_SHORT_ERR_RLS 0x02
@@ -705,6 +708,8 @@ · 13 unmodified lines
705#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F708#define CS35L41_INT1_MASK_DEFAULT 0x7FFCFE3F
706#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF709#define CS35L41_INT1_UNMASK_PUP 0xFEFFFFFF
707#define CS35L41_INT1_UNMASK_PDN 0xFF7FFFFF710#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)
708 713
709#define CS35L41_GPIO_DIR_MASK 0x80000000714#define CS35L41_GPIO_DIR_MASK 0x80000000
710#define CS35L41_GPIO_DIR_SHIFT 31715#define CS35L41_GPIO_DIR_SHIFT 31
@@ -742,6 +747,11 @@ · 31 unmodified lines
742enum cs35l41_boost_type {747enum cs35l41_boost_type {
743 CS35L41_INT_BOOST,748 CS35L41_INT_BOOST,
744 CS35L41_EXT_BOOST,749 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
745 CS35L41_EXT_BOOST_NO_VSPK_SWITCH,755 CS35L41_EXT_BOOST_NO_VSPK_SWITCH,
746};756};
747 757
@@ -891,6 +901,7 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); · 143 unmodified lines
891int cs35l41_init_boost(struct device *dev, struct regmap *regmap,901int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
892 struct cs35l41_hw_cfg *hw_cfg);902 struct cs35l41_hw_cfg *hw_cfg);
893bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);903bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
894int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable);904int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
905 struct completion *pll_lock);
895 906
896#endif /* __CS35L41_H */907#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
254extern struct regmap_config cs35l56_regmap_i2c;
255extern struct regmap_config cs35l56_regmap_spi;
256extern struct regmap_config cs35l56_regmap_sdw;
257
258extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
259extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
260extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
261
262void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap);
263int cs35l56_get_bclk_freq_id(unsigned int freq);
264void 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
25/* ------------------- DEFINES -------------------- */25/* ------------------- DEFINES -------------------- */
26 26
27#define EMUPAGESIZE 409627#define EMUPAGESIZE 4096
28#define MAXREQVOICES 8
29#define MAXPAGES0 4096 /* 32 bit mode */28#define MAXPAGES0 4096 /* 32 bit mode */
30#define MAXPAGES1 8192 /* 31 bit mode */29#define MAXPAGES1 8192 /* 31 bit mode */
31#define RESERVED 0
32#define NUM_MIDI 16
33#define NUM_G 64 /* use all channels */30#define NUM_G 64 /* use all channels */
34#define NUM_FXSENDS 4
35#define NUM_EFX_PLAYBACK 1631#define NUM_EFX_PLAYBACK 16
36 32
37/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */33/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
@@ -39,7 +35,6 @@ · 1 unmodified line
39#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */35#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */
40 36
41#define TMEMSIZE 256*102437#define TMEMSIZE 256*1024
42#define TMEMSIZEREG 4
43 38
44#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))39#define IP_TO_CP(ip) ((ip == 0) ? 0 : (((0x00001000uL | (ip & 0x00000FFFL)) << (((ip >> 12) & 0x000FL) + 4)) & 0xFFFF0000uL))
45 40
@@ -66,8 +61,8 @@ · 20 unmodified lines
66 /* the relevant bits and zero to the other bits */61 /* the relevant bits and zero to the other bits */
67#define IPR_P16V 0x80000000 /* Bit set when the CA0151 P16V chip wishes62#define IPR_P16V 0x80000000 /* Bit set when the CA0151 P16V chip wishes
68 to interrupt */63 to interrupt */
69#define IPR_GPIOMSG 0x20000000 /* GPIO message interrupt (RE'd, still not sure 64#define IPR_WATERMARK_REACHED 0x40000000
70 which INTE bits enable it) */65#define IPR_A_GPIO 0x20000000 /* GPIO input pin change */
71 66
72/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */67/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
73#define IPR_A_MIDITRANSBUFEMPTY2 0x10000000 /* MIDI UART transmit buffer empty */68#define IPR_A_MIDITRANSBUFEMPTY2 0x10000000 /* MIDI UART transmit buffer empty */
@@ -97,9 +92,9 @@ · 23 unmodified lines
97#define IPR_CHANNELLOOP 0x00000040 /* Channel (half) loop interrupt(s) pending */92#define IPR_CHANNELLOOP 0x00000040 /* Channel (half) loop interrupt(s) pending */
98#define IPR_CHANNELNUMBERMASK 0x0000003f /* When IPR_CHANNELLOOP is set, indicates the */93#define IPR_CHANNELNUMBERMASK 0x0000003f /* When IPR_CHANNELLOOP is set, indicates the */
99 /* highest set channel in CLIPL, CLIPH, HLIPL, */94 /* 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, */
101 /* the bit in H/CLIPL or H/CLIPH corresponding */96 /* 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. */
103 98
104#define INTE 0x0c /* Interrupt enable register */99#define INTE 0x0c /* Interrupt enable register */
105#define INTE_VIRTUALSB_MASK 0xc0000000 /* Virtual Soundblaster I/O port capture */100#define INTE_VIRTUALSB_MASK 0xc0000000 /* Virtual Soundblaster I/O port capture */
@@ -127,10 +122,14 @@ · 21 unmodified lines
127 /* behavior and possibly random segfaults and */122 /* behavior and possibly random segfaults and */
128 /* lockups if enabled. */123 /* lockups if enabled. */
129 124
125#define INTE_A_GPIOENABLE 0x00040000 /* Enable GPIO input change interrupts */
126
130/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */127/* The next two interrupts are for the midi port on the Audigy Drive (A_MPU1) */
131#define INTE_A_MIDITXENABLE2 0x00020000 /* Enable MIDI transmit-buffer-empty interrupts */128#define INTE_A_MIDITXENABLE2 0x00020000 /* Enable MIDI transmit-buffer-empty interrupts */
132#define INTE_A_MIDIRXENABLE2 0x00010000 /* Enable MIDI receive-buffer-empty interrupts */129#define INTE_A_MIDIRXENABLE2 0x00010000 /* Enable MIDI receive-buffer-empty interrupts */
133 130
131#define INTE_A_SPDIF_BUFFULL_ENABLE 0x00008000
132#define INTE_A_SPDIF_HALFBUFFULL_ENABLE 0x00004000
134 133
135#define INTE_SAMPLERATETRACKER 0x00002000 /* Enable sample rate tracker interrupts */134#define INTE_SAMPLERATETRACKER 0x00002000 /* Enable sample rate tracker interrupts */
136 /* NOTE: This bit must always be enabled */135 /* NOTE: This bit must always be enabled */
@@ -151,9 +150,10 @@ · 14 unmodified lines
151#define WC 0x10 /* Wall Clock register */150#define WC 0x10 /* Wall Clock register */
152#define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */151#define WC_SAMPLECOUNTER_MASK 0x03FFFFC0 /* Sample periods elapsed since reset */
153#define WC_SAMPLECOUNTER 0x14060010152#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 */
155 /* NOTE: Each channel takes 1/64th of a sample */154 /* NOTE: Each channel takes 1/64th of a sample */
156 /* period to be serviced. */155 /* period to be serviced. */
156#define WC_CURRENTCHANNEL 0x06000010
157 157
158#define HCFG 0x14 /* Hardware config register */158#define HCFG 0x14 /* Hardware config register */
159 /* NOTE: There is no reason to use the legacy */159 /* NOTE: There is no reason to use the legacy */
@@ -180,6 +180,7 @@ · 20 unmodified lines
180#define HCFG_CODECFORMAT_MASK 0x00030000 /* CODEC format */180#define HCFG_CODECFORMAT_MASK 0x00030000 /* CODEC format */
181 181
182/* Specific to Alice2, CA0102 */182/* Specific to Alice2, CA0102 */
183
183#define HCFG_CODECFORMAT_AC97_1 0x00000000 /* AC97 CODEC format -- Ver 1.03 */184#define HCFG_CODECFORMAT_AC97_1 0x00000000 /* AC97 CODEC format -- Ver 1.03 */
184#define HCFG_CODECFORMAT_AC97_2 0x00010000 /* AC97 CODEC format -- Ver 2.1 */185#define HCFG_CODECFORMAT_AC97_2 0x00010000 /* AC97 CODEC format -- Ver 2.1 */
185#define HCFG_AUTOMUTE_ASYNC 0x00008000 /* When set, the async sample rate convertors */186#define HCFG_AUTOMUTE_ASYNC 0x00008000 /* When set, the async sample rate convertors */
@@ -200,9 +201,8 @@ · 14 unmodified lines
200 /* I2S format input */201 /* I2S format input */
201/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc. */202/* Rest of HCFG 0x0000000f same as below. LOCKSOUNDCACHE etc. */
202 203
203
204
205/* Older chips */204/* Older chips */
205
206#define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */206#define HCFG_CODECFORMAT_AC97 0x00000000 /* AC97 CODEC format -- Primary Output */
207#define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */207#define HCFG_CODECFORMAT_I2S 0x00010000 /* I2S CODEC format -- Secondary (Rear) Output */
208#define HCFG_GPINPUT0 0x00004000 /* External pin112 */208#define HCFG_GPINPUT0 0x00004000 /* External pin112 */
@@ -238,7 +238,7 @@ · 29 unmodified lines
238 /* Should be set to 1 when the EMU10K1 is */238 /* Should be set to 1 when the EMU10K1 is */
239 /* completely initialized. */239 /* completely initialized. */
240 240
241//For Audigy, MPU port move to 0x70-0x74 ptr register241// On Audigy, the MPU port moved to the 0x70-0x74 ptr registers
242 242
243#define MUDATA 0x18 /* MPU401 data register (8 bits) */243#define MUDATA 0x18 /* MPU401 data register (8 bits) */
244 244
@@ -251,11 +251,17 @@ · 6 unmodified lines
251#define MUSTAT_IRDYN 0x80 /* 0 = MIDI data or command ACK */251#define MUSTAT_IRDYN 0x80 /* 0 = MIDI data or command ACK */
252#define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */252#define MUSTAT_ORDYN 0x40 /* 0 = MUDATA can accept a command or data */
253 253
254#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */254#define A_GPIO 0x18 /* GPIO on Audigy card (16bits) */
255#define A_GPINPUT_MASK 0xff00255#define A_GPINPUT_MASK 0xff00 /* Alice/2 has 8 input pins */
256#define A3_GPINPUT_MASK 0x3f00 /* ... while Tina/2 has only 6 */
256#define A_GPOUTPUT_MASK 0x00ff257#define A_GPOUTPUT_MASK 0x00ff
257 258
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
258// Audigy output/GPIO stuff taken from the kX drivers263// Audigy output/GPIO stuff taken from the kX drivers
264#define A_IOCFG A_GPIO
259#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */265#define A_IOCFG_GPOUT0 0x0044 /* analog/digital */
260#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */266#define A_IOCFG_DISABLE_ANALOG 0x0040 /* = 'enable' for Audigy2 (chiprev=4) */
261#define A_IOCFG_ENABLE_DIGITAL 0x0004267#define A_IOCFG_ENABLE_DIGITAL 0x0004
@@ -271,19 +277,12 @@ · 9 unmodified lines
271#define A_IOCFG_REAR_JACK 0x8000277#define A_IOCFG_REAR_JACK 0x8000
272#define A_IOCFG_PHONES_JACK 0x0100 /* LiveDrive */278#define A_IOCFG_PHONES_JACK 0x0100 /* LiveDrive */
273 279
274/* outputs:
275 * for audigy2 platinum: 0xa00
276 * for a2 platinum ex: 0x1c00
277 * for a1 platinum: 0x0
278 */
279
280#define TIMER 0x1a /* Timer terminal count register */280#define TIMER 0x1a /* Timer terminal count register */
281 /* NOTE: After the rate is changed, a maximum */281 /* NOTE: After the rate is changed, a maximum */
282 /* of 1024 sample periods should be allowed */282 /* of 1024 sample periods should be allowed */
283 /* before the new rate is guaranteed accurate. */283 /* 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 */
285 /* 0 == 1024 periods, [1..4] are not useful */285 /* 0 == 1024 periods, [1..4] are not useful */
286#define TIMER_RATE 0x0a00001a
287 286
288#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */287#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
289 288
@@ -317,7 +316,7 @@ · 27 unmodified lines
317 /* 0x00000000 2-channel output. */316 /* 0x00000000 2-channel output. */
318 /* 0x00000200 8-channel output. */317 /* 0x00000200 8-channel output. */
319 /* 0x00000004 pauses stream/irq fail. */318 /* 0x00000004 pauses stream/irq fail. */
320 /* Rest of bits no nothing to sound output */319 /* Rest of bits do nothing to sound output */
321 /* bit 0: Enable P16V audio.320 /* bit 0: Enable P16V audio.
322 * bit 1: Lock P16V record memory cache.321 * bit 1: Lock P16V record memory cache.
323 * bit 2: Lock P16V playback memory cache.322 * bit 2: Lock P16V playback memory cache.
@@ -331,6 +330,7 @@ · 7 unmodified lines
331 */330 */
332#define IPR3 0x38 /* Cdif interrupt pending register */331#define IPR3 0x38 /* Cdif interrupt pending register */
333#define INTE3 0x3c /* Cdif interrupt enable register. */332#define INTE3 0x3c /* Cdif interrupt enable register. */
333
334/************************************************************************************************/334/************************************************************************************************/
335/* PCI function 1 registers, address = <val> + PCIBASE1 */335/* PCI function 1 registers, address = <val> + PCIBASE1 */
336/************************************************************************************************/336/************************************************************************************************/
@@ -349,11 +349,38 @@ · 12 unmodified lines
349#define JOYSTICK_BUTTONS 0x0f /* Joystick button data */349#define JOYSTICK_BUTTONS 0x0f /* Joystick button data */
350#define JOYSTICK_COMPARATOR 0xf0 /* Joystick comparator data */350#define JOYSTICK_COMPARATOR 0xf0 /* Joystick comparator data */
351 351
352
353/********************************************************************************************************/352/********************************************************************************************************/
354/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers */353/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers */
355/********************************************************************************************************/354/********************************************************************************************************/
356 355
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
357#define CPF 0x00 /* Current pitch and fraction register */384#define CPF 0x00 /* Current pitch and fraction register */
358#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */385#define CPF_CURRENTPITCH_MASK 0xffff0000 /* Current pitch (linear, 0x4000 == unity pitch shift) */
359#define CPF_CURRENTPITCH 0x10100000386#define CPF_CURRENTPITCH 0x10100000
@@ -393,7 +420,7 @@ · 33 unmodified lines
393#define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */420#define PSST_LOOPSTARTADDR_MASK 0x00ffffff /* Loop start address of the specified channel */
394#define PSST_LOOPSTARTADDR 0x18000006421#define PSST_LOOPSTARTADDR 0x18000006
395 422
396#define DSL 0x07 /* Send D amount and loop start address register */423#define DSL 0x07 /* Send D amount and loop end address register */
397#define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */424#define DSL_FXSENDAMOUNT_D_MASK 0xff000000 /* Linear level of channel output sent to FX send bus D */
398 425
399#define DSL_FXSENDAMOUNT_D 0x08180007426#define DSL_FXSENDAMOUNT_D 0x08180007
@@ -402,8 +429,9 @@ · 2 unmodified lines
402#define DSL_LOOPENDADDR 0x18000007429#define DSL_LOOPENDADDR 0x18000007
403 430
404#define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */431#define CCCA 0x08 /* Filter Q, interp. ROM, byte size, cur. addr register */
405#define CCCA_RESONANCE 0xf0000000 /* Lowpass filter resonance (Q) height */432#define CCCA_RESONANCE_MASK 0xf0000000 /* Lowpass filter resonance (Q) height */
406#define CCCA_INTERPROMMASK 0x0e000000 /* Selects passband of interpolation ROM */433#define CCCA_RESONANCE 0x041c0008
434#define CCCA_INTERPROM_MASK 0x0e000000 /* Selects passband of interpolation ROM */
407 /* 1 == full band, 7 == lowpass */435 /* 1 == full band, 7 == lowpass */
408 /* ROM 0 is used when pitch shifting downward or less */436 /* ROM 0 is used when pitch shifting downward or less */
409 /* then 3 semitones upward. Increasingly higher ROM */437 /* then 3 semitones upward. Increasingly higher ROM */
@@ -418,25 +446,28 @@ · 8 unmodified lines
418#define CCCA_INTERPROM_6 0x0c000000 /* Select interpolation ROM 6 */446#define CCCA_INTERPROM_6 0x0c000000 /* Select interpolation ROM 6 */
419#define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */447#define CCCA_INTERPROM_7 0x0e000000 /* Select interpolation ROM 7 */
420#define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */448#define CCCA_8BITSELECT 0x01000000 /* 1 = Sound memory for this channel uses 8-bit samples */
449 /* 8-bit samples are unsigned, 16-bit ones signed */
421#define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */450#define CCCA_CURRADDR_MASK 0x00ffffff /* Current address of the selected channel */
422#define CCCA_CURRADDR 0x18000008451#define CCCA_CURRADDR 0x18000008
423 452
424#define CCR 0x09 /* Cache control register */453#define CCR 0x09 /* Cache control register */
425#define CCR_CACHEINVALIDSIZE 0x07190009454#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 */
427#define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */456#define CCR_CACHELOOPFLAG 0x01000000 /* 1 = Cache has a loop service pending */
428#define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */457#define CCR_INTERLEAVEDSAMPLES 0x00800000 /* 1 = A cache service will fetch interleaved samples */
458 /* Auto-set from CPF_STEREO_MASK */
429#define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */459#define CCR_WORDSIZEDSAMPLES 0x00400000 /* 1 = A cache service will fetch word sized samples */
460 /* Auto-set from CCCA_8BITSELECT */
430#define CCR_READADDRESS 0x06100009461#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 */
432#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */463#define CCR_LOOPINVALSIZE 0x0000fe00 /* Number of invalid samples in cache prior to loop */
433 /* NOTE: This is valid only if CACHELOOPFLAG is set */464 /* NOTE: This is valid only if CACHELOOPFLAG is set */
434#define CCR_LOOPFLAG 0x00000100 /* Set for a single sample period when a loop occurs */465#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 */
436 467
437#define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */468#define CLP 0x0a /* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
438 /* NOTE: This register is normally not used */469 /* 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 */
440 471
441#define FXRT 0x0b /* Effects send routing register */472#define FXRT 0x0b /* Effects send routing register */
442 /* NOTE: It is illegal to assign the same routing to */473 /* NOTE: It is illegal to assign the same routing to */
@@ -446,9 +477,7 @@ · 3 unmodified lines
446#define FXRT_CHANNELC 0x0f000000 /* Effects send bus number for channel's effects send C */477#define FXRT_CHANNELC 0x0f000000 /* Effects send bus number for channel's effects send C */
447#define FXRT_CHANNELD 0xf0000000 /* Effects send bus number for channel's effects send D */478#define FXRT_CHANNELD 0xf0000000 /* Effects send bus number for channel's effects send D */
448 479
449#define A_HR 0x0b /* High Resolution. 24bit playback from host to DSP. */
450#define MAPA 0x0c /* Cache map A */480#define MAPA 0x0c /* Cache map A */
451
452#define MAPB 0x0d /* Cache map B */481#define MAPB 0x0d /* Cache map B */
453 482
454#define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */483#define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */
@@ -457,22 +486,22 @@ · 2 unmodified lines
457#define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */486#define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */
458#define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */487#define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */
459 488
460/* 0x0e, 0x0f: Not used */489/* 0x0e, 0x0f: Internal state, at least on Audigy */
461 490
462#define ENVVOL 0x10 /* Volume envelope register */491#define ENVVOL 0x10 /* Volume envelope register */
463#define ENVVOL_MASK 0x0000ffff /* Current value of volume envelope state variable */ 492#define ENVVOL_MASK 0x0000ffff /* Current value of volume envelope state variable */
464 /* 0x8000-n == 666*n usec delay */493 /* 0x8000-n == 666*n usec delay */
465 494
466#define ATKHLDV 0x11 /* Volume envelope hold and attack register */495#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 */
468#define ATKHLDV_HOLDTIME_MASK 0x00007f00 /* Envelope hold time (127-n == n*88.2msec) */497#define ATKHLDV_HOLDTIME_MASK 0x00007f00 /* Envelope hold time (127-n == n*88.2msec) */
469#define ATKHLDV_ATTACKTIME_MASK 0x0000007f /* Envelope attack time, log encoded */498#define ATKHLDV_ATTACKTIME_MASK 0x0000007f /* Envelope attack time, log encoded */
470 /* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec */499 /* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec */
471 500
472#define DCYSUSV 0x12 /* Volume envelope sustain and decay register */501#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 */
474#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */503#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 */
476 /* this channel and from writing to pitch, filter and */505 /* this channel and from writing to pitch, filter and */
477 /* volume targets. */506 /* volume targets. */
478#define DCYSUSV_DECAYTIME_MASK 0x0000007f /* Volume envelope decay time, log encoded */507#define DCYSUSV_DECAYTIME_MASK 0x0000007f /* Volume envelope decay time, log encoded */
@@ -487,13 +516,13 @@ · 8 unmodified lines
487 /* 0x8000-n == 666*n usec delay */516 /* 0x8000-n == 666*n usec delay */
488 517
489#define ATKHLDM 0x15 /* Modulation envelope hold and attack register */518#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 */
491#define ATKHLDM_HOLDTIME 0x00007f00 /* Envelope hold time (127-n == n*42msec) */520#define ATKHLDM_HOLDTIME 0x00007f00 /* Envelope hold time (127-n == n*42msec) */
492#define ATKHLDM_ATTACKTIME 0x0000007f /* Envelope attack time, log encoded */521#define ATKHLDM_ATTACKTIME 0x0000007f /* Envelope attack time, log encoded */
493 /* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec */522 /* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec */
494 523
495#define DCYSUSM 0x16 /* Modulation envelope decay and sustain register */524#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 */
497#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */526#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00 /* 127 = full, 0 = off, 0.75dB increments */
498#define DCYSUSM_DECAYTIME_MASK 0x0000007f /* Envelope decay time, log encoded */527#define DCYSUSM_DECAYTIME_MASK 0x0000007f /* Envelope decay time, log encoded */
499 /* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec */528 /* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec */
@@ -515,7 +544,6 @@ · 15 unmodified lines
515#define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */544#define IFATN_ATTENUATION_MASK 0x000000ff /* Initial attenuation in 0.375dB steps */
516#define IFATN_ATTENUATION 0x08000019545#define IFATN_ATTENUATION 0x08000019
517 546
518
519#define PEFE 0x1a /* Pitch envelope and filter envelope amount register */547#define PEFE 0x1a /* Pitch envelope and filter envelope amount register */
520#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */548#define PEFE_PITCHAMOUNT_MASK 0x0000ff00 /* Pitch envlope amount */
521 /* Signed 2's complement, +/- one octave peak extremes */549 /* Signed 2's complement, +/- one octave peak extremes */
@@ -523,19 +551,19 @@ · 1 unmodified line
523#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */551#define PEFE_FILTERAMOUNT_MASK 0x000000ff /* Filter envlope amount */
524 /* Signed 2's complement, +/- six octaves peak extremes */552 /* Signed 2's complement, +/- six octaves peak extremes */
525#define PEFE_FILTERAMOUNT 0x0800001a553#define PEFE_FILTERAMOUNT 0x0800001a
554
526#define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */555#define FMMOD 0x1b /* Vibrato/filter modulation from LFO register */
527#define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */556#define FMMOD_MODVIBRATO 0x0000ff00 /* Vibrato LFO modulation depth */
528 /* Signed 2's complement, +/- one octave extremes */557 /* Signed 2's complement, +/- one octave extremes */
529#define FMMOD_MOFILTER 0x000000ff /* Filter LFO modulation depth */558#define FMMOD_MOFILTER 0x000000ff /* Filter LFO modulation depth */
530 /* Signed 2's complement, +/- three octave extremes */559 /* Signed 2's complement, +/- three octave extremes */
531 560
532
533#define TREMFRQ 0x1c /* Tremolo amount and modulation LFO frequency register */561#define TREMFRQ 0x1c /* Tremolo amount and modulation LFO frequency register */
534#define TREMFRQ_DEPTH 0x0000ff00 /* Tremolo depth */562#define TREMFRQ_DEPTH 0x0000ff00 /* Tremolo depth */
535 /* Signed 2's complement, with +/- 12dB extremes */563 /* Signed 2's complement, with +/- 12dB extremes */
536
537#define TREMFRQ_FREQUENCY 0x000000ff /* Tremolo LFO frequency */564#define TREMFRQ_FREQUENCY 0x000000ff /* Tremolo LFO frequency */
538 /* ??Hz steps, maximum of ?? Hz. */565 /* ??Hz steps, maximum of ?? Hz. */
566
539#define FM2FRQ2 0x1d /* Vibrato amount and vibrato LFO frequency register */567#define FM2FRQ2 0x1d /* Vibrato amount and vibrato LFO frequency register */
540#define FM2FRQ2_DEPTH 0x0000ff00 /* Vibrato LFO vibrato depth */568#define FM2FRQ2_DEPTH 0x0000ff00 /* Vibrato LFO vibrato depth */
541 /* Signed 2's complement, +/- one octave extremes */569 /* Signed 2's complement, +/- one octave extremes */
@@ -603,20 +631,6 @@ · 61 unmodified lines
603 /* is 16bit, 48KHz only. All 32 channels can be enabled */631 /* is 16bit, 48KHz only. All 32 channels can be enabled */
604 /* simultaneously. */632 /* simultaneously. */
605 633
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
620#define A_TBLSZ 0x43 /* Effects Tank Internal Table Size. Only low byte or register used */634#define A_TBLSZ 0x43 /* Effects Tank Internal Table Size. Only low byte or register used */
621 635
622#define TCBS 0x44 /* Tank cache buffer size register */636#define TCBS 0x44 /* Tank cache buffer size register */
@@ -639,7 +653,7 @@ · 16 unmodified lines
639#define FXBA 0x47 /* FX Buffer Address */653#define FXBA 0x47 /* FX Buffer Address */
640#define FXBA_MASK 0xfffff000 /* 20 bit base address */654#define FXBA_MASK 0xfffff000 /* 20 bit base address */
641 655
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 */
643 657
644#define MICBS 0x49 /* Microphone buffer size register */658#define MICBS 0x49 /* Microphone buffer size register */
645 659
@@ -647,9 +661,7 @@ · 1 unmodified line
647 661
648#define FXBS 0x4b /* FX buffer size register */662#define FXBS 0x4b /* FX buffer size register */
649 663
650/* register: 0x4c..4f: ffff-ffff current amounts, per-channel */664/* The following mask values define the size of the ADC, MIC and FX buffers in bytes */
651
652/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
653#define ADCBS_BUFSIZE_NONE 0x00000000665#define ADCBS_BUFSIZE_NONE 0x00000000
654#define ADCBS_BUFSIZE_384 0x00000001666#define ADCBS_BUFSIZE_384 0x00000001
655#define ADCBS_BUFSIZE_448 0x00000002667#define ADCBS_BUFSIZE_448 0x00000002
@@ -683,38 +695,27 @@ · 27 unmodified lines
683#define ADCBS_BUFSIZE_57344 0x0000001e695#define ADCBS_BUFSIZE_57344 0x0000001e
684#define ADCBS_BUFSIZE_65536 0x0000001f696#define ADCBS_BUFSIZE_65536 0x0000001f
685 697
686/* Current Send B, A Amounts */698#define A_CSBA 0x4c /* FX send B & A current amounts */
687#define A_CSBA 0x4c699#define A_CSDC 0x4d /* FX send D & C current amounts */
688 700#define A_CSFE 0x4e /* FX send F & E current amounts */
689/* Current Send D, C Amounts */701#define A_CSHG 0x4f /* FX send H & G current 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
697 702
703// NOTE: 0x50,51,52: 64-bit (split over voices 0 & 1)
704#define CDCS 0x50 /* CD-ROM digital channel status register */
698 705
699#define CDCS 0x50 /* CD-ROM digital channel status register */706#define GPSCS 0x51 /* General Purpose SPDIF channel status register */
700 707
701#define GPSCS 0x51 /* General Purpose SPDIF channel status register*/708// Corresponding EMU10K1_DBG_* constants are in the public header
709#define DBG 0x52
702 710
703#define DBG 0x52 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */711#define A_SPSC 0x52 /* S/PDIF Input C Channel Status */
704 712
705/* S/PDIF Input C Channel Status */713#define REG53 0x53 /* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
706#define A_SPSC 0x52
707 714
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
709 717
710#define A_DBG 0x53718// NOTE: 0x54,55,56: 64-bit (split over voices 0 & 1)
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#define SPCS0 0x54 /* SPDIF output Channel Status 0 register */719#define SPCS0 0x54 /* SPDIF output Channel Status 0 register */
719 720
720#define SPCS1 0x55 /* SPDIF output Channel Status 1 register */721#define SPCS1 0x55 /* SPDIF output Channel Status 1 register */
@@ -747,17 +748,14 @@ · 26 unmodified lines
747 748
748/* 0x57: Not used */749/* 0x57: Not used */
749 750
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 */
751#define CLIEL 0x58 /* Channel loop interrupt enable low register */752#define CLIEL 0x58 /* Channel loop interrupt enable low register */
752
753#define CLIEH 0x59 /* Channel loop interrupt enable high register */753#define CLIEH 0x59 /* Channel loop interrupt enable high register */
754 754
755#define CLIPL 0x5a /* Channel loop interrupt pending low register */755#define CLIPL 0x5a /* Channel loop interrupt pending low register */
756
757#define CLIPH 0x5b /* Channel loop interrupt pending high register */756#define CLIPH 0x5b /* Channel loop interrupt pending high register */
758 757
759#define SOLEL 0x5c /* Stop on loop enable low register */758#define SOLEL 0x5c /* Stop on loop enable low register */
760
761#define SOLEH 0x5d /* Stop on loop enable high register */759#define SOLEH 0x5d /* Stop on loop enable high register */
762 760
763#define SPBYPASS 0x5e /* SPDIF BYPASS mode register */761#define SPBYPASS 0x5e /* SPDIF BYPASS mode register */
@@ -767,13 +765,12 @@ · 3 unmodified lines
767#define SPBYPASS_FORMAT 0x00000f00 /* If 1, SPDIF XX uses 24 bit, if 0 - 20 bit */765#define SPBYPASS_FORMAT 0x00000f00 /* If 1, SPDIF XX uses 24 bit, if 0 - 20 bit */
768 766
769#define AC97SLOT 0x5f /* additional AC97 slots enable bits */767#define AC97SLOT 0x5f /* additional AC97 slots enable bits */
770#define AC97SLOT_REAR_RIGHT 0x01 /* Rear left */768#define AC97SLOT_REAR_RIGHT 0x01 /* Rear left */
771#define AC97SLOT_REAR_LEFT 0x02 /* Rear right */769#define AC97SLOT_REAR_LEFT 0x02 /* Rear right */
772#define AC97SLOT_CNTR 0x10 /* Center enable */770#define AC97SLOT_CNTR 0x10 /* Center enable */
773#define AC97SLOT_LFE 0x20 /* LFE enable */771#define AC97SLOT_LFE 0x20 /* LFE enable */
774 772
775/* PCB Revision */773#define A_PCB 0x5f /* PCB Revision */
776#define A_PCB 0x5f
777 774
778// NOTE: 0x60,61,62: 64-bit775// NOTE: 0x60,61,62: 64-bit
779#define CDSRCS 0x60 /* CD-ROM Sample Rate Converter status register */776#define CDSRCS 0x60 /* CD-ROM Sample Rate Converter status register */
@@ -813,27 +810,21 @@ · 33 unmodified lines
813#define FXIDX_MASK 0x0000ffff /* 16-bit value */810#define FXIDX_MASK 0x0000ffff /* 16-bit value */
814#define FXIDX_IDX 0x10000065811#define FXIDX_IDX 0x10000065
815 812
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 */
817#define HLIEL 0x66 /* Channel half loop interrupt enable low register */814#define HLIEL 0x66 /* Channel half loop interrupt enable low register */
818
819#define HLIEH 0x67 /* Channel half loop interrupt enable high register */815#define HLIEH 0x67 /* Channel half loop interrupt enable high register */
820 816
821#define HLIPL 0x68 /* Channel half loop interrupt pending low register */817#define HLIPL 0x68 /* Channel half loop interrupt pending low register */
822
823#define HLIPH 0x69 /* Channel half loop interrupt pending high register */818#define HLIPH 0x69 /* Channel half loop interrupt pending high register */
824 819
825/* S/PDIF Host Record Index (bypasses SRC) */820#define A_SPRI 0x6a /* S/PDIF Host Record Index (bypasses SRC) */
826#define A_SPRI 0x6a821#define A_SPRA 0x6b /* S/PDIF Host Record Address */
827/* S/PDIF Host Record Address */822#define A_SPRC 0x6c /* S/PDIF Host Record Control */
828#define A_SPRA 0x6b823
829/* S/PDIF Host Record Control */824#define A_DICE 0x6d /* Delayed Interrupt Counter & Enable */
830#define A_SPRC 0x6c825
831/* Delayed Interrupt Counter & Enable */826#define A_TTB 0x6e /* Tank Table Base */
832#define A_DICE 0x6d827#define A_TDOF 0x6f /* Tank Delay Offset */
833/* Tank Table Base */
834#define A_TTB 0x6e
835/* Tank Delay Offset */
836#define A_TDOF 0x6f
837 828
838/* This is the MPU port on the card (via the game port) */829/* This is the MPU port on the card (via the game port) */
839#define A_MUDATA1 0x70830#define A_MUDATA1 0x70
@@ -846,48 +837,53 @@ · 6 unmodified lines
846#define A_MUSTAT2 A_MUCMD2 837#define A_MUSTAT2 A_MUCMD2
847 838
848/* The next two are the Audigy equivalent of FXWC */839/* 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) */
850/* Each bit selects a channel for recording */841/* Each bit selects a channel for recording */
851#define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */842#define A_FXWC1 0x74 /* Selects 0x7f-0x60 for FX recording */
852#define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */843#define A_FXWC2 0x75 /* Selects 0x9f-0x80 for FX recording */
853 844
854/* Extended Hardware Control */845#define A_EHC 0x76 /* Extended Hardware Control */
855#define A_SPDIF_SAMPLERATE 0x76 /* Set the sample rate of SPDIF output */846
856#define A_SAMPLE_RATE 0x76 /* Various sample rate settings. */847#define A_SPDIF_SAMPLERATE A_EHC /* Set the sample rate of SPDIF output */
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. */
859#define A_SPDIF_RATE_MASK 0x000000e0 /* Any other values for rates, just use 48000 */848#define A_SPDIF_RATE_MASK 0x000000e0 /* Any other values for rates, just use 48000 */
860#define A_SPDIF_48000 0x00000000849#define A_SPDIF_48000 0x00000000 /* kX calls this BYPASS */
861#define A_SPDIF_192000 0x00000020850#define A_SPDIF_192000 0x00000020
862#define A_SPDIF_96000 0x00000040851#define A_SPDIF_96000 0x00000040
863#define A_SPDIF_44100 0x00000080852#define A_SPDIF_44100 0x00000080
853#define A_SPDIF_MUTED 0x000000c0
864 854
865#define A_I2S_CAPTURE_RATE_MASK 0x00000e00 /* This sets the capture PCM rate, but it is */855#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. */856#define A_I2S_CAPTURE_RATE 0x03090076 /* unclear if this sets the ADC rate as well. */
867#define A_I2S_CAPTURE_192000 0x00000200857#define A_I2S_CAPTURE_48000 0x0
868#define A_I2S_CAPTURE_96000 0x00000400858#define A_I2S_CAPTURE_192000 0x1
869#define A_I2S_CAPTURE_44100 0x00000800859#define A_I2S_CAPTURE_96000 0x2
870 860#define A_I2S_CAPTURE_44100 0x4
871#define A_PCM_RATE_MASK 0x0000e000 /* This sets the playback PCM rate on the P16V */861
872#define A_PCM_48000 0x00000000862#define A_EHC_SRC48_MASK 0x0000e000 /* This sets the playback PCM rate on the P16V */
873#define A_PCM_192000 0x00002000863#define A_EHC_SRC48_BYPASS 0x00000000
874#define A_PCM_96000 0x00004000864#define A_EHC_SRC48_192 0x00002000
875#define A_PCM_44100 0x00008000865#define A_EHC_SRC48_96 0x00004000
876 866#define A_EHC_SRC48_44 0x00008000
877/* I2S0 Sample Rate Tracker Status */867#define A_EHC_SRC48_MUTED 0x0000c000
878#define A_SRT3 0x77868
879 869#define A_EHC_P17V_TVM 0x00000001 /* Tank virtual memory mode */
880/* I2S1 Sample Rate Tracker Status */870#define A_EHC_P17V_SEL0_MASK 0x00030000 /* Aka A_EHC_P16V_PB_RATE; 00: 48, 01: 44.1, 10: 96, 11: 192 */
881#define A_SRT4 0x78871#define A_EHC_P17V_SEL1_MASK 0x000c0000
882 872#define A_EHC_P17V_SEL2_MASK 0x00300000
883/* I2S2 Sample Rate Tracker Status */873#define A_EHC_P17V_SEL3_MASK 0x00c00000
884#define A_SRT5 0x79874
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 */
885/* - default to 0x01080000 on my audigy 2 ZS --rlrevell */880/* - default to 0x01080000 on my audigy 2 ZS --rlrevell */
886 881
887/* Tank Table DMA Address */882#define A_SRT_ESTSAMPLERATE 0x001fffff
888#define A_TTDA 0x7a883#define A_SRT_RATELOCKED 0x01000000
889/* Tank Table DMA Data */884
890#define A_TTDD 0x7b885#define A_TTDA 0x7a /* Tank Table DMA Address */
886#define A_TTDD 0x7b /* Tank Table DMA Data */
891 887
892#define A_FXRT2 0x7c888#define A_FXRT2 0x7c
893#define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */889#define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */
@@ -900,6 +896,7 @@ · 6 unmodified lines
900#define A_FXSENDAMOUNT_F_MASK 0x00FF0000896#define A_FXSENDAMOUNT_F_MASK 0x00FF0000
901#define A_FXSENDAMOUNT_G_MASK 0x0000FF00897#define A_FXSENDAMOUNT_G_MASK 0x0000FF00
902#define A_FXSENDAMOUNT_H_MASK 0x000000FF898#define A_FXSENDAMOUNT_H_MASK 0x000000FF
899
903/* 0x7c, 0x7e "high bit is used for filtering" */900/* 0x7c, 0x7e "high bit is used for filtering" */
904 901
905/* The send amounts for this one are the same as used with the emu10k1 */902/* The send amounts for this one are the same as used with the emu10k1 */
@@ -910,55 +907,56 @@ · 4 unmodified lines
910#define A_FXRT_CHANNELD 0x3f000000907#define A_FXRT_CHANNELD 0x3f000000
911 908
912/* 0x7f: Not used */909/* 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 */
933 910
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. */
935 913
936/* Each DSP microcode instruction is mapped into 2 doublewords */914/* Each DSP microcode instruction is mapped into 2 doublewords */
937/* NOTE: When writing, always write the LO doubleword first. Reads can be in either order. */915/* NOTE: When writing, always write the LO doubleword first. Reads can be in either order. */
938#define LOWORD_OPX_MASK 0x000ffc00 /* Instruction operand X */916#define MICROCODEBASE 0x400 /* Microcode data base address */
939#define LOWORD_OPY_MASK 0x000003ff /* Instruction operand Y */917#define A_MICROCODEBASE 0x600
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 */
943 918
944 919
945/* Audigy Soundcard have a different instruction format */920/************************************************************************************************/
946#define A_MICROCODEBASE 0x600921/* E-MU Digital Audio System overview */
947#define A_LOWORD_OPY_MASK 0x000007ff922/************************************************************************************************/
948#define A_LOWORD_OPX_MASK 0x007ff000923
949#define A_HIWORD_OPCODE_MASK 0x0f000000924// - These cards use a regular PCI-attached Audigy chip (Alice2/Tina/Tina2);
950#define A_HIWORD_RESULT_MASK 0x007ff000925// the PCIe variants simply put the Audigy chip behind a PCI bridge.
951#define A_HIWORD_OPA_MASK 0x000007ff926// - 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.
952 946
953/************************************************************************************************/947/************************************************************************************************/
954/* EMU1010m HANA FPGA registers */948/* EMU1010 FPGA registers */
955/************************************************************************************************/949/************************************************************************************************/
950
956#define EMU_HANA_DESTHI 0x00 /* 0000xxx 3 bits Link Destination */951#define EMU_HANA_DESTHI 0x00 /* 0000xxx 3 bits Link Destination */
957#define EMU_HANA_DESTLO 0x01 /* 00xxxxx 5 bits */952#define EMU_HANA_DESTLO 0x01 /* 00xxxxx 5 bits */
953
958#define EMU_HANA_SRCHI 0x02 /* 0000xxx 3 bits Link Source */954#define EMU_HANA_SRCHI 0x02 /* 0000xxx 3 bits Link Source */
959#define EMU_HANA_SRCLO 0x03 /* 00xxxxx 5 bits */955#define EMU_HANA_SRCLO 0x03 /* 00xxxxx 5 bits */
956
960#define EMU_HANA_DOCK_PWR 0x04 /* 000000x 1 bits Audio Dock power */957#define EMU_HANA_DOCK_PWR 0x04 /* 000000x 1 bits Audio Dock power */
961#define EMU_HANA_DOCK_PWR_ON 0x01 /* Audio Dock power on */958#define EMU_HANA_DOCK_PWR_ON 0x01 /* Audio Dock power on */
959
962#define EMU_HANA_WCLOCK 0x05 /* 0000xxx 3 bits Word Clock source select */960#define EMU_HANA_WCLOCK 0x05 /* 0000xxx 3 bits Word Clock source select */
963 /* Must be written after power on to reset DLL */961 /* Must be written after power on to reset DLL */
964 /* One is unable to detect the Audio dock without this */962 /* One is unable to detect the Audio dock without this */
@@ -967,7 +965,7 @@ · 2 unmodified lines
967#define EMU_HANA_WCLOCK_INT_44_1K 0x01965#define EMU_HANA_WCLOCK_INT_44_1K 0x01
968#define EMU_HANA_WCLOCK_HANA_SPDIF_IN 0x02966#define EMU_HANA_WCLOCK_HANA_SPDIF_IN 0x02
969#define EMU_HANA_WCLOCK_HANA_ADAT_IN 0x03967#define EMU_HANA_WCLOCK_HANA_ADAT_IN 0x03
970#define EMU_HANA_WCLOCK_SYNC_BNCN 0x04968#define EMU_HANA_WCLOCK_SYNC_BNC 0x04
971#define EMU_HANA_WCLOCK_2ND_HANA 0x05969#define EMU_HANA_WCLOCK_2ND_HANA 0x05
972#define EMU_HANA_WCLOCK_SRC_RESERVED 0x06970#define EMU_HANA_WCLOCK_SRC_RESERVED 0x06
973#define EMU_HANA_WCLOCK_OFF 0x07 /* For testing, forces fallback to DEFCLOCK */971#define EMU_HANA_WCLOCK_OFF 0x07 /* For testing, forces fallback to DEFCLOCK */
@@ -996,10 +994,10 @@ · 22 unmodified lines
996#define EMU_HANA_IRQ_DOCK_LOST 0x08994#define EMU_HANA_IRQ_DOCK_LOST 0x08
997 995
998#define EMU_HANA_SPDIF_MODE 0x0a /* 00xxxxx 5 bits SPDIF MODE */996#define EMU_HANA_SPDIF_MODE 0x0a /* 00xxxxx 5 bits SPDIF MODE */
999#define EMU_HANA_SPDIF_MODE_TX_COMSUMER 0x00997#define EMU_HANA_SPDIF_MODE_TX_CONSUMER 0x00
1000#define EMU_HANA_SPDIF_MODE_TX_PRO 0x01998#define EMU_HANA_SPDIF_MODE_TX_PRO 0x01
1001#define EMU_HANA_SPDIF_MODE_TX_NOCOPY 0x02999#define EMU_HANA_SPDIF_MODE_TX_NOCOPY 0x02
1002#define EMU_HANA_SPDIF_MODE_RX_COMSUMER 0x001000#define EMU_HANA_SPDIF_MODE_RX_CONSUMER 0x00
1003#define EMU_HANA_SPDIF_MODE_RX_PRO 0x041001#define EMU_HANA_SPDIF_MODE_RX_PRO 0x04
1004#define EMU_HANA_SPDIF_MODE_RX_NOCOPY 0x081002#define EMU_HANA_SPDIF_MODE_RX_NOCOPY 0x08
1005#define EMU_HANA_SPDIF_MODE_RX_INVALID 0x101003#define EMU_HANA_SPDIF_MODE_RX_INVALID 0x10
@@ -1011,8 +1009,12 @@ · 5 unmodified lines
1011#define EMU_HANA_OPTICAL_OUT_ADAT 0x021009#define EMU_HANA_OPTICAL_OUT_ADAT 0x02
1012 1010
1013#define EMU_HANA_MIDI_IN 0x0c /* 000000x 1 bit Control MIDI */1011#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 */1012#define EMU_HANA_MIDI_INA_FROM_HAMOA 0x01 /* HAMOA MIDI in to Alice 2 MIDI A */
1015#define EMU_HANA_MIDI_IN_FROM_DOCK 0x01 /* Audio Dock MIDI in to Alice 2 MIDI B */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 */
1016 1018
1017#define EMU_HANA_DOCK_LEDS_1 0x0d /* 000xxxx 4 bit Audio Dock LEDs */1019#define EMU_HANA_DOCK_LEDS_1 0x0d /* 000xxxx 4 bit Audio Dock LEDs */
1018#define EMU_HANA_DOCK_LEDS_1_MIDI1 0x01 /* MIDI 1 LED on */1020#define EMU_HANA_DOCK_LEDS_1_MIDI1 0x01 /* MIDI 1 LED on */
@@ -1037,51 +1039,49 @@ · 18 unmodified lines
1037#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL 0x20 /* Manual Signal detection */1039#define EMU_HANA_DOCK_LEDS_3_MANUAL_SIGNAL 0x20 /* Manual Signal detection */
1038 1040
1039#define EMU_HANA_ADC_PADS 0x10 /* 0000xxx 3 bit Audio Dock ADC 14dB pads */1041#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 */1042#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 */1043#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 */1044#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 */1045#define EMU_HANA_0202_ADC_PAD1 0x08 /* 14dB Attenuation on 0202 ADC 1 */
1044 1046
1045#define EMU_HANA_DOCK_MISC 0x11 /* 0xxxxxx 6 bit Audio Dock misc bits */1047#define EMU_HANA_DOCK_MISC 0x11 /* 0xxxxxx 6 bit Audio Dock misc bits */
1046#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */1048#define EMU_HANA_DOCK_DAC1_MUTE 0x01 /* DAC 1 Mute */
1047#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */1049#define EMU_HANA_DOCK_DAC2_MUTE 0x02 /* DAC 2 Mute */
1048#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */1050#define EMU_HANA_DOCK_DAC3_MUTE 0x04 /* DAC 3 Mute */
1049#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */1051#define EMU_HANA_DOCK_DAC4_MUTE 0x08 /* DAC 4 Mute */
1050#define EMU_HANA_DOCK_PHONES_192_DAC1 0x00 /* DAC 1 Headphones source at 192kHz */1052#define EMU_HANA_DOCK_PHONES_192_DAC1 0x00 /* DAC 1 Headphones source at 192kHz */
1051#define EMU_HANA_DOCK_PHONES_192_DAC2 0x10 /* DAC 2 Headphones source at 192kHz */1053#define EMU_HANA_DOCK_PHONES_192_DAC2 0x10 /* DAC 2 Headphones source at 192kHz */
1052#define EMU_HANA_DOCK_PHONES_192_DAC3 0x20 /* DAC 3 Headphones source at 192kHz */1054#define EMU_HANA_DOCK_PHONES_192_DAC3 0x20 /* DAC 3 Headphones source at 192kHz */
1053#define EMU_HANA_DOCK_PHONES_192_DAC4 0x30 /* DAC 4 Headphones source at 192kHz */1055#define EMU_HANA_DOCK_PHONES_192_DAC4 0x30 /* DAC 4 Headphones source at 192kHz */
1054 1056
1055#define EMU_HANA_MIDI_OUT 0x12 /* 00xxxxx 5 bit Source for each MIDI out port */1057#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 */1058#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 */1059#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 */1060#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 */1061#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. */1062#define EMU_HANA_MIDI_OUT_LOOP 0x10 /* 0 = bits (3:0) normal. 1 = MIDI loopback enabled. */
1061 1063
1062#define EMU_HANA_DAC_PADS 0x13 /* 00xxxxx 5 bit DAC 14dB attenuation pads */1064#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 */1065#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 */1066#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 */1067#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 */1068#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 */1069#define EMU_HANA_0202_DAC_PAD1 0x10 /* 14dB Attenuation on 0202 DAC 1. Left and Right */
1068 1070
1069/* 0x14 - 0x1f Unused R/W registers */1071/* 0x14 - 0x1f Unused R/W registers */
1070#define EMU_HANA_IRQ_STATUS 0x20 /* 000xxxx 4 bits IRQ Status */1072
1071#if 0 /* Already defined for reg 0x09 IRQ_ENABLE */1073#define EMU_HANA_IRQ_STATUS 0x20 /* 00xxxxx 5 bits IRQ Status */
1072#define EMU_HANA_IRQ_WCLK_CHANGED 0x011074 /* Same bits as for EMU_HANA_IRQ_ENABLE */
1073#define EMU_HANA_IRQ_ADAT 0x021075 /* Reading the register resets it. */
1074#define EMU_HANA_IRQ_DOCK 0x04
1075#define EMU_HANA_IRQ_DOCK_LOST 0x08
1076#endif
1077 1076
1078#define EMU_HANA_OPTION_CARDS 0x21 /* 000xxxx 4 bits Presence of option cards */1077#define EMU_HANA_OPTION_CARDS 0x21 /* 000xxxx 4 bits Presence of option cards */
1079#define EMU_HANA_OPTION_HAMOA 0x01 /* HAMOA card present */1078#define EMU_HANA_OPTION_HAMOA 0x01 /* Hamoa (analog I/O) card present */
1080#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */1079#define EMU_HANA_OPTION_SYNC 0x02 /* Sync card present */
1081#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio Dock online and FPGA configured */1080#define EMU_HANA_OPTION_DOCK_ONLINE 0x04 /* Audio/Micro dock present and FPGA configured */
1082#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio Dock online and FPGA not configured */1081#define EMU_HANA_OPTION_DOCK_OFFLINE 0x08 /* Audio/Micro dock present and FPGA not configured */
1083 1082
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 */
1085 1085
1086#define EMU_HANA_MAJOR_REV 0x23 /* 0000xxx 3 bit Hana FPGA Major rev */1086#define EMU_HANA_MAJOR_REV 0x23 /* 0000xxx 3 bit Hana FPGA Major rev */
1087#define EMU_HANA_MINOR_REV 0x24 /* 0000xxx 3 bit Hana FPGA Minor rev */1087#define EMU_HANA_MINOR_REV 0x24 /* 0000xxx 3 bit Hana FPGA Minor rev */
@@ -1090,8 +1090,8 @@ · 2 unmodified lines
1090#define EMU_DOCK_MINOR_REV 0x26 /* 0000xxx 3 bit Audio Dock FPGA Minor rev */1090#define EMU_DOCK_MINOR_REV 0x26 /* 0000xxx 3 bit Audio Dock FPGA Minor rev */
1091 1091
1092#define EMU_DOCK_BOARD_ID 0x27 /* 00000xx 2 bits Audio Dock ID pins */1092#define EMU_DOCK_BOARD_ID 0x27 /* 00000xx 2 bits Audio Dock ID pins */
1093#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */1093#define EMU_DOCK_BOARD_ID0 0x00 /* ID bit 0 */
1094#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */1094#define EMU_DOCK_BOARD_ID1 0x03 /* ID bit 1 */
1095 1095
1096#define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */1096#define EMU_HANA_WC_SPDIF_HI 0x28 /* 0xxxxxx 6 bit SPDIF IN Word clock, upper 6 bits */
1097#define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */1097#define EMU_HANA_WC_SPDIF_LO 0x29 /* 0xxxxxx 6 bit SPDIF IN Word clock, lower 6 bits */
@@ -1104,31 +1104,35 @@ · 6 unmodified lines
1104 1104
1105#define EMU_HANA2_WC_SPDIF_HI 0x2e /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, upper 6 bits */1105#define EMU_HANA2_WC_SPDIF_HI 0x2e /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, upper 6 bits */
1106#define EMU_HANA2_WC_SPDIF_LO 0x2f /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, lower 6 bits */1106#define EMU_HANA2_WC_SPDIF_LO 0x2f /* 0xxxxxx 6 bit HANA2 SPDIF IN Word clock, lower 6 bits */
1107
1107/* 0x30 - 0x3f Unused Read only registers */1108/* 0x30 - 0x3f Unused Read only registers */
1108 1109
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
1109/************************************************************************************************/1114/************************************************************************************************/
1110/* EMU1010m HANA Destinations */1115/* EMU1010 Audio Destinations */
1111/************************************************************************************************/1116/************************************************************************************************/
1112/* Hana, original 1010,1212,1820 using Alice21117/* Hana, original 1010,1212m,1820[m] using Alice2
1113 * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1114 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice21118 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2
1115 * 0x01, 0x10-0x1f: 32 Elink channels to Audio Dock1119 * 0x01, 0x00-0x1f: 32 EDI channels to Audio Dock
1116 * 0x01, 0x00: Dock DAC 1 Left1120 * 0x00: Dock DAC 1 Left
1117 * 0x01, 0x04: Dock DAC 1 Right1121 * 0x04: Dock DAC 1 Right
1118 * 0x01, 0x08: Dock DAC 2 Left1122 * 0x08: Dock DAC 2 Left
1119 * 0x01, 0x0c: Dock DAC 2 Right1123 * 0x0c: Dock DAC 2 Right
1120 * 0x01, 0x10: Dock DAC 3 Left1124 * 0x10: Dock DAC 3 Left
1121 * 0x01, 0x12: PHONES Left1125 * 0x12: PHONES Left (n/a in 2x/4x mode; output mirrors DAC4 Left)
1122 * 0x01, 0x14: Dock DAC 3 Right1126 * 0x14: Dock DAC 3 Right
1123 * 0x01, 0x16: PHONES Right1127 * 0x16: PHONES Right (n/a in 2x/4x mode; output mirrors DAC4 Right)
1124 * 0x01, 0x18: Dock DAC 4 Left1128 * 0x18: Dock DAC 4 Left
1125 * 0x01, 0x1a: S/PDIF Left1129 * 0x1a: S/PDIF Left
1126 * 0x01, 0x1c: Dock DAC 4 Right1130 * 0x1c: Dock DAC 4 Right
1127 * 0x01, 0x1e: S/PDIF Right1131 * 0x1e: S/PDIF Right
1128 * 0x02, 0x00: Hana S/PDIF Left1132 * 0x02, 0x00: Hana S/PDIF Left
1129 * 0x02, 0x01: Hana S/PDIF Right1133 * 0x02, 0x01: Hana S/PDIF Right
1130 * 0x03, 0x00: Hanoa DAC Left1134 * 0x03, 0x00: Hamoa DAC Left
1131 * 0x03, 0x01: Hanoa DAC Right1135 * 0x03, 0x01: Hamoa DAC Right
1132 * 0x04, 0x00-0x07: Hana ADAT1136 * 0x04, 0x00-0x07: Hana ADAT
1133 * 0x05, 0x00: I2S0 Left to Alice21137 * 0x05, 0x00: I2S0 Left to Alice2
1134 * 0x05, 0x01: I2S0 Right to Alice21138 * 0x05, 0x01: I2S0 Right to Alice2
@@ -1140,40 +1144,29 @@ · 5 unmodified lines
1140 * Hana2 never released, but used Tina1144 * Hana2 never released, but used Tina
1141 * Not needed.1145 * Not needed.
1142 *1146 *
1143 * Hana3, rev2 1010,1212,1616 using Tina1147 * Hana3, rev2 1010,1212m,1616[m] using Tina
1144 * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1145 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina1148 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina
1146 * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock1149 * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
1147 * 0x01, 0x00: Dock DAC 1 Left1150 * 0x00: Dock DAC 1 Left
1148 * 0x01, 0x04: Dock DAC 1 Right1151 * 0x04: Dock DAC 1 Right
1149 * 0x01, 0x08: Dock DAC 2 Left1152 * 0x08: Dock DAC 2 Left
1150 * 0x01, 0x0c: Dock DAC 2 Right1153 * 0x0c: Dock DAC 2 Right
1151 * 0x01, 0x10: Dock DAC 3 Left1154 * 0x10: Dock DAC 3 Left
1152 * 0x01, 0x12: Dock S/PDIF Left1155 * 0x12: Dock S/PDIF Left
1153 * 0x01, 0x14: Dock DAC 3 Right1156 * 0x14: Dock DAC 3 Right
1154 * 0x01, 0x16: Dock S/PDIF Right1157 * 0x16: Dock S/PDIF Right
1155 * 0x01, 0x18-0x1f: Dock ADAT 0-71158 * 0x18-0x1f: Dock ADAT 0-7
1156 * 0x02, 0x00: Hana3 S/PDIF Left1159 * 0x02, 0x00: Hana3 S/PDIF Left
1157 * 0x02, 0x01: Hana3 S/PDIF Right1160 * 0x02, 0x01: Hana3 S/PDIF Right
1158 * 0x03, 0x00: Hanoa DAC Left1161 * 0x03, 0x00: Hamoa DAC Left
1159 * 0x03, 0x01: Hanoa DAC Right1162 * 0x03, 0x01: Hamoa DAC Right
1160 * 0x04, 0x00-0x07: Hana3 ADAT 0-71163 * 0x04, 0x00-0x07: Hana3 ADAT 0-7
1161 * 0x05, 0x00-0x0f: 16 EMU32B channels to Tina1164 * 0x05, 0x00-0x0f: 16 EMU32B channels to Tina
1162 * 0x06-0x07: Not used1165 * 0x06-0x07: Not used
1163 *1166 *
1164 * HanaLite, rev1 0404 using Alice21167 * HanaLite, rev1 0404 using Alice2
1165 * Destiniations for SRATEX = 1X rates: 44.1 kHz or 48 kHz1168 * HanaLiteLite, rev2 0404 using Tina
1166 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice21169 * 0x00, 0x00-0x0f: 16 EMU32 channels to Alice2/Tina
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
1177 * 0x01: Not used1170 * 0x01: Not used
1178 * 0x02, 0x00: S/PDIF Left1171 * 0x02, 0x00: S/PDIF Left
1179 * 0x02, 0x01: S/PDIF Right1172 * 0x02, 0x01: S/PDIF Right
@@ -1182,35 +1175,21 @@ · 2 unmodified lines
1182 * 0x04-0x07: Not used1175 * 0x04-0x07: Not used
1183 *1176 *
1184 * Mana, Cardbus 1616 using Tina21177 * Mana, Cardbus 1616 using Tina2
1185 * Destinations for SRATEX = 1X rates: 44.1 kHz or 48 kHz
1186 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina21178 * 0x00, 0x00-0x0f: 16 EMU32A channels to Tina2
1187 * 0x01, 0x10-0x1f: 32 EDI channels to Micro Dock1179 * 0x01, 0x00-0x1f: 32 EDI channels to Micro Dock
1188 * 0x01, 0x00: Dock DAC 1 Left1180 * (same as rev2 1010)
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
1197 * 0x02: Not used1181 * 0x02: Not used
1198 * 0x03, 0x00: Mana DAC Left1182 * 0x03, 0x00: Mana DAC Left
1199 * 0x03, 0x01: Mana DAC Right1183 * 0x03, 0x01: Mana DAC Right
1200 * 0x04, 0x00-0x0f: 16 EMU32B channels to Tina21184 * 0x04, 0x00-0x0f: 16 EMU32B channels to Tina2
1201 * 0x05-0x07: Not used1185 * 0x05-0x07: Not used
1202 *
1203 *
1204 */1186 */
1187
1205/* 32-bit destinations of signal in the Hana FPGA. Destinations are either1188/* 32-bit destinations of signal in the Hana FPGA. Destinations are either
1206 * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture1189 * physical outputs of Hana, or outputs going to Alice2/Tina for capture -
1207 * - 16 x EMU_DST_ALICE2_EMU32_X.1190 * 16 x EMU_DST_ALICE2_EMU32_X (2x on rev2 boards). Which data is fed into
1208 */1191 * a channel depends on the mixer control setting for each destination - see
1209/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */1192 * emumixer.c - snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[]
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[]
1214 */1193 */
1215#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */1194#define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */
1216#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */1195#define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */
@@ -1270,8 +1249,12 @@ · 53 unmodified lines
1270#define EMU_DST_DOCK_SPDIF_RIGHT2 0x011f /* Audio Dock SPDIF Right, 2nd or 96kHz */1249#define EMU_DST_DOCK_SPDIF_RIGHT2 0x011f /* Audio Dock SPDIF Right, 2nd or 96kHz */
1271#define EMU_DST_HANA_SPDIF_LEFT1 0x0200 /* Hana SPDIF Left, 1st or 48kHz only */1250#define EMU_DST_HANA_SPDIF_LEFT1 0x0200 /* Hana SPDIF Left, 1st or 48kHz only */
1272#define EMU_DST_HANA_SPDIF_LEFT2 0x0202 /* Hana SPDIF Left, 2nd or 96kHz */1251#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 */
1273#define EMU_DST_HANA_SPDIF_RIGHT1 0x0201 /* Hana SPDIF Right, 1st or 48kHz only */1254#define EMU_DST_HANA_SPDIF_RIGHT1 0x0201 /* Hana SPDIF Right, 1st or 48kHz only */
1274#define EMU_DST_HANA_SPDIF_RIGHT2 0x0203 /* Hana SPDIF Right, 2nd or 96kHz */1255#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 */
1275#define EMU_DST_HAMOA_DAC_LEFT1 0x0300 /* Hamoa DAC Left, 1st or 48kHz only */1258#define EMU_DST_HAMOA_DAC_LEFT1 0x0300 /* Hamoa DAC Left, 1st or 48kHz only */
1276#define EMU_DST_HAMOA_DAC_LEFT2 0x0302 /* Hamoa DAC Left, 2nd or 96kHz */1259#define EMU_DST_HAMOA_DAC_LEFT2 0x0302 /* Hamoa DAC Left, 2nd or 96kHz */
1277#define EMU_DST_HAMOA_DAC_LEFT3 0x0304 /* Hamoa DAC Left, 3rd or 192kHz */1260#define EMU_DST_HAMOA_DAC_LEFT3 0x0304 /* Hamoa DAC Left, 3rd or 192kHz */
@@ -1280,6 +1263,7 @@ · 2 unmodified lines
1280#define EMU_DST_HAMOA_DAC_RIGHT2 0x0303 /* Hamoa DAC Right, 2nd or 96kHz */1263#define EMU_DST_HAMOA_DAC_RIGHT2 0x0303 /* Hamoa DAC Right, 2nd or 96kHz */
1281#define EMU_DST_HAMOA_DAC_RIGHT3 0x0305 /* Hamoa DAC Right, 3rd or 192kHz */1264#define EMU_DST_HAMOA_DAC_RIGHT3 0x0305 /* Hamoa DAC Right, 3rd or 192kHz */
1282#define EMU_DST_HAMOA_DAC_RIGHT4 0x0307 /* Hamoa DAC Right, 4th or 192kHz */1265#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.
1283#define EMU_DST_HANA_ADAT 0x0400 /* Hana ADAT 8 channel out +0 to +7 */1267#define EMU_DST_HANA_ADAT 0x0400 /* Hana ADAT 8 channel out +0 to +7 */
1284#define EMU_DST_ALICE_I2S0_LEFT 0x0500 /* Alice2 I2S0 Left */1268#define EMU_DST_ALICE_I2S0_LEFT 0x0500 /* Alice2 I2S0 Left */
1285#define EMU_DST_ALICE_I2S0_RIGHT 0x0501 /* Alice2 I2S0 Right */1269#define EMU_DST_ALICE_I2S0_RIGHT 0x0501 /* Alice2 I2S0 Right */
@@ -1289,39 +1273,32 @@ · 3 unmodified lines
1289#define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */1273#define EMU_DST_ALICE_I2S2_RIGHT 0x0701 /* Alice2 I2S2 Right */
1290 1274
1291/* Additional destinations for 1616(M)/Microdock */1275/* Additional destinations for 1616(M)/Microdock */
1292/* Microdock S/PDIF OUT Left, 1st or 48kHz only */1276
1293#define EMU_DST_MDOCK_SPDIF_LEFT1 0x01121277#define EMU_DST_MDOCK_SPDIF_LEFT1 0x0112 /* Microdock S/PDIF OUT Left, 1st or 48kHz only */
1294/* Microdock S/PDIF OUT Left, 2nd or 96kHz */1278#define EMU_DST_MDOCK_SPDIF_LEFT2 0x0113 /* Microdock S/PDIF OUT Left, 2nd or 96kHz */
1295#define EMU_DST_MDOCK_SPDIF_LEFT2 0x01131279#define EMU_DST_MDOCK_SPDIF_RIGHT1 0x0116 /* Microdock S/PDIF OUT Right, 1st or 48kHz only */
1296/* 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 */
1297#define EMU_DST_MDOCK_SPDIF_RIGHT1 0x01161281#define EMU_DST_MDOCK_ADAT 0x0118 /* Microdock S/PDIF ADAT 8 channel out +8 to +f */
1298/* Microdock S/PDIF OUT Right, 2nd or 96kHz */1282
1299#define EMU_DST_MDOCK_SPDIF_RIGHT2 0x01171283#define EMU_DST_MANA_DAC_LEFT 0x0300 /* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
1300/* Microdock S/PDIF ADAT 8 channel out +8 to +f */1284#define EMU_DST_MANA_DAC_RIGHT 0x0301 /* Headphone jack on 1010 cardbus? 44.1/48kHz only? */
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
1307 1285
1308/************************************************************************************************/1286/************************************************************************************************/
1309/* EMU1010m HANA Sources */1287/* EMU1010 Audio Sources */
1310/************************************************************************************************/1288/************************************************************************************************/
1311/* Hana, original 1010,1212,1820 using Alice21289/* Hana, original 1010,1212m,1820[m] using Alice2
1312 * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz1290 * 0x00, 0x00-0x1f: Silence
1313 * 0x00,0x00-0x1f: Silence1291 * 0x01, 0x00-0x1f: 32 EDI channels from Audio Dock
1314 * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock1292 * 0x00: Dock Mic A
1315 * 0x01, 0x00: Dock Mic A1293 * 0x04: Dock Mic B
1316 * 0x01, 0x04: Dock Mic B1294 * 0x08: Dock ADC 1 Left
1317 * 0x01, 0x08: Dock ADC 1 Left1295 * 0x0c: Dock ADC 1 Right
1318 * 0x01, 0x0c: Dock ADC 1 Right1296 * 0x10: Dock ADC 2 Left
1319 * 0x01, 0x10: Dock ADC 2 Left1297 * 0x14: Dock ADC 2 Right
1320 * 0x01, 0x14: Dock ADC 2 Right1298 * 0x18: Dock ADC 3 Left
1321 * 0x01, 0x18: Dock ADC 3 Left1299 * 0x1c: Dock ADC 3 Right
1322 * 0x01, 0x1c: Dock ADC 3 Right1300 * 0x02, 0x00: Hamoa ADC Left
1323 * 0x02, 0x00: Hana ADC Left1301 * 0x02, 0x01: Hamoa ADC Right
1324 * 0x02, 0x01: Hana ADC Right
1325 * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output1302 * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output
1326 * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output1303 * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output
1327 * 0x04, 0x00-0x07: Hana ADAT1304 * 0x04, 0x00-0x07: Hana ADAT
@@ -1332,23 +1309,20 @@ · 4 unmodified lines
1332 * Hana2 never released, but used Tina1309 * Hana2 never released, but used Tina
1333 * Not needed.1310 * Not needed.
1334 *1311 *
1335 * Hana3, rev2 1010,1212,1616 using Tina1312 * Hana3, rev2 1010,1212m,1616[m] using Tina
1336 * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz1313 * 0x00, 0x00-0x1f: Silence
1337 * 0x00,0x00-0x1f: Silence1314 * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
1338 * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock1315 * 0x00: Dock Mic A
1339 * 0x01, 0x00: Dock Mic A1316 * 0x04: Dock Mic B
1340 * 0x01, 0x04: Dock Mic B1317 * 0x08: Dock ADC 1 Left
1341 * 0x01, 0x08: Dock ADC 1 Left1318 * 0x0c: Dock ADC 1 Right
1342 * 0x01, 0x0c: Dock ADC 1 Right1319 * 0x10: Dock ADC 2 Left
1343 * 0x01, 0x10: Dock ADC 2 Left1320 * 0x12: Dock S/PDIF Left
1344 * 0x01, 0x12: Dock S/PDIF Left1321 * 0x14: Dock ADC 2 Right
1345 * 0x01, 0x14: Dock ADC 2 Right1322 * 0x16: Dock S/PDIF Right
1346 * 0x01, 0x16: Dock S/PDIF Right1323 * 0x18-0x1f: Dock ADAT 0-7
1347 * 0x01, 0x18-0x1f: Dock ADAT 0-71324 * 0x02, 0x00: Hamoa ADC Left
1348 * 0x01, 0x18: Dock ADC 3 Left1325 * 0x02, 0x01: Hamoa ADC Right
1349 * 0x01, 0x1c: Dock ADC 3 Right
1350 * 0x02, 0x00: Hanoa ADC Left
1351 * 0x02, 0x01: Hanoa ADC Right
1352 * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output1326 * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output
1353 * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output1327 * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output
1354 * 0x04, 0x00-0x07: Hana3 ADAT1328 * 0x04, 0x00-0x07: Hana3 ADAT
@@ -1357,58 +1331,32 @@ · 2 unmodified lines
1357 * 0x06-0x07: Not used1331 * 0x06-0x07: Not used
1358 *1332 *
1359 * HanaLite, rev1 0404 using Alice21333 * HanaLite, rev1 0404 using Alice2
1360 * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz1334 * HanaLiteLite, rev2 0404 using Tina
1361 * 0x00,0x00-0x1f: Silence1335 * 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
1375 * 0x01: Not used1336 * 0x01: Not used
1376 * 0x02, 0x00: ADC Left1337 * 0x02, 0x00: ADC Left
1377 * 0x02, 0x01: ADC Right1338 * 0x02, 0x01: ADC Right
1378 * 0x03, 0x00-0x0f: 16 inputs from Alice2 Emu32A output1339 * 0x03, 0x00-0x0f: 16 inputs from Alice2/Tina Emu32A output
1379 * 0x03, 0x10-0x1f: 16 inputs from Alice2 Emu32B output1340 * 0x03, 0x10-0x1f: 16 inputs from Alice2/Tina Emu32B output
1380 * 0x04: Not used1341 * 0x04: Not used
1381 * 0x05, 0x00: S/PDIF Left1342 * 0x05, 0x00: S/PDIF Left
1382 * 0x05, 0x01: S/PDIF Right1343 * 0x05, 0x01: S/PDIF Right
1383 * 0x06-0x07: Not used1344 * 0x06-0x07: Not used
1384 *1345 *
1385 * Mana, Cardbus 1616 using Tina21346 * Mana, Cardbus 1616 using Tina2
1386 * Sources SRATEX = 1X rates: 44.1 kHz or 48 kHz1347 * 0x00, 0x00-0x1f: Silence
1387 * 0x00,0x00-0x1f: Silence1348 * 0x01, 0x00-0x1f: 32 EDI channels from Micro Dock
1388 * 0x01, 0x10-0x1f: 32 Elink channels from Audio Dock1349 * (same as rev2 1010)
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
1400 * 0x02: Not used1350 * 0x02: Not used
1401 * 0x03, 0x00-0x0f: 16 inputs from Tina Emu32A output1351 * 0x03, 0x00-0x0f: 16 inputs from Tina2 Emu32A output
1402 * 0x03, 0x10-0x1f: 16 inputs from Tina Emu32B output1352 * 0x03, 0x10-0x1f: 16 inputs from Tina2 Emu32B output
1403 * 0x04-0x07: Not used1353 * 0x04-0x07: Not used
1404 *
1405 */1354 */
1406 1355
1407/* 32-bit sources of signal in the Hana FPGA. The sources are routed to1356/* 32-bit sources of signal in the Hana FPGA. The sources are routed to
1408 * destinations using mixer control for each destination - see emumixer.c1357 * destinations using a mixer control for each destination - see emumixer.c.
1409 * Sources are either physical inputs of FPGA,1358 * Sources are either physical inputs of Hana, or inputs from Alice2/Tina -
1410 * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A +1359 * 16 x EMU_SRC_ALICE_EMU32A + 16 x EMU_SRC_ALICE_EMU32B.
1411 * 16 x EMU_SRC_ALICE_EMU32B
1412 */1360 */
1413#define EMU_SRC_SILENCE 0x0000 /* Silence */1361#define EMU_SRC_SILENCE 0x0000 /* Silence */
1414#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */1362#define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */
@@ -1453,23 +1401,24 @@ · 38 unmodified lines
1453#define EMU_SRC_HAMOA_ADC_RIGHT4 0x0207 /* Hamoa ADC Right, 4th or 192kHz */1401#define EMU_SRC_HAMOA_ADC_RIGHT4 0x0207 /* Hamoa ADC Right, 4th or 192kHz */
1454#define EMU_SRC_ALICE_EMU32A 0x0300 /* Alice2 EMU32a 16 outputs. +0 to +0xf */1402#define EMU_SRC_ALICE_EMU32A 0x0300 /* Alice2 EMU32a 16 outputs. +0 to +0xf */
1455#define EMU_SRC_ALICE_EMU32B 0x0310 /* Alice2 EMU32b 16 outputs. +0 to +0xf */1403#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.
1456#define EMU_SRC_HANA_ADAT 0x0400 /* Hana ADAT 8 channel in +0 to +7 */1405#define EMU_SRC_HANA_ADAT 0x0400 /* Hana ADAT 8 channel in +0 to +7 */
1457#define EMU_SRC_HANA_SPDIF_LEFT1 0x0500 /* Hana SPDIF Left, 1st or 48kHz only */1406#define EMU_SRC_HANA_SPDIF_LEFT1 0x0500 /* Hana SPDIF Left, 1st or 48kHz only */
1458#define EMU_SRC_HANA_SPDIF_LEFT2 0x0502 /* Hana SPDIF Left, 2nd or 96kHz */1407#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 */
1459#define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */1410#define EMU_SRC_HANA_SPDIF_RIGHT1 0x0501 /* Hana SPDIF Right, 1st or 48kHz only */
1460#define EMU_SRC_HANA_SPDIF_RIGHT2 0x0503 /* Hana SPDIF Right, 2nd or 96kHz */1411#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 */
1461 1414
1462/* Additional inputs for 1616(M)/Microdock */1415/* Additional inputs for 1616(M)/Microdock */
1463/* Microdock S/PDIF Left, 1st or 48kHz only */1416
1464#define EMU_SRC_MDOCK_SPDIF_LEFT1 0x01121417#define EMU_SRC_MDOCK_SPDIF_LEFT1 0x0112 /* Microdock S/PDIF Left, 1st or 48kHz only */
1465/* Microdock S/PDIF Left, 2nd or 96kHz */1418#define EMU_SRC_MDOCK_SPDIF_LEFT2 0x0113 /* Microdock S/PDIF Left, 2nd or 96kHz */
1466#define EMU_SRC_MDOCK_SPDIF_LEFT2 0x01131419#define EMU_SRC_MDOCK_SPDIF_RIGHT1 0x0116 /* Microdock S/PDIF Right, 1st or 48kHz only */
1467/* Microdock S/PDIF Right, 1st or 48kHz only */1420#define EMU_SRC_MDOCK_SPDIF_RIGHT2 0x0117 /* Microdock S/PDIF Right, 2nd or 96kHz */
1468#define EMU_SRC_MDOCK_SPDIF_RIGHT1 0x01161421#define EMU_SRC_MDOCK_ADAT 0x0118 /* Microdock ADAT 8 channel in +8 to +f */
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
1473 1422
1474/* 0x600 and 0x700 no used */1423/* 0x600 and 0x700 no used */
1475 1424
@@ -1485,7 +1434,6 @@ enum { · 9 unmodified lines
1485struct snd_emu10k1;1434struct snd_emu10k1;
1486 1435
1487struct snd_emu10k1_voice {1436struct snd_emu10k1_voice {
1488 struct snd_emu10k1 *emu;
1489 int number;1437 int number;
1490 unsigned int use: 1,1438 unsigned int use: 1,
1491 pcm: 1,1439 pcm: 1,
@@ -1599,10 +1547,8 @@ struct snd_emu10k1_fx8010_pcm { · 107 unmodified lines
1599};1547};
1600 1548
1601struct snd_emu10k1_fx8010 {1549struct snd_emu10k1_fx8010 {
1602 unsigned short fxbus_mask; /* used FX buses (bitmask) */1550 unsigned short extin_mask; /* used external inputs (bitmask); not used for Audigy */
1603 unsigned short extin_mask; /* used external inputs (bitmask) */1551 unsigned short extout_mask; /* used external outputs (bitmask); not used for Audigy */
1604 unsigned short extout_mask; /* used external outputs (bitmask) */
1605 unsigned short pad1;
1606 unsigned int itram_size; /* internal TRAM size in samples */1552 unsigned int itram_size; /* internal TRAM size in samples */
1607 struct snd_dma_buffer etram_pages; /* external TRAM pages and size */1553 struct snd_dma_buffer etram_pages; /* external TRAM pages and size */
1608 unsigned int dbg; /* FX debugger register */1554 unsigned int dbg; /* FX debugger register */
@@ -1639,14 +1585,26 @@ enum { · 30 unmodified lines
1639 EMU_MODEL_EMU0404,1585 EMU_MODEL_EMU0404,
1640};1586};
1641 1587
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
1642struct snd_emu_chip_details {1598struct snd_emu_chip_details {
1643 u32 vendor;1599 u32 vendor;
1644 u32 device;1600 u32 device;
1645 u32 subsystem;1601 u32 subsystem;
1646 unsigned char revision;1602 unsigned char revision;
1647 unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */1603 unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */
1604 /* Redundant with emu10k2_chip being unset. */
1648 unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */1605 unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
1649 unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */1606 unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
1607 /* Redundant with ca0108_chip being unset. */
1650 unsigned char ca0108_chip; /* Audigy 2 Value */1608 unsigned char ca0108_chip; /* Audigy 2 Value */
1651 unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */1609 unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
1652 unsigned char ca0151_chip; /* P16V */1610 unsigned char ca0151_chip; /* P16V */
@@ -1656,8 +1614,8 @@ struct snd_emu_chip_details { · 3 unmodified lines
1656 unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */1614 unsigned char ac97_chip; /* Has an AC97 chip: 1 = mandatory, 2 = optional */
1657 unsigned char ecard; /* APS EEPROM */1615 unsigned char ecard; /* APS EEPROM */
1658 unsigned char emu_model; /* EMU model type */1616 unsigned char emu_model; /* EMU model type */
1659 unsigned char spi_dac; /* SPI interface for DAC */1617 unsigned char spi_dac; /* SPI interface for DAC; requires ca0108_chip */
1660 unsigned char i2c_adc; /* I2C interface for ADC */1618 unsigned char i2c_adc; /* I2C interface for ADC; requires ca0108_chip */
1661 unsigned char adc_1361t; /* Use Philips 1361T ADC */1619 unsigned char adc_1361t; /* Use Philips 1361T ADC */
1662 unsigned char invert_shared_spdif; /* analog/digital switch inverted */1620 unsigned char invert_shared_spdif; /* analog/digital switch inverted */
1663 const char *driver;1621 const char *driver;
@@ -1691,7 +1649,6 @@ struct snd_emu10k1 { · 27 unmodified lines
1691 unsigned int revision; /* chip revision */1649 unsigned int revision; /* chip revision */
1692 unsigned int serial; /* serial number */1650 unsigned int serial; /* serial number */
1693 unsigned short model; /* subsystem id */1651 unsigned short model; /* subsystem id */
1694 unsigned int card_type; /* EMU10K1_CARD_* */
1695 unsigned int ecard_ctrl; /* ecard control bits */1652 unsigned int ecard_ctrl; /* ecard control bits */
1696 unsigned int address_mode; /* address mode */1653 unsigned int address_mode; /* address mode */
1697 unsigned long dma_mask; /* PCI DMA mask */1654 unsigned long dma_mask; /* PCI DMA mask */
@@ -1732,15 +1689,13 @@ struct snd_emu10k1 { · 34 unmodified lines
1732 void *synth;1689 void *synth;
1733 int (*get_synth_voice)(struct snd_emu10k1 *emu);1690 int (*get_synth_voice)(struct snd_emu10k1 *emu);
1734 1691
1735 spinlock_t reg_lock;1692 spinlock_t reg_lock; // high-level driver lock
1736 spinlock_t emu_lock;1693 spinlock_t emu_lock; // low-level i/o lock
1737 spinlock_t voice_lock;1694 spinlock_t voice_lock; // voice allocator lock
1738 spinlock_t spi_lock; /* serialises access to spi port */1695 spinlock_t spi_lock; /* serialises access to spi port */
1739 spinlock_t i2c_lock; /* serialises access to i2c port */1696 spinlock_t i2c_lock; /* serialises access to i2c port */
1740 1697
1741 struct snd_emu10k1_voice voices[NUM_G];1698 struct snd_emu10k1_voice voices[NUM_G];
1742 struct snd_emu10k1_voice p16v_voices[4];
1743 struct snd_emu10k1_voice p16v_capture_voice;
1744 int p16v_device_offset;1699 int p16v_device_offset;
1745 u32 p16v_capture_source;1700 u32 p16v_capture_source;
1746 u32 p16v_capture_channel;1701 u32 p16v_capture_channel;
@@ -1760,11 +1715,11 @@ struct snd_emu10k1 { · 13 unmodified lines
1760 void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1715 void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
1761 void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1716 void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
1762 void (*dsp_interrupt)(struct snd_emu10k1 *emu);1717 void (*dsp_interrupt)(struct snd_emu10k1 *emu);
1718 void (*p16v_interrupt)(struct snd_emu10k1 *emu);
1763 1719
1764 struct snd_pcm_substream *pcm_capture_substream;1720 struct snd_pcm_substream *pcm_capture_substream;
1765 struct snd_pcm_substream *pcm_capture_mic_substream;1721 struct snd_pcm_substream *pcm_capture_mic_substream;
1766 struct snd_pcm_substream *pcm_capture_efx_substream;1722 struct snd_pcm_substream *pcm_capture_efx_substream;
1767 struct snd_pcm_substream *pcm_playback_efx_substream;
1768 1723
1769 struct snd_timer *timer;1724 struct snd_timer *timer;
1770 1725
@@ -1824,9 +1779,9 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, · 53 unmodified lines
1824void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);1779void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
1825int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);1780int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
1826int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);1781int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
1827int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value);1782void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
1828int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value);1783void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value);
1829int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src);1784void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src);
1830unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);1785unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
1831void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);1786void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
1832void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);1787void 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
9struct hdac_bus;
10struct hdac_ext_link;
11
12#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
13
14int hda_bus_ml_init(struct hdac_bus *bus);
15void hda_bus_ml_free(struct hdac_bus *bus);
16
17int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid);
18void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable);
19bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid);
20
21int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd);
22int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd);
23
24int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid);
25int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus);
26
27void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
28void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink);
29
30int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid);
31int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus);
32
33bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid);
34bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus);
35
36int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink);
37int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
38
39int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink);
40int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink);
41
42int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink);
43int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
44
45int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
46
47void hda_bus_ml_put_all(struct hdac_bus *bus);
48void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
49int hda_bus_ml_resume(struct hdac_bus *bus);
50int hda_bus_ml_suspend(struct hdac_bus *bus);
51
52struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
53struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
54
55struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid);
56
57int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable);
58
59#else
60
61static inline int
62hda_bus_ml_init(struct hdac_bus *bus) { return 0; }
63
64static inline void hda_bus_ml_free(struct hdac_bus *bus) { }
65
66static inline int
67hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid) { return 0; }
68
69static inline void
70hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable) { }
71
72static inline bool
73hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid) { return false; }
74
75static inline int
76hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd)
77{
78 return 0;
79}
80
81static inline int
82hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd)
83{
84 return 0;
85}
86
87static inline int
88hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
89{
90 return 0;
91}
92
93static inline int
94hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus) { return 0; }
95
96static inline void
97hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink) { }
98
99static inline void
100hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink) { }
101
102static inline int
103hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid) { return 0; }
104
105static inline int
106hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus) { return 0; }
107
108static inline bool
109hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid) { return false; }
110
111static inline bool
112hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus) { return false; }
113
114static inline int
115hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
116{
117 return 0;
118}
119
120static inline int
121hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
122{
123 return 0;
124}
125
126static inline int
127hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink)
128{
129 return 0;
130}
131
132static inline int
133hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
134{
135 return 0;
136}
137
138static inline int
139hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
140
141static inline int
142hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
143
144static inline int
145hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
146
147static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
148static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
149static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
150static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
151
152static inline struct hdac_ext_link *
153hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }
154
155static inline struct hdac_ext_link *
156hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus) { return NULL; }
157
158static inline struct mutex *
159hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid) { return NULL; }
160
161static inline int
162hdac_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
258#define AZX_ML_BASE 0x40258#define AZX_ML_BASE 0x40
259#define AZX_ML_INTERVAL 0x40259#define AZX_ML_INTERVAL 0x40
260 260
261/* HDaudio registers valid for HDaudio and HDaudio extended links */
261#define AZX_REG_ML_LCAP 0x00262#define AZX_REG_ML_LCAP 0x00
262#define AZX_REG_ML_LCTL 0x04
263 263
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 */
264#define AZX_ML_LCTL_CPA BIT(23)275#define AZX_ML_LCTL_CPA BIT(23)
265#define AZX_ML_LCTL_CPA_SHIFT 23276#define AZX_ML_LCTL_CPA_SHIFT 23
266#define AZX_ML_LCTL_SPA BIT(16)277#define AZX_ML_LCTL_SPA BIT(16)
267#define AZX_ML_LCTL_SPA_SHIFT 16278#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 */
269 282
270#define AZX_REG_ML_LOSIDV 0x08283#define AZX_REG_ML_LOSIDV 0x08
271 284
@@ -273,12 +286,35 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; · 1 unmodified line
273#define AZX_ML_LOSIDV_STREAM_MASK 0xFFFE286#define AZX_ML_LOSIDV_STREAM_MASK 0xFFFE
274 287
275#define AZX_REG_ML_LSDIID 0x0C288#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 */
276#define AZX_REG_ML_LPSOO 0x10292#define AZX_REG_ML_LPSOO 0x10
277#define AZX_REG_ML_LPSIO 0x12293#define AZX_REG_ML_LPSIO 0x12
278#define AZX_REG_ML_LWALFC 0x18294#define AZX_REG_ML_LWALFC 0x18
279#define AZX_REG_ML_LOUTPAY 0x20295#define AZX_REG_ML_LOUTPAY 0x20
280#define AZX_REG_ML_LINPAY 0x30296#define AZX_REG_ML_LINPAY 0x30
281 297
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
282/* registers for DMA Resume Capability Structure */318/* registers for DMA Resume Capability Structure */
283#define AZX_DRSM_CAP_ID 0x5319#define AZX_DRSM_CAP_ID 0x5
284#define AZX_REG_DRSM_CTL 0x4320#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
44 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))44 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
45 diff += runtime->boundary;45 diff += runtime->boundary;
46 if (diff < 0)46 if (diff < 0)
47 return -EINVAL;47 return -EPIPE;
48 rec->sw_ready += (int)frames_to_bytes(runtime, diff);48 rec->sw_ready += (int)frames_to_bytes(runtime, diff);
49 rec->appl_ptr = appl_ptr;49 rec->appl_ptr = appl_ptr;
50 }50 }
@@ -83,6 +83,8 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream, · 32 unmodified lines
83 struct snd_pcm_indirect *rec, unsigned int ptr)83 struct snd_pcm_indirect *rec, unsigned int ptr)
84{84{
85 int bytes = ptr - rec->hw_io;85 int bytes = ptr - rec->hw_io;
86 int err;
87
86 if (bytes < 0)88 if (bytes < 0)
87 bytes += rec->hw_buffer_size;89 bytes += rec->hw_buffer_size;
88 rec->hw_io = ptr;90 rec->hw_io = ptr;
@@ -90,8 +92,11 @@ snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream, · 1 unmodified line
90 rec->sw_io += bytes;92 rec->sw_io += bytes;
91 if (rec->sw_io >= rec->sw_buffer_size)93 if (rec->sw_io >= rec->sw_buffer_size)
92 rec->sw_io -= rec->sw_buffer_size;94 rec->sw_io -= rec->sw_buffer_size;
93 if (substream->ops->ack)95 if (substream->ops->ack) {
94 substream->ops->ack(substream);96 err = substream->ops->ack(substream);
97 if (err == -EPIPE)
98 return SNDRV_PCM_POS_XRUN;
99 }
95 return bytes_to_frames(substream->runtime, rec->sw_io);100 return bytes_to_frames(substream->runtime, rec->sw_io);
96}101}
97 102
@@ -112,7 +117,7 @@ snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream, · 14 unmodified lines
112 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))117 if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
113 diff += runtime->boundary;118 diff += runtime->boundary;
114 if (diff < 0)119 if (diff < 0)
115 return -EINVAL;120 return -EPIPE;
116 rec->sw_ready -= frames_to_bytes(runtime, diff);121 rec->sw_ready -= frames_to_bytes(runtime, diff);
117 rec->appl_ptr = appl_ptr;122 rec->appl_ptr = appl_ptr;
118 }123 }
@@ -152,6 +157,8 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream, · 33 unmodified lines
152{157{
153 int qsize;158 int qsize;
154 int bytes = ptr - rec->hw_io;159 int bytes = ptr - rec->hw_io;
160 int err;
161
155 if (bytes < 0)162 if (bytes < 0)
156 bytes += rec->hw_buffer_size;163 bytes += rec->hw_buffer_size;
157 rec->hw_io = ptr;164 rec->hw_io = ptr;
@@ -162,8 +169,11 @@ snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream, · 4 unmodified lines
162 rec->sw_io += bytes;169 rec->sw_io += bytes;
163 if (rec->sw_io >= rec->sw_buffer_size)170 if (rec->sw_io >= rec->sw_buffer_size)
164 rec->sw_io -= rec->sw_buffer_size;171 rec->sw_io -= rec->sw_buffer_size;
165 if (substream->ops->ack)172 if (substream->ops->ack) {
166 substream->ops->ack(substream);173 err = substream->ops->ack(substream);
174 if (err == -EPIPE)
175 return SNDRV_PCM_POS_XRUN;
176 }
167 return bytes_to_frames(substream->runtime, rec->sw_io);177 return bytes_to_frames(substream->runtime, rec->sw_io);
168}178}
169 179
include/sound/pcm.h+7−7
@@ -378,18 +378,18 @@ struct snd_pcm_runtime { · 377 unmodified lines
378 unsigned int rate_den;378 unsigned int rate_den;
379 unsigned int no_period_wakeup: 1;379 unsigned int no_period_wakeup: 1;
380 380
381 /* -- SW params -- */381 /* -- SW params; see struct snd_pcm_sw_params for comments -- */
382 int tstamp_mode; /* mmap timestamp is updated */382 int tstamp_mode;
383 unsigned int period_step;383 unsigned int period_step;
384 snd_pcm_uframes_t start_threshold;384 snd_pcm_uframes_t start_threshold;
385 snd_pcm_uframes_t stop_threshold;385 snd_pcm_uframes_t stop_threshold;
386 snd_pcm_uframes_t silence_threshold; /* Silence filling happens when386 snd_pcm_uframes_t silence_threshold;
387 noise is nearest than this */387 snd_pcm_uframes_t silence_size;
388 snd_pcm_uframes_t silence_size; /* Silence filling size */388 snd_pcm_uframes_t boundary;
389 snd_pcm_uframes_t boundary; /* pointers wrap point */
390 389
390 /* internal data of auto-silencer */
391 snd_pcm_uframes_t silence_start; /* starting pointer to silence area */391 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 */
393 393
394 union snd_pcm_sync_id sync; /* hardware synchronization ID */394 union snd_pcm_sync_id sync; /* hardware synchronization ID */
395 395
include/sound/soc-card.h+16−1
@@ -9,10 +9,25 @@ · 8 unmodified lines
9#define __SOC_CARD_H9#define __SOC_CARD_H
10 10
11enum snd_soc_card_subclass {11enum snd_soc_card_subclass {
12 SND_SOC_CARD_CLASS_INIT = 0,12 SND_SOC_CARD_CLASS_ROOT = 0,
13 SND_SOC_CARD_CLASS_RUNTIME = 1,13 SND_SOC_CARD_CLASS_RUNTIME = 1,
14};14};
15 15
16static 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
21static 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
26static inline void snd_soc_card_mutex_unlock(struct snd_soc_card *card)
27{
28 mutex_unlock(&card->mutex);
29}
30
16struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,31struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
17 const char *name);32 const char *name);
18int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,33int 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
527 SND_SOC_DAPM_TYPE_COUNT527 SND_SOC_DAPM_TYPE_COUNT
528};528};
529 529
530enum snd_soc_dapm_subclass {
531 SND_SOC_DAPM_CLASS_INIT = 0,
532 SND_SOC_DAPM_CLASS_RUNTIME = 1,
533};
534
535/*530/*
536 * DAPM audio route definition.531 * DAPM audio route definition.
537 *532 *
include/sound/soc-dpcm.h+0−1
@@ -91,7 +91,6 @@ struct snd_soc_dpcm_runtime { · 90 unmodified lines
91 struct list_head fe_clients;91 struct list_head fe_clients;
92 92
93 int users;93 int users;
94 struct snd_pcm_runtime *runtime;
95 struct snd_pcm_hw_params hw_params;94 struct snd_pcm_hw_params hw_params;
96 95
97 /* state and update */96 /* state and update */
include/sound/soc.h+109−10
@@ -684,8 +684,11 @@ struct snd_soc_dai_link { · 683 unmodified lines
684 684
685 int id; /* optional ID for machine driver link identification */685 int id; /* optional ID for machine driver link identification */
686 686
687 const struct snd_soc_pcm_stream *params;687 /*
688 unsigned int num_params;688 * for Codec2Codec
689 */
690 const struct snd_soc_pcm_stream *c2c_params;
691 unsigned int num_c2c_params;
689 692
690 unsigned int dai_fmt; /* format to set on init */693 unsigned int dai_fmt; /* format to set on init */
691 694
@@ -1065,7 +1068,7 @@ struct snd_soc_pcm_runtime { · 373 unmodified lines
1065 struct snd_soc_dai_link *dai_link;1068 struct snd_soc_dai_link *dai_link;
1066 struct snd_pcm_ops ops;1069 struct snd_pcm_ops ops;
1067 1070
1068 unsigned int params_select; /* currently selected param for dai link */1071 unsigned int c2c_params_select; /* currently selected c2c_param for dai link */
1069 1072
1070 /* Dynamic PCM BE runtime data */1073 /* Dynamic PCM BE runtime data */
1071 struct snd_soc_dpcm_runtime dpcm[SNDRV_PCM_STREAM_LAST + 1];1074 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
1302 struct snd_soc_dai_link *dai_link);1305 struct snd_soc_dai_link *dai_link);
1303void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link);1306void snd_soc_of_put_dai_link_cpus(struct snd_soc_dai_link *dai_link);
1304 1307
1305int snd_soc_add_pcm_runtime(struct snd_soc_card *card,1308int snd_soc_add_pcm_runtimes(struct snd_soc_card *card,
1306 struct snd_soc_dai_link *dai_link);1309 struct snd_soc_dai_link *dai_link,
1310 int num_dai_link);
1307void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,1311void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
1308 struct snd_soc_pcm_runtime *rtd);1312 struct snd_soc_pcm_runtime *rtd);
1309 1313
@@ -1360,17 +1364,112 @@ extern struct dentry *snd_soc_debugfs_root; · 50 unmodified lines
1360 1364
1361extern const struct dev_pm_ops snd_soc_pm_ops;1365extern const struct dev_pm_ops snd_soc_pm_ops;
1362 1366
1363/* Helper functions */1367/*
1364static inline void snd_soc_dapm_mutex_lock(struct snd_soc_dapm_context *dapm)1368 * DAPM helper functions
1369 */
1370enum snd_soc_dapm_subclass {
1371 SND_SOC_DAPM_CLASS_ROOT = 0,
1372 SND_SOC_DAPM_CLASS_RUNTIME = 1,
1373};
1374
1375static 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
1380static 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
1385static inline void _snd_soc_dapm_mutex_unlock_c(struct snd_soc_card *card)
1386{
1387 mutex_unlock(&card->dapm_mutex);
1388}
1389
1390static inline void _snd_soc_dapm_mutex_assert_held_c(struct snd_soc_card *card)
1391{
1392 lockdep_assert_held(&card->dapm_mutex);
1393}
1394
1395static 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
1400static 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
1405static inline void _snd_soc_dapm_mutex_unlock_d(struct snd_soc_dapm_context *dapm)
1365{1406{
1366 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);1407 _snd_soc_dapm_mutex_unlock_c(dapm->card);
1367}1408}
1368 1409
1369static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)1410static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context *dapm)
1370{1411{
1371 mutex_unlock(&dapm->card->dapm_mutex);1412 _snd_soc_dapm_mutex_assert_held_c(dapm->card);
1372}1413}
1373 1414
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 */
1431static 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
1436static inline void _snd_soc_dpcm_mutex_unlock_c(struct snd_soc_card *card)
1437{
1438 mutex_unlock(&card->pcm_mutex);
1439}
1440
1441static inline void _snd_soc_dpcm_mutex_assert_held_c(struct snd_soc_card *card)
1442{
1443 lockdep_assert_held(&card->pcm_mutex);
1444}
1445
1446static 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
1451static 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
1456static 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
1374#include <sound/soc-component.h>1473#include <sound/soc-component.h>
1375#include <sound/soc-card.h>1474#include <sound/soc-card.h>
1376#include <sound/soc-jack.h>1475#include <sound/soc-jack.h>
include/sound/sof.h+5−0
@@ -21,6 +21,7 @@ struct snd_sof_dev; · 20 unmodified lines
21/**21/**
22 * enum sof_fw_state - DSP firmware state definitions22 * enum sof_fw_state - DSP firmware state definitions
23 * @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started23 * @SOF_FW_BOOT_NOT_STARTED: firmware boot is not yet started
24 * @SOF_DSPLESS_MODE: DSP is not used
24 * @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple)25 * @SOF_FW_BOOT_PREPARE: preparing for boot (firmware loading for exaqmple)
25 * @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress26 * @SOF_FW_BOOT_IN_PROGRESS: firmware boot is in progress
26 * @SOF_FW_BOOT_FAILED: firmware boot failed27 * @SOF_FW_BOOT_FAILED: firmware boot failed
@@ -31,6 +32,7 @@ struct snd_sof_dev; · 4 unmodified lines
31 */32 */
32enum sof_fw_state {33enum sof_fw_state {
33 SOF_FW_BOOT_NOT_STARTED = 0,34 SOF_FW_BOOT_NOT_STARTED = 0,
35 SOF_DSPLESS_MODE,
34 SOF_FW_BOOT_PREPARE,36 SOF_FW_BOOT_PREPARE,
35 SOF_FW_BOOT_IN_PROGRESS,37 SOF_FW_BOOT_IN_PROGRESS,
36 SOF_FW_BOOT_FAILED,38 SOF_FW_BOOT_FAILED,
@@ -130,6 +132,9 @@ struct sof_dev_desc { · 93 unmodified lines
130 unsigned int ipc_supported_mask;132 unsigned int ipc_supported_mask;
131 enum sof_ipc_type ipc_default;133 enum sof_ipc_type ipc_default;
132 134
135 /* The platform supports DSPless mode */
136 bool dspless_mode_supported;
137
133 /* defaults paths for firmware, library and topology files */138 /* defaults paths for firmware, library and topology files */
134 const char *default_fw_path[SOF_IPC_TYPE_COUNT];139 const char *default_fw_path[SOF_IPC_TYPE_COUNT];
135 const char *default_lib_path[SOF_IPC_TYPE_COUNT];140 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
176#define SOF_IPC4_GLB_PIPE_EXT_LP_MASK BIT(0)176#define SOF_IPC4_GLB_PIPE_EXT_LP_MASK BIT(0)
177#define SOF_IPC4_GLB_PIPE_EXT_LP(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_LP_SHIFT)177#define SOF_IPC4_GLB_PIPE_EXT_LP(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_LP_SHIFT)
178 178
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
179/* pipeline set state ipc msg */183/* pipeline set state ipc msg */
180#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16184#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
181#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)185#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
@@ -192,6 +196,35 @@ enum sof_ipc4_pipeline_state { · 10 unmodified lines
192#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16196#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16
193#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT)197#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT)
194 198
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
195enum sof_ipc4_channel_config {228enum sof_ipc4_channel_config {
196 /* one channel only. */229 /* one channel only. */
197 SOF_IPC4_CHANNEL_CONFIG_MONO,230 SOF_IPC4_CHANNEL_CONFIG_MONO,
include/uapi/sound/asound.h+10−4
@@ -429,9 +429,14 @@ struct snd_pcm_sw_params { · 428 unmodified lines
429 snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */429 snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */
430 snd_pcm_uframes_t xfer_align; /* obsolete: xfer size need to be a multiple */430 snd_pcm_uframes_t xfer_align; /* obsolete: xfer size need to be a multiple */
431 snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */431 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 */432 /*
433 snd_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */433 * The following two thresholds alleviate playback buffer underruns; when
434 snd_pcm_uframes_t silence_size; /* silence block size */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 */
435 snd_pcm_uframes_t boundary; /* pointers wrap point */440 snd_pcm_uframes_t boundary; /* pointers wrap point */
436 unsigned int proto; /* protocol version */441 unsigned int proto; /* protocol version */
437 unsigned int tstamp_type; /* timestamp type (req. proto >= 2.0.12) */442 unsigned int tstamp_type; /* timestamp type (req. proto >= 2.0.12) */
@@ -570,7 +575,8 @@ struct __snd_pcm_mmap_status64 { · 132 unmodified lines
570struct __snd_pcm_mmap_control64 {575struct __snd_pcm_mmap_control64 {
571 __pad_before_uframe __pad1;576 __pad_before_uframe __pad1;
572 snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */577 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.
574 580
575 __pad_before_uframe __pad3;581 __pad_before_uframe __pad3;
576 snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */582 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
15 * ---- FX8010 ----15 * ---- FX8010 ----
16 */16 */
17 17
18#define EMU10K1_CARD_CREATIVE 0x00000000
19#define EMU10K1_CARD_EMUAPS 0x00000001
20
21#define EMU10K1_FX8010_PCM_COUNT 818#define EMU10K1_FX8010_PCM_COUNT 8
22 19
23/*20/*
@@ -46,6 +43,19 @@ · 22 unmodified lines
46#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */43#define iINTERP 0x0e /* R = A + (X * (Y - A) >> 31) ; saturation */
47#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */44#define iSKIP 0x0f /* R = A (cc_reg), X (count), Y (cc_test) */
48 45
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
49/* GPRs */59/* GPRs */
50#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */60#define FXBUS(x) (0x00 + (x)) /* x = 0x00 - 0x0f */
51#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */61#define EXTIN(x) (0x10 + (x)) /* x = 0x00 - 0x0f */
@@ -53,6 +63,16 @@ · 1 unmodified line
53#define FXBUS2(x) (0x30 + (x)) /* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */63#define FXBUS2(x) (0x30 + (x)) /* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */
54 /* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */64 /* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */
55 65
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
56#define C_00000000 0x4076#define C_00000000 0x40
57#define C_00000001 0x4177#define C_00000001 0x41
58#define C_00000002 0x4278#define C_00000002 0x42
@@ -81,12 +101,66 @@ · 22 unmodified lines
81#define GPR_NOISE1 0x59 /* noise source */101#define GPR_NOISE1 0x59 /* noise source */
82#define GPR_IRQ 0x5a /* IRQ register */102#define GPR_IRQ 0x5a /* IRQ register */
83#define GPR_DBAC 0x5b /* TRAM Delay Base Address Counter */103#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
84#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */157#define GPR(x) (FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
85#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */158#define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
86#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */159#define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
87#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */160#define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
88#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */161#define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
89 162
163#define A_GPR(x) (A_FXGPREGBASE + (x))
90#define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */164#define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
91#define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */165#define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
92#define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */166#define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
@@ -94,17 +168,6 @@ · 1 unmodified line
94#define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */168#define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
95#define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */169#define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
96 170
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
108/* cc_reg constants */171/* cc_reg constants */
109#define CC_REG_NORMALIZED C_00000001172#define CC_REG_NORMALIZED C_00000001
110#define CC_REG_BORROW C_00000002173#define CC_REG_BORROW C_00000002
@@ -113,7 +176,17 @@ · 2 unmodified lines
113#define CC_REG_SATURATE C_00000010176#define CC_REG_SATURATE C_00000010
114#define CC_REG_NONZERO C_00000100177#define CC_REG_NONZERO C_00000100
115 178
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
116/* FX buses */186/* 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.
117#define FXBUS_PCM_LEFT 0x00190#define FXBUS_PCM_LEFT 0x00
118#define FXBUS_PCM_RIGHT 0x01191#define FXBUS_PCM_RIGHT 0x01
119#define FXBUS_PCM_LEFT_REAR 0x02192#define FXBUS_PCM_LEFT_REAR 0x02
@@ -203,38 +276,7 @@ · 83 unmodified lines
203#define A_EXTOUT_ADC_CAP_R 0x17 /* right */276#define A_EXTOUT_ADC_CAP_R 0x17 /* right */
204#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */277#define A_EXTOUT_MIC_CAP 0x18 /* Mic capture buffer */
205 278
206/* Audigy constants */279/* Definitions for debug register. Note that these are for emu10k1 ONLY. */
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 */
238#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */280#define EMU10K1_DBG_ZC 0x80000000 /* zero tram counter */
239#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */281#define EMU10K1_DBG_SATURATION_OCCURED 0x02000000 /* saturation control */
240#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */282#define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000 /* saturation address */
@@ -243,14 +285,14 @@ · 2 unmodified lines
243#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */285#define EMU10K1_DBG_CONDITION_CODE 0x00003e00 /* condition code */
244#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */286#define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */
245 287
246/* tank memory address line */288/* Definitions for emu10k2 debug register. */
247#ifndef __KERNEL__289#define A_DBG_ZC 0x40000000 /* zero tram counter */
248#define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */290#define A_DBG_SATURATION_OCCURED 0x20000000
249#define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */291#define A_DBG_SATURATION_ADDR 0x0ffc0000
250#define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */292#define A_DBG_SINGLE_STEP 0x00020000 /* Set to zero to start dsp */
251#define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */293#define A_DBG_STEP 0x00010000
252#define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */294#define A_DBG_CONDITION_CODE 0x0000f800
253#endif295#define A_DBG_STEP_ADDR 0x000003ff
254 296
255struct snd_emu10k1_fx8010_info {297struct snd_emu10k1_fx8010_info {
256 unsigned int internal_tram_size; /* in samples */298 unsigned int internal_tram_size; /* in samples */
include/uapi/sound/sof/abi.h+2−0
@@ -60,5 +60,7 @@ · 59 unmodified lines
60 60
61/* SOF ABI magic number "SOF\0". */61/* SOF ABI magic number "SOF\0". */
62#define SOF_ABI_MAGIC 0x00464F5362#define SOF_ABI_MAGIC 0x00464F53
63/* SOF IPC4 ABI magic number "SOF4". */
64#define SOF_IPC4_ABI_MAGIC 0x34464F53
63 65
64#endif66#endif
include/uapi/sound/sof/header.h+19−8
@@ -11,19 +11,30 @@ · 10 unmodified lines
11 11
12#include <linux/types.h>12#include <linux/types.h>
13 13
14/*14/**
15 * Header for all non IPC ABI data.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
16 *27 *
17 * Identifies data type, size and ABI.28 * Identifies data type, size and ABI.
18 * Used by any bespoke component data structures or binary blobs.29 * Used by any bespoke component data structures or binary blobs.
19 */30 */
20struct sof_abi_hdr {31struct sof_abi_hdr {
21 __u32 magic; /**< 'S', 'O', 'F', '\0' */32 __u32 magic;
22 __u32 type; /**< component specific type */33 __u32 type;
23 __u32 size; /**< size in bytes of data excl. this struct */34 __u32 size;
24 __u32 abi; /**< SOF ABI version */35 __u32 abi;
25 __u32 reserved[4]; /**< reserved for future use */36 __u32 reserved[4];
26 __u32 data[]; /**< Component data - opaque to core */37 __u32 data[];
27} __packed;38} __packed;
28 39
29#define SOF_MANIFEST_DATA_TYPE_NHLT 140#define SOF_MANIFEST_DATA_TYPE_NHLT 1
include/uapi/sound/sof/tokens.h+13−8
@@ -54,6 +54,7 @@ · 53 unmodified lines
54#define SOF_TKN_SCHED_DYNAMIC_PIPELINE 20654#define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
55#define SOF_TKN_SCHED_LP_MODE 20755#define SOF_TKN_SCHED_LP_MODE 207
56#define SOF_TKN_SCHED_MEM_USAGE 20856#define SOF_TKN_SCHED_MEM_USAGE 208
57#define SOF_TKN_SCHED_USE_CHAIN_DMA 209
57 58
58/* volume */59/* volume */
59#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 25060#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
@@ -88,14 +89,16 @@ · 28 unmodified lines
88#define SOF_TKN_COMP_CPC 40689#define SOF_TKN_COMP_CPC 406
89#define SOF_TKN_COMP_IS_PAGES 40990#define SOF_TKN_COMP_IS_PAGES 409
90#define SOF_TKN_COMP_NUM_AUDIO_FORMATS 41091#define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410
91#define SOF_TKN_COMP_NUM_SINK_PINS 41192#define SOF_TKN_COMP_NUM_INPUT_PINS 411
92#define SOF_TKN_COMP_NUM_SOURCE_PINS 41293#define SOF_TKN_COMP_NUM_OUTPUT_PINS 412
93/*94/*
94 * The token for sink/source pin binding, it specifies the widget95 * The token for input/output pin binding, it specifies the widget
95 * name that the sink/source pin is connected from/to.96 * name that the input/output pin is connected from/to.
96 */97 */
97#define SOF_TKN_COMP_SINK_PIN_BINDING_WNAME 41398#define SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME 413
98#define SOF_TKN_COMP_SRC_PIN_BINDING_WNAME 41499#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
99 102
100 103
101/* SSP */104/* SSP */
@@ -173,17 +176,18 @@ · 71 unmodified lines
173/* CAVS AUDIO FORMAT */176/* CAVS AUDIO FORMAT */
174#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900177#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900
175#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901178#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901
176#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902179#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT_DEPTH 1902
177#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903180#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903
178#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904181#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904
179#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905182#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905
180#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906183#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906
181#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907184#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907
182#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908185#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908
186#define SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX 1909
183/* intentional token numbering discontinuity, reserved for future use */187/* intentional token numbering discontinuity, reserved for future use */
184#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930188#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930
185#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931189#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931
186#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932190#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT_DEPTH 1932
187#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933191#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933
188#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934192#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934
189#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935193#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935
@@ -197,6 +201,7 @@ · 7 unmodified lines
197 201
198/* COPIER */202/* COPIER */
199#define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980203#define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980
204#define SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS 1981
200 205
201/* ACP I2S */206/* ACP I2S */
202#define SOF_TKN_AMD_ACPI2S_RATE 1700207#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
75}75}
76EXPORT_SYMBOL_GPL(snd_ac97_reset);76EXPORT_SYMBOL_GPL(snd_ac97_reset);
77 77
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 */
83static int ac97_bus_match(struct device *dev, struct device_driver *drv)
84{
85 return 1;
86}
87
88struct bus_type ac97_bus_type = {78struct bus_type ac97_bus_type = {
89 .name = "ac97",79 .name = "ac97",
90 .match = ac97_bus_match,
91};80};
92 81
93static int __init ac97_bus_init(void)82static int __init ac97_bus_init(void)
sound/arm/pxa2xx-ac97.c+2−4
@@ -262,7 +262,7 @@ err_dev: · 261 unmodified lines
262 return ret;262 return ret;
263}263}
264 264
265static int pxa2xx_ac97_remove(struct platform_device *dev)265static void pxa2xx_ac97_remove(struct platform_device *dev)
266{266{
267 struct snd_card *card = platform_get_drvdata(dev);267 struct snd_card *card = platform_get_drvdata(dev);
268 268
@@ -270,13 +270,11 @@ static int pxa2xx_ac97_remove(struct platform_device *dev) · 1 unmodified line
270 snd_card_free(card);270 snd_card_free(card);
271 pxa2xx_ac97_hw_remove(dev);271 pxa2xx_ac97_hw_remove(dev);
272 }272 }
273
274 return 0;
275}273}
276 274
277static struct platform_driver pxa2xx_ac97_driver = {275static struct platform_driver pxa2xx_ac97_driver = {
278 .probe = pxa2xx_ac97_probe,276 .probe = pxa2xx_ac97_probe,
279 .remove = pxa2xx_ac97_remove,277 .remove_new = pxa2xx_ac97_remove,
280 .driver = {278 .driver = {
281 .name = "pxa2xx-ac97",279 .name = "pxa2xx-ac97",
282#ifdef CONFIG_PM_SLEEP280#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
843#define ATMEL_AC97C_PM_OPS NULL843#define ATMEL_AC97C_PM_OPS NULL
844#endif844#endif
845 845
846static int atmel_ac97c_remove(struct platform_device *pdev)846static void atmel_ac97c_remove(struct platform_device *pdev)
847{847{
848 struct snd_card *card = platform_get_drvdata(pdev);848 struct snd_card *card = platform_get_drvdata(pdev);
849 struct atmel_ac97c *chip = get_chip(card);849 struct atmel_ac97c *chip = get_chip(card);
@@ -858,13 +858,11 @@ static int atmel_ac97c_remove(struct platform_device *pdev) · 8 unmodified lines
858 free_irq(chip->irq, chip);858 free_irq(chip->irq, chip);
859 859
860 snd_card_free(card);860 snd_card_free(card);
861
862 return 0;
863}861}
864 862
865static struct platform_driver atmel_ac97c_driver = {863static struct platform_driver atmel_ac97c_driver = {
866 .probe = atmel_ac97c_probe,864 .probe = atmel_ac97c_probe,
867 .remove = atmel_ac97c_remove,865 .remove_new = atmel_ac97c_remove,
868 .driver = {866 .driver = {
869 .name = "atmel_ac97c",867 .name = "atmel_ac97c",
870 .pm = ATMEL_AC97C_PM_OPS,868 .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
42 *42 *
43 * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately43 * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
44 */44 */
45void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)45void snd_pcm_playback_silence(struct snd_pcm_substream *substream)
46{46{
47 struct snd_pcm_runtime *runtime = substream->runtime;47 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;
49 int err;51 int err;
50 52
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;
51 if (runtime->silence_size < runtime->boundary) {72 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;
69 frames = runtime->silence_threshold - noise_dist;73 frames = runtime->silence_threshold - noise_dist;
74 if (frames <= 0)
75 return;
70 if (frames > runtime->silence_size)76 if (frames > runtime->silence_size)
71 frames = runtime->silence_size;77 frames = runtime->silence_size;
72 } else {78 } else {
73 if (new_hw_ptr == ULONG_MAX) { /* initialization */79 frames = runtime->buffer_size - noise_dist;
74 snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);80 if (frames <= 0)
75 if (avail > runtime->buffer_size)81 return;
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;
95 }82 }
83
96 if (snd_BUG_ON(frames > runtime->buffer_size))84 if (snd_BUG_ON(frames > runtime->buffer_size))
97 return;85 return;
98 if (frames == 0)86 ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size;
99 return;87 do {
100 ofs = runtime->silence_start % runtime->buffer_size;
101 while (frames > 0) {
102 transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;88 transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
103 err = fill_silence_frames(substream, ofs, transfer);89 err = fill_silence_frames(substream, ofs, transfer);
104 snd_BUG_ON(err < 0);90 snd_BUG_ON(err < 0);
105 runtime->silence_filled += transfer;91 runtime->silence_filled += transfer;
106 frames -= transfer;92 frames -= transfer;
107 ofs = 0;93 ofs = 0;
108 }94 } while (frames > 0);
109 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);95 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
110}96}
111 97
@@ -439,10 +425,6 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 327 unmodified lines
439 return 0;425 return 0;
440 }426 }
441 427
442 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
443 runtime->silence_size > 0)
444 snd_pcm_playback_silence(substream, new_hw_ptr);
445
446 if (in_interrupt) {428 if (in_interrupt) {
447 delta = new_hw_ptr - runtime->hw_ptr_interrupt;429 delta = new_hw_ptr - runtime->hw_ptr_interrupt;
448 if (delta < 0)430 if (delta < 0)
@@ -460,6 +442,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, · 11 unmodified lines
460 runtime->hw_ptr_wrap += runtime->boundary;442 runtime->hw_ptr_wrap += runtime->boundary;
461 }443 }
462 444
445 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
446 runtime->silence_size > 0)
447 snd_pcm_playback_silence(substream);
448
463 update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);449 update_audio_tstamp(substream, &curr_tstamp, &audio_tstamp);
464 450
465 return snd_pcm_update_state(substream, runtime);451 return snd_pcm_update_state(substream, runtime);
@@ -1878,15 +1864,14 @@ static int wait_for_avail(struct snd_pcm_substream *substream, · 1412 unmodified lines
1878 if (substream->wait_time) {1864 if (substream->wait_time) {
1879 wait_time = substream->wait_time;1865 wait_time = substream->wait_time;
1880 } else {1866 } else {
1881 wait_time = 10;1867 wait_time = 100;
1882 1868
1883 if (runtime->rate) {1869 if (runtime->rate) {
1884 long t = runtime->period_size * 2 /1870 long t = runtime->buffer_size * 1100 / runtime->rate;
1885 runtime->rate;
1886 wait_time = max(t, wait_time);1871 wait_time = max(t, wait_time);
1887 }1872 }
1888 wait_time = msecs_to_jiffies(wait_time * 1000);
1889 }1873 }
1874 wait_time = msecs_to_jiffies(wait_time);
1890 }1875 }
1891 1876
1892 for (;;) {1877 for (;;) {
@@ -1934,8 +1919,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream, · 41 unmodified lines
1934 }1919 }
1935 if (!tout) {1920 if (!tout) {
1936 pcm_dbg(substream->pcm,1921 pcm_dbg(substream->pcm,
1937 "%s write error (DMA or IRQ trouble?)\n",1922 "%s timeout (DMA or IRQ trouble?)\n",
1938 is_playback ? "playback" : "capture");1923 is_playback ? "playback write" : "capture read");
1939 err = -EIO;1924 err = -EIO;
1940 break;1925 break;
1941 }1926 }
sound/core/pcm_local.h+1−2
@@ -29,8 +29,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, · 28 unmodified lines
29 struct snd_pcm_runtime *runtime);29 struct snd_pcm_runtime *runtime);
30int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);30int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
31 31
32void snd_pcm_playback_silence(struct snd_pcm_substream *substream,32void snd_pcm_playback_silence(struct snd_pcm_substream *substream);
33 snd_pcm_uframes_t new_hw_ptr);
34 33
35static inline snd_pcm_uframes_t34static inline snd_pcm_uframes_t
36snd_pcm_avail(struct snd_pcm_substream *substream)35snd_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
958 if (snd_pcm_running(substream)) {958 if (snd_pcm_running(substream)) {
959 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&959 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
960 runtime->silence_size > 0)960 runtime->silence_size > 0)
961 snd_pcm_playback_silence(substream, ULONG_MAX);961 snd_pcm_playback_silence(substream);
962 err = snd_pcm_update_state(substream, runtime);962 err = snd_pcm_update_state(substream, runtime);
963 }963 }
964 snd_pcm_stream_unlock_irq(substream);964 snd_pcm_stream_unlock_irq(substream);
@@ -1455,7 +1455,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, · 490 unmodified lines
1455 __snd_pcm_set_state(runtime, state);1455 __snd_pcm_set_state(runtime, state);
1456 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&1456 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1457 runtime->silence_size > 0)1457 runtime->silence_size > 0)
1458 snd_pcm_playback_silence(substream, ULONG_MAX);1458 snd_pcm_playback_silence(substream);
1459 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);1459 snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MSTART);
1460}1460}
1461 1461
@@ -1916,7 +1916,7 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream, · 454 unmodified lines
1916 runtime->control->appl_ptr = runtime->status->hw_ptr;1916 runtime->control->appl_ptr = runtime->status->hw_ptr;
1917 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&1917 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1918 runtime->silence_size > 0)1918 runtime->silence_size > 0)
1919 snd_pcm_playback_silence(substream, ULONG_MAX);1919 snd_pcm_playback_silence(substream);
1920 snd_pcm_stream_unlock_irq(substream);1920 snd_pcm_stream_unlock_irq(substream);
1921}1921}
1922 1922
@@ -2159,12 +2159,12 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, · 236 unmodified lines
2159 if (runtime->no_period_wakeup)2159 if (runtime->no_period_wakeup)
2160 tout = MAX_SCHEDULE_TIMEOUT;2160 tout = MAX_SCHEDULE_TIMEOUT;
2161 else {2161 else {
2162 tout = 10;2162 tout = 100;
2163 if (runtime->rate) {2163 if (runtime->rate) {
2164 long t = runtime->period_size * 2 / runtime->rate;2164 long t = runtime->buffer_size * 1100 / runtime->rate;
2165 tout = max(t, tout);2165 tout = max(t, tout);
2166 }2166 }
2167 tout = msecs_to_jiffies(tout * 1000);2167 tout = msecs_to_jiffies(tout);
2168 }2168 }
2169 tout = schedule_timeout(tout);2169 tout = schedule_timeout(tout);
2170 2170
@@ -2187,7 +2187,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, · 16 unmodified lines
2187 result = -ESTRPIPE;2187 result = -ESTRPIPE;
2188 else {2188 else {
2189 dev_dbg(substream->pcm->card->dev,2189 dev_dbg(substream->pcm->card->dev,
2190 "playback drain error (DMA or IRQ trouble?)\n");2190 "playback drain timeout (DMA or IRQ trouble?)\n");
2191 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);2191 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
2192 result = -EIO;2192 result = -EIO;
2193 }2193 }
sound/drivers/mts64.c+2−4
@@ -999,19 +999,17 @@ __err: · 998 unmodified lines
999 return err;999 return err;
1000}1000}
1001 1001
1002static int snd_mts64_remove(struct platform_device *pdev)1002static void snd_mts64_remove(struct platform_device *pdev)
1003{1003{
1004 struct snd_card *card = platform_get_drvdata(pdev);1004 struct snd_card *card = platform_get_drvdata(pdev);
1005 1005
1006 if (card)1006 if (card)
1007 snd_card_free(card);1007 snd_card_free(card);
1008
1009 return 0;
1010}1008}
1011 1009
1012static struct platform_driver snd_mts64_driver = {1010static struct platform_driver snd_mts64_driver = {
1013 .probe = snd_mts64_probe,1011 .probe = snd_mts64_probe,
1014 .remove = snd_mts64_remove,1012 .remove_new = snd_mts64_remove,
1015 .driver = {1013 .driver = {
1016 .name = PLATFORM_DRIVER,1014 .name = PLATFORM_DRIVER,
1017 }1015 }
sound/drivers/portman2x4.c+2−14
@@ -182,21 +182,11 @@ static inline void portman_write_command(struct portman *pm, u8 value) · 181 unmodified lines
182 parport_write_control(pm->pardev->port, value);182 parport_write_control(pm->pardev->port, value);
183}183}
184 184
185static inline u8 portman_read_command(struct portman *pm)
186{
187 return parport_read_control(pm->pardev->port);
188}
189
190static inline u8 portman_read_status(struct portman *pm)185static inline u8 portman_read_status(struct portman *pm)
191{186{
192 return parport_read_status(pm->pardev->port);187 return parport_read_status(pm->pardev->port);
193}188}
194 189
195static inline u8 portman_read_data(struct portman *pm)
196{
197 return parport_read_data(pm->pardev->port);
198}
199
200static inline void portman_write_data(struct portman *pm, u8 value)190static inline void portman_write_data(struct portman *pm, u8 value)
201{191{
202 parport_write_data(pm->pardev->port, value);192 parport_write_data(pm->pardev->port, value);
@@ -795,20 +785,18 @@ __err: · 592 unmodified lines
795 return err;785 return err;
796}786}
797 787
798static int snd_portman_remove(struct platform_device *pdev)788static void snd_portman_remove(struct platform_device *pdev)
799{789{
800 struct snd_card *card = platform_get_drvdata(pdev);790 struct snd_card *card = platform_get_drvdata(pdev);
801 791
802 if (card)792 if (card)
803 snd_card_free(card);793 snd_card_free(card);
804
805 return 0;
806}794}
807 795
808 796
809static struct platform_driver snd_portman_driver = {797static struct platform_driver snd_portman_driver = {
810 .probe = snd_portman_probe,798 .probe = snd_portman_probe,
811 .remove = snd_portman_remove,799 .remove_new = snd_portman_remove,
812 .driver = {800 .driver = {
813 .name = PLATFORM_DRIVER,801 .name = PLATFORM_DRIVER,
814 }802 }
sound/mips/hal2.c+2−3
@@ -877,17 +877,16 @@ static int hal2_probe(struct platform_device *pdev) · 876 unmodified lines
877 return 0;877 return 0;
878}878}
879 879
880static int hal2_remove(struct platform_device *pdev)880static void hal2_remove(struct platform_device *pdev)
881{881{
882 struct snd_card *card = platform_get_drvdata(pdev);882 struct snd_card *card = platform_get_drvdata(pdev);
883 883
884 snd_card_free(card);884 snd_card_free(card);
885 return 0;
886}885}
887 886
888static struct platform_driver hal2_driver = {887static struct platform_driver hal2_driver = {
889 .probe = hal2_probe,888 .probe = hal2_probe,
890 .remove = hal2_remove,889 .remove_new = hal2_remove,
891 .driver = {890 .driver = {
892 .name = "sgihal2",891 .name = "sgihal2",
893 }892 }
sound/mips/sgio2audio.c+2−3
@@ -908,17 +908,16 @@ static int snd_sgio2audio_probe(struct platform_device *pdev) · 907 unmodified lines
908 return 0;908 return 0;
909}909}
910 910
911static int snd_sgio2audio_remove(struct platform_device *pdev)911static void snd_sgio2audio_remove(struct platform_device *pdev)
912{912{
913 struct snd_card *card = platform_get_drvdata(pdev);913 struct snd_card *card = platform_get_drvdata(pdev);
914 914
915 snd_card_free(card);915 snd_card_free(card);
916 return 0;
917}916}
918 917
919static struct platform_driver sgio2audio_driver = {918static struct platform_driver sgio2audio_driver = {
920 .probe = snd_sgio2audio_probe,919 .probe = snd_sgio2audio_probe,
921 .remove = snd_sgio2audio_remove,920 .remove_new = snd_sgio2audio_remove,
922 .driver = {921 .driver = {
923 .name = "sgio2audio",922 .name = "sgio2audio",
924 }923 }
sound/pci/Kconfig+2−2
@@ -461,7 +461,7 @@ config SND_INDIGODJX · 460 unmodified lines
461 will be called snd-indigodjx461 will be called snd-indigodjx
462 462
463config SND_EMU10K1463config 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)"
465 select FW_LOADER465 select FW_LOADER
466 select SND_HWDEP466 select SND_HWDEP
467 select SND_RAWMIDI467 select SND_RAWMIDI
@@ -471,7 +471,7 @@ config SND_EMU10K1 · 3 unmodified lines
471 depends on ZONE_DMA471 depends on ZONE_DMA
472 help472 help
473 Say Y to include support for Sound Blaster PCI 512, Live!,473 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.
475 475
476 The confusing multitude of mixer controls is documented in476 The confusing multitude of mixer controls is documented in
477 <file:Documentation/sound/cards/sb-live-mixer.rst> and477 <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
1253 int local_count = count;1253 int local_count = count;
1254 int xfer_size;1254 int xfer_size;
1255 u32 *pdata = dest;1255 u32 *pdata = dest;
1256 u32 loop_count = 0;
1257 1256
1258 while (local_count) {1257 while (local_count) {
1259 if (local_count > c6711_burst_size)1258 if (local_count > c6711_burst_size)
@@ -1273,7 +1272,6 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, · 13 unmodified lines
1273 pdata += xfer_size;1272 pdata += xfer_size;
1274 local_hpi_address += sizeof(u32) * xfer_size;1273 local_hpi_address += sizeof(u32) * xfer_size;
1275 local_count -= xfer_size;1274 local_count -= xfer_size;
1276 loop_count++;
1277 }1275 }
1278 1276
1279 if (time_out)1277 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
68 { 0, }68 { 0, }
69};69};
70 70
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
82MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);71MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
83 72
84static int snd_card_emu10k1_probe(struct pci_dev *pci,73static 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
531static void531static void
532set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)532set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
533{533{
534 unsigned int val;534 snd_emu10k1_ptr_write(hw, CCCA_RESONANCE, vp->ch, vp->reg.parm.filterQ);
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);
538}535}
sound/pci/emu10k1/emu10k1_main.c+97−159
@@ -140,7 +140,7 @@ static const unsigned int i2c_adc_init[][2] = { · 139 unmodified lines
140 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */140 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
141};141};
142 142
143static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)143static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir)
144{144{
145 unsigned int silent_page;145 unsigned int silent_page;
146 int ch;146 int ch;
@@ -162,6 +162,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 15 unmodified lines
162 outl(0, emu->port + INTE);162 outl(0, emu->port + INTE);
163 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);163 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
164 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);164 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
165
166 /* disable stop on loop end */
165 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);167 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
166 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);168 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
167 169
@@ -181,13 +183,11 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 13 unmodified lines
181 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);183 snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
182 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);184 snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
183 185
184 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */186 if (emu->card_capabilities->emu_model) {
187 } else if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
185 /* Hacks for Alice3 to work independent of haP16V driver */188 /* Hacks for Alice3 to work independent of haP16V driver */
186 /* Setup SRCMulti_I2S SamplingRate */189 /* Setup SRCMulti_I2S SamplingRate */
187 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);190 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, 0, A_I2S_CAPTURE_96000);
188 tmp &= 0xfffff1ff;
189 tmp |= (0x2<<9);
190 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
191 191
192 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */192 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
193 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);193 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
199 outl(0x0201, emu->port + HCFG2);199 outl(0x0201, emu->port + HCFG2);
200 /* Set playback routing. */200 /* Set playback routing. */
201 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);201 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
202 }202 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
203 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
204 /* Hacks for Alice3 to work independent of haP16V driver */203 /* Hacks for Alice3 to work independent of haP16V driver */
205 dev_info(emu->card->dev, "Audigy2 value: Special config.\n");204 dev_info(emu->card->dev, "Audigy2 value: Special config.\n");
206 /* Setup SRCMulti_I2S SamplingRate */205 /* Setup SRCMulti_I2S SamplingRate */
207 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);206 snd_emu10k1_ptr_write(emu, A_I2S_CAPTURE_RATE, 0, A_I2S_CAPTURE_96000);
208 tmp &= 0xfffff1ff;
209 tmp |= (0x2<<9);
210 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
211 207
212 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */208 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
213 outl(0x600000, emu->port + 0x20);209 snd_emu10k1_ptr20_write(emu, P17V_SRCSel, 0, 0x14);
214 outl(0x14, emu->port + 0x24);
215 210
216 /* Setup SRCMulti Input Audio Enable */211 /* Setup SRCMulti Input Audio Enable */
217 outl(0x7b0000, emu->port + 0x20);212 snd_emu10k1_ptr20_write(emu, P17V_MIXER_I2S_ENABLE, 0, 0xFF000000);
218 outl(0xFF000000, emu->port + 0x24);
219 213
220 /* Setup SPDIF Out Audio Enable */214 /* Setup SPDIF Out Audio Enable */
221 /* The Audigy 2 Value has a separate SPDIF out,215 /* The Audigy 2 Value has a separate SPDIF out,
222 * so no need for a mixer switch216 * so no need for a mixer switch
223 */217 */
224 outl(0x7a0000, emu->port + 0x20);218 snd_emu10k1_ptr20_write(emu, P17V_MIXER_SPDIF_ENABLE, 0, 0xFF000000);
225 outl(0xFF000000, emu->port + 0x24);219
226 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */220 tmp = inw(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
227 outl(tmp, emu->port + A_IOCFG);221 outw(tmp, emu->port + A_IOCFG);
228 }222 }
229 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */223 if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
230 int size, n;224 int size, n;
@@ -244,15 +238,15 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) · 13 unmodified lines
244 * GPIO6: Unknown238 * GPIO6: Unknown
245 * GPIO7: Unknown239 * GPIO7: Unknown
246 */240 */
247 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */241 outw(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
248 }242 }
249 if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */243 if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */
250 int size, n;244 int size, n;
251 245
252 snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f);246 snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f);
253 tmp = inl(emu->port + A_IOCFG);247 tmp = inw(emu->port + A_IOCFG);
254 outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */248 outw(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */
255 tmp = inl(emu->port + A_IOCFG);249 tmp = inw(emu->port + A_IOCFG);
256 size = ARRAY_SIZE(i2c_adc_init);250 size = ARRAY_SIZE(i2c_adc_init);
257 for (n = 0; n < size; n++)251 for (n = 0; n < size; n++)
258 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);252 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
308 } else if (emu->card_capabilities->i2c_adc) {302 } else if (emu->card_capabilities->i2c_adc) {
309 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */303 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
310 } else if (emu->audigy) {304 } else if (emu->audigy) {
311 unsigned int reg = inl(emu->port + A_IOCFG);305 u16 reg = inw(emu->port + A_IOCFG);
312 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);306 outw(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
313 udelay(500);307 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);
315 udelay(100);309 udelay(100);
316 outl(reg, emu->port + A_IOCFG);310 outw(reg, emu->port + A_IOCFG);
317 } else {311 } else {
318 unsigned int reg = inl(emu->port + HCFG);312 unsigned int reg = inl(emu->port + HCFG);
319 outl(reg | HCFG_GPOUT2, emu->port + HCFG);313 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
329 } else if (emu->card_capabilities->i2c_adc) {323 } else if (emu->card_capabilities->i2c_adc) {
330 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */324 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
331 } else if (emu->audigy) { /* enable analog output */325 } else if (emu->audigy) { /* enable analog output */
332 unsigned int reg = inl(emu->port + A_IOCFG);326 u16 reg = inw(emu->port + A_IOCFG);
333 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);327 outw(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
334 }328 }
335 329
336 if (emu->address_mode == 0) {330 if (emu->address_mode == 0) {
@@ -354,19 +348,19 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) · 17 unmodified lines
354 } else if (emu->card_capabilities->i2c_adc) {348 } else if (emu->card_capabilities->i2c_adc) {
355 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */349 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
356 } else if (emu->audigy) {350 } 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);
358 352
359 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */353 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
360 /* Unmute Analog now. Set GPO6 to 1 for Apollo.354 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
361 * This has to be done after init ALice3 I2SOut beyond 48KHz.355 * This has to be done after init ALice3 I2SOut beyond 48KHz.
362 * So, sequence is important. */356 * 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);
364 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */358 } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
365 /* Unmute Analog now. */359 /* 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);
367 } else {361 } else {
368 /* Disable routing from AC97 line out to Front speakers */362 /* 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);
370 }364 }
371 }365 }
372 366
@@ -651,26 +645,27 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 278 unmodified lines
651 const struct firmware *fw_entry)645 const struct firmware *fw_entry)
652{646{
653 int n, i;647 int n, i;
654 int reg;648 u16 reg;
655 int value;649 u8 value;
656 __always_unused unsigned int write_post;650 __always_unused u16 write_post;
657 unsigned long flags;651 unsigned long flags;
658 652
659 if (!fw_entry)653 if (!fw_entry)
660 return -EIO;654 return -EIO;
661 655
662 /* The FPGA is a Xilinx Spartan IIE XC2S50E */656 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
657 /* On E-MU 0404b it is a Xilinx Spartan III XC3S50 */
663 /* GPIO7 -> FPGA PGMN658 /* GPIO7 -> FPGA PGMN
664 * GPIO6 -> FPGA CCLK659 * GPIO6 -> FPGA CCLK
665 * GPIO5 -> FPGA DIN660 * GPIO5 -> FPGA DIN
666 * FPGA CONFIG OFF -> FPGA PGMN661 * FPGA CONFIG OFF -> FPGA PGMN
667 */662 */
668 spin_lock_irqsave(&emu->emu_lock, flags);663 spin_lock_irqsave(&emu->emu_lock, flags);
669 outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */664 outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
670 write_post = inl(emu->port + A_IOCFG);665 write_post = inw(emu->port + A_GPIO);
671 udelay(100);666 udelay(100);
672 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */667 outw(0x80, emu->port + A_GPIO); /* Leave bit 7 set during netlist setup. */
673 write_post = inl(emu->port + A_IOCFG);668 write_post = inw(emu->port + A_GPIO);
674 udelay(100); /* Allow FPGA memory to clean */669 udelay(100); /* Allow FPGA memory to clean */
675 for (n = 0; n < fw_entry->size; n++) {670 for (n = 0; n < fw_entry->size; n++) {
676 value = fw_entry->data[n];671 value = fw_entry->data[n];
@@ -679,15 +674,15 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 2 unmodified lines
679 if (value & 0x1)674 if (value & 0x1)
680 reg = reg | 0x20;675 reg = reg | 0x20;
681 value = value >> 1;676 value = value >> 1;
682 outl(reg, emu->port + A_IOCFG);677 outw(reg, emu->port + A_GPIO);
683 write_post = inl(emu->port + A_IOCFG);678 write_post = inw(emu->port + A_GPIO);
684 outl(reg | 0x40, emu->port + A_IOCFG);679 outw(reg | 0x40, emu->port + A_GPIO);
685 write_post = inl(emu->port + A_IOCFG);680 write_post = inw(emu->port + A_GPIO);
686 }681 }
687 }682 }
688 /* After programming, set GPIO bit 4 high again. */683 /* After programming, set GPIO bit 4 high again. */
689 outl(0x10, emu->port + A_IOCFG);684 outw(0x10, emu->port + A_GPIO);
690 write_post = inl(emu->port + A_IOCFG);685 write_post = inw(emu->port + A_GPIO);
691 spin_unlock_irqrestore(&emu->emu_lock, flags);686 spin_unlock_irqrestore(&emu->emu_lock, flags);
692 687
693 return 0;688 return 0;
@@ -782,7 +777,7 @@ static void emu1010_firmware_work(struct work_struct *work) · 88 unmodified lines
782 } else if (!reg && emu->emu1010.last_reg) {777 } else if (!reg && emu->emu1010.last_reg) {
783 /* Audio Dock removed */778 /* Audio Dock removed */
784 dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");779 dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");
785 /* Unmute all */780 /* The hardware auto-mutes all, so we unmute again */
786 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);781 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
787 }782 }
788 783
@@ -794,29 +789,6 @@ static void emu1010_firmware_work(struct work_struct *work) · 5 unmodified lines
794}789}
795 790
796/*791/*
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 *
820 * Current status of the driver:792 * Current status of the driver:
821 * ----------------------------793 * ----------------------------
822 * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz)794 * * 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
831 int err;803 int err;
832 804
833 dev_info(emu->card->dev, "emu1010: Special config.\n");805 dev_info(emu->card->dev, "emu1010: Special config.\n");
834 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,806
835 * Lock Sound Memory Cache, Lock Tank Memory Cache,807 /* Mute, and disable audio and lock cache, just in case.
836 * Mute all codecs.808 * Proper init follows in snd_emu10k1_init(). */
837 */809 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
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);
852 810
853 /* Disable 48Volt power to Audio Dock */811 /* Disable 48Volt power to Audio Dock */
854 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);812 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
897 855
898 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);856 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
899 dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);857 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);
903 /* Optical -> ADAT I/O */858 /* Optical -> ADAT I/O */
904 /* 0 : SPDIF
905 * 1 : ADAT
906 */
907 emu->emu1010.optical_in = 1; /* IN_ADAT */859 emu->emu1010.optical_in = 1; /* IN_ADAT */
908 emu->emu1010.optical_out = 1; /* IN_ADAT */860 emu->emu1010.optical_out = 1; /* OUT_ADAT */
909 tmp = 0;
910 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |861 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
911 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);862 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
912 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);863 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
913 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
914 /* Set no attenuation on Audio Dock pads. */864 /* Set no attenuation on Audio Dock pads. */
915 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);865 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
916 emu->emu1010.adc_pads = 0x00;866 emu->emu1010.adc_pads = 0x00;
917 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
918 /* Unmute Audio dock DACs, Headphone source DAC-4. */867 /* Unmute Audio dock DACs, Headphone source DAC-4. */
919 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);868 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);
922 /* DAC PADs. */869 /* DAC PADs. */
923 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);870 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
924 emu->emu1010.dac_pads = 0x0f;871 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);
928 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */872 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
929 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);873 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
930 /* MIDI routing */874 /* MIDI routing */
@@ -936,8 +880,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 5 unmodified lines
936 /* IRQ Enable: All off */880 /* IRQ Enable: All off */
937 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);881 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
938 882
939 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);883 emu->emu1010.internal_clock = 1; /* 48000 */
940 dev_info(emu->card->dev, "emu1010: Card options3 = 0x%x\n", reg);
941 /* Default WCLK set to 48kHz. */884 /* Default WCLK set to 48kHz. */
942 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);885 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
943 /* Word Clock source, Internal 48kHz x1 */886 /* Word Clock source, Internal 48kHz x1 */
@@ -1073,29 +1016,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 129 unmodified lines
1073 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);1016 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
1074 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */1017 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
1075 1018
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
1099#if 01019#if 0
1100 snd_emu1010_fpga_link_dst_src_write(emu,1020 snd_emu1010_fpga_link_dst_src_write(emu,
1101 EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */1021 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
1215 EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);1135 EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
1216 emu->emu1010.output_source[23] = 28;1136 emu->emu1010.output_source[23] = 28;
1217 }1137 }
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 */
1233 1138
1234 return 0;1139 return 0;
1235}1140}
@@ -1343,6 +1248,15 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 107 unmodified lines
1343 * AC97: STAC97501248 * AC97: STAC9750
1344 * CA0151: None1249 * CA0151: None
1345 */1250 */
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 */
1346 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,1260 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1347 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",1261 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
1348 .id = "Audigy2",1262 .id = "Audigy2",
@@ -1391,6 +1305,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 42 unmodified lines
1391 .spi_dac = 1,1305 .spi_dac = 1,
1392 .i2c_adc = 1,1306 .i2c_adc = 1,
1393 .spk71 = 1} ,1307 .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). */
1394 /* Tested by James@superbug.co.uk 4th Nov 2007. */1311 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1395 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,1312 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
1396 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",1313 .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
1401 .spk71 = 1 ,1318 .spk71 = 1 ,
1402 .emu_model = EMU_MODEL_EMU1616},1319 .emu_model = EMU_MODEL_EMU1616},
1403 /* Tested by James@superbug.co.uk 4th Nov 2007. */1320 /* 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. */
1405 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,1325 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
1406 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",1326 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
1407 .id = "EMU1010",1327 .id = "EMU1010",
@@ -1411,6 +1331,11 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 3 unmodified lines
1411 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */1331 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
1412 /* Tested by Maxim Kachur <mcdebugger@duganet.ru> 17th Oct 2012. */1332 /* Tested by Maxim Kachur <mcdebugger@duganet.ru> 17th Oct 2012. */
1413 /* This is MAEM8986, 0202 is MAEM8980 */1333 /* 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. */
1414 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40071102,1339 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40071102,
1415 .driver = "Audigy2", .name = "E-mu 1010 PCIe [MAEM8986]",1340 .driver = "Audigy2", .name = "E-mu 1010 PCIe [MAEM8986]",
1416 .id = "EMU1010",1341 .id = "EMU1010",
@@ -1419,7 +1344,10 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 2 unmodified lines
1419 .spk71 = 1,1344 .spk71 = 1,
1420 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 PCIe */1345 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 PCIe */
1421 /* Tested by James@superbug.co.uk 8th July 2005. */1346 /* 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. */
1423 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,1351 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
1424 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",1352 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
1425 .id = "EMU1010",1353 .id = "EMU1010",
@@ -1427,7 +1355,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
1427 .ca0102_chip = 1,1355 .ca0102_chip = 1,
1428 .spk71 = 1,1356 .spk71 = 1,
1429 .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */1357 .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. */
1431 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,1361 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
1432 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",1362 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
1433 .id = "EMU0404",1363 .id = "EMU0404",
@@ -1435,6 +1365,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
1435 .ca0108_chip = 1,1365 .ca0108_chip = 1,
1436 .spk71 = 1,1366 .spk71 = 1,
1437 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */1367 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
1368 /* This is MAEM8850 "HanaLite" */
1369 /* Supports sync daughter card. */
1438 /* Tested by James@superbug.co.uk 20-3-2007. */1370 /* Tested by James@superbug.co.uk 20-3-2007. */
1439 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,1371 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
1440 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",1372 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
@@ -1444,6 +1376,7 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 3 unmodified lines
1444 .spk71 = 1,1376 .spk71 = 1,
1445 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */1377 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1446 /* EMU0404 PCIe */1378 /* EMU0404 PCIe */
1379 /* Does NOT support sync daughter card. */
1447 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,1380 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40051102,
1448 .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",1381 .driver = "Audigy2", .name = "E-mu 0404 PCIe [MAEM8984]",
1449 .id = "EMU0404",1382 .id = "EMU0404",
@@ -1451,7 +1384,6 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 1 unmodified line
1451 .ca0108_chip = 1,1384 .ca0108_chip = 1,
1452 .spk71 = 1,1385 .spk71 = 1,
1453 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */1386 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 PCIe ver_03 */
1454 /* Note that all E-mu cards require kernel 2.6 or newer. */
1455 {.vendor = 0x1102, .device = 0x0008,1387 {.vendor = 0x1102, .device = 0x0008,
1456 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",1388 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
1457 .id = "Audigy2",1389 .id = "Audigy2",
@@ -1532,6 +1464,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 74 unmodified lines
1532 .spdif_bug = 1,1464 .spdif_bug = 1,
1533 .adc_1361t = 1, /* 24 bit capture instead of 16bit */1465 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1534 .ac97_chip = 1} ,1466 .ac97_chip = 1} ,
1467 /* Audigy 2 Platinum EX */
1468 /* Win driver sets A_IOCFG output to 0x1c00 */
1535 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,1469 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
1536 .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]",1470 .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]",
1537 .id = "Audigy2",1471 .id = "Audigy2",
@@ -1552,6 +1486,8 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 14 unmodified lines
1552 .spdif_bug = 1,1486 .spdif_bug = 1,
1553 .invert_shared_spdif = 1, /* digital/analog switch swapped */1487 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1554 .ac97_chip = 1} ,1488 .ac97_chip = 1} ,
1489 /* Audigy 2 Platinum */
1490 /* Win driver sets A_IOCFG output to 0xa00 */
1555 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,1491 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
1556 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",1492 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
1557 .id = "Audigy2",1493 .id = "Audigy2",
@@ -1657,6 +1593,9 @@ static const struct snd_emu_chip_details emu_chip_details[] = { · 99 unmodified lines
1657 .emu10k1_chip = 1,1593 .emu10k1_chip = 1,
1658 .ac97_chip = 1,1594 .ac97_chip = 1,
1659 .sblive51 = 1} ,1595 .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. */
1660 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,1599 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
1661 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",1600 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
1662 .id = "Live",1601 .id = "Live",
@@ -1901,11 +1840,12 @@ int snd_emu10k1_create(struct snd_card *card, · 238 unmodified lines
1901 1840
1902 pci_set_master(pci);1841 pci_set_master(pci);
1903 1842
1904 emu->fx8010.fxbus_mask = 0x303f;1843 // The masks are not used for Audigy.
1844 // FIXME: these should come from the card_capabilites table.
1905 if (extin_mask == 0)1845 if (extin_mask == 0)
1906 extin_mask = 0x3fcf;1846 extin_mask = 0x3fcf; // EXTIN_*
1907 if (extout_mask == 0)1847 if (extout_mask == 0)
1908 extout_mask = 0x7fff;1848 extout_mask = 0x7fff; // EXTOUT_*
1909 emu->fx8010.extin_mask = extin_mask;1849 emu->fx8010.extin_mask = extin_mask;
1910 emu->fx8010.extout_mask = extout_mask;1850 emu->fx8010.extout_mask = extout_mask;
1911 emu->enable_ir = enable_ir;1851 emu->enable_ir = enable_ir;
@@ -1970,12 +1910,10 @@ int snd_emu10k1_create(struct snd_card *card, · 58 unmodified lines
1970 pgtbl[idx] = cpu_to_le32(silent_page | idx);1910 pgtbl[idx] = cpu_to_le32(silent_page | idx);
1971 1911
1972 /* set up voice indices */1912 /* set up voice indices */
1973 for (idx = 0; idx < NUM_G; idx++) {1913 for (idx = 0; idx < NUM_G; idx++)
1974 emu->voices[idx].emu = emu;
1975 emu->voices[idx].number = idx;1914 emu->voices[idx].number = idx;
1976 }
1977 1915
1978 err = snd_emu10k1_init(emu, enable_ir, 0);1916 err = snd_emu10k1_init(emu, enable_ir);
1979 if (err < 0)1917 if (err < 0)
1980 return err;1918 return err;
1981#ifdef CONFIG_PM_SLEEP1919#ifdef CONFIG_PM_SLEEP
@@ -2007,7 +1945,7 @@ static const unsigned char saved_regs[] = { · 25 unmodified lines
2007 0xff /* end */1945 0xff /* end */
2008};1946};
2009static const unsigned char saved_regs_audigy[] = {1947static 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,
2011 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,1949 A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
2012 0xff /* end */1950 0xff /* end */
2013};1951};
@@ -2054,7 +1992,7 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) · 40 unmodified lines
2054 *val = snd_emu10k1_ptr_read(emu, *reg, i);1992 *val = snd_emu10k1_ptr_read(emu, *reg, i);
2055 }1993 }
2056 if (emu->audigy)1994 if (emu->audigy)
2057 emu->saved_a_iocfg = inl(emu->port + A_IOCFG);1995 emu->saved_a_iocfg = inw(emu->port + A_IOCFG);
2058 emu->saved_hcfg = inl(emu->port + HCFG);1996 emu->saved_hcfg = inl(emu->port + HCFG);
2059}1997}
2060 1998
@@ -2068,7 +2006,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) · 7 unmodified lines
2068 snd_emu10k1_emu1010_init(emu);2006 snd_emu10k1_emu1010_init(emu);
2069 else2007 else
2070 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);2008 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);
2072}2010}
2073 2011
2074void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)2012void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
@@ -2081,7 +2019,7 @@ void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu) · 6 unmodified lines
2081 2019
2082 /* resore for spdif */2020 /* resore for spdif */
2083 if (emu->audigy)2021 if (emu->audigy)
2084 outl(emu->saved_a_iocfg, emu->port + A_IOCFG);2022 outw(emu->saved_a_iocfg, emu->port + A_IOCFG);
2085 outl(emu->saved_hcfg, emu->port + HCFG);2023 outl(emu->saved_hcfg, emu->port + HCFG);
2086 2024
2087 val = emu->saved_ptr;2025 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
641 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {641 list_for_each_entry(ctl, &emu->fx8010.gpr_ctl, list) {
642 kcontrol = ctl->kcontrol;642 kcontrol = ctl->kcontrol;
643 if (kcontrol->id.iface == id->iface &&643 if (kcontrol->id.iface == id->iface &&
644 !strcmp(kcontrol->id.name, id->name) &&644 kcontrol->id.index == id->index &&
645 kcontrol->id.index == id->index)645 !strcmp(kcontrol->id.name, id->name))
646 return ctl;646 return ctl;
647 }647 }
648 return NULL;648 return NULL;
@@ -1187,8 +1187,8 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl · 538 unmodified lines
1187}1187}
1188 1188
1189/*1189/*
1190 * Used for emu1010 - conversion from 32-bit capture inputs from HANA1190 * 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.1191 * to 2 x 16-bit registers in Audigy - their values are read via DMA.
1192 * Conversion is performed by Audigy DSP instructions of FX8010.1192 * Conversion is performed by Audigy DSP instructions of FX8010.
1193 */1193 */
1194static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(1194static 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
1213 1213
1214static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)1214static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1215{1215{
1216 int err, i, z, gpr, nctl;1216 int err, z, gpr, nctl;
1217 int bit_shifter16;1217 int bit_shifter16;
1218 const int playback = 10;1218 const int playback = 10;
1219 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */1219 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
1245 icode->code = icode->tram_addr_map + 256;1245 icode->code = icode->tram_addr_map + 256;
1246 1246
1247 /* clear free GPRs */1247 /* clear free GPRs */
1248 for (i = 0; i < 512; i++)1248 memset(icode->gpr_valid, 0xff, 512 / 8);
1249 set_bit(i, icode->gpr_valid);
1250 1249
1251 /* clear TRAM data & address lines */1250 /* clear TRAM data & address lines */
1252 for (i = 0; i < 256; i++)1251 memset(icode->tram_valid, 0xff, 256 / 8);
1253 set_bit(i, icode->tram_valid);
1254 1252
1255 strcpy(icode->name, "Audigy DSP code for ALSA");1253 strcpy(icode->name, "Audigy DSP code for ALSA");
1256 ptr = 0;1254 ptr = 0;
@@ -1261,9 +1259,6 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) · 4 unmodified lines
1261 gpr_map[gpr++] = 0x0000ffff;1259 gpr_map[gpr++] = 0x0000ffff;
1262 bit_shifter16 = gpr;1260 bit_shifter16 = gpr;
1263 1261
1264 /* stop FX processor */
1265 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1266
1267#if 11262#if 1
1268 /* PCM front Playback Volume (independent from stereo mix)1263 /* PCM front Playback Volume (independent from stereo mix)
1269 * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31)1264 * 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
1332#define A_ADD_VOLUME_IN(var,vol,input) \1327#define A_ADD_VOLUME_IN(var,vol,input) \
1333A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))1328A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1334 1329
1335 /* emu1212 DSP 0 and DSP 1 Capture */
1336 if (emu->card_capabilities->emu_model) {1330 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.
1337 if (emu->card_capabilities->ca0108_chip) {1333 if (emu->card_capabilities->ca0108_chip) {
1338 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */1334 /* Note:JCD:No longer bit shift lower 16bits to upper 16bits of 32bit value. */
1339 A_OP(icode, &ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A3_EMU32IN(0x0), A_C_00000001);1335 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
1638#endif1634#endif
1639 1635
1640 if (emu->card_capabilities->emu_model) {1636 if (emu->card_capabilities->emu_model) {
1637 /* Capture 16 channels of S32_LE sound. */
1641 if (emu->card_capabilities->ca0108_chip) {1638 if (emu->card_capabilities->ca0108_chip) {
1642 dev_info(emu->card->dev, "EMU2 inputs on\n");1639 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
1643 for (z = 0; z < 0x10; z++) {1642 for (z = 0; z < 0x10; z++) {
1644 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, 1643 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp,
1645 bit_shifter16,1644 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
1648 }1647 }
1649 } else {1648 } else {
1650 dev_info(emu->card->dev, "EMU inputs on\n");1649 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. */
1652 1651
1653 /*1652 /*
1654 dev_dbg(emu->card->dev, "emufx.c: gpr=0x%x, tmp=0x%x\n",1653 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
1886 icode->code = icode->tram_addr_map + 160;1885 icode->code = icode->tram_addr_map + 160;
1887 1886
1888 /* clear free GPRs */1887 /* clear free GPRs */
1889 for (i = 0; i < 256; i++)1888 memset(icode->gpr_valid, 0xff, 256 / 8);
1890 set_bit(i, icode->gpr_valid);
1891 1889
1892 /* clear TRAM data & address lines */1890 /* clear TRAM data & address lines */
1893 for (i = 0; i < 160; i++)1891 memset(icode->tram_valid, 0xff, 160 / 8);
1894 set_bit(i, icode->tram_valid);
1895 1892
1896 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");1893 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1897 ptr = 0; i = 0;1894 ptr = 0; i = 0;
@@ -1903,9 +1900,6 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) · 5 unmodified lines
1903 tmp = 0x88; /* we need 4 temporary GPR */1900 tmp = 0x88; /* we need 4 temporary GPR */
1904 /* from 0x8c to 0xff is the area for tone control */1901 /* from 0x8c to 0xff is the area for tone control */
1905 1902
1906 /* stop FX processor */
1907 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1908
1909 /*1903 /*
1910 * Process FX Buses1904 * Process FX Buses
1911 */1905 */
@@ -2523,7 +2517,7 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu, · 611 unmodified lines
2523 struct snd_emu10k1_fx8010_info *info)2517 struct snd_emu10k1_fx8010_info *info)
2524{2518{
2525 const char * const *fxbus, * const *extin, * const *extout;2519 const char * const *fxbus, * const *extin, * const *extout;
2526 unsigned short fxbus_mask, extin_mask, extout_mask;2520 unsigned short extin_mask, extout_mask;
2527 int res;2521 int res;
2528 2522
2529 info->internal_tram_size = emu->fx8010.itram_size;2523 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
2531 fxbus = fxbuses;2525 fxbus = fxbuses;
2532 extin = emu->audigy ? audigy_ins : creative_ins;2526 extin = emu->audigy ? audigy_ins : creative_ins;
2533 extout = emu->audigy ? audigy_outs : creative_outs;2527 extout = emu->audigy ? audigy_outs : creative_outs;
2534 fxbus_mask = emu->fx8010.fxbus_mask;2528 extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask;
2535 extin_mask = emu->fx8010.extin_mask;2529 extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask;
2536 extout_mask = emu->fx8010.extout_mask;
2537 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {2530 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);
2539 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);2532 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2540 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);2533 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2541 }2534 }
@@ -2651,17 +2644,19 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un · 109 unmodified lines
2651 return -EPERM;2644 return -EPERM;
2652 if (get_user(addr, (unsigned int __user *)argp))2645 if (get_user(addr, (unsigned int __user *)argp))
2653 return -EFAULT;2646 return -EFAULT;
2654 if (addr > 0x1ff)2647 if (emu->audigy) {
2655 return -EINVAL;2648 if (addr > A_DBG_STEP_ADDR)
2656 if (emu->audigy)2649 return -EINVAL;
2657 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);2650 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2658 else2651 udelay(10);
2659 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);2652 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_STEP | addr);
2660 udelay(10);2653 } else {
2661 if (emu->audigy)2654 if (addr > EMU10K1_DBG_SINGLE_STEP_ADDR)
2662 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);2655 return -EINVAL;
2663 else2656 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2664 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);2657 udelay(10);
2658 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_STEP | addr);
2659 }
2665 return 0;2660 return 0;
2666 case SNDRV_EMU10K1_IOCTL_DBG_READ:2661 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2667 if (emu->audigy)2662 if (emu->audigy)
sound/pci/emu10k1/emumixer.c+23−22
@@ -346,7 +346,7 @@ static const unsigned int emu1616_output_dst[] = { · 345 unmodified lines
346};346};
347 347
348/*348/*
349 * Data destinations - HANA outputs going to Alice2 (audigy) for349 * Data destinations - FPGA outputs going to Alice2 (Audigy) for
350 * capture (EMU32 + I2S links)350 * capture (EMU32 + I2S links)
351 * Each destination has an enum mixer control to choose a data source351 * Each destination has an enum mixer control to choose a data source
352 */352 */
@@ -367,6 +367,7 @@ static const unsigned int emu1010_input_dst[] = { · 14 unmodified lines
367 EMU_DST_ALICE2_EMU32_D,367 EMU_DST_ALICE2_EMU32_D,
368 EMU_DST_ALICE2_EMU32_E,368 EMU_DST_ALICE2_EMU32_E,
369 EMU_DST_ALICE2_EMU32_F,369 EMU_DST_ALICE2_EMU32_F,
370 /* These exist only on rev1 EMU1010 cards. */
370 EMU_DST_ALICE_I2S0_LEFT,371 EMU_DST_ALICE_I2S0_LEFT,
371 EMU_DST_ALICE_I2S0_RIGHT,372 EMU_DST_ALICE_I2S0_RIGHT,
372 EMU_DST_ALICE_I2S1_LEFT,373 EMU_DST_ALICE_I2S1_LEFT,
@@ -708,7 +709,7 @@ static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol, · 335 unmodified lines
708 /* 44100 */709 /* 44100 */
709 /* Mute all */710 /* Mute all */
710 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );711 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
711 /* Default fallback clock 48kHz */712 /* Default fallback clock 44.1kHz */
712 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );713 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );
713 /* Word Clock source, Internal 44.1kHz x1 */714 /* Word Clock source, Internal 44.1kHz x1 */
714 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,715 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
924 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);925 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
925 unsigned int source_id;926 unsigned int source_id;
926 unsigned int ngain, ogain;927 unsigned int ngain, ogain;
927 u32 gpio;928 u16 gpio;
928 int change = 0;929 int change = 0;
929 unsigned long flags;930 unsigned long flags;
930 u32 source;931 u32 source;
@@ -941,11 +942,11 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, · 10 unmodified lines
941 if (change) {942 if (change) {
942 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */943 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
943 spin_lock_irqsave(&emu->emu_lock, flags);944 spin_lock_irqsave(&emu->emu_lock, flags);
944 gpio = inl(emu->port + A_IOCFG);945 gpio = inw(emu->port + A_IOCFG);
945 if (source_id==0)946 if (source_id==0)
946 outl(gpio | 0x4, emu->port + A_IOCFG);947 outw(gpio | 0x4, emu->port + A_IOCFG);
947 else948 else
948 outl(gpio & ~0x4, emu->port + A_IOCFG);949 outw(gpio & ~0x4, emu->port + A_IOCFG);
949 spin_unlock_irqrestore(&emu->emu_lock, flags);950 spin_unlock_irqrestore(&emu->emu_lock, flags);
950 951
951 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */952 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
1005{1006{
1006 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1007 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1007 unsigned int ogain;1008 unsigned int ogain;
1008 unsigned int ngain;1009 unsigned int ngain0, ngain1;
1009 unsigned int source_id;1010 unsigned int source_id;
1010 int change = 0;1011 int change = 0;
1011 1012
@@ -1014,24 +1015,24 @@ static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol, · 2 unmodified lines
1014 /* capture_source: uinfo->value.enumerated.items = 2 */1015 /* capture_source: uinfo->value.enumerated.items = 2 */
1015 if (source_id >= 2)1016 if (source_id >= 2)
1016 return -EINVAL;1017 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;
1017 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */1024 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
1018 ngain = ucontrol->value.integer.value[0];1025 if (ogain != ngain0) {
1019 if (ngain > 0xff)
1020 return 0;
1021 if (ogain != ngain) {
1022 if (emu->i2c_capture_source == source_id)1026 if (emu->i2c_capture_source == source_id)
1023 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );1027 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ngain0);
1024 emu->i2c_capture_volume[source_id][0] = ngain;1028 emu->i2c_capture_volume[source_id][0] = ngain0;
1025 change = 1;1029 change = 1;
1026 }1030 }
1027 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */1031 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
1028 ngain = ucontrol->value.integer.value[1];1032 if (ogain != ngain1) {
1029 if (ngain > 0xff)
1030 return 0;
1031 if (ogain != ngain) {
1032 if (emu->i2c_capture_source == source_id)1033 if (emu->i2c_capture_source == source_id)
1033 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));1034 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ngain1);
1034 emu->i2c_capture_volume[source_id][1] = ngain;1035 emu->i2c_capture_volume[source_id][1] = ngain1;
1035 change = 1;1036 change = 1;
1036 }1037 }
1037 1038
@@ -1632,7 +1633,7 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, · 594 unmodified lines
1632 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1633 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1633 1634
1634 if (emu->audigy)1635 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;
1636 else1637 else
1637 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;1638 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
1638 if (emu->card_capabilities->invert_shared_spdif)1639 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
1657 if ( emu->card_capabilities->i2c_adc) {1658 if ( emu->card_capabilities->i2c_adc) {
1658 /* Do nothing for Audigy 2 ZS Notebook */1659 /* Do nothing for Audigy 2 ZS Notebook */
1659 } else if (emu->audigy) {1660 } else if (emu->audigy) {
1660 reg = inl(emu->port + A_IOCFG);1661 reg = inw(emu->port + A_IOCFG);
1661 val = sw ? A_IOCFG_GPOUT0 : 0;1662 val = sw ? A_IOCFG_GPOUT0 : 0;
1662 change = (reg & A_IOCFG_GPOUT0) != val;1663 change = (reg & A_IOCFG_GPOUT0) != val;
1663 if (change) {1664 if (change) {
1664 reg &= ~A_IOCFG_GPOUT0;1665 reg &= ~A_IOCFG_GPOUT0;
1665 reg |= val;1666 reg |= val;
1666 outl(reg | val, emu->port + A_IOCFG);1667 outw(reg | val, emu->port + A_IOCFG);
1667 }1668 }
1668 }1669 }
1669 reg = inl(emu->port + HCFG);1670 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
76 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);76 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
77} 77}
78 78
79static 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
96static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)79static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)
97{80{
98 int err, i;81 int err, i;
@@ -343,7 +326,6 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, · 244 unmodified lines
343 } else326 } else
344 snd_emu10k1_ptr_write(emu, FXRT, voice,327 snd_emu10k1_ptr_write(emu, FXRT, voice,
345 snd_emu10k1_compose_send_routing(send_routing));328 snd_emu10k1_compose_send_routing(send_routing));
346 /* Stop CA */
347 /* Assumption that PT is already 0 so no harm overwriting */329 /* Assumption that PT is already 0 so no harm overwriting */
348 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);330 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
349 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));331 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
429}411}
430 412
431static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream)413static 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
461static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
462{414{
463 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);415 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
464 struct snd_pcm_runtime *runtime = substream->runtime;416 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
527 start_addr = epcm->start_addr;479 start_addr = epcm->start_addr;
528 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);480 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
529 481
530 /*
531 * the kX driver leaves some space between voices
532 */
533 channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;482 channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
534 483
535 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,484 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
1091 epcm->type = PLAYBACK_EFX;1040 epcm->type = PLAYBACK_EFX;
1092 epcm->substream = substream;1041 epcm->substream = substream;
1093 1042
1094 emu->pcm_playback_efx_substream = substream;
1095
1096 runtime->private_data = epcm;1043 runtime->private_data = epcm;
1097 runtime->private_free = snd_emu10k1_pcm_free_substream;1044 runtime->private_free = snd_emu10k1_pcm_free_substream;
1098 runtime->hw = snd_emu10k1_efx_playback;1045 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
1267 runtime->hw.rate_min = runtime->hw.rate_max = 48000;1214 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1268 spin_lock_irq(&emu->reg_lock);1215 spin_lock_irq(&emu->reg_lock);
1269 if (emu->card_capabilities->emu_model) {1216 if (emu->card_capabilities->emu_model) {
1270 /* Nb. of channels has been increased to 16 */
1271 /* TODO1217 /* TODO
1272 * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
1273 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |1218 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
1274 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |1219 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
1275 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_1920001220 * 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
1280 * Need to add mixer control to fix sample rate1225 * Need to add mixer control to fix sample rate
1281 * 1226 *
1282 * There are 32 mono channels of 16bits each.1227 * There are 32 mono channels of 16bits each.
1283 * 24bit Audio uses 2x channels over 16bit1228 * 24bit Audio uses 2x channels over 16bit,
1284 * 96kHz uses 2x channels over 48kHz1229 * 96kHz uses 2x channels over 48kHz,
1285 * 192kHz uses 4x channels over 48kHz1230 * 192kHz uses 4x channels over 48kHz.
1286 * So, for 48kHz 24bit, one has 16 channels1231 * So, for 48kHz 24bit, one has 16 channels,
1287 * for 96kHz 24bit, one has 8 channels1232 * for 96kHz 24bit, one has 8 channels,
1288 * for 192kHz 24bit, one has 4 channels1233 * for 192kHz 24bit, one has 4 channels.
1289 *1234 * 1010rev2 and 1616(m) cards have double that,
1235 * but we don't exceed 16 channels anyway.
1290 */1236 */
1291#if 11237#if 1
1292 switch (emu->emu1010.internal_clock) {1238 switch (emu->emu1010.internal_clock) {
@@ -1372,10 +1318,10 @@ static const struct snd_pcm_ops snd_emu10k1_efx_playback_ops = { · 79 unmodified lines
1372 .open = snd_emu10k1_efx_playback_open,1318 .open = snd_emu10k1_efx_playback_open,
1373 .close = snd_emu10k1_efx_playback_close,1319 .close = snd_emu10k1_efx_playback_close,
1374 .hw_params = snd_emu10k1_playback_hw_params,1320 .hw_params = snd_emu10k1_playback_hw_params,
1375 .hw_free = snd_emu10k1_efx_playback_hw_free,1321 .hw_free = snd_emu10k1_playback_hw_free,
1376 .prepare = snd_emu10k1_efx_playback_prepare,1322 .prepare = snd_emu10k1_efx_playback_prepare,
1377 .trigger = snd_emu10k1_efx_playback_trigger,1323 .trigger = snd_emu10k1_efx_playback_trigger,
1378 .pointer = snd_emu10k1_efx_playback_pointer,1324 .pointer = snd_emu10k1_playback_pointer,
1379};1325};
1380 1326
1381int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device)1327int 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
1508 nval[idx / 32] |= 1 << (idx % 32);1454 nval[idx / 32] |= 1 << (idx % 32);
1509 bits++;1455 bits++;
1510 }1456 }
1511 1457
1458 // Check that the number of requested channels is a power of two
1459 // not bigger than the number of available channels.
1512 for (idx = 0; idx < nefxb; idx++)1460 for (idx = 0; idx < nefxb; idx++)
1513 if (1 << idx == bits)1461 if (1 << idx == bits)
1514 break;1462 break;
1515
1516 if (idx >= nefxb)1463 if (idx >= nefxb)
1517 return -EINVAL;1464 return -EINVAL;
1518 1465
@@ -1802,7 +1749,6 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device) · 283 unmodified lines
1802 * to these1749 * to these
1803 */ 1750 */
1804 1751
1805 /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
1806 if (emu->audigy) {1752 if (emu->audigy) {
1807 emu->efx_voices_mask[0] = 0;1753 emu->efx_voices_mask[0] = 0;
1808 if (emu->card_capabilities->emu_model)1754 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
477 for(i = offset; i < offset+length; i++) {477 for(i = offset; i < offset+length; i++) {
478 snd_iprintf(buffer, "%02X: ",i);478 snd_iprintf(buffer, "%02X: ",i);
479 for (j = 0; j < voices; j++) {479 for (j = 0; j < voices; j++) {
480 if(iobase == 0)480 value = snd_ptr_read(emu, iobase, i, j);
481 value = snd_ptr_read(emu, 0, i, j);
482 else
483 value = snd_ptr_read(emu, 0x20, i, j);
484 snd_iprintf(buffer, "%08lX ", value);481 snd_iprintf(buffer, "%08lX ", value);
485 }482 }
486 snd_iprintf(buffer, "\n");483 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
233 return err;233 return err;
234}234}
235 235
236int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, u32 reg, u32 value)236void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
237{237{
238 unsigned long flags;238 unsigned long flags;
239 239
240 if (reg > 0x3f)240 if (snd_BUG_ON(reg > 0x3f))
241 return 1;241 return;
242 reg += 0x40; /* 0x40 upwards are registers. */242 reg += 0x40; /* 0x40 upwards are registers. */
243 if (value > 0x3f) /* 0 to 0x3f are values */243 if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */
244 return 1;244 return;
245 spin_lock_irqsave(&emu->emu_lock, flags);245 spin_lock_irqsave(&emu->emu_lock, flags);
246 outl(reg, emu->port + A_IOCFG);246 outw(reg, emu->port + A_GPIO);
247 udelay(10);247 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. */
249 udelay(10);249 udelay(10);
250 outl(value, emu->port + A_IOCFG);250 outw(value, emu->port + A_GPIO);
251 udelay(10);251 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. */
253 spin_unlock_irqrestore(&emu->emu_lock, flags);253 spin_unlock_irqrestore(&emu->emu_lock, flags);
254
255 return 0;
256}254}
257 255
258int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, u32 reg, u32 *value)256void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
259{257{
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;
260 unsigned long flags;261 unsigned long flags;
261 if (reg > 0x3f)262 if (snd_BUG_ON(reg > 0x3f))
262 return 1;263 return;
263 reg += 0x40; /* 0x40 upwards are registers. */264 reg += 0x40; /* 0x40 upwards are registers. */
264 spin_lock_irqsave(&emu->emu_lock, flags);265 spin_lock_irqsave(&emu->emu_lock, flags);
265 outl(reg, emu->port + A_IOCFG);266 outw(reg, emu->port + A_GPIO);
266 udelay(10);267 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. */
268 udelay(10);269 udelay(10);
269 *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);270 *value = ((inw(emu->port + A_GPIO) >> 8) & mask);
270 spin_unlock_irqrestore(&emu->emu_lock, flags);271 spin_unlock_irqrestore(&emu->emu_lock, flags);
271
272 return 0;
273}272}
274 273
275/* Each Destination has one and only one Source,274/* Each Destination has one and only one Source,
276 * but one Source can feed any number of Destinations simultaneously.275 * but one Source can feed any number of Destinations simultaneously.
277 */276 */
278int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, u32 dst, u32 src)277void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
279{278{
280 snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );279 if (snd_BUG_ON(dst & ~0x71f))
281 snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );280 return;
282 snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );281 if (snd_BUG_ON(src & ~0x71f))
283 snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );282 return;
284 283 snd_emu1010_fpga_write(emu, 0x00, dst >> 8);
285 return 0;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);
286}287}
287 288
288void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)289void 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
313 unsigned int val;314 unsigned int val;
314 315
315 spin_lock_irqsave(&emu->emu_lock, flags);316 spin_lock_irqsave(&emu->emu_lock, flags);
316 /* voice interrupt */
317 if (voicenum >= 32) {317 if (voicenum >= 32) {
318 outl(CLIEH << 16, emu->port + PTR);318 outl(CLIEH << 16, emu->port + PTR);
319 val = inl(emu->port + DATA);319 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
333 unsigned int val;333 unsigned int val;
334 334
335 spin_lock_irqsave(&emu->emu_lock, flags);335 spin_lock_irqsave(&emu->emu_lock, flags);
336 /* voice interrupt */
337 if (voicenum >= 32) {336 if (voicenum >= 32) {
338 outl(CLIEH << 16, emu->port + PTR);337 outl(CLIEH << 16, emu->port + PTR);
339 val = inl(emu->port + DATA);338 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
352 unsigned long flags;351 unsigned long flags;
353 352
354 spin_lock_irqsave(&emu->emu_lock, flags);353 spin_lock_irqsave(&emu->emu_lock, flags);
355 /* voice interrupt */
356 if (voicenum >= 32) {354 if (voicenum >= 32) {
357 outl(CLIPH << 16, emu->port + PTR);355 outl(CLIPH << 16, emu->port + PTR);
358 voicenum = 1 << (voicenum - 32);356 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
370 unsigned int val;368 unsigned int val;
371 369
372 spin_lock_irqsave(&emu->emu_lock, flags);370 spin_lock_irqsave(&emu->emu_lock, flags);
373 /* voice interrupt */
374 if (voicenum >= 32) {371 if (voicenum >= 32) {
375 outl(HLIEH << 16, emu->port + PTR);372 outl(HLIEH << 16, emu->port + PTR);
376 val = inl(emu->port + DATA);373 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
390 unsigned int val;387 unsigned int val;
391 388
392 spin_lock_irqsave(&emu->emu_lock, flags);389 spin_lock_irqsave(&emu->emu_lock, flags);
393 /* voice interrupt */
394 if (voicenum >= 32) {390 if (voicenum >= 32) {
395 outl(HLIEH << 16, emu->port + PTR);391 outl(HLIEH << 16, emu->port + PTR);
396 val = inl(emu->port + DATA);392 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
409 unsigned long flags;405 unsigned long flags;
410 406
411 spin_lock_irqsave(&emu->emu_lock, flags);407 spin_lock_irqsave(&emu->emu_lock, flags);
412 /* voice interrupt */
413 if (voicenum >= 32) {408 if (voicenum >= 32) {
414 outl(HLIPH << 16, emu->port + PTR);409 outl(HLIPH << 16, emu->port + PTR);
415 voicenum = 1 << (voicenum - 32);410 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
427 unsigned int sol;422 unsigned int sol;
428 423
429 spin_lock_irqsave(&emu->emu_lock, flags);424 spin_lock_irqsave(&emu->emu_lock, flags);
430 /* voice interrupt */
431 if (voicenum >= 32) {425 if (voicenum >= 32) {
432 outl(SOLEH << 16, emu->port + PTR);426 outl(SOLEH << 16, emu->port + PTR);
433 sol = inl(emu->port + DATA);427 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
447 unsigned int sol;441 unsigned int sol;
448 442
449 spin_lock_irqsave(&emu->emu_lock, flags);443 spin_lock_irqsave(&emu->emu_lock, flags);
450 /* voice interrupt */
451 if (voicenum >= 32) {444 if (voicenum >= 32) {
452 outl(SOLEH << 16, emu->port + PTR);445 outl(SOLEH << 16, emu->port + PTR);
453 sol = inl(emu->port + DATA);446 sol = inl(emu->port + DATA);
sound/pci/emu10k1/irq.c+5−27
@@ -18,7 +18,7 @@ · 17 unmodified lines
18irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)18irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id)
19{19{
20 struct snd_emu10k1 *emu = dev_id;20 struct snd_emu10k1 *emu = dev_id;
21 unsigned int status, status2, orig_status, orig_status2;21 unsigned int status, orig_status;
22 int handled = 0;22 int handled = 0;
23 int timeout = 0;23 int timeout = 0;
24 24
@@ -139,32 +139,10 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) · 114 unmodified lines
139 status &= ~IPR_FXDSP;139 status &= ~IPR_FXDSP;
140 }140 }
141 if (status & IPR_P16V) {141 if (status & IPR_P16V) {
142 while ((status2 = inl(emu->port + IPR2)) != 0) {142 if (emu->p16v_interrupt)
143 u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */143 emu->p16v_interrupt(emu);
144 struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]);144 else
145 struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice);145 outl(0, emu->port + INTE2);
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 }
168 status &= ~IPR_P16V;146 status &= ~IPR_P16V;
169 }147 }
170 148
sound/pci/emu10k1/p16v.c+44−69
@@ -149,42 +149,19 @@ static const struct snd_pcm_hardware snd_p16v_capture_hw = { · 148 unmodified lines
149 .fifo_size = 0,149 .fifo_size = 0,
150};150};
151 151
152static 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
159/* open_playback callback */152/* open_playback callback */
160static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)153static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
161{154{
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;
165 struct snd_pcm_runtime *runtime = substream->runtime;155 struct snd_pcm_runtime *runtime = substream->runtime;
166 int err;156 int err;
167 157
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;
175 /*158 /*
176 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",159 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
177 substream->pcm->device, channel_id);160 substream->pcm->device, channel_id);
178 */161 */
179 runtime->private_data = epcm;
180 runtime->private_free = snd_p16v_pcm_free_substream;
181 162
182 runtime->hw = snd_p16v_playback_hw;163 runtime->hw = snd_p16v_playback_hw;
183 164
184 channel->emu = emu;
185 channel->number = channel_id;
186
187 channel->use=1;
188#if 0 /* debug */165#if 0 /* debug */
189 dev_dbg(emu->card->dev,166 dev_dbg(emu->card->dev,
190 "p16v: open channel_id=%d, channel=%p, use=0x%x\n",167 "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
193 channel_id, chip, channel);170 channel_id, chip, channel);
194#endif /* debug */171#endif /* debug */
195 /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */172 /* channel->interrupt = snd_p16v_pcm_channel_interrupt; */
196 channel->epcm = epcm;
197 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);173 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
198 if (err < 0)174 if (err < 0)
199 return err;175 return err;
@@ -205,44 +181,20 @@ static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substrea · 5 unmodified lines
205 181
206 return 0;182 return 0;
207}183}
184
208/* open_capture callback */185/* open_capture callback */
209static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)186static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
210{187{
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;
214 struct snd_pcm_runtime *runtime = substream->runtime;188 struct snd_pcm_runtime *runtime = substream->runtime;
215 int err;189 int err;
216 190
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;
224 /*191 /*
225 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",192 dev_dbg(emu->card->dev, "epcm device=%d, channel_id=%d\n",
226 substream->pcm->device, channel_id);193 substream->pcm->device, channel_id);
227 */194 */
228 runtime->private_data = epcm;
229 runtime->private_free = snd_p16v_pcm_free_substream;
230 195
231 runtime->hw = snd_p16v_capture_hw;196 runtime->hw = snd_p16v_capture_hw;
232 197
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;
246 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);198 err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
247 if (err < 0)199 if (err < 0)
248 return err;200 return err;
@@ -254,22 +206,12 @@ static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream · 5 unmodified lines
254/* close callback */206/* close callback */
255static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)207static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
256{208{
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 */
262 return 0;209 return 0;
263}210}
264 211
265/* close callback */212/* close callback */
266static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)213static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
267{214{
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 */
273 return 0;215 return 0;
274}216}
275 217
@@ -411,13 +353,48 @@ static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb) · 135 unmodified lines
411 spin_unlock_irqrestore(&emu->emu_lock, flags);353 spin_unlock_irqrestore(&emu->emu_lock, flags);
412}354}
413 355
356static 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
414/* trigger_playback callback */392/* trigger_playback callback */
415static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,393static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
416 int cmd)394 int cmd)
417{395{
418 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);396 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
419 struct snd_pcm_runtime *runtime;397 struct snd_pcm_runtime *runtime;
420 struct snd_emu10k1_pcm *epcm;
421 int channel;398 int channel;
422 int result = 0;399 int result = 0;
423 struct snd_pcm_substream *s;400 struct snd_pcm_substream *s;
@@ -439,10 +416,9 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, · 15 unmodified lines
439 s->stream != SNDRV_PCM_STREAM_PLAYBACK)416 s->stream != SNDRV_PCM_STREAM_PLAYBACK)
440 continue;417 continue;
441 runtime = s->runtime;418 runtime = s->runtime;
442 epcm = runtime->private_data;
443 channel = substream->pcm->device-emu->p16v_device_offset;419 channel = substream->pcm->device-emu->p16v_device_offset;
444 /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */420 /* dev_dbg(emu->card->dev, "p16v channel=%d\n", channel); */
445 epcm->running = running;421 runtime->private_data = (void *)(ptrdiff_t)running;
446 basic |= (0x1<<channel);422 basic |= (0x1<<channel);
447 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);423 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
448 snd_pcm_trigger_done(s, substream);424 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
471{447{
472 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);448 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
473 struct snd_pcm_runtime *runtime = substream->runtime;449 struct snd_pcm_runtime *runtime = substream->runtime;
474 struct snd_emu10k1_pcm *epcm = runtime->private_data;
475 int channel = 0;450 int channel = 0;
476 int result = 0;451 int result = 0;
477 u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;452 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
480 case SNDRV_PCM_TRIGGER_START:455 case SNDRV_PCM_TRIGGER_START:
481 snd_p16v_intr_enable(emu, inte);456 snd_p16v_intr_enable(emu, inte);
482 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));457 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;
484 break;459 break;
485 case SNDRV_PCM_TRIGGER_STOP:460 case SNDRV_PCM_TRIGGER_STOP:
486 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));461 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
487 snd_p16v_intr_disable(emu, inte);462 snd_p16v_intr_disable(emu, inte);
488 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));463 //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;
490 break;465 break;
491 default:466 default:
492 result = -EINVAL;467 result = -EINVAL;
@@ -501,10 +476,10 @@ snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream) · 8 unmodified lines
501{476{
502 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);477 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
503 struct snd_pcm_runtime *runtime = substream->runtime;478 struct snd_pcm_runtime *runtime = substream->runtime;
504 struct snd_emu10k1_pcm *epcm = runtime->private_data;
505 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;479 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
506 int channel = substream->pcm->device - emu->p16v_device_offset;480 int channel = substream->pcm->device - emu->p16v_device_offset;
507 if (!epcm->running)481
482 if (!runtime->private_data)
508 return 0;483 return 0;
509 484
510 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);485 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
526{501{
527 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);502 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
528 struct snd_pcm_runtime *runtime = substream->runtime;503 struct snd_pcm_runtime *runtime = substream->runtime;
529 struct snd_emu10k1_pcm *epcm = runtime->private_data;
530 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;504 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
531 int channel = 0;505 int channel = 0;
532 506
533 if (!epcm->running)507 if (!runtime->private_data)
534 return 0;508 return 0;
535 509
536 ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);510 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
591 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;565 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
592 strcpy(pcm->name, "p16v");566 strcpy(pcm->name, "p16v");
593 emu->pcm_p16v = pcm;567 emu->pcm_p16v = pcm;
568 emu->p16v_interrupt = snd_p16v_interrupt;
594 569
595 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 570 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
596 substream; 571 substream;
sound/pci/emu10k1/p16v.h+1−1
@@ -64,7 +64,7 @@ · 63 unmodified lines
64 */64 */
65 65
66/********************************************************************************************************/66/********************************************************************************************************/
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 */
68/********************************************************************************************************/68/********************************************************************************************************/
69 69
70/* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.70/* 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
6 */6 */
7 7
8/******************************************************************************/8/******************************************************************************/
9/* Audigy2Value Tina (P17V) pointer-offset register set,9/* Audigy2Value Tina (P17V) pointer-offset register set, */
10 * accessed through the PTR20 and DATA24 registers */10/* accessed through the PTR2 and DATA2 registers */
11/******************************************************************************/11/******************************************************************************/
12 12
13/* 00 - 07: Not used */13/* 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
514 break;514 break;
515 case HDA_GEN_PCM_ACT_PREPARE:515 case HDA_GEN_PCM_ACT_PREPARE:
516 mutex_lock(&cs35l41->fw_mutex);516 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);
518 mutex_unlock(&cs35l41->fw_mutex);518 mutex_unlock(&cs35l41->fw_mutex);
519 break;519 break;
520 case HDA_GEN_PCM_ACT_CLEANUP:520 case HDA_GEN_PCM_ACT_CLEANUP:
521 mutex_lock(&cs35l41->fw_mutex);521 mutex_lock(&cs35l41->fw_mutex);
522 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));522 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);
524 mutex_unlock(&cs35l41->fw_mutex);524 mutex_unlock(&cs35l41->fw_mutex);
525 break;525 break;
526 case HDA_GEN_PCM_ACT_CLOSE:526 case HDA_GEN_PCM_ACT_CLOSE:
@@ -672,7 +672,7 @@ static int cs35l41_runtime_suspend(struct device *dev) · 145 unmodified lines
672 if (cs35l41->playback_started) {672 if (cs35l41->playback_started) {
673 regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,673 regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
674 ARRAY_SIZE(cs35l41_hda_mute));674 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);
676 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,676 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
677 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);677 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
678 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)678 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
2528 /* Meteorlake-P */2528 /* Meteorlake-P */
2529 { PCI_DEVICE(0x8086, 0x7e28),2529 { PCI_DEVICE(0x8086, 0x7e28),
2530 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2530 .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},
2531 /* Broxton-P(Apollolake) */2534 /* Broxton-P(Apollolake) */
2532 { PCI_DEVICE(0x8086, 0x5a98),2535 { PCI_DEVICE(0x8086, 0x5a98),
2533 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },2536 .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
580 return; /* no error return from async probe */580 return; /* no error return from async probe */
581}581}
582 582
583static int hda_tegra_remove(struct platform_device *pdev)583static void hda_tegra_remove(struct platform_device *pdev)
584{584{
585 snd_card_free(dev_get_drvdata(&pdev->dev));585 snd_card_free(dev_get_drvdata(&pdev->dev));
586 pm_runtime_disable(&pdev->dev);586 pm_runtime_disable(&pdev->dev);
587
588 return 0;
589}587}
590 588
591static void hda_tegra_shutdown(struct platform_device *pdev)589static void hda_tegra_shutdown(struct platform_device *pdev)
@@ -607,7 +605,7 @@ static struct platform_driver tegra_platform_hda = { · 15 unmodified lines
607 .of_match_table = hda_tegra_match,605 .of_match_table = hda_tegra_match,
608 },606 },
609 .probe = hda_tegra_probe,607 .probe = hda_tegra_probe,
610 .remove = hda_tegra_remove,608 .remove_new = hda_tegra_remove,
611 .shutdown = hda_tegra_shutdown,609 .shutdown = hda_tegra_shutdown,
612};610};
613module_platform_driver(tegra_platform_hda);611module_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
2104 goto unlock;2104 goto unlock;
2105 }2105 }
2106 2106
2107 if (snd_BUG_ON(pin_idx < 0)) {
2108 err = -EINVAL;
2109 goto unlock;
2110 }
2111 per_pin = get_pin(spec, pin_idx);2107 per_pin = get_pin(spec, pin_idx);
2112 2108
2113 /* Verify pin:cvt selections to avoid silent audio after S3.2109 /* 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
2199 snd_hda_spdif_ctls_unassign(codec, pcm_idx);2195 snd_hda_spdif_ctls_unassign(codec, pcm_idx);
2200 clear_bit(pcm_idx, &spec->pcm_in_use);2196 clear_bit(pcm_idx, &spec->pcm_in_use);
2201 pin_idx = hinfo_to_pin_index(codec, hinfo);2197 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 */
2202 if (pin_idx < 0)2202 if (pin_idx < 0)
2203 goto unlock;2203 goto unlock;
2204 2204
2205 if (snd_BUG_ON(pin_idx < 0)) {
2206 err = -EINVAL;
2207 goto unlock;
2208 }
2209 per_pin = get_pin(spec, pin_idx);2205 per_pin = get_pin(spec, pin_idx);
2210 2206
2211 if (spec->dyn_pin_out) {2207 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
6146 return 0;6146 return 0;
6147}6147}
6148 6148
6149static 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
6155static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,6149static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6156 unsigned int cmd, unsigned long arg)6150 unsigned int cmd, unsigned long arg)
6157{6151{
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
98 case 0x204: legacy_ctrl2 |= 2 << 6; break;98 case 0x204: legacy_ctrl2 |= 2 << 6; break;
99 case 0x205: legacy_ctrl2 |= 3 << 6; break;99 case 0x205: legacy_ctrl2 |= 3 << 6; break;
100 default:100 default:
101 dev_err(chip->card->dev,101 if (io_port > 0)
102 "invalid joystick port %#x", io_port);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);
103 return -EINVAL;105 return -EINVAL;
104 }106 }
105 }107 }
@@ -186,6 +188,13 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 80 unmodified lines
186 default: model = str = "???"; break;188 default: model = str = "???"; break;
187 }189 }
188 190
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
189 legacy_ctrl = 0;198 legacy_ctrl = 0;
190 legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */199 legacy_ctrl2 = 0x0800; /* SBEN = 0, SMOD = 01, LAD = 0 */
191 200
@@ -218,7 +227,13 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, · 26 unmodified lines
218 case 0x398: legacy_ctrl2 |= 1; break;227 case 0x398: legacy_ctrl2 |= 1; break;
219 case 0x3a0: legacy_ctrl2 |= 2; break;228 case 0x3a0: legacy_ctrl2 |= 2; break;
220 case 0x3a8: legacy_ctrl2 |= 3; break;229 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;
222 }237 }
223 if (fm_port[dev] > 0)238 if (fm_port[dev] > 0)
224 fm_res = devm_request_region(&pci->dev, fm_port[dev],239 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
234 case 0x300: legacy_ctrl2 |= 1 << 4; break;249 case 0x300: legacy_ctrl2 |= 1 << 4; break;
235 case 0x332: legacy_ctrl2 |= 2 << 4; break;250 case 0x332: legacy_ctrl2 |= 2 << 4; break;
236 case 0x334: legacy_ctrl2 |= 3 << 4; break;251 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;
238 }259 }
239 if (mpu_port[dev] > 0)260 if (mpu_port[dev] > 0)
240 mpu_res = devm_request_region(&pci->dev, mpu_port[dev],261 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
257 if (err < 0)278 if (err < 0)
258 return err;279 return err;
259 280
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);
266 err = snd_ymfpci_pcm(chip, 0);281 err = snd_ymfpci_pcm(chip, 0);
267 if (err < 0)282 if (err < 0)
268 return err;283 return err;
@@ -337,11 +352,9 @@ static struct pci_driver ymfpci_driver = { · 68 unmodified lines
337 .name = KBUILD_MODNAME,352 .name = KBUILD_MODNAME,
338 .id_table = snd_ymfpci_ids,353 .id_table = snd_ymfpci_ids,
339 .probe = snd_card_ymfpci_probe,354 .probe = snd_card_ymfpci_probe,
340#ifdef CONFIG_PM_SLEEP
341 .driver = {355 .driver = {
342 .pm = &snd_ymfpci_pm,356 .pm = pm_sleep_ptr(&snd_ymfpci_pm),
343 },357 },
344#endif
345};358};
346 359
347module_pci_driver(ymfpci_driver);360module_pci_driver(ymfpci_driver);
sound/pci/ymfpci/ymfpci.h+47−7
@@ -268,6 +268,49 @@ struct snd_ymfpci_pcm { · 267 unmodified lines
268 u32 shift;268 u32 shift;
269};269};
270 270
271static 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
300static 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
312static_assert(DSXG_PCI_NUM_SAVED_LEGACY_REGS <= DSXG_PCI_NUM_SAVED_REGS);
313
271struct snd_ymfpci {314struct snd_ymfpci {
272 int irq;315 int irq;
273 316
@@ -276,7 +319,7 @@ struct snd_ymfpci { · 2 unmodified lines
276 unsigned long reg_area_phys;319 unsigned long reg_area_phys;
277 void __iomem *reg_area_virt;320 void __iomem *reg_area_virt;
278 321
279 unsigned short old_legacy_ctrl;322 u16 old_legacy_ctrl;
280#ifdef SUPPORT_JOYSTICK323#ifdef SUPPORT_JOYSTICK
281 struct gameport *gameport;324 struct gameport *gameport;
282#endif325#endif
@@ -345,17 +388,14 @@ struct snd_ymfpci { · 62 unmodified lines
345 const struct firmware *dsp_microcode;388 const struct firmware *dsp_microcode;
346 const struct firmware *controller_microcode;389 const struct firmware *controller_microcode;
347 390
348#ifdef CONFIG_PM_SLEEP391 u32 saved_regs[YDSXGR_NUM_SAVED_REGS];
349 u32 *saved_regs;
350 u32 saved_ydsxgr_mode;392 u32 saved_ydsxgr_mode;
351 u16 saved_dsxg_legacy;393 u16 saved_dsxg_pci_regs[DSXG_PCI_NUM_SAVED_REGS];
352 u16 saved_dsxg_elegacy;
353#endif
354};394};
355 395
356int snd_ymfpci_create(struct snd_card *card,396int snd_ymfpci_create(struct snd_card *card,
357 struct pci_dev *pci,397 struct pci_dev *pci,
358 unsigned short old_legacy_ctrl);398 u16 old_legacy_ctrl);
359void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);399void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
360 400
361extern const struct dev_pm_ops snd_ymfpci_pm;401extern const struct dev_pm_ops snd_ymfpci_pm;
sound/pci/ymfpci/ymfpci_main.c+22−57
@@ -31,11 +31,6 @@ · 30 unmodified lines
31 31
32static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);32static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);
33 33
34static inline u8 snd_ymfpci_readb(struct snd_ymfpci *chip, u32 offset)
35{
36 return readb(chip->reg_area_virt + offset);
37}
38
39static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)34static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)
40{35{
41 writeb(val, chip->reg_area_virt + offset);36 writeb(val, chip->reg_area_virt + offset);
@@ -2219,57 +2214,33 @@ static void snd_ymfpci_free(struct snd_card *card) · 2177 unmodified lines
2219 2214
2220 snd_ymfpci_free_gameport(chip);2215 snd_ymfpci_free_gameport(chip);
2221 2216
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);
2223 2218
2224 release_firmware(chip->dsp_microcode);2219 release_firmware(chip->dsp_microcode);
2225 release_firmware(chip->controller_microcode);2220 release_firmware(chip->controller_microcode);
2226}2221}
2227 2222
2228#ifdef CONFIG_PM_SLEEP
2229static 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
2258static int snd_ymfpci_suspend(struct device *dev)2223static int snd_ymfpci_suspend(struct device *dev)
2259{2224{
2260 struct snd_card *card = dev_get_drvdata(dev);2225 struct snd_card *card = dev_get_drvdata(dev);
2261 struct snd_ymfpci *chip = card->private_data;2226 struct snd_ymfpci *chip = card->private_data;
2262 unsigned int i;2227 unsigned int i, legacy_reg_count = DSXG_PCI_NUM_SAVED_LEGACY_REGS;
2263 2228
2229 if (chip->pci->device >= 0x0010) /* YMF 744/754 */
2230 legacy_reg_count = DSXG_PCI_NUM_SAVED_REGS;
2231
2264 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);2232 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2265 snd_ac97_suspend(chip->ac97);2233 snd_ac97_suspend(chip->ac97);
2234
2266 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)2235 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2267 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);2236 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2237
2268 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);2238 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2269 pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,2239
2270 &chip->saved_dsxg_legacy);2240 for (i = 0; i < legacy_reg_count; i++)
2271 pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,2241 pci_read_config_word(chip->pci, pci_saved_regs_index[i],
2272 &chip->saved_dsxg_elegacy);2242 chip->saved_dsxg_pci_regs + i);
2243
2273 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);2244 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2274 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);2245 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2275 snd_ymfpci_disable_dsp(chip);2246 snd_ymfpci_disable_dsp(chip);
@@ -2281,7 +2252,10 @@ static int snd_ymfpci_resume(struct device *dev) · 5 unmodified lines
2281 struct pci_dev *pci = to_pci_dev(dev);2252 struct pci_dev *pci = to_pci_dev(dev);
2282 struct snd_card *card = dev_get_drvdata(dev);2253 struct snd_card *card = dev_get_drvdata(dev);
2283 struct snd_ymfpci *chip = card->private_data;2254 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;
2285 2259
2286 snd_ymfpci_aclink_reset(pci);2260 snd_ymfpci_aclink_reset(pci);
2287 snd_ymfpci_codec_ready(chip, 0);2261 snd_ymfpci_codec_ready(chip, 0);
@@ -2293,10 +2267,9 @@ static int snd_ymfpci_resume(struct device *dev) · 5 unmodified lines
2293 2267
2294 snd_ac97_resume(chip->ac97);2268 snd_ac97_resume(chip->ac97);
2295 2269
2296 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,2270 for (i = 0; i < legacy_reg_count; i++)
2297 chip->saved_dsxg_legacy);2271 pci_write_config_word(chip->pci, pci_saved_regs_index[i],
2298 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,2272 chip->saved_dsxg_pci_regs[i]);
2299 chip->saved_dsxg_elegacy);
2300 2273
2301 /* start hw again */2274 /* start hw again */
2302 if (chip->start_count > 0) {2275 if (chip->start_count > 0) {
@@ -2309,12 +2282,11 @@ static int snd_ymfpci_resume(struct device *dev) · 6 unmodified lines
2309 return 0;2282 return 0;
2310}2283}
2311 2284
2312SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);2285DEFINE_SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
2313#endif /* CONFIG_PM_SLEEP */
2314 2286
2315int snd_ymfpci_create(struct snd_card *card,2287int snd_ymfpci_create(struct snd_card *card,
2316 struct pci_dev *pci,2288 struct pci_dev *pci,
2317 unsigned short old_legacy_ctrl)2289 u16 old_legacy_ctrl)
2318{2290{
2319 struct snd_ymfpci *chip = card->private_data;2291 struct snd_ymfpci *chip = card->private_data;
2320 int err;2292 int err;
@@ -2379,13 +2351,6 @@ int snd_ymfpci_create(struct snd_card *card, · 58 unmodified lines
2379 if (err < 0)2351 if (err < 0)
2380 return err;2352 return err;
2381 2353
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
2389 snd_ymfpci_proc_init(card, chip);2354 snd_ymfpci_proc_init(card, chip);
2390 2355
2391 return 0;2356 return 0;
sound/ppc/powermac.c+2−3
@@ -130,10 +130,9 @@ __error: · 129 unmodified lines
130}130}
131 131
132 132
133static int snd_pmac_remove(struct platform_device *devptr)133static void snd_pmac_remove(struct platform_device *devptr)
134{134{
135 snd_card_free(platform_get_drvdata(devptr));135 snd_card_free(platform_get_drvdata(devptr));
136 return 0;
137}136}
138 137
139#ifdef CONFIG_PM_SLEEP138#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
161 160
162static struct platform_driver snd_pmac_driver = {161static struct platform_driver snd_pmac_driver = {
163 .probe = snd_pmac_probe,162 .probe = snd_pmac_probe,
164 .remove = snd_pmac_remove,163 .remove_new = snd_pmac_remove,
165 .driver = {164 .driver = {
166 .name = SND_PMAC_DRIVER,165 .name = SND_PMAC_DRIVER,
167 .pm = SND_PMAC_PM_OPS,166 .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
1361 1361
1362 for_each_child_of_node(chip->node, np) {1362 for_each_child_of_node(chip->node, np) {
1363 if (of_node_name_eq(np, "sound")) {1363 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"))
1365 mix->anded_reset = 1;1365 mix->anded_reset = 1;
1366 if (of_get_property(np, "layout-id", NULL))1366 if (of_property_present(np, "layout-id"))
1367 mix->reset_on_sleep = 0;1367 mix->reset_on_sleep = 0;
1368 of_node_put(np);1368 of_node_put(np);
1369 break;1369 break;
sound/sh/aica.c+2−5
@@ -539,15 +539,12 @@ static int add_aicamixer_controls(struct snd_card_aica *dreamcastcard) · 538 unmodified lines
539 return 0;539 return 0;
540}540}
541 541
542static int snd_aica_remove(struct platform_device *devptr)542static void snd_aica_remove(struct platform_device *devptr)
543{543{
544 struct snd_card_aica *dreamcastcard;544 struct snd_card_aica *dreamcastcard;
545 dreamcastcard = platform_get_drvdata(devptr);545 dreamcastcard = platform_get_drvdata(devptr);
546 if (unlikely(!dreamcastcard))
547 return -ENODEV;
548 snd_card_free(dreamcastcard->card);546 snd_card_free(dreamcastcard->card);
549 kfree(dreamcastcard);547 kfree(dreamcastcard);
550 return 0;
551}548}
552 549
553static int snd_aica_probe(struct platform_device *devptr)550static int snd_aica_probe(struct platform_device *devptr)
@@ -594,7 +591,7 @@ static int snd_aica_probe(struct platform_device *devptr) · 40 unmodified lines
594 591
595static struct platform_driver snd_aica_driver = {592static struct platform_driver snd_aica_driver = {
596 .probe = snd_aica_probe,593 .probe = snd_aica_probe,
597 .remove = snd_aica_remove,594 .remove_new = snd_aica_remove,
598 .driver = {595 .driver = {
599 .name = SND_AICA_DRIVER,596 .name = SND_AICA_DRIVER,
600 },597 },
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
257 257
258 258
259/* driver .remove -- destructor */259/* driver .remove -- destructor */
260static int snd_sh_dac_remove(struct platform_device *devptr)260static void snd_sh_dac_remove(struct platform_device *devptr)
261{261{
262 snd_card_free(platform_get_drvdata(devptr));262 snd_card_free(platform_get_drvdata(devptr));
263 return 0;
264}263}
265 264
266/* free -- it has been defined by create */265/* free -- it has been defined by create */
@@ -403,7 +402,7 @@ probe_error: · 136 unmodified lines
403 */402 */
404static struct platform_driver sh_dac_driver = {403static struct platform_driver sh_dac_driver = {
405 .probe = snd_sh_dac_probe,404 .probe = snd_sh_dac_probe,
406 .remove = snd_sh_dac_remove,405 .remove_new = snd_sh_dac_remove,
407 .driver = {406 .driver = {
408 .name = "dac_audio",407 .name = "dac_audio",
409 },408 },
sound/soc/adi/axi-i2s.c+2−4
@@ -274,13 +274,11 @@ err_clk_disable: · 273 unmodified lines
274 return ret;274 return ret;
275}275}
276 276
277static int axi_i2s_dev_remove(struct platform_device *pdev)277static void axi_i2s_dev_remove(struct platform_device *pdev)
278{278{
279 struct axi_i2s *i2s = platform_get_drvdata(pdev);279 struct axi_i2s *i2s = platform_get_drvdata(pdev);
280 280
281 clk_disable_unprepare(i2s->clk);281 clk_disable_unprepare(i2s->clk);
282
283 return 0;
284}282}
285 283
286static const struct of_device_id axi_i2s_of_match[] = {284static const struct of_device_id axi_i2s_of_match[] = {
@@ -295,7 +293,7 @@ static struct platform_driver axi_i2s_driver = { · 8 unmodified lines
295 .of_match_table = axi_i2s_of_match,293 .of_match_table = axi_i2s_of_match,
296 },294 },
297 .probe = axi_i2s_probe,295 .probe = axi_i2s_probe,
298 .remove = axi_i2s_dev_remove,296 .remove_new = axi_i2s_dev_remove,
299};297};
300module_platform_driver(axi_i2s_driver);298module_platform_driver(axi_i2s_driver);
301 299
sound/soc/adi/axi-spdif.c+2−4
@@ -239,13 +239,11 @@ err_clk_disable: · 238 unmodified lines
239 return ret;239 return ret;
240}240}
241 241
242static int axi_spdif_dev_remove(struct platform_device *pdev)242static void axi_spdif_dev_remove(struct platform_device *pdev)
243{243{
244 struct axi_spdif *spdif = platform_get_drvdata(pdev);244 struct axi_spdif *spdif = platform_get_drvdata(pdev);
245 245
246 clk_disable_unprepare(spdif->clk);246 clk_disable_unprepare(spdif->clk);
247
248 return 0;
249}247}
250 248
251static const struct of_device_id axi_spdif_of_match[] = {249static const struct of_device_id axi_spdif_of_match[] = {
@@ -260,7 +258,7 @@ static struct platform_driver axi_spdif_driver = { · 8 unmodified lines
260 .of_match_table = axi_spdif_of_match,258 .of_match_table = axi_spdif_of_match,
261 },259 },
262 .probe = axi_spdif_probe,260 .probe = axi_spdif_probe,
263 .remove = axi_spdif_dev_remove,261 .remove_new = axi_spdif_dev_remove,
264};262};
265module_platform_driver(axi_spdif_driver);263module_platform_driver(axi_spdif_driver);
266 264
sound/soc/amd/Kconfig+2−0
@@ -90,6 +90,7 @@ config SND_SOC_AMD_VANGOGH_MACH · 89 unmodified lines
90 90
91config SND_SOC_AMD_ACP6x91config SND_SOC_AMD_ACP6x
92 tristate "AMD Audio Coprocessor-v6.x Yellow Carp support"92 tristate "AMD Audio Coprocessor-v6.x Yellow Carp support"
93 select SND_AMD_ACP_CONFIG
93 depends on X86 && PCI94 depends on X86 && PCI
94 help95 help
95 This option enables Audio Coprocessor i.e ACP v6.x support on96 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
130 131
131config SND_SOC_AMD_PS132config SND_SOC_AMD_PS
132 tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"133 tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
134 select SND_AMD_ACP_CONFIG
133 depends on X86 && PCI && ACPI135 depends on X86 && PCI && ACPI
134 help136 help
135 This option enables Audio Coprocessor i.e ACP v6.3 support on137 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
1323 return status;1323 return status;
1324}1324}
1325 1325
1326static int acp_audio_remove(struct platform_device *pdev)1326static void acp_audio_remove(struct platform_device *pdev)
1327{1327{
1328 int status;1328 int status;
1329 struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev);1329 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
1332 if (status)1332 if (status)
1333 dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);1333 dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status);
1334 pm_runtime_disable(&pdev->dev);1334 pm_runtime_disable(&pdev->dev);
1335
1336 return 0;
1337}1335}
1338 1336
1339static int acp_pcm_resume(struct device *dev)1337static int acp_pcm_resume(struct device *dev)
@@ -1428,7 +1426,7 @@ static const struct dev_pm_ops acp_pm_ops = { · 88 unmodified lines
1428 1426
1429static struct platform_driver acp_dma_driver = {1427static struct platform_driver acp_dma_driver = {
1430 .probe = acp_audio_probe,1428 .probe = acp_audio_probe,
1431 .remove = acp_audio_remove,1429 .remove_new = acp_audio_remove,
1432 .driver = {1430 .driver = {
1433 .name = DRV_NAME,1431 .name = DRV_NAME,
1434 .pm = &acp_pm_ops,1432 .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
366 return 0;366 return 0;
367}367}
368 368
369static int rembrandt_audio_remove(struct platform_device *pdev)369static void rembrandt_audio_remove(struct platform_device *pdev)
370{370{
371 struct device *dev = &pdev->dev;371 struct device *dev = &pdev->dev;
372 struct acp_dev_data *adata = dev_get_drvdata(dev);372 struct acp_dev_data *adata = dev_get_drvdata(dev);
373 struct acp_chip_info *chip;373 struct acp_chip_info *chip = dev_get_platdata(dev);
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 }
380 374
381 rmb_acp_deinit(chip->base);375 rmb_acp_deinit(chip->base);
382 376
383 acp6x_disable_interrupts(adata);377 acp6x_disable_interrupts(adata);
384 acp_platform_unregister(dev);378 acp_platform_unregister(dev);
385 return 0;
386}379}
387 380
388static struct platform_driver rembrandt_driver = {381static struct platform_driver rembrandt_driver = {
389 .probe = rembrandt_audio_probe,382 .probe = rembrandt_audio_probe,
390 .remove = rembrandt_audio_remove,383 .remove_new = rembrandt_audio_remove,
391 .driver = {384 .driver = {
392 .name = "acp_asoc_rembrandt",385 .name = "acp_asoc_rembrandt",
393 },386 },
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
313 return 0;313 return 0;
314}314}
315 315
316static int renoir_audio_remove(struct platform_device *pdev)316static void renoir_audio_remove(struct platform_device *pdev)
317{317{
318 struct device *dev = &pdev->dev;318 struct device *dev = &pdev->dev;
319 struct acp_dev_data *adata = dev_get_drvdata(dev);319 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
329 dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret));329 dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret));
330 330
331 acp_platform_unregister(dev);331 acp_platform_unregister(dev);
332 return 0;
333}332}
334 333
335static struct platform_driver renoir_driver = {334static struct platform_driver renoir_driver = {
336 .probe = renoir_audio_probe,335 .probe = renoir_audio_probe,
337 .remove = renoir_audio_remove,336 .remove_new = renoir_audio_remove,
338 .driver = {337 .driver = {
339 .name = "acp_asoc_renoir",338 .name = "acp_asoc_renoir",
340 },339 },
sound/soc/amd/ps/acp63.h+2−0
@@ -111,3 +111,5 @@ struct acp63_dev_data { · 110 unmodified lines
111 u16 pdev_count;111 u16 pdev_count;
112 u16 pdm_dev_index;112 u16 pdm_dev_index;
113};113};
114
115int 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
91 dev_err(dev, "ACP reset failed\n");91 dev_err(dev, "ACP reset failed\n");
92 return ret;92 return ret;
93 }93 }
94 acp63_writel(0x03, acp_base + ACP_CLKMUX_SEL);
95 acp63_enable_interrupts(acp_base);94 acp63_enable_interrupts(acp_base);
96 return 0;95 return 0;
97}96}
@@ -106,7 +105,6 @@ static int acp63_deinit(void __iomem *acp_base, struct device *dev) · 8 unmodified lines
106 dev_err(dev, "ACP reset failed\n");105 dev_err(dev, "ACP reset failed\n");
107 return ret;106 return ret;
108 }107 }
109 acp63_writel(0, acp_base + ACP_CLKMUX_SEL);
110 acp63_writel(0, acp_base + ACP_CONTROL);108 acp63_writel(0, acp_base + ACP_CONTROL);
111 return 0;109 return 0;
112}110}
@@ -249,11 +247,17 @@ static int snd_acp63_probe(struct pci_dev *pci, · 136 unmodified lines
249{247{
250 struct acp63_dev_data *adata;248 struct acp63_dev_data *adata;
251 u32 addr;249 u32 addr;
252 u32 irqflags;250 u32 irqflags, flag;
253 int val;251 int val;
254 int ret;252 int ret;
255 253
256 irqflags = IRQF_SHARED;254 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
257 /* Pink Sardine device check */261 /* Pink Sardine device check */
258 switch (pci->revision) {262 switch (pci->revision) {
259 case 0x63:263 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
399 return 0;399 return 0;
400}400}
401 401
402static int acp63_pdm_audio_remove(struct platform_device *pdev)402static void acp63_pdm_audio_remove(struct platform_device *pdev)
403{403{
404 pm_runtime_disable(&pdev->dev);404 pm_runtime_disable(&pdev->dev);
405 return 0;
406}405}
407 406
408static int __maybe_unused acp63_pdm_resume(struct device *dev)407static 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
451 450
452static struct platform_driver acp63_pdm_dma_driver = {451static struct platform_driver acp63_pdm_dma_driver = {
453 .probe = acp63_pdm_audio_probe,452 .probe = acp63_pdm_audio_probe,
454 .remove = acp63_pdm_audio_remove,453 .remove_new = acp63_pdm_audio_remove,
455 .driver = {454 .driver = {
456 .name = "acp_ps_pdm_dma",455 .name = "acp_ps_pdm_dma",
457 .pm = &acp63_pdm_pm_ops,456 .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
421 return 0;421 return 0;
422}422}
423 423
424static int acp3x_audio_remove(struct platform_device *pdev)424static void acp3x_audio_remove(struct platform_device *pdev)
425{425{
426 pm_runtime_disable(&pdev->dev);426 pm_runtime_disable(&pdev->dev);
427 return 0;
428}427}
429 428
430static int acp3x_resume(struct device *dev)429static int acp3x_resume(struct device *dev)
@@ -509,7 +508,7 @@ static const struct dev_pm_ops acp3x_pm_ops = { · 78 unmodified lines
509 508
510static struct platform_driver acp3x_dma_driver = {509static struct platform_driver acp3x_dma_driver = {
511 .probe = acp3x_audio_probe,510 .probe = acp3x_audio_probe,
512 .remove = acp3x_audio_remove,511 .remove_new = acp3x_audio_remove,
513 .driver = {512 .driver = {
514 .name = "acp3x_rv_i2s_dma",513 .name = "acp3x_rv_i2s_dma",
515 .pm = &acp3x_pm_ops,514 .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
435 return 0;435 return 0;
436}436}
437 437
438static int acp_pdm_audio_remove(struct platform_device *pdev)438static void acp_pdm_audio_remove(struct platform_device *pdev)
439{439{
440 pm_runtime_disable(&pdev->dev);440 pm_runtime_disable(&pdev->dev);
441 return 0;
442}441}
443 442
444static int acp_pdm_resume(struct device *dev)443static int acp_pdm_resume(struct device *dev)
@@ -489,7 +488,7 @@ static const struct dev_pm_ops acp_pdm_pm_ops = { · 44 unmodified lines
489 488
490static struct platform_driver acp_pdm_dma_driver = {489static struct platform_driver acp_pdm_dma_driver = {
491 .probe = acp_pdm_audio_probe,490 .probe = acp_pdm_audio_probe,
492 .remove = acp_pdm_audio_remove,491 .remove_new = acp_pdm_audio_remove,
493 .driver = {492 .driver = {
494 .name = "acp_rn_pdm_dma",493 .name = "acp_rn_pdm_dma",
495 .pm = &acp_pdm_pm_ops,494 .pm = &acp_pdm_pm_ops,
sound/soc/amd/vangogh/acp5x-mach.c+144−153
@@ -6,37 +6,40 @@ · 5 unmodified lines
6 * Copyright 2021 Advanced Micro Devices, Inc.6 * Copyright 2021 Advanced Micro Devices, Inc.
7 */7 */
8 8
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>
22#include <linux/acpi.h>9#include <linux/acpi.h>
23#include <linux/dmi.h>10#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>
24 19
25#include "../../codecs/nau8821.h"20#include "../../codecs/nau8821.h"
26#include "../../codecs/cs35l41.h"
27
28#include "acp5x.h"21#include "acp5x.h"
29 22
30#define DRV_NAME "acp5x_mach"23#define DRV_NAME "acp5x_mach"
31#define DUAL_CHANNEL 224#define DUAL_CHANNEL 2
32#define ACP5X_NUVOTON_CODEC_DAI "nau8821-hifi"25#define VG_JUPITER 1
33#define VG_JUPITER 126#define ACP5X_NAU8821_BCLK 3072000
34#define ACP5X_NUVOTON_BCLK 307200027#define ACP5X_NAU8821_FREQ_OUT 12288000
35#define ACP5X_NAU8821_FREQ_OUT 1228800028#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"
36 33
37static unsigned long acp5x_machine_id;34static unsigned long acp5x_machine_id;
38static struct snd_soc_jack vg_headset;35static struct snd_soc_jack vg_headset;
39 36
37SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
38SND_SOC_DAILINK_DEF(acp5x_i2s, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0")));
39SND_SOC_DAILINK_DEF(acp5x_bt, DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1")));
40SND_SOC_DAILINK_DEF(nau8821, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_NAU8821_COMP_NAME,
41 ACP5X_NAU8821_DAI_NAME)));
42
40static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = {43static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = {
41 {44 {
42 .pin = "Headphone",45 .pin = "Headphone",
@@ -48,18 +51,54 @@ static struct snd_soc_jack_pin acp5x_nau8821_jack_pins[] = { · 5 unmodified lines
48 },51 },
49};52};
50 53
54static 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
60static 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
51static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd)92static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd)
52{93{
94 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
53 int ret;95 int ret;
54 struct snd_soc_card *card = rtd->card;
55 struct snd_soc_component *component =
56 asoc_rtd_to_codec(rtd, 0)->component;
57 96
58 /*97 /*
59 * Headset buttons map to the google Reference headset.98 * Headset buttons map to the google Reference headset.
60 * These can be configured by userspace.99 * These can be configured by userspace.
61 */100 */
62 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",101 ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",
63 SND_JACK_HEADSET | SND_JACK_BTN_0,102 SND_JACK_HEADSET | SND_JACK_BTN_0,
64 &vg_headset, acp5x_nau8821_jack_pins,103 &vg_headset, acp5x_nau8821_jack_pins,
65 ARRAY_SIZE(acp5x_nau8821_jack_pins));104 ARRAY_SIZE(acp5x_nau8821_jack_pins));
@@ -70,12 +109,8 @@ static int acp5x_8821_init(struct snd_soc_pcm_runtime *rtd) · 4 unmodified lines
70 109
71 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_MEDIA);110 snd_jack_set_key(vg_headset.jack, SND_JACK_BTN_0, KEY_MEDIA);
72 nau8821_enable_jack_detect(component, &vg_headset);111 nau8821_enable_jack_detect(component, &vg_headset);
73 return ret;
74}
75 112
76static int acp5x_cs35l41_init(struct snd_soc_pcm_runtime *rtd)113 return ret;
77{
78 return 0;
79}114}
80 115
81static const unsigned int rates[] = {116static const unsigned int rates[] = {
@@ -109,8 +144,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) · 27 unmodified lines
109{144{
110 struct snd_pcm_runtime *runtime = substream->runtime;145 struct snd_pcm_runtime *runtime = substream->runtime;
111 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);146 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
112 struct snd_soc_card *card = rtd->card;147 struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
113 struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);
114 148
115 machine->play_i2s_instance = I2S_SP_INSTANCE;149 machine->play_i2s_instance = I2S_SP_INSTANCE;
116 machine->cap_i2s_instance = I2S_SP_INSTANCE;150 machine->cap_i2s_instance = I2S_SP_INSTANCE;
@@ -123,6 +157,7 @@ static int acp5x_8821_startup(struct snd_pcm_substream *substream) · 6 unmodified lines
123 snd_pcm_hw_constraint_list(substream->runtime, 0,157 snd_pcm_hw_constraint_list(substream->runtime, 0,
124 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,158 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
125 &constraints_sample_bits);159 &constraints_sample_bits);
160
126 return 0;161 return 0;
127}162}
128 163
@@ -131,29 +166,36 @@ static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream, · 2 unmodified lines
131{166{
132 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);167 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
133 struct snd_soc_card *card = rtd->card;168 struct snd_soc_card *card = rtd->card;
134 struct snd_soc_dai *codec_dai =169 struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
135 snd_soc_card_get_codec_dai(card,170 int ret, bclk;
136 ACP5X_NUVOTON_CODEC_DAI);
137 int ret;
138 171
139 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,172 ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
140 SND_SOC_CLOCK_IN);
141 if (ret < 0)173 if (ret < 0)
142 dev_err(card->dev, "can't set FS clock %d\n", ret);174 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),175
144 params_rate(params) * 256);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);
145 if (ret < 0)183 if (ret < 0)
146 dev_err(card->dev, "can't set FLL: %d\n", ret);184 dev_err(card->dev, "can't set FLL: %d\n", ret);
147 185
148 return ret;186 return ret;
149}187}
150 188
189static const struct snd_soc_ops acp5x_8821_ops = {
190 .startup = acp5x_8821_startup,
191 .hw_params = acp5x_nau8821_hw_params,
192};
193
151static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)194static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream)
152{195{
153 struct snd_pcm_runtime *runtime = substream->runtime;
154 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);196 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
155 struct snd_soc_card *card = rtd->card;197 struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
156 struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(card);198 struct snd_pcm_runtime *runtime = substream->runtime;
157 199
158 machine->play_i2s_instance = I2S_HS_INSTANCE;200 machine->play_i2s_instance = I2S_HS_INSTANCE;
159 201
@@ -162,6 +204,7 @@ static int acp5x_cs35l41_startup(struct snd_pcm_substream *substream) · 2 unmodified lines
162 &constraints_channels);204 &constraints_channels);
163 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,205 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
164 &constraints_rates);206 &constraints_rates);
207
165 return 0;208 return 0;
166}209}
167 210
@@ -169,80 +212,66 @@ static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream, · 1 unmodified line
169 struct snd_pcm_hw_params *params)212 struct snd_pcm_hw_params *params)
170{213{
171 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);214 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
172 struct snd_soc_card *card = rtd->card;215 unsigned int bclk, rate = params_rate(params);
173 struct snd_soc_dai *codec_dai;216 struct snd_soc_component *comp;
174 int ret, i;217 int ret, i;
175 unsigned int num_codecs = rtd->dai_link->num_codecs;218
176 unsigned int bclk_val;219 switch (rate) {
177 220 case 48000:
178 ret = 0;221 bclk = 1536000;
179 for (i = 0; i < num_codecs; i++) {222 break;
180 codec_dai = asoc_rtd_to_codec(rtd, i);223 default:
181 if (strcmp(codec_dai->name, "cs35l41-pcm") == 0) {224 bclk = 0;
182 switch (params_rate(params)) {225 break;
183 case 48000:226 }
184 bclk_val = 1536000;227
185 break;228 for_each_rtd_components(rtd, i, comp) {
186 default:229 if (!(strcmp(comp->name, ACP5X_CS35L41_COMP_LNAME)) ||
187 dev_err(card->dev, "Invalid Samplerate:0x%x\n",230 !(strcmp(comp->name, ACP5X_CS35L41_COMP_RNAME))) {
188 params_rate(params));231 if (!bclk) {
232 dev_err(comp->dev, "Invalid sample rate: 0x%x\n", rate);
189 return -EINVAL;233 return -EINVAL;
190 }234 }
191 ret = snd_soc_component_set_sysclk(codec_dai->component,235
192 0, 0, bclk_val, SND_SOC_CLOCK_IN);236 ret = snd_soc_component_set_sysclk(comp, 0, 0, bclk, SND_SOC_CLOCK_IN);
193 if (ret < 0) {237 if (ret) {
194 dev_err(card->dev, "failed to set sysclk for CS35l41 dai\n");238 dev_err(comp->dev, "failed to set SYSCLK: %d\n", ret);
195 return ret;239 return ret;
196 }240 }
197 }241 }
198 }242 }
199 243
200 return ret;244 return 0;
201}
202 245
203static const struct snd_soc_ops acp5x_8821_ops = {246}
204 .startup = acp5x_8821_startup,
205 .hw_params = acp5x_nau8821_hw_params,
206};
207 247
208static const struct snd_soc_ops acp5x_cs35l41_play_ops = {248static const struct snd_soc_ops acp5x_cs35l41_play_ops = {
209 .startup = acp5x_cs35l41_startup,249 .startup = acp5x_cs35l41_startup,
210 .hw_params = acp5x_cs35l41_hw_params,250 .hw_params = acp5x_cs35l41_hw_params,
211};251};
212 252
213static struct snd_soc_codec_conf cs35l41_conf[] = {253static struct snd_soc_codec_conf acp5x_cs35l41_conf[] = {
214 {254 {
215 .dlc = COMP_CODEC_CONF("spi-VLV1776:00"),255 .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_LNAME),
216 .name_prefix = "Left",256 .name_prefix = "Left",
217 },257 },
218 {258 {
219 .dlc = COMP_CODEC_CONF("spi-VLV1776:01"),259 .dlc = COMP_CODEC_CONF(ACP5X_CS35L41_COMP_RNAME),
220 .name_prefix = "Right",260 .name_prefix = "Right",
221 },261 },
222};262};
223 263
224SND_SOC_DAILINK_DEF(acp5x_i2s,264SND_SOC_DAILINK_DEF(cs35l41, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_CS35L41_COMP_LNAME,
225 DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.0")));265 ACP5X_CS35L41_DAI_NAME),
266 COMP_CODEC(ACP5X_CS35L41_COMP_RNAME,
267 ACP5X_CS35L41_DAI_NAME)));
226 268
227SND_SOC_DAILINK_DEF(acp5x_bt,269static struct snd_soc_dai_link acp5x_8821_35l41_dai[] = {
228 DAILINK_COMP_ARRAY(COMP_CPU("acp5x_i2s_playcap.1")));
229
230SND_SOC_DAILINK_DEF(nau8821,
231 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
232 "nau8821-hifi")));
233
234SND_SOC_DAILINK_DEF(cs35l41,
235 DAILINK_COMP_ARRAY(COMP_CODEC("spi-VLV1776:00", "cs35l41-pcm"),
236 COMP_CODEC("spi-VLV1776:01", "cs35l41-pcm")));
237
238SND_SOC_DAILINK_DEF(platform,
239 DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
240
241static struct snd_soc_dai_link acp5x_dai[] = {
242 {270 {
243 .name = "acp5x-8821-play",271 .name = "acp5x-8821-play",
244 .stream_name = "Playback/Capture",272 .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 |
246 SND_SOC_DAIFMT_CBC_CFC,275 SND_SOC_DAIFMT_CBC_CFC,
247 .dpcm_playback = 1,276 .dpcm_playback = 1,
248 .dpcm_capture = 1,277 .dpcm_capture = 1,
@@ -253,65 +282,28 @@ static struct snd_soc_dai_link acp5x_dai[] = { · 4 unmodified lines
253 {282 {
254 .name = "acp5x-CS35L41-Stereo",283 .name = "acp5x-CS35L41-Stereo",
255 .stream_name = "CS35L41 Stereo Playback",284 .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 |
257 SND_SOC_DAIFMT_CBC_CFC,287 SND_SOC_DAIFMT_CBC_CFC,
258 .dpcm_playback = 1,288 .dpcm_playback = 1,
259 .playback_only = 1,289 .playback_only = 1,
260 .ops = &acp5x_cs35l41_play_ops,290 .ops = &acp5x_cs35l41_play_ops,
261 .init = acp5x_cs35l41_init,
262 SND_SOC_DAILINK_REG(acp5x_bt, cs35l41, platform),291 SND_SOC_DAILINK_REG(acp5x_bt, cs35l41, platform),
263 },292 },
264};293};
265 294
266static 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;
273 295
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 }
279 296
280 if (SND_SOC_DAPM_EVENT_OFF(event)) {297static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = {
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
300static 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
306static const struct snd_soc_dapm_widget acp5x_8821_widgets[] = {
307 SND_SOC_DAPM_HP("Headphone", NULL),298 SND_SOC_DAPM_HP("Headphone", NULL),
308 SND_SOC_DAPM_MIC("Headset Mic", NULL),299 SND_SOC_DAPM_MIC("Headset Mic", NULL),
309 SND_SOC_DAPM_MIC("Int Mic", NULL),300 SND_SOC_DAPM_MIC("Int Mic", NULL),
310 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,301 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),
312};304};
313 305
314static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = {306static const struct snd_soc_dapm_route acp5x_8821_35l41_audio_route[] = {
315 /* HP jack connectors - unknown if we have jack detection */307 /* HP jack connectors - unknown if we have jack detection */
316 { "Headphone", NULL, "HPOL" },308 { "Headphone", NULL, "HPOL" },
317 { "Headphone", NULL, "HPOR" },309 { "Headphone", NULL, "HPOR" },
@@ -324,17 +316,17 @@ static const struct snd_soc_dapm_route acp5x_8821_audio_route[] = { · 6 unmodified lines
324 { "Int Mic", NULL, "Platform Clock" },316 { "Int Mic", NULL, "Platform Clock" },
325};317};
326 318
327static struct snd_soc_card acp5x_card = {319static struct snd_soc_card acp5x_8821_35l41_card = {
328 .name = "acp5x",320 .name = "acp5x",
329 .owner = THIS_MODULE,321 .owner = THIS_MODULE,
330 .dai_link = acp5x_dai,322 .dai_link = acp5x_8821_35l41_dai,
331 .num_links = ARRAY_SIZE(acp5x_dai),323 .num_links = ARRAY_SIZE(acp5x_8821_35l41_dai),
332 .dapm_widgets = acp5x_8821_widgets,324 .dapm_widgets = acp5x_8821_35l41_widgets,
333 .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_widgets),325 .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_35l41_widgets),
334 .dapm_routes = acp5x_8821_audio_route,326 .dapm_routes = acp5x_8821_35l41_audio_route,
335 .num_dapm_routes = ARRAY_SIZE(acp5x_8821_audio_route),327 .num_dapm_routes = ARRAY_SIZE(acp5x_8821_35l41_audio_route),
336 .codec_conf = cs35l41_conf,328 .codec_conf = acp5x_cs35l41_conf,
337 .num_configs = ARRAY_SIZE(cs35l41_conf),329 .num_configs = ARRAY_SIZE(acp5x_cs35l41_conf),
338 .controls = acp5x_8821_controls,330 .controls = acp5x_8821_controls,
339 .num_controls = ARRAY_SIZE(acp5x_8821_controls),331 .num_controls = ARRAY_SIZE(acp5x_8821_controls),
340};332};
@@ -342,6 +334,7 @@ static struct snd_soc_card acp5x_card = { · 1 unmodified line
342static int acp5x_vg_quirk_cb(const struct dmi_system_id *id)334static int acp5x_vg_quirk_cb(const struct dmi_system_id *id)
343{335{
344 acp5x_machine_id = VG_JUPITER;336 acp5x_machine_id = VG_JUPITER;
337
345 return 1;338 return 1;
346}339}
347 340
@@ -358,33 +351,31 @@ static const struct dmi_system_id acp5x_vg_quirk_table[] = { · 10 unmodified lines
358 351
359static int acp5x_probe(struct platform_device *pdev)352static int acp5x_probe(struct platform_device *pdev)
360{353{
361 int ret;
362 struct acp5x_platform_info *machine;354 struct acp5x_platform_info *machine;
355 struct device *dev = &pdev->dev;
363 struct snd_soc_card *card;356 struct snd_soc_card *card;
357 int ret;
364 358
365 machine = devm_kzalloc(&pdev->dev, sizeof(struct acp5x_platform_info),359 machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);
366 GFP_KERNEL);
367 if (!machine)360 if (!machine)
368 return -ENOMEM;361 return -ENOMEM;
369 362
370 dmi_check_system(acp5x_vg_quirk_table);363 dmi_check_system(acp5x_vg_quirk_table);
371 switch (acp5x_machine_id) {364 switch (acp5x_machine_id) {
372 case VG_JUPITER:365 case VG_JUPITER:
373 card = &acp5x_card;366 card = &acp5x_8821_35l41_card;
374 acp5x_card.dev = &pdev->dev;
375 break;367 break;
376 default:368 default:
377 return -ENODEV;369 return -ENODEV;
378 }370 }
371 card->dev = dev;
379 platform_set_drvdata(pdev, card);372 platform_set_drvdata(pdev, card);
380 snd_soc_card_set_drvdata(card, machine);373 snd_soc_card_set_drvdata(card, machine);
381 374
382 ret = devm_snd_soc_register_card(&pdev->dev, card);375 ret = devm_snd_soc_register_card(dev, card);
383 if (ret) {376 if (ret)
384 return dev_err_probe(&pdev->dev, ret,377 return dev_err_probe(dev, ret, "Register card (%s) failed\n", card->name);
385 "snd_soc_register_card(%s) failed\n",378
386 acp5x_card.name);
387 }
388 return 0;379 return 0;
389}380}
390 381
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
415 return 0;415 return 0;
416}416}
417 417
418static int acp5x_audio_remove(struct platform_device *pdev)418static void acp5x_audio_remove(struct platform_device *pdev)
419{419{
420 pm_runtime_disable(&pdev->dev);420 pm_runtime_disable(&pdev->dev);
421 return 0;
422}421}
423 422
424static int __maybe_unused acp5x_pcm_resume(struct device *dev)423static 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
500 499
501static struct platform_driver acp5x_dma_driver = {500static struct platform_driver acp5x_dma_driver = {
502 .probe = acp5x_audio_probe,501 .probe = acp5x_audio_probe,
503 .remove = acp5x_audio_remove,502 .remove_new = acp5x_audio_remove,
504 .driver = {503 .driver = {
505 .name = "acp5x_i2s_dma",504 .name = "acp5x_i2s_dma",
506 .pm = &acp5x_pm_ops,505 .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
45};45};
46 46
47static const struct dmi_system_id yc_acp_quirk_table[] = {47static 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 },
48 {55 {
49 .driver_data = &acp6x_card,56 .driver_data = &acp6x_card,
50 .matches = {57 .matches = {
@@ -178,6 +185,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 127 unmodified lines
178 DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),185 DMI_MATCH(DMI_PRODUCT_NAME, "21EN"),
179 }186 }
180 },187 },
188 {
189 .driver_data = &acp6x_card,
190 .matches = {
191 DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
192 DMI_MATCH(DMI_PRODUCT_NAME, "21HY"),
193 }
194 },
181 {195 {
182 .driver_data = &acp6x_card,196 .driver_data = &acp6x_card,
183 .matches = {197 .matches = {
@@ -262,6 +276,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { · 78 unmodified lines
262 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),276 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16z-n000"),
263 }277 }
264 },278 },
279 {
280 .driver_data = &acp6x_card,
281 .matches = {
282 DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
283 DMI_MATCH(DMI_BOARD_NAME, "8A42"),
284 }
285 },
265 {286 {
266 .driver_data = &acp6x_card,287 .driver_data = &acp6x_card,
267 .matches = {288 .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
388 return 0;388 return 0;
389}389}
390 390
391static int acp6x_pdm_audio_remove(struct platform_device *pdev)391static void acp6x_pdm_audio_remove(struct platform_device *pdev)
392{392{
393 pm_runtime_disable(&pdev->dev);393 pm_runtime_disable(&pdev->dev);
394 return 0;
395}394}
396 395
397static int __maybe_unused acp6x_pdm_resume(struct device *dev)396static 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
440 439
441static struct platform_driver acp6x_pdm_dma_driver = {440static struct platform_driver acp6x_pdm_dma_driver = {
442 .probe = acp6x_pdm_audio_probe,441 .probe = acp6x_pdm_audio_probe,
443 .remove = acp6x_pdm_audio_remove,442 .remove_new = acp6x_pdm_audio_remove,
444 .driver = {443 .driver = {
445 .name = "acp_yc_pdm_dma",444 .name = "acp_yc_pdm_dma",
446 .pm = &acp6x_pdm_pm_ops,445 .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
105{105{
106 writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);106 writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
107}107}
108
109int 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
149 int index = 0;149 int index = 0;
150 int val = 0x00;150 int val = 0x00;
151 u32 addr;151 u32 addr;
152 unsigned int irqflags;152 unsigned int irqflags, flag;
153 int ret;153 int ret;
154 154
155 irqflags = IRQF_SHARED;155 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
156 /* Yellow Carp device check */162 /* Yellow Carp device check */
157 switch (pci->revision) {163 switch (pci->revision) {
158 case 0x60:164 case 0x60:
sound/soc/apple/mca.c+2−3
@@ -1159,13 +1159,12 @@ err_release: · 1158 unmodified lines
1159 return ret;1159 return ret;
1160}1160}
1161 1161
1162static int apple_mca_remove(struct platform_device *pdev)1162static void apple_mca_remove(struct platform_device *pdev)
1163{1163{
1164 struct mca_data *mca = platform_get_drvdata(pdev);1164 struct mca_data *mca = platform_get_drvdata(pdev);
1165 1165
1166 snd_soc_unregister_component(&pdev->dev);1166 snd_soc_unregister_component(&pdev->dev);
1167 apple_mca_release(mca);1167 apple_mca_release(mca);
1168 return 0;
1169}1168}
1170 1169
1171static const struct of_device_id apple_mca_of_match[] = {1170static const struct of_device_id apple_mca_of_match[] = {
@@ -1180,7 +1179,7 @@ static struct platform_driver apple_mca_driver = { · 8 unmodified lines
1180 .of_match_table = apple_mca_of_match,1179 .of_match_table = apple_mca_of_match,
1181 },1180 },
1182 .probe = apple_mca_probe,1181 .probe = apple_mca_probe,
1183 .remove = apple_mca_remove,1182 .remove_new = apple_mca_remove,
1184};1183};
1185module_platform_driver(apple_mca_driver);1184module_platform_driver(apple_mca_driver);
1186 1185
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
473 if (!dai_link)473 if (!dai_link)
474 return -ENOMEM;474 return -ENOMEM;
475 475
476 comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);476 comp = devm_kzalloc(dev, 2 * sizeof(*comp), GFP_KERNEL);
477 if (!comp)477 if (!comp)
478 return -ENOMEM;478 return -ENOMEM;
479 479
480 dai_link->cpus = &comp[0];480 dai_link->cpus = &comp[0];
481 dai_link->codecs = &comp[1];481 dai_link->codecs = &comp[1];
482 dai_link->platforms = &comp[2];
483 482
484 dai_link->num_cpus = 1;483 dai_link->num_cpus = 1;
485 dai_link->num_codecs = 1;484 dai_link->num_codecs = 1;
486 dai_link->num_platforms = 1;
487 485
488 dai_link->name = "CLASSD";486 dai_link->name = "CLASSD";
489 dai_link->stream_name = "CLASSD PCM";487 dai_link->stream_name = "CLASSD PCM";
490 dai_link->codecs->dai_name = "snd-soc-dummy-dai";488 dai_link->codecs->dai_name = "snd-soc-dummy-dai";
491 dai_link->cpus->dai_name = dev_name(dev);489 dai_link->cpus->dai_name = dev_name(dev);
492 dai_link->codecs->name = "snd-soc-dummy";490 dai_link->codecs->name = "snd-soc-dummy";
493 dai_link->platforms->name = dev_name(dev);
494 491
495 card->dai_link = dai_link;492 card->dai_link = dai_link;
496 card->num_links = 1;493 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
717 return 0;717 return 0;
718}718}
719 719
720static int atmel_i2s_remove(struct platform_device *pdev)720static void atmel_i2s_remove(struct platform_device *pdev)
721{721{
722 struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);722 struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
723 723
724 clk_disable_unprepare(dev->pclk);724 clk_disable_unprepare(dev->pclk);
725
726 return 0;
727}725}
728 726
729static struct platform_driver atmel_i2s_driver = {727static struct platform_driver atmel_i2s_driver = {
@@ -732,7 +730,7 @@ static struct platform_driver atmel_i2s_driver = { · 2 unmodified lines
732 .of_match_table = of_match_ptr(atmel_i2s_dt_ids),730 .of_match_table = of_match_ptr(atmel_i2s_dt_ids),
733 },731 },
734 .probe = atmel_i2s_probe,732 .probe = atmel_i2s_probe,
735 .remove = atmel_i2s_remove,733 .remove_new = atmel_i2s_remove,
736};734};
737module_platform_driver(atmel_i2s_driver);735module_platform_driver(atmel_i2s_driver);
738 736
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
496 if (!dai_link)496 if (!dai_link)
497 return -ENOMEM;497 return -ENOMEM;
498 498
499 comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);499 comp = devm_kzalloc(dev, 2 * sizeof(*comp), GFP_KERNEL);
500 if (!comp)500 if (!comp)
501 return -ENOMEM;501 return -ENOMEM;
502 502
503 dai_link->cpus = &comp[0];503 dai_link->cpus = &comp[0];
504 dai_link->codecs = &comp[1];504 dai_link->codecs = &comp[1];
505 dai_link->platforms = &comp[2];
506 505
507 dai_link->num_cpus = 1;506 dai_link->num_cpus = 1;
508 dai_link->num_codecs = 1;507 dai_link->num_codecs = 1;
509 dai_link->num_platforms = 1;
510 508
511 dai_link->name = "PDMIC";509 dai_link->name = "PDMIC";
512 dai_link->stream_name = "PDMIC PCM";510 dai_link->stream_name = "PDMIC PCM";
513 dai_link->codecs->dai_name = "snd-soc-dummy-dai";511 dai_link->codecs->dai_name = "snd-soc-dummy-dai";
514 dai_link->cpus->dai_name = dev_name(dev);512 dai_link->cpus->dai_name = dev_name(dev);
515 dai_link->codecs->name = "snd-soc-dummy";513 dai_link->codecs->name = "snd-soc-dummy";
516 dai_link->platforms->name = dev_name(dev);
517 514
518 card->dai_link = dai_link;515 card->dai_link = dai_link;
519 card->num_links = 1;516 card->num_links = 1;
sound/soc/atmel/atmel_wm8904.c+2−4
@@ -161,7 +161,7 @@ err_set_audio: · 160 unmodified lines
161 return ret;161 return ret;
162}162}
163 163
164static int atmel_asoc_wm8904_remove(struct platform_device *pdev)164static void atmel_asoc_wm8904_remove(struct platform_device *pdev)
165{165{
166 struct snd_soc_card *card = platform_get_drvdata(pdev);166 struct snd_soc_card *card = platform_get_drvdata(pdev);
167 struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;167 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
171 171
172 snd_soc_unregister_card(card);172 snd_soc_unregister_card(card);
173 atmel_ssc_put_audio(id);173 atmel_ssc_put_audio(id);
174
175 return 0;
176}174}
177 175
178#ifdef CONFIG_OF176#ifdef CONFIG_OF
@@ -190,7 +188,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = { · 11 unmodified lines
190 .pm = &snd_soc_pm_ops,188 .pm = &snd_soc_pm_ops,
191 },189 },
192 .probe = atmel_asoc_wm8904_probe,190 .probe = atmel_asoc_wm8904_probe,
193 .remove = atmel_asoc_wm8904_remove,191 .remove_new = atmel_asoc_wm8904_remove,
194};192};
195 193
196module_platform_driver(atmel_asoc_wm8904_driver);194module_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
1088 return 0;1088 return 0;
1089}1089}
1090 1090
1091static int mchp_i2s_mcc_remove(struct platform_device *pdev)1091static void mchp_i2s_mcc_remove(struct platform_device *pdev)
1092{1092{
1093 struct mchp_i2s_mcc_dev *dev = platform_get_drvdata(pdev);1093 struct mchp_i2s_mcc_dev *dev = platform_get_drvdata(pdev);
1094 1094
1095 clk_disable_unprepare(dev->pclk);1095 clk_disable_unprepare(dev->pclk);
1096
1097 return 0;
1098}1096}
1099 1097
1100static struct platform_driver mchp_i2s_mcc_driver = {1098static struct platform_driver mchp_i2s_mcc_driver = {
@@ -1103,7 +1101,7 @@ static struct platform_driver mchp_i2s_mcc_driver = { · 2 unmodified lines
1103 .of_match_table = of_match_ptr(mchp_i2s_mcc_dt_ids),1101 .of_match_table = of_match_ptr(mchp_i2s_mcc_dt_ids),
1104 },1102 },
1105 .probe = mchp_i2s_mcc_probe,1103 .probe = mchp_i2s_mcc_probe,
1106 .remove = mchp_i2s_mcc_remove,1104 .remove_new = mchp_i2s_mcc_remove,
1107};1105};
1108module_platform_driver(mchp_i2s_mcc_driver);1106module_platform_driver(mchp_i2s_mcc_driver);
1109 1107
sound/soc/atmel/mchp-pdmc.c+9−16
@@ -8,6 +8,7 @@ · 7 unmodified lines
8 8
9#include <dt-bindings/sound/microchip,pdmc.h>9#include <dt-bindings/sound/microchip,pdmc.h>
10 10
11#include <linux/bitfield.h>
11#include <linux/clk.h>12#include <linux/clk.h>
12#include <linux/module.h>13#include <linux/module.h>
13#include <linux/of.h>14#include <linux/of.h>
@@ -49,8 +50,6 @@ · 35 unmodified lines
49#define MCHP_PDMC_MR_OSR256 (3 << 16)50#define MCHP_PDMC_MR_OSR256 (3 << 16)
50 51
51#define MCHP_PDMC_MR_SINCORDER_MASK GENMASK(23, 20)52#define MCHP_PDMC_MR_SINCORDER_MASK GENMASK(23, 20)
52#define MCHP_PDMC_MR_SINCORDER(order) (((order) << 20) & \
53 MCHP_PDMC_MR_SINCORDER_MASK)
54 53
55#define MCHP_PDMC_MR_SINC_OSR_MASK GENMASK(27, 24)54#define MCHP_PDMC_MR_SINC_OSR_MASK GENMASK(27, 24)
56#define MCHP_PDMC_MR_SINC_OSR_DIS (0 << 24)55#define MCHP_PDMC_MR_SINC_OSR_DIS (0 << 24)
@@ -62,8 +61,6 @@ · 5 unmodified lines
62#define MCHP_PDMC_MR_SINC_OSR_256 (6 << 24)61#define MCHP_PDMC_MR_SINC_OSR_256 (6 << 24)
63 62
64#define MCHP_PDMC_MR_CHUNK_MASK GENMASK(31, 28)63#define MCHP_PDMC_MR_CHUNK_MASK GENMASK(31, 28)
65#define MCHP_PDMC_MR_CHUNK(chunk) (((chunk) << 28) & \
66 MCHP_PDMC_MR_CHUNK_MASK)
67 64
68/*65/*
69 * ---- Configuration Register (Read/Write) ----66 * ---- Configuration Register (Read/Write) ----
@@ -617,10 +614,10 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream, · 547 unmodified lines
617 614
618 mr_val |= mchp_pdmc_mr_set_osr(dd->audio_filter_en, osr);615 mr_val |= mchp_pdmc_mr_set_osr(dd->audio_filter_en, osr);
619 616
620 mr_val |= MCHP_PDMC_MR_SINCORDER(dd->sinc_order);617 mr_val |= FIELD_PREP(MCHP_PDMC_MR_SINCORDER_MASK, dd->sinc_order);
621 618
622 dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream));619 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);
624 dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);621 dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);
625 622
626 snd_soc_component_update_bits(comp, MCHP_PDMC_MR,623 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
762 int ret;759 int ret;
763 760
764 ret = mchp_pdmc_add_chmap_ctls(rtd->pcm, dd);761 ret = mchp_pdmc_add_chmap_ctls(rtd->pcm, dd);
765 if (ret < 0) {762 if (ret < 0)
766 dev_err(dd->dev, "failed to add channel map controls: %d\n", ret);763 dev_err(dd->dev, "failed to add channel map controls: %d\n", ret);
767 return ret;
768 }
769 764
770 return 0;765 return ret;
771}766}
772 767
773static struct snd_soc_dai_driver mchp_pdmc_dai = {768static struct snd_soc_dai_driver mchp_pdmc_dai = {
@@ -788,7 +783,7 @@ static struct snd_soc_dai_driver mchp_pdmc_dai = { · 14 unmodified lines
788/* PDMC interrupt handler */783/* PDMC interrupt handler */
789static irqreturn_t mchp_pdmc_interrupt(int irq, void *dev_id)784static irqreturn_t mchp_pdmc_interrupt(int irq, void *dev_id)
790{785{
791 struct mchp_pdmc *dd = (struct mchp_pdmc *)dev_id;786 struct mchp_pdmc *dd = dev_id;
792 u32 isr, msr, pending;787 u32 isr, msr, pending;
793 irqreturn_t ret = IRQ_NONE;788 irqreturn_t ret = IRQ_NONE;
794 789
@@ -1082,7 +1077,7 @@ static int mchp_pdmc_probe(struct platform_device *pdev) · 287 unmodified lines
1082 }1077 }
1083 1078
1084 ret = devm_request_irq(dev, irq, mchp_pdmc_interrupt, 0,1079 ret = devm_request_irq(dev, irq, mchp_pdmc_interrupt, 0,
1085 dev_name(&pdev->dev), (void *)dd);1080 dev_name(&pdev->dev), dd);
1086 if (ret < 0) {1081 if (ret < 0) {
1087 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",1082 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
1088 irq, ret);1083 irq, ret);
@@ -1134,7 +1129,7 @@ pm_runtime_suspend: · 45 unmodified lines
1134 return ret;1129 return ret;
1135}1130}
1136 1131
1137static int mchp_pdmc_remove(struct platform_device *pdev)1132static void mchp_pdmc_remove(struct platform_device *pdev)
1138{1133{
1139 struct mchp_pdmc *dd = platform_get_drvdata(pdev);1134 struct mchp_pdmc *dd = platform_get_drvdata(pdev);
1140 1135
@@ -1142,8 +1137,6 @@ static int mchp_pdmc_remove(struct platform_device *pdev) · 1 unmodified line
1142 mchp_pdmc_runtime_suspend(dd->dev);1137 mchp_pdmc_runtime_suspend(dd->dev);
1143 1138
1144 pm_runtime_disable(dd->dev);1139 pm_runtime_disable(dd->dev);
1145
1146 return 0;
1147}1140}
1148 1141
1149static const struct of_device_id mchp_pdmc_of_match[] = {1142static const struct of_device_id mchp_pdmc_of_match[] = {
@@ -1168,7 +1161,7 @@ static struct platform_driver mchp_pdmc_driver = { · 18 unmodified lines
1168 .pm = pm_ptr(&mchp_pdmc_pm_ops),1161 .pm = pm_ptr(&mchp_pdmc_pm_ops),
1169 },1162 },
1170 .probe = mchp_pdmc_probe,1163 .probe = mchp_pdmc_probe,
1171 .remove = mchp_pdmc_remove,1164 .remove_new = mchp_pdmc_remove,
1172};1165};
1173module_platform_driver(mchp_pdmc_driver);1166module_platform_driver(mchp_pdmc_driver);
1174 1167
sound/soc/atmel/mchp-spdifrx.c+2−4
@@ -1183,20 +1183,18 @@ pm_runtime_disable: · 1182 unmodified lines
1183 return err;1183 return err;
1184}1184}
1185 1185
1186static int mchp_spdifrx_remove(struct platform_device *pdev)1186static void mchp_spdifrx_remove(struct platform_device *pdev)
1187{1187{
1188 struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev);1188 struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev);
1189 1189
1190 pm_runtime_disable(dev->dev);1190 pm_runtime_disable(dev->dev);
1191 if (!pm_runtime_status_suspended(dev->dev))1191 if (!pm_runtime_status_suspended(dev->dev))
1192 mchp_spdifrx_runtime_suspend(dev->dev);1192 mchp_spdifrx_runtime_suspend(dev->dev);
1193
1194 return 0;
1195}1193}
1196 1194
1197static struct platform_driver mchp_spdifrx_driver = {1195static struct platform_driver mchp_spdifrx_driver = {
1198 .probe = mchp_spdifrx_probe,1196 .probe = mchp_spdifrx_probe,
1199 .remove = mchp_spdifrx_remove,1197 .remove_new = mchp_spdifrx_remove,
1200 .driver = {1198 .driver = {
1201 .name = "mchp_spdifrx",1199 .name = "mchp_spdifrx",
1202 .of_match_table = of_match_ptr(mchp_spdifrx_dt_ids),1200 .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
72 72
73/* Valid Bits per Sample */73/* Valid Bits per Sample */
74#define SPDIFTX_MR_VBPS_MASK GENMASK(13, 8)74#define SPDIFTX_MR_VBPS_MASK GENMASK(13, 8)
75#define SPDIFTX_MR_VBPS(bps) FIELD_PREP(SPDIFTX_MR_VBPS_MASK, bps)
76 75
77/* Chunk Size */76/* Chunk Size */
78#define SPDIFTX_MR_CHUNK_MASK GENMASK(19, 16)77#define SPDIFTX_MR_CHUNK_MASK GENMASK(19, 16)
79#define SPDIFTX_MR_CHUNK(size) FIELD_PREP(SPDIFTX_MR_CHUNK_MASK, size)
80 78
81/* Validity Bits for Channels 1 and 2 */79/* Validity Bits for Channels 1 and 2 */
82#define SPDIFTX_MR_VALID1 BIT(24)80#define SPDIFTX_MR_VALID1 BIT(24)
@@ -89,7 +87,6 @@ · 6 unmodified lines
89 87
90/* Bytes per Sample */88/* Bytes per Sample */
91#define SPDIFTX_MR_BPS_MASK GENMASK(29, 28)89#define SPDIFTX_MR_BPS_MASK GENMASK(29, 28)
92#define SPDIFTX_MR_BPS(bytes) FIELD_PREP(SPDIFTX_MR_BPS_MASK, (bytes - 1))
93 90
94/*91/*
95 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----92 * ---- 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
309{306{
310 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);307 struct mchp_spdiftx_dev *dev = snd_soc_dai_get_drvdata(dai);
311 struct mchp_spdiftx_mixer_control *ctrl = &dev->control;308 struct mchp_spdiftx_mixer_control *ctrl = &dev->control;
312 u32 mr;
313 int running;
314 int ret;309 int ret;
315 310
316 /* do not start/stop while channel status or user data is updated */311 /* do not start/stop while channel status or user data is updated */
317 spin_lock(&ctrl->lock);312 spin_lock(&ctrl->lock);
318 regmap_read(dev->regmap, SPDIFTX_MR, &mr);
319 running = !!(mr & SPDIFTX_MR_TXEN_ENABLE);
320
321 switch (cmd) {313 switch (cmd) {
322 case SNDRV_PCM_TRIGGER_RESUME:314 case SNDRV_PCM_TRIGGER_RESUME:
323 case SNDRV_PCM_TRIGGER_START:315 case SNDRV_PCM_TRIGGER_START:
@@ -326,10 +318,8 @@ static int mchp_spdiftx_trigger(struct snd_pcm_substream *substream, int cmd, · 2 unmodified lines
326 dev->suspend_irq = 0;318 dev->suspend_irq = 0;
327 fallthrough;319 fallthrough;
328 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:320 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
329 if (!running) {321 ret = regmap_update_bits(dev->regmap, SPDIFTX_MR, SPDIFTX_MR_TXEN_MASK,
330 mr &= ~SPDIFTX_MR_TXEN_MASK;322 SPDIFTX_MR_TXEN_ENABLE);
331 mr |= SPDIFTX_MR_TXEN_ENABLE;
332 }
333 break;323 break;
334 case SNDRV_PCM_TRIGGER_SUSPEND:324 case SNDRV_PCM_TRIGGER_SUSPEND:
335 regmap_read(dev->regmap, SPDIFTX_IMR, &dev->suspend_irq);325 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
339 SPDIFTX_IR_TXUDR | SPDIFTX_IR_TXOVR);329 SPDIFTX_IR_TXUDR | SPDIFTX_IR_TXOVR);
340 fallthrough;330 fallthrough;
341 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:331 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
342 if (running) {332 ret = regmap_update_bits(dev->regmap, SPDIFTX_MR, SPDIFTX_MR_TXEN_MASK,
343 mr &= ~SPDIFTX_MR_TXEN_MASK;333 SPDIFTX_MR_TXEN_DISABLE);
344 mr |= SPDIFTX_MR_TXEN_DISABLE;
345 }
346 break;334 break;
347 default:335 default:
348 spin_unlock(&ctrl->lock);336 ret = -EINVAL;
349 return -EINVAL;
350 }337 }
351
352 ret = regmap_write(dev->regmap, SPDIFTX_MR, mr);
353 spin_unlock(&ctrl->lock);338 spin_unlock(&ctrl->lock);
354 if (ret)339 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);
356 341
357 return ret;342 return ret;
358}343}
@@ -402,47 +387,47 @@ static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream, · 43 unmodified lines
402 params_channels(params));387 params_channels(params));
403 return -EINVAL;388 return -EINVAL;
404 }389 }
405 mr |= SPDIFTX_MR_CHUNK(dev->playback.maxburst);390 mr |= FIELD_PREP(SPDIFTX_MR_CHUNK_MASK, dev->playback.maxburst);
406 391
407 switch (params_format(params)) {392 switch (params_format(params)) {
408 case SNDRV_PCM_FORMAT_S8:393 case SNDRV_PCM_FORMAT_S8:
409 mr |= SPDIFTX_MR_VBPS(8);394 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 8);
410 break;395 break;
411 case SNDRV_PCM_FORMAT_S16_BE:396 case SNDRV_PCM_FORMAT_S16_BE:
412 mr |= SPDIFTX_MR_ENDIAN_BIG;397 mr |= SPDIFTX_MR_ENDIAN_BIG;
413 fallthrough;398 fallthrough;
414 case SNDRV_PCM_FORMAT_S16_LE:399 case SNDRV_PCM_FORMAT_S16_LE:
415 mr |= SPDIFTX_MR_VBPS(16);400 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 16);
416 break;401 break;
417 case SNDRV_PCM_FORMAT_S18_3BE:402 case SNDRV_PCM_FORMAT_S18_3BE:
418 mr |= SPDIFTX_MR_ENDIAN_BIG;403 mr |= SPDIFTX_MR_ENDIAN_BIG;
419 fallthrough;404 fallthrough;
420 case SNDRV_PCM_FORMAT_S18_3LE:405 case SNDRV_PCM_FORMAT_S18_3LE:
421 mr |= SPDIFTX_MR_VBPS(18);406 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 18);
422 break;407 break;
423 case SNDRV_PCM_FORMAT_S20_3BE:408 case SNDRV_PCM_FORMAT_S20_3BE:
424 mr |= SPDIFTX_MR_ENDIAN_BIG;409 mr |= SPDIFTX_MR_ENDIAN_BIG;
425 fallthrough;410 fallthrough;
426 case SNDRV_PCM_FORMAT_S20_3LE:411 case SNDRV_PCM_FORMAT_S20_3LE:
427 mr |= SPDIFTX_MR_VBPS(20);412 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 20);
428 break;413 break;
429 case SNDRV_PCM_FORMAT_S24_3BE:414 case SNDRV_PCM_FORMAT_S24_3BE:
430 mr |= SPDIFTX_MR_ENDIAN_BIG;415 mr |= SPDIFTX_MR_ENDIAN_BIG;
431 fallthrough;416 fallthrough;
432 case SNDRV_PCM_FORMAT_S24_3LE:417 case SNDRV_PCM_FORMAT_S24_3LE:
433 mr |= SPDIFTX_MR_VBPS(24);418 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 24);
434 break;419 break;
435 case SNDRV_PCM_FORMAT_S24_BE:420 case SNDRV_PCM_FORMAT_S24_BE:
436 mr |= SPDIFTX_MR_ENDIAN_BIG;421 mr |= SPDIFTX_MR_ENDIAN_BIG;
437 fallthrough;422 fallthrough;
438 case SNDRV_PCM_FORMAT_S24_LE:423 case SNDRV_PCM_FORMAT_S24_LE:
439 mr |= SPDIFTX_MR_VBPS(24);424 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 24);
440 break;425 break;
441 case SNDRV_PCM_FORMAT_S32_BE:426 case SNDRV_PCM_FORMAT_S32_BE:
442 mr |= SPDIFTX_MR_ENDIAN_BIG;427 mr |= SPDIFTX_MR_ENDIAN_BIG;
443 fallthrough;428 fallthrough;
444 case SNDRV_PCM_FORMAT_S32_LE:429 case SNDRV_PCM_FORMAT_S32_LE:
445 mr |= SPDIFTX_MR_VBPS(32);430 mr |= FIELD_PREP(SPDIFTX_MR_VBPS_MASK, 32);
446 break;431 break;
447 default:432 default:
448 dev_err(dev->dev, "unsupported PCM format: %d\n",433 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
450 return -EINVAL;435 return -EINVAL;
451 }436 }
452 437
453 mr |= SPDIFTX_MR_BPS(bps);438 mr |= FIELD_PREP(SPDIFTX_MR_BPS_MASK, bps - 1);
454 439
455 switch (params_rate(params)) {440 switch (params_rate(params)) {
456 case 22050:441 case 22050:
@@ -891,7 +876,7 @@ pm_runtime_suspend: · 434 unmodified lines
891 return err;876 return err;
892}877}
893 878
894static int mchp_spdiftx_remove(struct platform_device *pdev)879static void mchp_spdiftx_remove(struct platform_device *pdev)
895{880{
896 struct mchp_spdiftx_dev *dev = platform_get_drvdata(pdev);881 struct mchp_spdiftx_dev *dev = platform_get_drvdata(pdev);
897 882
@@ -899,13 +884,11 @@ static int mchp_spdiftx_remove(struct platform_device *pdev) · 1 unmodified line
899 mchp_spdiftx_runtime_suspend(dev->dev);884 mchp_spdiftx_runtime_suspend(dev->dev);
900 885
901 pm_runtime_disable(dev->dev);886 pm_runtime_disable(dev->dev);
902
903 return 0;
904}887}
905 888
906static struct platform_driver mchp_spdiftx_driver = {889static struct platform_driver mchp_spdiftx_driver = {
907 .probe = mchp_spdiftx_probe,890 .probe = mchp_spdiftx_probe,
908 .remove = mchp_spdiftx_remove,891 .remove_new = mchp_spdiftx_remove,
909 .driver = {892 .driver = {
910 .name = "mchp_spdiftx",893 .name = "mchp_spdiftx",
911 .of_match_table = of_match_ptr(mchp_spdiftx_dt_ids),894 .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
155 return ret;155 return ret;
156}156}
157 157
158static int snd_proto_remove(struct platform_device *pdev)158static void snd_proto_remove(struct platform_device *pdev)
159{159{
160 snd_soc_unregister_card(&snd_proto);160 snd_soc_unregister_card(&snd_proto);
161
162 return 0;
163}161}
164 162
165static const struct of_device_id snd_proto_of_match[] = {163static const struct of_device_id snd_proto_of_match[] = {
@@ -174,7 +172,7 @@ static struct platform_driver snd_proto_driver = { · 8 unmodified lines
174 .of_match_table = snd_proto_of_match,172 .of_match_table = snd_proto_of_match,
175 },173 },
176 .probe = snd_proto_probe,174 .probe = snd_proto_probe,
177 .remove = snd_proto_remove,175 .remove_new = snd_proto_remove,
178};176};
179 177
180module_platform_driver(snd_proto_driver);178module_platform_driver(snd_proto_driver);
sound/soc/atmel/sam9g20_wm8731.c+2−4
@@ -186,14 +186,12 @@ err: · 185 unmodified lines
186 return ret;186 return ret;
187}187}
188 188
189static int at91sam9g20ek_audio_remove(struct platform_device *pdev)189static void at91sam9g20ek_audio_remove(struct platform_device *pdev)
190{190{
191 struct snd_soc_card *card = platform_get_drvdata(pdev);191 struct snd_soc_card *card = platform_get_drvdata(pdev);
192 192
193 snd_soc_unregister_card(card);193 snd_soc_unregister_card(card);
194 atmel_ssc_put_audio(0);194 atmel_ssc_put_audio(0);
195
196 return 0;
197}195}
198 196
199#ifdef CONFIG_OF197#ifdef CONFIG_OF
@@ -210,7 +208,7 @@ static struct platform_driver at91sam9g20ek_audio_driver = { · 10 unmodified lines
210 .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),208 .of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
211 },209 },
212 .probe = at91sam9g20ek_audio_probe,210 .probe = at91sam9g20ek_audio_probe,
213 .remove = at91sam9g20ek_audio_remove,211 .remove_new = at91sam9g20ek_audio_remove,
214};212};
215 213
216module_platform_driver(at91sam9g20ek_audio_driver);214module_platform_driver(at91sam9g20ek_audio_driver);
sound/soc/atmel/sam9x5_wm8731.c+2−4
@@ -176,14 +176,12 @@ out: · 175 unmodified lines
176 return ret;176 return ret;
177}177}
178 178
179static int sam9x5_wm8731_driver_remove(struct platform_device *pdev)179static void sam9x5_wm8731_driver_remove(struct platform_device *pdev)
180{180{
181 struct snd_soc_card *card = platform_get_drvdata(pdev);181 struct snd_soc_card *card = platform_get_drvdata(pdev);
182 struct sam9x5_drvdata *priv = card->drvdata;182 struct sam9x5_drvdata *priv = card->drvdata;
183 183
184 atmel_ssc_put_audio(priv->ssc_id);184 atmel_ssc_put_audio(priv->ssc_id);
185
186 return 0;
187}185}
188 186
189static const struct of_device_id sam9x5_wm8731_of_match[] = {187static const struct of_device_id sam9x5_wm8731_of_match[] = {
@@ -198,7 +196,7 @@ static struct platform_driver sam9x5_wm8731_driver = { · 8 unmodified lines
198 .of_match_table = of_match_ptr(sam9x5_wm8731_of_match),196 .of_match_table = of_match_ptr(sam9x5_wm8731_of_match),
199 },197 },
200 .probe = sam9x5_wm8731_driver_probe,198 .probe = sam9x5_wm8731_driver_probe,
201 .remove = sam9x5_wm8731_driver_remove,199 .remove_new = sam9x5_wm8731_driver_remove,
202};200};
203module_platform_driver(sam9x5_wm8731_driver);201module_platform_driver(sam9x5_wm8731_driver);
204 202
sound/soc/atmel/tse850-pcm5142.c+2−4
@@ -412,15 +412,13 @@ err_disable_ana: · 411 unmodified lines
412 return ret;412 return ret;
413}413}
414 414
415static int tse850_remove(struct platform_device *pdev)415static void tse850_remove(struct platform_device *pdev)
416{416{
417 struct snd_soc_card *card = platform_get_drvdata(pdev);417 struct snd_soc_card *card = platform_get_drvdata(pdev);
418 struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);418 struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
419 419
420 snd_soc_unregister_card(card);420 snd_soc_unregister_card(card);
421 regulator_disable(tse850->ana);421 regulator_disable(tse850->ana);
422
423 return 0;
424}422}
425 423
426static const struct of_device_id tse850_dt_ids[] = {424static const struct of_device_id tse850_dt_ids[] = {
@@ -435,7 +433,7 @@ static struct platform_driver tse850_driver = { · 8 unmodified lines
435 .of_match_table = of_match_ptr(tse850_dt_ids),433 .of_match_table = of_match_ptr(tse850_dt_ids),
436 },434 },
437 .probe = tse850_probe,435 .probe = tse850_probe,
438 .remove = tse850_remove,436 .remove_new = tse850_remove,
439};437};
440 438
441module_platform_driver(tse850_driver);439module_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
285 return 0;285 return 0;
286}286}
287 287
288static int au1xac97c_drvremove(struct platform_device *pdev)288static void au1xac97c_drvremove(struct platform_device *pdev)
289{289{
290 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);290 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
291 291
@@ -294,8 +294,6 @@ static int au1xac97c_drvremove(struct platform_device *pdev) · 2 unmodified lines
294 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */294 WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */
295 295
296 ac97c_workdata = NULL; /* MDEV */296 ac97c_workdata = NULL; /* MDEV */
297
298 return 0;
299}297}
300 298
301#ifdef CONFIG_PM299#ifdef CONFIG_PM
@@ -338,7 +336,7 @@ static struct platform_driver au1xac97c_driver = { · 36 unmodified lines
338 .pm = AU1XPSCAC97_PMOPS,336 .pm = AU1XPSCAC97_PMOPS,
339 },337 },
340 .probe = au1xac97c_drvprobe,338 .probe = au1xac97c_drvprobe,
341 .remove = au1xac97c_drvremove,339 .remove_new = au1xac97c_drvremove,
342};340};
343 341
344module_platform_driver(au1xac97c_driver);342module_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
270 &au1xi2s_dai_driver, 1);270 &au1xi2s_dai_driver, 1);
271}271}
272 272
273static int au1xi2s_drvremove(struct platform_device *pdev)273static void au1xi2s_drvremove(struct platform_device *pdev)
274{274{
275 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);275 struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
276 276
277 snd_soc_unregister_component(&pdev->dev);277 snd_soc_unregister_component(&pdev->dev);
278 278
279 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */279 WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */
280
281 return 0;
282}280}
283 281
284#ifdef CONFIG_PM282#ifdef CONFIG_PM
@@ -315,7 +313,7 @@ static struct platform_driver au1xi2s_driver = { · 30 unmodified lines
315 .pm = AU1XI2SC_PMOPS,313 .pm = AU1XI2SC_PMOPS,
316 },314 },
317 .probe = au1xi2s_drvprobe,315 .probe = au1xi2s_drvprobe,
318 .remove = au1xi2s_drvremove,316 .remove_new = au1xi2s_drvremove,
319};317};
320 318
321module_platform_driver(au1xi2s_driver);319module_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
421 return 0;421 return 0;
422}422}
423 423
424static int au1xpsc_ac97_drvremove(struct platform_device *pdev)424static void au1xpsc_ac97_drvremove(struct platform_device *pdev)
425{425{
426 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);426 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
427 427
@@ -434,8 +434,6 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) · 6 unmodified lines
434 wmb(); /* drain writebuffer */434 wmb(); /* drain writebuffer */
435 435
436 au1xpsc_ac97_workdata = NULL; /* MDEV */436 au1xpsc_ac97_workdata = NULL; /* MDEV */
437
438 return 0;
439}437}
440 438
441#ifdef CONFIG_PM439#ifdef CONFIG_PM
@@ -488,7 +486,7 @@ static struct platform_driver au1xpsc_ac97_driver = { · 46 unmodified lines
488 .pm = AU1XPSCAC97_PMOPS,486 .pm = AU1XPSCAC97_PMOPS,
489 },487 },
490 .probe = au1xpsc_ac97_drvprobe,488 .probe = au1xpsc_ac97_drvprobe,
491 .remove = au1xpsc_ac97_drvremove,489 .remove_new = au1xpsc_ac97_drvremove,
492};490};
493 491
494module_platform_driver(au1xpsc_ac97_driver);492module_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
344 &au1xpsc_i2s_component, &wd->dai_drv, 1);344 &au1xpsc_i2s_component, &wd->dai_drv, 1);
345}345}
346 346
347static int au1xpsc_i2s_drvremove(struct platform_device *pdev)347static void au1xpsc_i2s_drvremove(struct platform_device *pdev)
348{348{
349 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);349 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
350 350
@@ -352,8 +352,6 @@ static int au1xpsc_i2s_drvremove(struct platform_device *pdev) · 1 unmodified line
352 wmb(); /* drain writebuffer */352 wmb(); /* drain writebuffer */
353 __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));353 __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
354 wmb(); /* drain writebuffer */354 wmb(); /* drain writebuffer */
355
356 return 0;
357}355}
358 356
359#ifdef CONFIG_PM357#ifdef CONFIG_PM
@@ -406,7 +404,7 @@ static struct platform_driver au1xpsc_i2s_driver = { · 46 unmodified lines
406 .pm = AU1XPSCI2S_PMOPS,404 .pm = AU1XPSCI2S_PMOPS,
407 },405 },
408 .probe = au1xpsc_i2s_drvprobe,406 .probe = au1xpsc_i2s_drvprobe,
409 .remove = au1xpsc_i2s_drvremove,407 .remove_new = au1xpsc_i2s_drvremove,
410};408};
411 409
412module_platform_driver(au1xpsc_i2s_driver);410module_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
289 return ret;289 return ret;
290}290}
291 291
292static int bcm63xx_i2s_dev_remove(struct platform_device *pdev)292static void bcm63xx_i2s_dev_remove(struct platform_device *pdev)
293{293{
294 bcm63xx_soc_platform_remove(pdev);294 bcm63xx_soc_platform_remove(pdev);
295 return 0;
296}295}
297 296
298#ifdef CONFIG_OF297#ifdef CONFIG_OF
@@ -308,7 +307,7 @@ static struct platform_driver bcm63xx_i2s_driver = { · 9 unmodified lines
308 .of_match_table = of_match_ptr(snd_soc_bcm_audio_match),307 .of_match_table = of_match_ptr(snd_soc_bcm_audio_match),
309 },308 },
310 .probe = bcm63xx_i2s_dev_probe,309 .probe = bcm63xx_i2s_dev_probe,
311 .remove = bcm63xx_i2s_dev_remove,310 .remove_new = bcm63xx_i2s_dev_remove,
312};311};
313 312
314module_platform_driver(bcm63xx_i2s_driver);313module_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
1377 return 0;1377 return 0;
1378}1378}
1379 1379
1380static int cygnus_ssp_remove(struct platform_device *pdev)1380static void cygnus_ssp_remove(struct platform_device *pdev)
1381{1381{
1382 cygnus_soc_platform_unregister(&pdev->dev);1382 cygnus_soc_platform_unregister(&pdev->dev);
1383
1384 return 0;
1385}1383}
1386 1384
1387static const struct of_device_id cygnus_ssp_of_match[] = {1385static const struct of_device_id cygnus_ssp_of_match[] = {
@@ -1392,7 +1390,7 @@ MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match); · 4 unmodified lines
1392 1390
1393static struct platform_driver cygnus_ssp_driver = {1391static struct platform_driver cygnus_ssp_driver = {
1394 .probe = cygnus_ssp_probe,1392 .probe = cygnus_ssp_probe,
1395 .remove = cygnus_ssp_remove,1393 .remove_new = cygnus_ssp_remove,
1396 .driver = {1394 .driver = {
1397 .name = "cygnus-ssp",1395 .name = "cygnus-ssp",
1398 .of_match_table = cygnus_ssp_of_match,1396 .of_match_table = cygnus_ssp_of_match,
sound/soc/cirrus/Kconfig+5−1
@@ -8,7 +8,11 @@ config SND_EP93XX_SOC · 7 unmodified lines
8 the EP93xx I2S or AC97 interfaces.8 the EP93xx I2S or AC97 interfaces.
9 9
10config SND_EP93XX_SOC_I2S10config SND_EP93XX_SOC_I2S
11 tristate11 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.
12 16
13if SND_EP93XX_SOC_I2S17if SND_EP93XX_SOC_I2S
14 18
sound/soc/cirrus/edb93xx.c+2−4
@@ -93,14 +93,12 @@ static int edb93xx_probe(struct platform_device *pdev) · 92 unmodified lines
93 return ret;93 return ret;
94}94}
95 95
96static int edb93xx_remove(struct platform_device *pdev)96static void edb93xx_remove(struct platform_device *pdev)
97{97{
98 struct snd_soc_card *card = platform_get_drvdata(pdev);98 struct snd_soc_card *card = platform_get_drvdata(pdev);
99 99
100 snd_soc_unregister_card(card);100 snd_soc_unregister_card(card);
101 ep93xx_i2s_release();101 ep93xx_i2s_release();
102
103 return 0;
104}102}
105 103
106static struct platform_driver edb93xx_driver = {104static struct platform_driver edb93xx_driver = {
@@ -108,7 +106,7 @@ static struct platform_driver edb93xx_driver = { · 1 unmodified line
108 .name = "edb93xx-audio",106 .name = "edb93xx-audio",
109 },107 },
110 .probe = edb93xx_probe,108 .probe = edb93xx_probe,
111 .remove = edb93xx_remove,109 .remove_new = edb93xx_remove,
112};110};
113 111
114module_platform_driver(edb93xx_driver);112module_platform_driver(edb93xx_driver);
sound/soc/cirrus/ep93xx-i2s.c+21−4
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/slab.h>15#include <linux/slab.h>
16#include <linux/clk.h>16#include <linux/clk.h>
17#include <linux/io.h>17#include <linux/io.h>
18#include <linux/of.h>
18 19
19#include <sound/core.h>20#include <sound/core.h>
20#include <sound/dmaengine_pcm.h>21#include <sound/dmaengine_pcm.h>
@@ -208,6 +209,16 @@ static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) · 187 unmodified lines
208 return 0;209 return 0;
209}210}
210 211
212static 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
211static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,222static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
212 struct snd_soc_dai *dai)223 struct snd_soc_dai *dai)
213{224{
@@ -348,7 +359,6 @@ static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream, · 134 unmodified lines
348 if (err)359 if (err)
349 return err;360 return err;
350 361
351 ep93xx_i2s_enable(info, substream->stream);
352 return 0;362 return 0;
353}363}
354 364
@@ -397,6 +407,7 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component) · 42 unmodified lines
397#endif407#endif
398 408
399static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {409static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
410 .startup = ep93xx_i2s_startup,
400 .shutdown = ep93xx_i2s_shutdown,411 .shutdown = ep93xx_i2s_shutdown,
401 .hw_params = ep93xx_i2s_hw_params,412 .hw_params = ep93xx_i2s_hw_params,
402 .set_sysclk = ep93xx_i2s_set_sysclk,413 .set_sysclk = ep93xx_i2s_set_sysclk,
@@ -495,21 +506,27 @@ fail: · 92 unmodified lines
495 return err;506 return err;
496}507}
497 508
498static int ep93xx_i2s_remove(struct platform_device *pdev)509static void ep93xx_i2s_remove(struct platform_device *pdev)
499{510{
500 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);511 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
501 512
502 clk_put(info->lrclk);513 clk_put(info->lrclk);
503 clk_put(info->sclk);514 clk_put(info->sclk);
504 clk_put(info->mclk);515 clk_put(info->mclk);
505 return 0;
506}516}
507 517
518static const struct of_device_id ep93xx_i2s_of_ids[] = {
519 { .compatible = "cirrus,ep9301-i2s" },
520 {}
521};
522MODULE_DEVICE_TABLE(of, ep93xx_i2s_of_ids);
523
508static struct platform_driver ep93xx_i2s_driver = {524static struct platform_driver ep93xx_i2s_driver = {
509 .probe = ep93xx_i2s_probe,525 .probe = ep93xx_i2s_probe,
510 .remove = ep93xx_i2s_remove,526 .remove_new = ep93xx_i2s_remove,
511 .driver = {527 .driver = {
512 .name = "ep93xx-i2s",528 .name = "ep93xx-i2s",
529 .of_match_table = ep93xx_i2s_of_ids,
513 },530 },
514};531};
515 532
sound/soc/codecs/Kconfig+62−0
@@ -68,6 +68,9 @@ config SND_SOC_ALL_CODECS · 67 unmodified lines
68 imply SND_SOC_CS35L41_I2C68 imply SND_SOC_CS35L41_I2C
69 imply SND_SOC_CS35L45_I2C69 imply SND_SOC_CS35L45_I2C
70 imply SND_SOC_CS35L45_SPI70 imply SND_SOC_CS35L45_SPI
71 imply SND_SOC_CS35L56_I2C
72 imply SND_SOC_CS35L56_SPI
73 imply SND_SOC_CS35L56_SDW
71 imply SND_SOC_CS42L4274 imply SND_SOC_CS42L42
72 imply SND_SOC_CS42L42_SDW75 imply SND_SOC_CS42L42_SDW
73 imply SND_SOC_CS42L51_I2C76 imply SND_SOC_CS42L51_I2C
@@ -130,6 +133,7 @@ config SND_SOC_ALL_CODECS · 56 unmodified lines
130 imply SND_SOC_MAX98925133 imply SND_SOC_MAX98925
131 imply SND_SOC_MAX98926134 imply SND_SOC_MAX98926
132 imply SND_SOC_MAX98927135 imply SND_SOC_MAX98927
136 imply SND_SOC_MAX98363
133 imply SND_SOC_MAX98373_I2C137 imply SND_SOC_MAX98373_I2C
134 imply SND_SOC_MAX98373_SDW138 imply SND_SOC_MAX98373_SDW
135 imply SND_SOC_MAX98390139 imply SND_SOC_MAX98390
@@ -200,6 +204,7 @@ config SND_SOC_ALL_CODECS · 64 unmodified lines
200 imply SND_SOC_RT711_SDW204 imply SND_SOC_RT711_SDW
201 imply SND_SOC_RT711_SDCA_SDW205 imply SND_SOC_RT711_SDCA_SDW
202 imply SND_SOC_RT712_SDCA_SDW206 imply SND_SOC_RT712_SDCA_SDW
207 imply SND_SOC_RT712_SDCA_DMIC_SDW
203 imply SND_SOC_RT715_SDW208 imply SND_SOC_RT715_SDW
204 imply SND_SOC_RT715_SDCA_SDW209 imply SND_SOC_RT715_SDCA_SDW
205 imply SND_SOC_RT1308_SDW210 imply SND_SOC_RT1308_SDW
@@ -364,6 +369,9 @@ config SND_SOC_WM_ADSP · 158 unmodified lines
364 default y if SND_SOC_WM2200=y369 default y if SND_SOC_WM2200=y
365 default y if SND_SOC_CS35L41_SPI=y370 default y if SND_SOC_CS35L41_SPI=y
366 default y if SND_SOC_CS35L41_I2C=y371 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
367 default m if SND_SOC_MADERA=m375 default m if SND_SOC_MADERA=m
368 default m if SND_SOC_CS47L24=m376 default m if SND_SOC_CS47L24=m
369 default m if SND_SOC_WM5102=m377 default m if SND_SOC_WM5102=m
@@ -371,6 +379,9 @@ config SND_SOC_WM_ADSP · 1 unmodified line
371 default m if SND_SOC_WM2200=m379 default m if SND_SOC_WM2200=m
372 default m if SND_SOC_CS35L41_SPI=m380 default m if SND_SOC_CS35L41_SPI=m
373 default m if SND_SOC_CS35L41_I2C=m381 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
374 385
375config SND_SOC_AB8500_CODEC386config SND_SOC_AB8500_CODEC
376 tristate387 tristate
@@ -711,6 +722,41 @@ config SND_SOC_CS35L45_I2C · 334 unmodified lines
711 Enable support for Cirrus Logic CS35L45 smart speaker amplifier722 Enable support for Cirrus Logic CS35L45 smart speaker amplifier
712 with I2C control.723 with I2C control.
713 724
725config SND_SOC_CS35L56
726 tristate
727
728config SND_SOC_CS35L56_SHARED
729 tristate
730
731config 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
741config 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
751config 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
714config SND_SOC_CS42L42_CORE760config SND_SOC_CS42L42_CORE
715 tristate761 tristate
716 762
@@ -1089,6 +1135,16 @@ config SND_SOC_MAX98520 · 372 unmodified lines
1089 1135
1090 To compile this driver as a module, choose M here.1136 To compile this driver as a module, choose M here.
1091 1137
1138config 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
1092config SND_SOC_MAX983731148config SND_SOC_MAX98373
1093 tristate1149 tristate
1094 1150
@@ -1477,6 +1533,12 @@ config SND_SOC_RT712_SDCA_SDW · 382 unmodified lines
1477 select REGMAP_SOUNDWIRE1533 select REGMAP_SOUNDWIRE
1478 select REGMAP_SOUNDWIRE_MBQ1534 select REGMAP_SOUNDWIRE_MBQ
1479 1535
1536config 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
1480config SND_SOC_RT7151542config SND_SOC_RT715
1481 tristate1543 tristate
1482 1544
sound/soc/codecs/Makefile+14−0
@@ -66,6 +66,11 @@ snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o · 65 unmodified lines
66snd-soc-cs35l45-objs := cs35l45.o cs35l45-tables.o66snd-soc-cs35l45-objs := cs35l45.o cs35l45-tables.o
67snd-soc-cs35l45-spi-objs := cs35l45-spi.o67snd-soc-cs35l45-spi-objs := cs35l45-spi.o
68snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o68snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o
69snd-soc-cs35l56-objs := cs35l56.o
70snd-soc-cs35l56-shared-objs := cs35l56-shared.o
71snd-soc-cs35l56-i2c-objs := cs35l56-i2c.o
72snd-soc-cs35l56-spi-objs := cs35l56-spi.o
73snd-soc-cs35l56-sdw-objs := cs35l56-sdw.o
69snd-soc-cs42l42-objs := cs42l42.o74snd-soc-cs42l42-objs := cs42l42.o
70snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o75snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
71snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o76snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
@@ -143,6 +148,7 @@ snd-soc-max98925-objs := max98925.o · 71 unmodified lines
143snd-soc-max98926-objs := max98926.o148snd-soc-max98926-objs := max98926.o
144snd-soc-max98927-objs := max98927.o149snd-soc-max98927-objs := max98927.o
145snd-soc-max98520-objs := max98520.o150snd-soc-max98520-objs := max98520.o
151snd-soc-max98363-objs := max98363.o
146snd-soc-max98373-objs := max98373.o152snd-soc-max98373-objs := max98373.o
147snd-soc-max98373-i2c-objs := max98373-i2c.o153snd-soc-max98373-i2c-objs := max98373-i2c.o
148snd-soc-max98373-sdw-objs := max98373-sdw.o154snd-soc-max98373-sdw-objs := max98373-sdw.o
@@ -228,6 +234,7 @@ snd-soc-rt700-objs := rt700.o rt700-sdw.o · 79 unmodified lines
228snd-soc-rt711-objs := rt711.o rt711-sdw.o234snd-soc-rt711-objs := rt711.o rt711-sdw.o
229snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o235snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o
230snd-soc-rt712-sdca-objs := rt712-sdca.o rt712-sdca-sdw.o236snd-soc-rt712-sdca-objs := rt712-sdca.o rt712-sdca-sdw.o
237snd-soc-rt712-sdca-dmic-objs := rt712-sdca-dmic.o
231snd-soc-rt715-objs := rt715.o rt715-sdw.o238snd-soc-rt715-objs := rt715.o rt715-sdw.o
232snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o239snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o
233snd-soc-rt9120-objs := rt9120.o240snd-soc-rt9120-objs := rt9120.o
@@ -433,6 +440,11 @@ obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o · 199 unmodified lines
433obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o440obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o
434obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o441obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o
435obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o442obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o
443obj-$(CONFIG_SND_SOC_CS35L56) += snd-soc-cs35l56.o
444obj-$(CONFIG_SND_SOC_CS35L56_SHARED) += snd-soc-cs35l56-shared.o
445obj-$(CONFIG_SND_SOC_CS35L56_I2C) += snd-soc-cs35l56-i2c.o
446obj-$(CONFIG_SND_SOC_CS35L56_SPI) += snd-soc-cs35l56-spi.o
447obj-$(CONFIG_SND_SOC_CS35L56_SDW) += snd-soc-cs35l56-sdw.o
436obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o448obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o
437obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o449obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o
438obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o450obj-$(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
505obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o517obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
506obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o518obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
507obj-$(CONFIG_SND_SOC_MAX98520) += snd-soc-max98520.o519obj-$(CONFIG_SND_SOC_MAX98520) += snd-soc-max98520.o
520obj-$(CONFIG_SND_SOC_MAX98363) += snd-soc-max98363.o
508obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o521obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o
509obj-$(CONFIG_SND_SOC_MAX98373_I2C) += snd-soc-max98373-i2c.o522obj-$(CONFIG_SND_SOC_MAX98373_I2C) += snd-soc-max98373-i2c.o
510obj-$(CONFIG_SND_SOC_MAX98373_SDW) += snd-soc-max98373-sdw.o523obj-$(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
591obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o604obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
592obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o605obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o
593obj-$(CONFIG_SND_SOC_RT712_SDCA_SDW) += snd-soc-rt712-sdca.o606obj-$(CONFIG_SND_SOC_RT712_SDCA_SDW) += snd-soc-rt712-sdca.o
607obj-$(CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW) += snd-soc-rt712-sdca-dmic.o
594obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o608obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o
595obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o609obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o
596obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o610obj-$(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
55};55};
56MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);56MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
57 57
58static const struct of_device_id adau1977_spi_of_match[] = {58static const struct of_device_id adau1977_spi_of_match[] __maybe_unused = {
59 { .compatible = "adi,adau1977" },59 { .compatible = "adi,adau1977" },
60 { .compatible = "adi,adau1978" },60 { .compatible = "adi,adau1978" },
61 { .compatible = "adi,adau1979" },61 { .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
1114 { 0x00000040, 0x00000033 },1114 { 0x00000040, 0x00000033 },
1115};1115};
1116 1116
1117static 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
1124static 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
1117int cs35l41_init_boost(struct device *dev, struct regmap *regmap,1133int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
1118 struct cs35l41_hw_cfg *hw_cfg)1134 struct cs35l41_hw_cfg *hw_cfg)
1119{1135{
1120 int ret;1136 int ret;
1121 1137
1122 switch (hw_cfg->bst_type) {1138 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;
1123 case CS35L41_INT_BOOST:1142 case CS35L41_INT_BOOST:
1124 ret = cs35l41_boost_config(dev, regmap, hw_cfg->bst_ind,1143 ret = cs35l41_boost_config(dev, regmap, hw_cfg->bst_ind,
1125 hw_cfg->bst_cap, hw_cfg->bst_ipk);1144 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
1138 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,1157 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
1139 CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT);1158 CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT);
1140 break;1159 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;
1141 default:1164 default:
1142 dev_err(dev, "Boost type %d not supported\n", hw_cfg->bst_type);1165 dev_err(dev, "Boost type %d not supported\n", hw_cfg->bst_type);
1143 ret = -EINVAL;1166 ret = -EINVAL;
@@ -1165,11 +1188,59 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type) · 21 unmodified lines
1165}1188}
1166EXPORT_SYMBOL_GPL(cs35l41_safe_reset);1189EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
1167 1190
1168int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable)1191int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
1192 struct completion *pll_lock)
1169{1193{
1170 int ret;1194 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 };
1171 1206
1172 switch (b_type) {1207 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;
1173 case CS35L41_INT_BOOST:1244 case CS35L41_INT_BOOST:
1174 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,1245 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
1175 enable << CS35L41_GLOBAL_EN_SHIFT);1246 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
150 { 5644800, 16, 24 },150 { 5644800, 16, 24 },
151 { 6000000, 16, 24 },151 { 6000000, 16, 24 },
152 { 6144000, 16, 24 },152 { 6144000, 16, 24 },
153 { 12288000, 0, 0 },
153};154};
154 155
155static int cs35l41_get_fs_mon_config_index(int freq)156static 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
356 WM_ADSP_FW_CONTROL("DSP1", 0),357 WM_ADSP_FW_CONTROL("DSP1", 0),
357};358};
358 359
360static 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
375static 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
359static irqreturn_t cs35l41_irq(int irq, void *data)384static irqreturn_t cs35l41_irq(int irq, void *data)
360{385{
361 struct cs35l41_private *cs35l41 = data;386 struct cs35l41_private *cs35l41 = data;
@@ -392,94 +417,49 @@ static irqreturn_t cs35l41_irq(int irq, void *data) · 30 unmodified lines
392 */417 */
393 if (status[0] & CS35L41_AMP_SHORT_ERR) {418 if (status[0] & CS35L41_AMP_SHORT_ERR) {
394 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");419 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
395 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,420 cs35l41_error_release(cs35l41, CS35L41_AMP_SHORT_ERR, CS35L41_AMP_SHORT_ERR_RLS);
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);
403 ret = IRQ_HANDLED;421 ret = IRQ_HANDLED;
404 }422 }
405 423
406 if (status[0] & CS35L41_TEMP_WARN) {424 if (status[0] & CS35L41_TEMP_WARN) {
407 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");425 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
408 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,426 cs35l41_error_release(cs35l41, CS35L41_TEMP_WARN, CS35L41_TEMP_WARN_ERR_RLS);
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);
416 ret = IRQ_HANDLED;427 ret = IRQ_HANDLED;
417 }428 }
418 429
419 if (status[0] & CS35L41_TEMP_ERR) {430 if (status[0] & CS35L41_TEMP_ERR) {
420 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");431 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
421 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,432 cs35l41_error_release(cs35l41, CS35L41_TEMP_ERR, CS35L41_TEMP_ERR_RLS);
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);
429 ret = IRQ_HANDLED;433 ret = IRQ_HANDLED;
430 }434 }
431 435
432 if (status[0] & CS35L41_BST_OVP_ERR) {436 if (status[0] & CS35L41_BST_OVP_ERR) {
433 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");437 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
434 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,438 cs35l41_boost_enable(cs35l41, 0);
435 CS35L41_BST_EN_MASK, 0);439 cs35l41_error_release(cs35l41, CS35L41_BST_OVP_ERR, CS35L41_BST_OVP_ERR_RLS);
436 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,440 cs35l41_boost_enable(cs35l41, 1);
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);
447 ret = IRQ_HANDLED;441 ret = IRQ_HANDLED;
448 }442 }
449 443
450 if (status[0] & CS35L41_BST_DCM_UVP_ERR) {444 if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
451 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");445 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
452 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,446 cs35l41_boost_enable(cs35l41, 0);
453 CS35L41_BST_EN_MASK, 0);447 cs35l41_error_release(cs35l41, CS35L41_BST_DCM_UVP_ERR, CS35L41_BST_UVP_ERR_RLS);
454 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,448 cs35l41_boost_enable(cs35l41, 1);
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);
465 ret = IRQ_HANDLED;449 ret = IRQ_HANDLED;
466 }450 }
467 451
468 if (status[0] & CS35L41_BST_SHORT_ERR) {452 if (status[0] & CS35L41_BST_SHORT_ERR) {
469 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");453 dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
470 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,454 cs35l41_boost_enable(cs35l41, 0);
471 CS35L41_BST_EN_MASK, 0);455 cs35l41_error_release(cs35l41, CS35L41_BST_SHORT_ERR, CS35L41_BST_SHORT_ERR_RLS);
472 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,456 cs35l41_boost_enable(cs35l41, 1);
473 CS35L41_BST_SHORT_ERR);457 ret = IRQ_HANDLED;
474 regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);458 }
475 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,459
476 CS35L41_BST_SHORT_ERR_RLS,460 if (status[2] & CS35L41_PLL_LOCK) {
477 CS35L41_BST_SHORT_ERR_RLS);461 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS3, CS35L41_PLL_LOCK);
478 regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,462 complete(&cs35l41->pll_lock);
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);
483 ret = IRQ_HANDLED;463 ret = IRQ_HANDLED;
484 }464 }
485 465
@@ -520,10 +500,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, · 34 unmodified lines
520 cs35l41_pup_patch,500 cs35l41_pup_patch,
521 ARRAY_SIZE(cs35l41_pup_patch));501 ARRAY_SIZE(cs35l41_pup_patch));
522 502
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);
524 break;505 break;
525 case SND_SOC_DAPM_POST_PMD:506 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);
527 509
528 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,510 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
529 val, val & CS35L41_PDN_DONE_MASK,511 val, val & CS35L41_PDN_DONE_MASK,
@@ -830,6 +812,10 @@ static const struct snd_pcm_hw_constraint_list cs35l41_constraints = { · 300 unmodified lines
830static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,812static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
831 struct snd_soc_dai *dai)813 struct snd_soc_dai *dai)
832{814{
815 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
816
817 reinit_completion(&cs35l41->pll_lock);
818
833 if (substream->runtime)819 if (substream->runtime)
834 return snd_pcm_hw_constraint_list(substream->runtime, 0,820 return snd_pcm_hw_constraint_list(substream->runtime, 0,
835 SNDRV_PCM_HW_PARAM_RATE,821 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
1037 unsigned int val;1023 unsigned int val;
1038 int ret;1024 int ret;
1039 1025
1040 ret = device_property_read_u32(dev, "cirrus,boost-type", &val);1026 /* Some ACPI systems received the Shared Boost feature before the upstream driver,
1041 if (ret >= 0)1027 * leaving those systems with deprecated _DSD properties.
1042 hw_cfg->bst_type = val;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 }
1043 1041
1044 ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);1042 ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1045 if (ret >= 0)1043 if (ret >= 0)
@@ -1280,6 +1278,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * · 234 unmodified lines
1280 /* Set interrupt masks for critical errors */1278 /* Set interrupt masks for critical errors */
1281 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,1279 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1282 CS35L41_INT1_MASK_DEFAULT);1280 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);
1283 1285
1284 ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,1286 ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1285 IRQF_ONESHOT | IRQF_SHARED | irq_pol,1287 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
1303 if (ret < 0)1305 if (ret < 0)
1304 goto err;1306 goto err;
1305 1307
1308 init_completion(&cs35l41->pll_lock);
1309
1306 pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);1310 pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
1307 pm_runtime_use_autosuspend(cs35l41->dev);1311 pm_runtime_use_autosuspend(cs35l41->dev);
1308 pm_runtime_mark_last_busy(cs35l41->dev);1312 pm_runtime_mark_last_busy(cs35l41->dev);
@@ -1345,6 +1349,10 @@ void cs35l41_remove(struct cs35l41_private *cs35l41) · 36 unmodified lines
1345 pm_runtime_disable(cs35l41->dev);1349 pm_runtime_disable(cs35l41->dev);
1346 1350
1347 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);1351 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);
1348 kfree(cs35l41->dsp.system_name);1356 kfree(cs35l41->dsp.system_name);
1349 wm_adsp2_remove(&cs35l41->dsp);1357 wm_adsp2_remove(&cs35l41->dsp);
1350 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);1358 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
33 int irq;33 int irq;
34 /* GPIO for /RST */34 /* GPIO for /RST */
35 struct gpio_desc *reset_gpio;35 struct gpio_desc *reset_gpio;
36 struct completion pll_lock;
36};37};
37 38
38int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg);39int 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
32 }32 }
33 33
34 cs35l45->dev = dev;34 cs35l45->dev = dev;
35 cs35l45->irq = client->irq;
36 cs35l45->bus_type = CONTROL_BUS_I2C;
37 cs35l45->i2c_addr = client->addr;
35 38
36 return cs35l45_probe(cs35l45);39 return cs35l45_probe(cs35l45);
37}40}
sound/soc/codecs/cs35l45-spi.c+5−0
@@ -23,6 +23,9 @@ static int cs35l45_spi_probe(struct spi_device *spi) · 22 unmodified lines
23 if (cs35l45 == NULL)23 if (cs35l45 == NULL)
24 return -ENOMEM;24 return -ENOMEM;
25 25
26 spi->max_speed_hz = CS35L45_SPI_MAX_FREQ;
27 spi_setup(spi);
28
26 spi_set_drvdata(spi, cs35l45);29 spi_set_drvdata(spi, cs35l45);
27 cs35l45->regmap = devm_regmap_init_spi(spi, &cs35l45_spi_regmap);30 cs35l45->regmap = devm_regmap_init_spi(spi, &cs35l45_spi_regmap);
28 if (IS_ERR(cs35l45->regmap)) {31 if (IS_ERR(cs35l45->regmap)) {
@@ -32,6 +35,8 @@ static int cs35l45_spi_probe(struct spi_device *spi) · 3 unmodified lines
32 }35 }
33 36
34 cs35l45->dev = dev;37 cs35l45->dev = dev;
38 cs35l45->irq = spi->irq;
39 cs35l45->bus_type = CONTROL_BUS_SPI;
35 40
36 return cs35l45_probe(cs35l45);41 return cs35l45_probe(cs35l45);
37}42}
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
43static const struct reg_default cs35l45_defaults[] = {43static const struct reg_default cs35l45_defaults[] = {
44 { CS35L45_BLOCK_ENABLES, 0x00003323 },44 { CS35L45_BLOCK_ENABLES, 0x00003323 },
45 { CS35L45_BLOCK_ENABLES2, 0x00000010 },45 { 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 },
46 { CS35L45_REFCLK_INPUT, 0x00000510 },52 { CS35L45_REFCLK_INPUT, 0x00000510 },
47 { CS35L45_GLOBAL_SAMPLE_RATE, 0x00000003 },53 { CS35L45_GLOBAL_SAMPLE_RATE, 0x00000003 },
48 { CS35L45_ASP_ENABLES1, 0x00000000 },54 { CS35L45_ASP_ENABLES1, 0x00000000 },
@@ -60,7 +66,53 @@ static const struct reg_default cs35l45_defaults[] = { · 11 unmodified lines
60 { CS35L45_ASPTX3_INPUT, 0x00000020 },66 { CS35L45_ASPTX3_INPUT, 0x00000020 },
61 { CS35L45_ASPTX4_INPUT, 0x00000028 },67 { CS35L45_ASPTX4_INPUT, 0x00000028 },
62 { CS35L45_ASPTX5_INPUT, 0x00000048 },68 { 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 },
63 { CS35L45_AMP_PCM_CONTROL, 0x00100000 },93 { 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 },
64};116};
65 117
66static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)118static 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
72 case CS35L45_BLOCK_ENABLES:124 case CS35L45_BLOCK_ENABLES:
73 case CS35L45_BLOCK_ENABLES2:125 case CS35L45_BLOCK_ENABLES2:
74 case CS35L45_ERROR_RELEASE:126 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:
75 case CS35L45_REFCLK_INPUT:134 case CS35L45_REFCLK_INPUT:
76 case CS35L45_GLOBAL_SAMPLE_RATE:135 case CS35L45_GLOBAL_SAMPLE_RATE:
77 case CS35L45_ASP_ENABLES1:136 case CS35L45_ASP_ENABLES1:
@@ -89,9 +148,59 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg) · 11 unmodified lines
89 case CS35L45_ASPTX3_INPUT:148 case CS35L45_ASPTX3_INPUT:
90 case CS35L45_ASPTX4_INPUT:149 case CS35L45_ASPTX4_INPUT:
91 case CS35L45_ASPTX5_INPUT:150 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:
92 case CS35L45_AMP_PCM_CONTROL:159 case CS35L45_AMP_PCM_CONTROL:
93 case CS35L45_AMP_PCM_HPF_TST:160 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:
95 return true;204 return true;
96 default:205 default:
97 return false;206 return false;
@@ -106,7 +215,29 @@ static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg) · 8 unmodified lines
106 case CS35L45_GLOBAL_ENABLES:215 case CS35L45_GLOBAL_ENABLES:
107 case CS35L45_ERROR_RELEASE:216 case CS35L45_ERROR_RELEASE:
108 case CS35L45_AMP_PCM_HPF_TST: /* not cachable */217 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:
110 return true;241 return true;
111 default:242 default:
112 return false;243 return false;
sound/soc/codecs/cs35l45.c+620−10
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/module.h>10#include <linux/module.h>
11#include <linux/pm_runtime.h>11#include <linux/pm_runtime.h>
12#include <linux/property.h>12#include <linux/property.h>
13#include <linux/firmware.h>
13#include <linux/regulator/consumer.h>14#include <linux/regulator/consumer.h>
14#include <sound/core.h>15#include <sound/core.h>
15#include <sound/pcm.h>16#include <sound/pcm.h>
@@ -19,6 +20,71 @@ · 3 unmodified lines
19 20
20#include "cs35l45.h"21#include "cs35l45.h"
21 22
23static 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
46static 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
22static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,88static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w,
23 struct snd_kcontrol *kcontrol, int event)89 struct snd_kcontrol *kcontrol, int event)
24{90{
@@ -46,10 +112,68 @@ static int cs35l45_global_en_ev(struct snd_soc_dapm_widget *w, · 21 unmodified lines
46 return 0;112 return 0;
47}113}
48 114
115static 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
152static 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
49static const char * const cs35l45_asp_tx_txt[] = {172static const char * const cs35l45_asp_tx_txt[] = {
50 "Zero", "ASP_RX1", "ASP_RX2",173 "Zero", "ASP_RX1", "ASP_RX2",
51 "VMON", "IMON", "ERR_VOL",174 "VMON", "IMON", "ERR_VOL",
52 "VDD_BATTMON", "VDD_BSTMON",175 "VDD_BATTMON", "VDD_BSTMON",
176 "DSP_TX1", "DSP_TX2",
53 "Interpolator", "IL_TARGET",177 "Interpolator", "IL_TARGET",
54};178};
55 179
@@ -57,6 +181,7 @@ static const unsigned int cs35l45_asp_tx_val[] = { · 1 unmodified line
57 CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,181 CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2,
58 CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,182 CS35L45_PCM_SRC_VMON, CS35L45_PCM_SRC_IMON, CS35L45_PCM_SRC_ERR_VOL,
59 CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON,183 CS35L45_PCM_SRC_VDD_BATTMON, CS35L45_PCM_SRC_VDD_BSTMON,
184 CS35L45_PCM_SRC_DSP_TX1, CS35L45_PCM_SRC_DSP_TX2,
60 CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET,185 CS35L45_PCM_SRC_INTERPOLATOR, CS35L45_PCM_SRC_IL_TARGET,
61};186};
62 187
@@ -78,12 +203,54 @@ static const struct soc_enum cs35l45_asp_tx_enums[] = { · 15 unmodified lines
78 cs35l45_asp_tx_val),203 cs35l45_asp_tx_val),
79};204};
80 205
206static 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
213static 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
220static 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
81static const char * const cs35l45_dac_txt[] = {247static const char * const cs35l45_dac_txt[] = {
82 "Zero", "ASP_RX1", "ASP_RX2"248 "Zero", "ASP_RX1", "ASP_RX2", "DSP_TX1", "DSP_TX2"
83};249};
84 250
85static const unsigned int cs35l45_dac_val[] = {251static const unsigned int cs35l45_dac_val[] = {
86 CS35L45_PCM_SRC_ZERO, CS35L45_PCM_SRC_ASP_RX1, CS35L45_PCM_SRC_ASP_RX2252 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
87};254};
88 255
89static const struct soc_enum cs35l45_dacpcm_enums[] = {256static const struct soc_enum cs35l45_dacpcm_enums[] = {
@@ -100,11 +267,29 @@ static const struct snd_kcontrol_new cs35l45_asp_muxes[] = { · 10 unmodified lines
100 SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]),267 SOC_DAPM_ENUM("ASP_TX5 Source", cs35l45_asp_tx_enums[4]),
101};268};
102 269
270static 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
103static const struct snd_kcontrol_new cs35l45_dac_muxes[] = {281static const struct snd_kcontrol_new cs35l45_dac_muxes[] = {
104 SOC_DAPM_ENUM("DACPCM1 Source", cs35l45_dacpcm_enums[0]),282 SOC_DAPM_ENUM("DACPCM1 Source", cs35l45_dacpcm_enums[0]),
105};283};
106 284
107static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = {285static 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),
108 SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0,293 SND_SOC_DAPM_SUPPLY("GLOBAL_EN", SND_SOC_NOPM, 0, 0,
109 cs35l45_global_en_ev,294 cs35l45_global_en_ev,
110 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),295 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
139 SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]),324 SND_SOC_DAPM_MUX("ASP_TX4 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[3]),
140 SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]),325 SND_SOC_DAPM_MUX("ASP_TX5 Source", SND_SOC_NOPM, 0, 0, &cs35l45_asp_muxes[4]),
141 326
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
142 SND_SOC_DAPM_MUX("DACPCM1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]),336 SND_SOC_DAPM_MUX("DACPCM1 Source", SND_SOC_NOPM, 0, 0, &cs35l45_dac_muxes[0]),
143 337
144 SND_SOC_DAPM_OUT_DRV("AMP", SND_SOC_NOPM, 0, 0, NULL, 0),338 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
149#define CS35L45_ASP_MUX_ROUTE(name) \343#define CS35L45_ASP_MUX_ROUTE(name) \
150 { name" Source", "ASP_RX1", "ASP_RX1" }, \344 { name" Source", "ASP_RX1", "ASP_RX1" }, \
151 { name" Source", "ASP_RX2", "ASP_RX2" }, \345 { name" Source", "ASP_RX2", "ASP_RX2" }, \
346 { name" Source", "DSP_TX1", "DSP1" }, \
347 { name" Source", "DSP_TX2", "DSP1" }, \
152 { name" Source", "VMON", "VMON" }, \348 { name" Source", "VMON", "VMON" }, \
153 { name" Source", "IMON", "IMON" }, \349 { name" Source", "IMON", "IMON" }, \
154 { name" Source", "ERR_VOL", "ERR_VOL" }, \350 { name" Source", "ERR_VOL", "ERR_VOL" }, \
@@ -157,10 +353,16 @@ static const struct snd_soc_dapm_widget cs35l45_dapm_widgets[] = { · 2 unmodified lines
157 { name" Source", "Interpolator", "AMP_INTP" }, \353 { name" Source", "Interpolator", "AMP_INTP" }, \
158 { name" Source", "IL_TARGET", "IL_TARGET" }354 { name" Source", "IL_TARGET", "IL_TARGET" }
159 355
160#define CS35L45_DAC_MUX_ROUTE(name) \356#define CS35L45_DSP_MUX_ROUTE(name) \
161 { name" Source", "ASP_RX1", "ASP_RX1" }, \357 { name" Source", "ASP_RX1", "ASP_RX1" }, \
162 { name" Source", "ASP_RX2", "ASP_RX2" }358 { name" Source", "ASP_RX2", "ASP_RX2" }
163 359
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
164static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {366static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = {
165 /* Feedback */367 /* Feedback */
166 { "VMON", NULL, "VMON_SRC" },368 { "VMON", NULL, "VMON_SRC" },
@@ -204,6 +406,27 @@ static const struct snd_soc_dapm_route cs35l45_dapm_routes[] = { · 37 unmodified lines
204 { "AMP", NULL, "DACPCM1 Source"},406 { "AMP", NULL, "DACPCM1 Source"},
205 { "AMP", NULL, "GLOBAL_EN"},407 { "AMP", NULL, "GLOBAL_EN"},
206 408
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
207 CS35L45_DAC_MUX_ROUTE("DACPCM1"),430 CS35L45_DAC_MUX_ROUTE("DACPCM1"),
208 431
209 { "SPK", NULL, "AMP"},432 { "SPK", NULL, "AMP"},
@@ -219,6 +442,8 @@ static const struct snd_kcontrol_new cs35l45_controls[] = { · 9 unmodified lines
219 -409, 48,442 -409, 48,
220 (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,443 (CS35L45_AMP_VOL_PCM_WIDTH - 1) - 1,
221 0, cs35l45_dig_pcm_vol_tlv),444 0, cs35l45_dig_pcm_vol_tlv),
445 WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
446 WM_ADSP_FW_CONTROL("DSP1", 0),
222};447};
223 448
224static int cs35l45_set_pll(struct cs35l45_private *cs35l45, unsigned int freq)449static 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
489 },714 },
490};715};
491 716
717static 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
724static 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
492static const struct snd_soc_component_driver cs35l45_component = {731static const struct snd_soc_component_driver cs35l45_component = {
732 .probe = cs35l45_component_probe,
733 .remove = cs35l45_component_remove,
734
493 .dapm_widgets = cs35l45_dapm_widgets,735 .dapm_widgets = cs35l45_dapm_widgets,
494 .num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets),736 .num_dapm_widgets = ARRAY_SIZE(cs35l45_dapm_widgets),
495 737
@@ -504,11 +746,81 @@ static const struct snd_soc_component_driver cs35l45_component = { · 8 unmodified lines
504 .endianness = 1,746 .endianness = 1,
505};747};
506 748
749static 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
772static 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
784static 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
507static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)813static int __maybe_unused cs35l45_runtime_suspend(struct device *dev)
508{814{
509 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);815 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
510 816
817 if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
818 return 0;
819
820 cs35l45_enter_hibernate(cs35l45);
821
511 regcache_cache_only(cs35l45->regmap, true);822 regcache_cache_only(cs35l45->regmap, true);
823 regcache_mark_dirty(cs35l45->regmap);
512 824
513 dev_dbg(cs35l45->dev, "Runtime suspended\n");825 dev_dbg(cs35l45->dev, "Runtime suspended\n");
514 826
@@ -520,9 +832,17 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev) · 5 unmodified lines
520 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);832 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev);
521 int ret;833 int ret;
522 834
835 if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
836 return 0;
837
523 dev_dbg(cs35l45->dev, "Runtime resume\n");838 dev_dbg(cs35l45->dev, "Runtime resume\n");
524 839
525 regcache_cache_only(cs35l45->regmap, false);840 regcache_cache_only(cs35l45->regmap, false);
841
842 ret = cs35l45_exit_hibernate(cs35l45);
843 if (ret)
844 return ret;
845
526 ret = regcache_sync(cs35l45->regmap);846 ret = regcache_sync(cs35l45->regmap);
527 if (ret != 0)847 if (ret != 0)
528 dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret);848 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
536 856
537static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)857static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
538{858{
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;
539 unsigned int val;865 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 }
540 919
541 if (device_property_read_u32(cs35l45->dev,920 if (device_property_read_u32(cs35l45->dev,
542 "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {921 "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
@@ -548,6 +927,134 @@ static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45) · 5 unmodified lines
548 return 0;927 return 0;
549}928}
550 929
930static 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
964static 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
984static 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
993static 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
1002static irqreturn_t cs35l45_spk_safe_err(int irq, void *data);
1003
1004static 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
1019static 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
1031static 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
1046static 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
551static int cs35l45_initialize(struct cs35l45_private *cs35l45)1058static int cs35l45_initialize(struct cs35l45_private *cs35l45)
552{1059{
553 struct device *dev = cs35l45->dev;1060 struct device *dev = cs35l45->dev;
@@ -593,18 +1100,68 @@ static int cs35l45_initialize(struct cs35l45_private *cs35l45) · 39 unmodified lines
593 if (ret < 0)1100 if (ret < 0)
594 return ret;1101 return ret;
595 1102
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
601 return 0;1103 return 0;
602}1104}
603 1105
1106static 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
1125static 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
1133static 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
604int cs35l45_probe(struct cs35l45_private *cs35l45)1160int cs35l45_probe(struct cs35l45_private *cs35l45)
605{1161{
606 struct device *dev = cs35l45->dev;1162 struct device *dev = cs35l45->dev;
607 int ret;1163 unsigned long irq_pol = IRQF_ONESHOT | IRQF_SHARED;
1164 int ret, i, irq;
608 1165
609 cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");1166 cs35l45->vdd_batt = devm_regulator_get(dev, "vdd-batt");
610 if (IS_ERR(cs35l45->vdd_batt))1167 if (IS_ERR(cs35l45->vdd_batt))
@@ -649,14 +1206,63 @@ int cs35l45_probe(struct cs35l45_private *cs35l45) · 38 unmodified lines
649 if (ret < 0)1206 if (ret < 0)
650 goto err_reset;1207 goto err_reset;
651 1208
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
652 ret = devm_snd_soc_register_component(dev, &cs35l45_component,1251 ret = devm_snd_soc_register_component(dev, &cs35l45_component,
653 cs35l45_dai,1252 cs35l45_dai,
654 ARRAY_SIZE(cs35l45_dai));1253 ARRAY_SIZE(cs35l45_dai));
655 if (ret < 0)1254 if (ret < 0)
656 goto err_reset;1255 goto err_dsp;
1256
1257 pm_runtime_put_autosuspend(cs35l45->dev);
657 1258
658 return 0;1259 return 0;
659 1260
1261err_dsp:
1262 pm_runtime_disable(cs35l45->dev);
1263 pm_runtime_put_noidle(cs35l45->dev);
1264 wm_adsp2_remove(&cs35l45->dsp);
1265
660err_reset:1266err_reset:
661 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);1267 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
662err:1268err:
@@ -669,9 +1275,13 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_probe, SND_SOC_CS35L45); · 6 unmodified lines
669 1275
670void cs35l45_remove(struct cs35l45_private *cs35l45)1276void cs35l45_remove(struct cs35l45_private *cs35l45)
671{1277{
1278 pm_runtime_get_sync(cs35l45->dev);
672 pm_runtime_disable(cs35l45->dev);1279 pm_runtime_disable(cs35l45->dev);
1280 wm_adsp2_remove(&cs35l45->dsp);
673 1281
674 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);1282 gpiod_set_value_cansleep(cs35l45->reset_gpio, 0);
1283
1284 pm_runtime_put_noidle(cs35l45->dev);
675 regulator_disable(cs35l45->vdd_a);1285 regulator_disable(cs35l45->vdd_a);
676 /* VDD_BATT must be the last to power-off */1286 /* VDD_BATT must be the last to power-off */
677 regulator_disable(cs35l45->vdd_batt);1287 regulator_disable(cs35l45->vdd_batt);
sound/soc/codecs/cs35l45.h+266−1
@@ -14,6 +14,8 @@ · 13 unmodified lines
14#include <linux/pm_runtime.h>14#include <linux/pm_runtime.h>
15#include <linux/regmap.h>15#include <linux/regmap.h>
16#include <linux/regulator/consumer.h>16#include <linux/regulator/consumer.h>
17#include <dt-bindings/sound/cs35l45.h>
18#include "wm_adsp.h"
17 19
18#define CS35L45_DEVID 0x0000000020#define CS35L45_DEVID 0x00000000
19#define CS35L45_REVID 0x0000000421#define CS35L45_REVID 0x00000004
@@ -24,6 +26,13 @@ · 4 unmodified lines
24#define CS35L45_BLOCK_ENABLES 0x0000201826#define CS35L45_BLOCK_ENABLES 0x00002018
25#define CS35L45_BLOCK_ENABLES2 0x0000201C27#define CS35L45_BLOCK_ENABLES2 0x0000201C
26#define CS35L45_ERROR_RELEASE 0x0000203428#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
27#define CS35L45_REFCLK_INPUT 0x00002C0436#define CS35L45_REFCLK_INPUT 0x00002C04
28#define CS35L45_GLOBAL_SAMPLE_RATE 0x00002C0C37#define CS35L45_GLOBAL_SAMPLE_RATE 0x00002C0C
29#define CS35L45_BOOST_CCM_CFG 0x0000380838#define CS35L45_BOOST_CCM_CFG 0x00003808
@@ -44,11 +53,105 @@ · 14 unmodified lines
44#define CS35L45_ASPTX3_INPUT 0x00004C2853#define CS35L45_ASPTX3_INPUT 0x00004C28
45#define CS35L45_ASPTX4_INPUT 0x00004C2C54#define CS35L45_ASPTX4_INPUT 0x00004C2C
46#define CS35L45_ASPTX5_INPUT 0x00004C3055#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
47#define CS35L45_LDPM_CONFIG 0x0000640464#define CS35L45_LDPM_CONFIG 0x00006404
48#define CS35L45_AMP_PCM_CONTROL 0x0000700065#define CS35L45_AMP_PCM_CONTROL 0x00007000
49#define CS35L45_AMP_PCM_HPF_TST 0x0000700466#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
50#define CS35L45_IRQ1_EINT_4 0x0000E01C72#define CS35L45_IRQ1_EINT_4 0x0000E01C
51#define CS35L45_LASTREG 0x0000E01C73#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
52 155
53/* SFT_RESET */156/* SFT_RESET */
54#define CS35L45_SOFT_RESET_TRIGGER 0x5A000000157#define CS35L45_SOFT_RESET_TRIGGER 0x5A000000
@@ -70,9 +173,20 @@ · 15 unmodified lines
70/* BLOCK_ENABLES2 */173/* BLOCK_ENABLES2 */
71#define CS35L45_ASP_EN_SHIFT 27174#define CS35L45_ASP_EN_SHIFT 27
72 175
176#define CS35L45_MEM_RDY_SHIFT 1
177#define CS35L45_MEM_RDY_MASK BIT(1)
178
73/* ERROR_RELEASE */179/* ERROR_RELEASE */
74#define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11)180#define CS35L45_GLOBAL_ERR_RLS_MASK BIT(11)
75 181
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
76/* REFCLK_INPUT */190/* REFCLK_INPUT */
77#define CS35L45_PLL_FORCE_EN_SHIFT 16191#define CS35L45_PLL_FORCE_EN_SHIFT 16
78#define CS35L45_PLL_FORCE_EN_MASK BIT(16)192#define CS35L45_PLL_FORCE_EN_MASK BIT(16)
@@ -165,6 +279,56 @@ · 86 unmodified lines
165#define CS35L45_OTP_BOOT_DONE_STS_MASK BIT(1)279#define CS35L45_OTP_BOOT_DONE_STS_MASK BIT(1)
166#define CS35L45_OTP_BUSY_MASK BIT(0)280#define CS35L45_OTP_BUSY_MASK BIT(0)
167 281
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
168/* Mixer sources */332/* Mixer sources */
169#define CS35L45_PCM_SRC_MASK 0x7F333#define CS35L45_PCM_SRC_MASK 0x7F
170#define CS35L45_PCM_SRC_ZERO 0x00334#define CS35L45_PCM_SRC_ZERO 0x00
@@ -176,6 +340,8 @@ · 5 unmodified lines
176#define CS35L45_PCM_SRC_CLASSH_TGT 0x21340#define CS35L45_PCM_SRC_CLASSH_TGT 0x21
177#define CS35L45_PCM_SRC_VDD_BATTMON 0x28341#define CS35L45_PCM_SRC_VDD_BATTMON 0x28
178#define CS35L45_PCM_SRC_VDD_BSTMON 0x29342#define CS35L45_PCM_SRC_VDD_BSTMON 0x29
343#define CS35L45_PCM_SRC_DSP_TX1 0x32
344#define CS35L45_PCM_SRC_DSP_TX2 0x33
179#define CS35L45_PCM_SRC_TEMPMON 0x3A345#define CS35L45_PCM_SRC_TEMPMON 0x3A
180#define CS35L45_PCM_SRC_INTERPOLATOR 0x40346#define CS35L45_PCM_SRC_INTERPOLATOR 0x40
181#define CS35L45_PCM_SRC_IL_TARGET 0x48347#define CS35L45_PCM_SRC_IL_TARGET 0x48
@@ -185,6 +351,51 @@ · 3 unmodified lines
185#define CS35L45_POST_GLOBAL_EN_US 5000351#define CS35L45_POST_GLOBAL_EN_US 5000
186#define CS35L45_PRE_GLOBAL_DIS_US 3000352#define CS35L45_PRE_GLOBAL_DIS_US 3000
187 353
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
375enum 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
382enum 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
394enum control_bus_type {
395 CONTROL_BUS_I2C = 0,
396 CONTROL_BUS_SPI = 1,
397};
398
188#define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \399#define CS35L45_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
189 SNDRV_PCM_FMTBIT_S24_3LE| \400 SNDRV_PCM_FMTBIT_S24_3LE| \
190 SNDRV_PCM_FMTBIT_S24_LE)401 SNDRV_PCM_FMTBIT_S24_LE)
@@ -194,7 +405,56 @@ · 3 unmodified lines
194 SNDRV_PCM_RATE_88200 | \405 SNDRV_PCM_RATE_88200 | \
195 SNDRV_PCM_RATE_96000)406 SNDRV_PCM_RATE_96000)
196 407
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
418struct 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
430enum 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
451enum mbox3_events {
452 EVENT_SPEAKER_STATUS = 0x66,
453 EVENT_BOOT_DONE = 0x67,
454};
455
197struct cs35l45_private {456struct cs35l45_private {
457 struct wm_adsp dsp; /* needs to be first member */
198 struct device *dev;458 struct device *dev;
199 struct regmap *regmap;459 struct regmap *regmap;
200 struct gpio_desc *reset_gpio;460 struct gpio_desc *reset_gpio;
@@ -204,6 +464,11 @@ struct cs35l45_private { · 3 unmodified lines
204 bool sysclk_set;464 bool sysclk_set;
205 u8 slot_width;465 u8 slot_width;
206 u8 slot_count;466 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;
207};472};
208 473
209extern const struct dev_pm_ops cs35l45_pm_ops;474extern 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
18static 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
52static 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
59static const struct i2c_device_id cs35l56_id_i2c[] = {
60 { "cs35l56", 0 },
61 {}
62};
63MODULE_DEVICE_TABLE(i2c, cs35l56_id_i2c);
64
65static 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
75module_i2c_driver(cs35l56_i2c_driver);
76
77MODULE_DESCRIPTION("ASoC CS35L56 I2C driver");
78MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
79MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
80MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
81MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
82MODULE_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
26static 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
41static 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
77static 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
86static 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
100static 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
140static 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 */
156static 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
164static 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
189out:
190 pm_runtime_mark_last_busy(cs35l56->dev);
191 pm_runtime_put_autosuspend(cs35l56->dev);
192}
193
194static 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
227static 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
243static 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
275static 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
302static 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
358static 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
373static 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
384static 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
394static 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
418static 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
428static 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
453static 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
476static 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
486static 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
519static 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
535static 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
542static const struct sdw_device_id cs35l56_sdw_id[] = {
543 SDW_SLAVE_ENTRY(0x01FA, 0x3556, 0),
544 {},
545};
546MODULE_DEVICE_TABLE(sdw, cs35l56_sdw_id);
547
548static 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
559module_sdw_driver(cs35l56_sdw_driver);
560
561MODULE_DESCRIPTION("ASoC CS35L56 SoundWire driver");
562MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
563MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
564MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
565MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
566MODULE_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
14static 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
43static 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
59static 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
125static 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
137static 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
184static const u32 cs35l56_firmware_registers[] = {
185 CS35L56_MAIN_RENDER_USER_MUTE,
186 CS35L56_MAIN_RENDER_USER_VOLUME,
187 CS35L56_MAIN_POSTURE_NUMBER,
188};
189
190void 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}
201EXPORT_SYMBOL_NS_GPL(cs35l56_reread_firmware_registers, SND_SOC_CS35L56_SHARED);
202
203const 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};
210EXPORT_SYMBOL_NS_GPL(cs35l56_dsp1_regions, SND_SOC_CS35L56_SHARED);
211
212static 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
244int 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}
259EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED);
260
261static const char * const cs35l56_supplies[/* auto-sized */] = {
262 "VDD_P",
263 "VDD_IO",
264 "VDD_A",
265};
266
267void 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}
275EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED);
276
277const 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};
283EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED);
284
285const 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};
308EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED);
309
310struct 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};
324EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED);
325
326struct 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};
341EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED);
342
343struct 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};
357EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED);
358
359MODULE_DESCRIPTION("ASoC CS35L56 Shared");
360MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
361MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
362MODULE_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
17static 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
49static 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
56static const struct spi_device_id cs35l56_id_spi[] = {
57 { "cs35l56", 0 },
58 {}
59};
60MODULE_DEVICE_TABLE(spi, cs35l56_id_spi);
61
62static 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
72module_spi_driver(cs35l56_spi_driver);
73
74MODULE_DESCRIPTION("ASoC CS35L56 SPI driver");
75MODULE_IMPORT_NS(SND_SOC_CS35L56_CORE);
76MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
77MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
78MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
79MODULE_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
34static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w,
35 struct snd_kcontrol *kcontrol, int event);
36
37static 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
54static void cs35l56_wait_dsp_ready(struct cs35l56_private *cs35l56)
55{
56 /* Wait for patching to complete */
57 flush_work(&cs35l56->dsp_work);
58}
59
60static 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
70static 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
80static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
81
82static 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
97static 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
103static const struct snd_kcontrol_new asp1_tx1_mux =
104 SOC_DAPM_ENUM("ASP1TX1 SRC", cs35l56_asp1tx1_enum);
105
106static 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
112static const struct snd_kcontrol_new asp1_tx2_mux =
113 SOC_DAPM_ENUM("ASP1TX2 SRC", cs35l56_asp1tx2_enum);
114
115static 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
121static const struct snd_kcontrol_new asp1_tx3_mux =
122 SOC_DAPM_ENUM("ASP1TX3 SRC", cs35l56_asp1tx3_enum);
123
124static 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
130static const struct snd_kcontrol_new asp1_tx4_mux =
131 SOC_DAPM_ENUM("ASP1TX4 SRC", cs35l56_asp1tx4_enum);
132
133static 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
139static const struct snd_kcontrol_new sdw1_tx1_mux =
140 SOC_DAPM_ENUM("SDW1TX1 SRC", cs35l56_sdw1tx1_enum);
141
142static 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
148static const struct snd_kcontrol_new sdw1_tx2_mux =
149 SOC_DAPM_ENUM("SDW1TX2 SRC", cs35l56_sdw1tx2_enum);
150
151static 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
157static const struct snd_kcontrol_new sdw1_tx3_mux =
158 SOC_DAPM_ENUM("SDW1TX3 SRC", cs35l56_sdw1tx3_enum);
159
160static 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
166static const struct snd_kcontrol_new sdw1_tx4_mux =
167 SOC_DAPM_ENUM("SDW1TX4 SRC", cs35l56_sdw1tx4_enum);
168
169static 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
201static 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
268static 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
307static 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
318irqreturn_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
376err:
377 pm_runtime_put(cs35l56->dev);
378err_unlock:
379 mutex_unlock(&cs35l56->irq_lock);
380
381 return ret;
382}
383EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_CORE);
384
385int 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}
402EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_CORE);
403
404static 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
464static 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
491static 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
533static 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
591static 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
614static 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
621static 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
627static 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
639static 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.