History

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

Pull sound updates from Takashi Iwai: "We've received a fairly wide range of changes at this time, including for ALSA and ASoC core, but all of them are rather small changes. Here are some highlights: ALSA / ASoC Core: - Fixes of inconsistent locking around control API helpers - A few new control API functions and cleanups - Workarounds for potential UAFs by delayed kobj releases - Unified PCM copy ops with iov_iter - Continued efforts for ASoC API cleanups ASoC: - An adaptor to allow use of IIO DACs and ADCs in ASoC which pulls in some IIO changes - Create a library function for intlog10() and use it in the NAU8825 driver - Convert drivers to use the more modern maple tree register cache - Lots of work on the SOF framework, AMD and Intel drivers, including a lot of cleanup and new device support - Standardization of the presentation of jacks from drivers - Provision of some generic sound card DT properties - Support for AMD Van Gogh, AMD machines with MAX98388 and NAU8821, AWInic AW88261, Cirrus Logic CS35L36 and CS42L43, various Intel platforms including AVS machines with ES8336 and RT5663, Mediatek MT7986, NXP i.MX93, RealTek RT1017 and StarFive JH7110 Others: - New test coverage including ASoC and topology tests in KUnit; this also involves enabling UML builds of ALSA since that's the default KUnit test environment which pulls in the addition of some stubs to the driver - More enhancement of pcmtest driver - A few fixes / enhancements of MIDI 2.0 UMP core - Using PCI definitions in allover HD-audio code - Support for Cirrus CS35L56 and TI TAS2781 HD-audio sub-codecs - CS35L41 HD-audio sub-codec improvements - Continued emu10k1 improvements" * tag 'sound-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (693 commits) ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl ASoC: dwc: i2s: Fix unused functions ALSA: usb-audio: Don't try to submit URBs after disconnection ALSA: emu10k1: add separate documentation for E-MU cards ALSA: emu10k1: more documentation updates ALSA: emu10k1: de-duplicate audigy-mixer.rst vs. sb-live-mixer.rst ALSA: ump: Fix -Wformat-truncation warnings ALSA: hda: Add missing dependency on CONFIG_EFI for Cirrus/TI sub-codecs ALSA: doc: Fix missing backquote in midi-2.0.rst ALSA: hda/realtek: Add quirk for mute LEDs on HP ENVY x360 15-eu0xxx ALSA: hda/tas2781: Switch back to use struct i2c_driver's .probe() ASoC: soc-core.c: Do not error if a DAI link component is not found ASoC: codecs: Fix error code in aw88261_i2c_probe() ASoC: audio-graph-card.c: move audio_graph_parse_of() ASoC: cs42l43: Use new-style PM runtime macros ALSA: documentation: Add description for USB MIDI 2.0 gadget driver ALSA: ump: Don't create unused substreams for static blocks ALSA: ump: Fill group names for legacy rawmidi substreams ALSA: usb-audio: Attach legacy rawmidi after probing all UMP EPs ALSA: ac97: Fix possible error value of *rac97 ...

Linus Torvalds committed 3 years ago

Commit 4fb0dac2 parents 461f35f 358040e663 files · +23653 −7607Browse files

Unified · Split

663 files
  1. Documentation/core-api/kernel-api.rst +4 −2
  2. Documentation/devicetree/bindings/sound/amlogic,axg-sound-card.yaml +3 −12
  3. Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml +4 −13
  4. Documentation/devicetree/bindings/sound/audio-iio-aux.yaml +64 −0
  5. Documentation/devicetree/bindings/sound/awinic,aw88395.yaml +3 −1
  6. Documentation/devicetree/bindings/sound/fsl,rpmsg.yaml +5 −13
  7. Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml +4 −13
  8. Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml +4 −13
  9. Documentation/devicetree/bindings/sound/gtm601.txt +0 −19
  10. Documentation/devicetree/bindings/sound/imx-audio-card.yaml +4 −14
  11. Documentation/devicetree/bindings/sound/max9892x.txt +0 −44
  12. Documentation/devicetree/bindings/sound/maxim,max98925.yaml +98 −0
  13. Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml +160 −0
  14. Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml +67 −0
  15. Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml +7 −0
  16. Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml +7 −10
  17. Documentation/devicetree/bindings/sound/nau8821.txt +0 −55
  18. Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml +132 −0
  19. Documentation/devicetree/bindings/sound/nuvoton,nau8822.yaml +12 −0
  20. Documentation/devicetree/bindings/sound/option,gtm601.yaml +42 −0
  21. Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt +0 −101
  22. Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml +153 −0
  23. Documentation/devicetree/bindings/sound/renesas,rsnd.yaml +31 −29
  24. Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml +8 −8
  25. Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml +8 −8
  26. Documentation/devicetree/bindings/sound/samsung,odroid.yaml +7 −7
  27. Documentation/devicetree/bindings/sound/samsung,tm2.yaml +8 −8
  28. Documentation/devicetree/bindings/sound/simple-card.yaml +53 −0
  29. Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml +105 −3
  30. Documentation/devicetree/bindings/sound/sound-card-common.yaml +27 −0
  31. Documentation/devicetree/bindings/sound/wlf,wm8904.yaml +74 −0
  32. Documentation/devicetree/bindings/sound/wlf,wm8960.yaml +20 −0
  33. Documentation/devicetree/bindings/sound/wm8904.txt +0 −33
  34. Documentation/driver-api/media/dtv-common.rst +0 −9
  35. Documentation/sound/cards/audigy-mixer.rst +66 −131
  36. Documentation/sound/cards/emu-mixer.rst +226 −0
  37. Documentation/sound/cards/index.rst +1 −0
  38. Documentation/sound/cards/sb-live-mixer.rst +12 −12
  39. Documentation/sound/designs/midi-2.0.rst +188 −0
  40. Documentation/sound/kernel-api/writing-an-alsa-driver.rst +19 −39
  41. drivers/firmware/cirrus/cs_dsp.c +2 −1
  42. drivers/gpu/drm/vc4/vc4_hdmi.c +5 −1
  43. drivers/iio/inkern.c +73 −13
  44. drivers/media/dvb-core/Makefile +1 −1
  45. drivers/media/dvb-frontends/af9013_priv.h +1 −1
  46. drivers/media/dvb-frontends/af9033_priv.h +1 −1
  47. drivers/media/dvb-frontends/cxd2820r_priv.h +1 −1
  48. drivers/media/dvb-frontends/cxd2841er.c +1 −1
  49. drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c +1 −1
  50. drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c +1 −1
  51. drivers/media/dvb-frontends/cxd2880/cxd2880_top.c +1 −1
  52. drivers/media/dvb-frontends/dib7000p.c +1 −1
  53. drivers/media/dvb-frontends/dib8000.c +1 −1
  54. drivers/media/dvb-frontends/dib9000.c +1 −1
  55. drivers/media/dvb-frontends/drxk_hard.c +1 −1
  56. drivers/media/dvb-frontends/lgdt3305.c +1 −1
  57. drivers/media/dvb-frontends/lgdt3306a.c +1 −1
  58. drivers/media/dvb-frontends/lgdt330x.c +1 −1
  59. drivers/media/dvb-frontends/m88ds3103_priv.h +1 −1
  60. drivers/media/dvb-frontends/mn88443x.c +1 −1
  61. drivers/media/dvb-frontends/mn88472_priv.h +1 −1
  62. drivers/media/dvb-frontends/mn88473_priv.h +1 −1
  63. drivers/media/dvb-frontends/or51132.c +1 −1
  64. drivers/media/dvb-frontends/or51211.c +1 −1
  65. drivers/media/dvb-frontends/rtl2830_priv.h +1 −1
  66. drivers/media/dvb-frontends/rtl2832_priv.h +1 −1
  67. drivers/media/dvb-frontends/si2165.c +1 −1
  68. drivers/media/dvb-frontends/stv0367.c +1 −1
  69. drivers/media/dvb-frontends/tc90522.c +1 −1
  70. drivers/media/dvb-frontends/tda10048.c +1 −1
  71. drivers/media/pci/solo6x10/solo6x10-g723.c +6 −33
  72. drivers/staging/greybus/audio_codec.c +7 −11
  73. drivers/staging/greybus/audio_codec.h +1 −0
  74. drivers/staging/greybus/audio_helper.c +4 −16
  75. include/linux/device.h +26 −0
  76. include/linux/firmware/imx/dsp.h +0 −6
  77. include/linux/firmware/mediatek/mtk-adsp-ipc.h +0 −6
  78. include/linux/iio/consumer.h +27 −10
  79. include/linux/int_log.h +4 −14
  80. include/linux/minmax.h +64 −0
  81. include/linux/pci_ids.h +90 −16
  82. include/linux/platform_device.h +28 −0
  83. include/linux/soundwire/sdw.h +5 −0
  84. include/linux/soundwire/sdw_intel.h +1 −6
  85. include/sound/compress_driver.h +1 −1
  86. include/sound/control.h +29 −2
  87. include/sound/core.h +2 −2
  88. include/sound/cs35l41.h +3 −2
  89. include/sound/cs35l56.h +27 −2
  90. include/sound/cs42l43.h +17 −0
  91. include/sound/designware_i2s.h +3 −0
  92. include/sound/dmaengine_pcm.h +1 −1
  93. include/sound/emu10k1.h +14 −6
  94. include/sound/hda-mlink.h +4 −0
  95. include/sound/hda_codec.h +0 −3
  96. include/sound/hdaudio.h +26 −0
  97. include/sound/hwdep.h +1 −1
  98. include/sound/info.h +0 −2
  99. include/sound/l3.h +0 −28
  100. include/sound/pcm.h +9 −6
  101. include/sound/rawmidi.h +1 −1
  102. include/sound/rt5665.h +0 −2
  103. include/sound/rt5668.h +0 −3
  104. include/sound/rt5682.h +0 −3
  105. include/sound/rt5682s.h +0 −3
  106. include/sound/simple_card_utils.h +2 −3
  107. include/sound/soc-acpi.h +7 −0
  108. include/sound/soc-component.h +7 −7
  109. include/sound/soc-dai.h +16 −13
  110. include/sound/soc-dapm.h +93 −46
  111. include/sound/soc.h +6 −0
  112. include/sound/sof/topology.h +2 −2
  113. include/sound/uda134x.h +0 −24
  114. include/sound/ump.h +1 −0
  115. include/uapi/sound/sof/tokens.h +5 −1
  116. lib/iov_iter.c +1 −0
  117. lib/math/Makefile +1 −1
  118. lib/math/int_log.c +9 −17
  119. sound/Kconfig +0 −4
  120. sound/ac97/bus.c +1 −1
  121. sound/aoa/soundbus/i2sbus/pcm.c +2 −2
  122. sound/atmel/ac97c.c +1 −2
  123. sound/core/compress_offload.c +10 −6
  124. sound/core/control.c +108 −32
  125. sound/core/control_compat.c +1 −1
  126. sound/core/control_led.c +3 −3
  127. sound/core/hwdep.c +21 −17
  128. sound/core/init.c +18 −10
  129. sound/core/jack.c +0 −2
  130. sound/core/memory.c +48 −8
  131. sound/core/oss/mixer_oss.c +5 −5
  132. sound/core/pcm.c +13 −11
  133. sound/core/pcm_compat.c +6 −2
  134. sound/core/pcm_lib.c +51 −44
  135. sound/core/pcm_native.c +1 −1
  136. sound/core/rawmidi.c +13 −16
  137. sound/core/seq/seq_clientmgr.c +9 −7
  138. sound/core/timer.c +9 −7
  139. sound/core/ump.c +57 −9
  140. sound/core/vmaster.c +28 −0
  141. sound/drivers/Kconfig +1 −0
  142. sound/drivers/dummy.c +2 −10
  143. sound/drivers/pcmtest.c +70 −32
  144. sound/drivers/serial-generic.c +2 −2
  145. sound/firewire/dice/Makefile +1 −1
  146. sound/firewire/dice/dice-weiss.c +104 −0
  147. sound/firewire/dice/dice.c +63 −0
  148. sound/firewire/dice/dice.h +1 −0
  149. sound/hda/hdac_i915.c +11 −10
  150. sound/hda/intel-dsp-config.c +119 −75
  151. sound/isa/gus/gus_pcm.c +3 −20
  152. sound/isa/sb/emu8000.c +0 −2
  153. sound/isa/sb/emu8000_pcm.c +16 −58
  154. sound/isa/sb/sb16_csp.c +0 −2
  155. sound/pci/ac97/ac97_codec.c +2 −3
  156. sound/pci/ac97/ac97_patch.c +2 −20
  157. sound/pci/asihpi/hpi.h +0 −16
  158. sound/pci/asihpi/hpi_internal.h +0 −5
  159. sound/pci/ca0106/ca0106_mixer.c +7 −23
  160. sound/pci/cmipci.c +1 −5
  161. sound/pci/cs46xx/cs46xx_lib.c +2 −5
  162. sound/pci/emu10k1/emu10k1.c +3 −10
  163. sound/pci/emu10k1/emu10k1_main.c +61 −37
  164. sound/pci/emu10k1/emu10k1_synth.c +4 −6
  165. sound/pci/emu10k1/emufx.c +3 −14
  166. sound/pci/emu10k1/emumixer.c +36 −53
  167. sound/pci/emu10k1/emumpu401.c +17 −23
  168. sound/pci/emu10k1/emupcm.c +6 −11
  169. sound/pci/emu10k1/emuproc.c +8 −15
  170. sound/pci/emu10k1/io.c +6 −6
  171. sound/pci/emu10k1/irq.c +7 −6
  172. sound/pci/emu10k1/p16v.h +0 −56
  173. sound/pci/emu10k1/p17v.h +0 −1
  174. sound/pci/emu10k1/timer.c +2 −6
  175. sound/pci/emu10k1/tina2.h +0 −1
  176. sound/pci/emu10k1/voice.c +3 −9
  177. sound/pci/es1938.c +5 −25
  178. sound/pci/es1968.c +4 −11
  179. sound/pci/hda/Kconfig +49 −0
  180. sound/pci/hda/Makefile +9 −1
  181. sound/pci/hda/cs35l41_hda.c +245 −115
  182. sound/pci/hda/cs35l41_hda.h +1 −0
  183. sound/pci/hda/cs35l41_hda_property.c +105 −0
  184. sound/pci/hda/cs35l41_hda_property.h +18 −0
  185. sound/pci/hda/cs35l56_hda.c +1034 −0
  186. sound/pci/hda/cs35l56_hda.h +48 −0
  187. sound/pci/hda/cs35l56_hda_i2c.c +69 −0
  188. sound/pci/hda/cs35l56_hda_spi.c +68 −0
  189. sound/pci/hda/hda_auto_parser.h +2 −0
  190. sound/pci/hda/hda_codec.c +0 −2
  191. sound/pci/hda/hda_component.h +2 −0
  192. sound/pci/hda/hda_generic.h +3 −0
  193. sound/pci/hda/hda_hwdep.c +2 −2
  194. sound/pci/hda/hda_intel.c +146 −229
  195. sound/pci/hda/hda_tegra.c +4 −3
  196. sound/pci/hda/patch_hdmi.c +3 −2
  197. sound/pci/hda/patch_realtek.c +124 −4
  198. sound/pci/hda/tas2781_hda_i2c.c +856 −0
  199. sound/pci/ice1712/juli.c +3 −25
  200. sound/pci/ice1712/psc724.c +8 −11
  201. sound/pci/ice1712/quartet.c +3 −21
  202. sound/pci/ice1712/wm8776.c +1 −5
  203. sound/pci/korg1212/korg1212.c +12 −38
  204. sound/pci/maestro3.c +4 −11
  205. sound/pci/nm256/nm256.c +6 −36
  206. sound/pci/rme32.c +11 −39
  207. sound/pci/rme96.c +8 −34
  208. sound/pci/rme9652/hdsp.c +6 −36
  209. sound/pci/rme9652/rme9652.c +6 −40
  210. sound/pci/via82xx.c +1 −5
  211. sound/ppc/awacs.c +1 −0
  212. sound/ppc/burgundy.c +1 −0
  213. sound/sh/sh_dac_audio.c +3 −22
  214. sound/soc/Kconfig +11 −0
  215. sound/soc/adi/axi-i2s.c +1 −1
  216. sound/soc/adi/axi-spdif.c +1 −1
  217. sound/soc/amd/Kconfig +3 −2
  218. sound/soc/amd/acp-config.c +33 −0
  219. sound/soc/amd/acp-da7219-max98357a.c +31 −10
  220. sound/soc/amd/acp-rt5645.c +17 −5
  221. sound/soc/amd/acp/Kconfig +8 −0
  222. sound/soc/amd/acp/Makefile +2 −0
  223. sound/soc/amd/acp/acp-i2s.c +14 −12
  224. sound/soc/amd/acp/acp-legacy-common.c +347 −0
  225. sound/soc/amd/acp/acp-legacy-mach.c +1 −21
  226. sound/soc/amd/acp/acp-mach-common.c +496 −29
  227. sound/soc/amd/acp/acp-mach.h +2 −0
  228. sound/soc/amd/acp/acp-pci.c +56 −1
  229. sound/soc/amd/acp/acp-pdm.c +1 −12
  230. sound/soc/amd/acp/acp-platform.c +4 −2
  231. sound/soc/amd/acp/acp-rembrandt.c +59 −128
  232. sound/soc/amd/acp/acp-renoir.c +2 −115
  233. sound/soc/amd/acp/acp-sof-mach.c +15 −18
  234. sound/soc/amd/acp/amd.h +51 −1
  235. sound/soc/amd/acp3x-rt5682-max9836.c +18 −5
  236. sound/soc/amd/mach-config.h +1 −0
  237. sound/soc/amd/ps/ps-sdw-dma.c +2 −3
  238. sound/soc/amd/vangogh/acp5x-mach.c +131 −21
  239. sound/soc/atmel/atmel-i2s.c +9 −9
  240. sound/soc/atmel/atmel-pdmic.c +1 −1
  241. sound/soc/atmel/mchp-i2s-mcc.c +13 −13
  242. sound/soc/atmel/mchp-pdmc.c +12 −20
  243. sound/soc/atmel/mchp-spdifrx.c +8 −8
  244. sound/soc/atmel/mchp-spdiftx.c +10 −10
  245. sound/soc/atmel/tse850-pcm5142.c +1 −1
  246. sound/soc/au1x/ac97c.c +5 −5
  247. sound/soc/au1x/psc-ac97.c +1 −1
  248. sound/soc/bcm/bcm2835-i2s.c +12 −12
  249. sound/soc/bcm/bcm63xx-i2s-whistler.c +1 −15
  250. sound/soc/bcm/cygnus-ssp.h +0 −2
  251. sound/soc/cirrus/ep93xx-i2s.c +1 −1
  252. sound/soc/codecs/88pm860x-codec.c +2 −2
  253. sound/soc/codecs/Kconfig +50 −8
  254. sound/soc/codecs/Makefile +10 −4
  255. sound/soc/codecs/ad1836.c +1 −1
  256. sound/soc/codecs/ad1980.c +1 −1
  257. sound/soc/codecs/adau1372.c +1 −1
  258. sound/soc/codecs/adau1373.c +1 −1
  259. sound/soc/codecs/adau1701.c +1 −1
  260. sound/soc/codecs/adau1761.c +1 −1
  261. sound/soc/codecs/adau1781.c +1 −1
  262. sound/soc/codecs/adau1977.c +1 −1
  263. sound/soc/codecs/adau7118-i2c.c +1 −1
  264. sound/soc/codecs/adav80x.c +1 −1
  265. sound/soc/codecs/ak4613.c +1 −10
  266. sound/soc/codecs/audio-iio-aux.c +344 −0
  267. sound/soc/codecs/aw88261.c +1300 −0
  268. sound/soc/codecs/aw88261.h +459 −0
  269. sound/soc/codecs/aw88395/aw88395_lib.c +176 −17
  270. sound/soc/codecs/aw88395/aw88395_reg.h +1 −0
  271. sound/soc/codecs/cs35l36.c +1 −1
  272. sound/soc/codecs/cs35l41-lib.c +104 −18
  273. sound/soc/codecs/cs35l41.c +4 −14
  274. sound/soc/codecs/cs35l45-tables.c +2 −2
  275. sound/soc/codecs/cs35l56-i2c.c +7 −7
  276. sound/soc/codecs/cs35l56-sdw.c +37 −35
  277. sound/soc/codecs/cs35l56-shared.c +463 −19
  278. sound/soc/codecs/cs35l56-spi.c +5 −5
  279. sound/soc/codecs/cs35l56.c +156 −543
  280. sound/soc/codecs/cs35l56.h +2 −13
  281. sound/soc/codecs/cs4265.c +1 −1
  282. sound/soc/codecs/cs4270.c +1 −1
  283. sound/soc/codecs/cs42l43-jack.c +946 −0
  284. sound/soc/codecs/cs42l43-sdw.c +74 −0
  285. sound/soc/codecs/cs42l43.c +2278 −0
  286. sound/soc/codecs/cs42l43.h +131 −0
  287. sound/soc/codecs/cs42l51-i2c.c +1 −1
  288. sound/soc/codecs/cs42l51.c +1 −1
  289. sound/soc/codecs/cs42l52.c +1 −1
  290. sound/soc/codecs/cs42l56.c +1 −1
  291. sound/soc/codecs/cs42xx8.c +1 −1
  292. sound/soc/codecs/cs43130.h +69 −69
  293. sound/soc/codecs/cs4349.c +1 −1
  294. sound/soc/codecs/cs47l15.c +5 −1
  295. sound/soc/codecs/cs47l24.c +6 −2
  296. sound/soc/codecs/cs47l35.c +6 −2
  297. sound/soc/codecs/cs47l85.c +6 −2
  298. sound/soc/codecs/cs47l90.c +6 −2
  299. sound/soc/codecs/cs47l92.c +5 −1
  300. sound/soc/codecs/cx2072x.c +9 −2
  301. sound/soc/codecs/es8316.c +3 −2
  302. sound/soc/codecs/es8326.c +270 −115
  303. sound/soc/codecs/es8326.h +22 −8
  304. sound/soc/codecs/hdmi-codec.c +22 −22
  305. sound/soc/codecs/jz4740.c +1 −1
  306. sound/soc/codecs/l3.c +0 −132
  307. sound/soc/codecs/lpass-rx-macro.c +5 −5
  308. sound/soc/codecs/lpass-tx-macro.c +5 −5
  309. sound/soc/codecs/lpass-va-macro.c +3 −3
  310. sound/soc/codecs/lpass-wsa-macro.c +5 −5
  311. sound/soc/codecs/max98363.c +24 −17
  312. sound/soc/codecs/max98373-sdw.c +26 −21
  313. sound/soc/codecs/max98926.c +2 −1
  314. sound/soc/codecs/max98927.c +145 −212
  315. sound/soc/codecs/msm8916-wcd-analog.c +15 −41
  316. sound/soc/codecs/nau8821.c +41 −1
  317. sound/soc/codecs/nau8821.h +25 −0
  318. sound/soc/codecs/nau8825.c +3 −90
  319. sound/soc/codecs/rt1011.c +0 −2
  320. sound/soc/codecs/rt1015.c +0 −1
  321. sound/soc/codecs/rt1015p.c +0 −1
  322. sound/soc/codecs/rt1016.c +0 −1
  323. sound/soc/codecs/rt1017-sdca-sdw.c +824 −0
  324. sound/soc/codecs/rt1017-sdca-sdw.h +183 −0
  325. sound/soc/codecs/rt1019.c +0 −1
  326. sound/soc/codecs/rt1305.c +0 −2
  327. sound/soc/codecs/rt1308-sdw.c +30 −24
  328. sound/soc/codecs/rt1308.c +0 −2
  329. sound/soc/codecs/rt1316-sdw.c +39 −17
  330. sound/soc/codecs/rt1318-sdw.c +26 −17
  331. sound/soc/codecs/rt5514-spi.c +0 −1
  332. sound/soc/codecs/rt5514.c +0 −1
  333. sound/soc/codecs/rt5640.c +17 −42
  334. sound/soc/codecs/rt5640.h +1 −1
  335. sound/soc/codecs/rt5645.c +60 −5
  336. sound/soc/codecs/rt5659.c +0 −1
  337. sound/soc/codecs/rt5660.c +0 −2
  338. sound/soc/codecs/rt5665.c +8 −9
  339. sound/soc/codecs/rt5668.c +8 −9
  340. sound/soc/codecs/rt5677.c +38 −79
  341. sound/soc/codecs/rt5677.h +15 −77
  342. sound/soc/codecs/rt5682-i2c.c +4 −7
  343. sound/soc/codecs/rt5682-sdw.c +38 −25
  344. sound/soc/codecs/rt5682.c +18 −5
  345. sound/soc/codecs/rt5682.h +3 −0
  346. sound/soc/codecs/rt5682s.c +7 −9
  347. sound/soc/codecs/rt5682s.h +2 −0
  348. sound/soc/codecs/rt700-sdw.c +2 −5
  349. sound/soc/codecs/rt700.c +30 −16
  350. sound/soc/codecs/rt711-sdca-sdw.c +1 −2
  351. sound/soc/codecs/rt711-sdca.c +34 −14
  352. sound/soc/codecs/rt711-sdw.c +2 −5
  353. sound/soc/codecs/rt711.c +31 −16
  354. sound/soc/codecs/rt712-sdca-dmic.c +29 −18
  355. sound/soc/codecs/rt712-sdca-sdw.c +1 −2
  356. sound/soc/codecs/rt712-sdca.c +31 −14
  357. sound/soc/codecs/rt715-sdca-sdw.c +1 −4
  358. sound/soc/codecs/rt715-sdca.c +31 −10
  359. sound/soc/codecs/rt715-sdw.c +2 −7
  360. sound/soc/codecs/rt715.c +84 −16
  361. sound/soc/codecs/rt715.h +7 −0
  362. sound/soc/codecs/rt722-sdca-sdw.c +1 −1
  363. sound/soc/codecs/rt722-sdca.c +1 −2
  364. sound/soc/codecs/sigmadsp.c +4 −21
  365. sound/soc/codecs/ssm3515.c +1 −1
  366. sound/soc/codecs/sta32x.c +1 −1
  367. sound/soc/codecs/sta350.c +1 −1
  368. sound/soc/codecs/sta529.c +1 −1
  369. sound/soc/codecs/stac9766.c +1 −1
  370. sound/soc/codecs/sti-sas.c +1 −1
  371. sound/soc/codecs/tas2781-i2c.c +0 −1
  372. sound/soc/codecs/tas5805m.c +1 −2
  373. sound/soc/codecs/tlv320aic32x4-clk.c +11 −5
  374. sound/soc/codecs/tlv320aic32x4.c +1 −1
  375. sound/soc/codecs/tlv320aic32x4.h +3 −2
  376. sound/soc/codecs/uda134x.c +0 −587
  377. sound/soc/codecs/uda134x.h +0 −33
  378. sound/soc/codecs/wcd9335.c +1 −1
  379. sound/soc/codecs/wcd938x-sdw.c +1 −1
  380. sound/soc/codecs/wm2200.c +7 −7
  381. sound/soc/codecs/wm5100.c +1 −1
  382. sound/soc/codecs/wm5102.c +5 −1
  383. sound/soc/codecs/wm5110.c +6 −2
  384. sound/soc/codecs/wm8510.c +1 −1
  385. sound/soc/codecs/wm8523.c +1 −1
  386. sound/soc/codecs/wm8580.c +1 −1
  387. sound/soc/codecs/wm8711.c +1 −1
  388. sound/soc/codecs/wm8728.c +1 −1
  389. sound/soc/codecs/wm8731.c +1 −1
  390. sound/soc/codecs/wm8737.c +1 −1
  391. sound/soc/codecs/wm8741.c +1 −1
  392. sound/soc/codecs/wm8750.c +1 −1
  393. sound/soc/codecs/wm8753.c +1 −1
  394. sound/soc/codecs/wm8770.c +1 −1
  395. sound/soc/codecs/wm8776.c +1 −1
  396. sound/soc/codecs/wm8804.c +1 −1
  397. sound/soc/codecs/wm8900.c +1 −1
  398. sound/soc/codecs/wm8903.c +1 −1
  399. sound/soc/codecs/wm8904.c +2 −2
  400. sound/soc/codecs/wm8940.c +1 −1
  401. sound/soc/codecs/wm8955.c +1 −1
  402. sound/soc/codecs/wm8960.c +52 −2
  403. sound/soc/codecs/wm8960.h +2 −2
  404. sound/soc/codecs/wm8961.c +1 −1
  405. sound/soc/codecs/wm8962.c +1 −1
  406. sound/soc/codecs/wm8971.c +1 −1
  407. sound/soc/codecs/wm8978.c +1 −1
  408. sound/soc/codecs/wm8983.c +1 −1
  409. sound/soc/codecs/wm8985.c +1 −1
  410. sound/soc/codecs/wm8988.c +1 −1
  411. sound/soc/codecs/wm8991.c +1 −1
  412. sound/soc/codecs/wm8993.c +1 −1
  413. sound/soc/codecs/wm8994.c +1 −1
  414. sound/soc/codecs/wm8995.c +1 −1
  415. sound/soc/codecs/wm8996.c +1 −1
  416. sound/soc/codecs/wm9081.c +1 −1
  417. sound/soc/codecs/wm9090.c +1 −1
  418. sound/soc/codecs/wm9705.c +1 −1
  419. sound/soc/codecs/wm9712.c +1 −1
  420. sound/soc/codecs/wm9713.c +1 −1
  421. sound/soc/codecs/wm_adsp.c +16 −8
  422. sound/soc/codecs/wm_adsp.h +2 −1
  423. sound/soc/codecs/wsa881x.c +1 −1
  424. sound/soc/codecs/wsa883x.c +1 −1
  425. sound/soc/dwc/dwc-i2s.c +352 −29
  426. sound/soc/dwc/dwc-pcm.c +4 −4
  427. sound/soc/dwc/local.h +25 −0
  428. sound/soc/fsl/fsl_asrc.c +8 −8
  429. sound/soc/fsl/fsl_aud2htx.c +5 −5
  430. sound/soc/fsl/fsl_easrc.c +8 −8
  431. sound/soc/fsl/fsl_esai.c +10 −10
  432. sound/soc/fsl/fsl_micfil.c +90 −26
  433. sound/soc/fsl/fsl_micfil.h +64 −0
  434. sound/soc/fsl/fsl_qmc_audio.c +14 −14
  435. sound/soc/fsl/fsl_rpmsg.c +8 −0
  436. sound/soc/fsl/fsl_sai.c +12 −12
  437. sound/soc/fsl/fsl_spdif.c +14 −11
  438. sound/soc/fsl/fsl_spdif.h +4 −2
  439. sound/soc/fsl/fsl_ssi.c +1 −2
  440. sound/soc/fsl/fsl_xcvr.c +8 −8
  441. sound/soc/fsl/imx-audio-rpmsg.c +0 −1
  442. sound/soc/fsl/imx-es8328.c +22 −3
  443. sound/soc/fsl/imx-pcm-rpmsg.c +8 −4
  444. sound/soc/fsl/mpc5200_psc_ac97.c +1 −1
  445. sound/soc/generic/audio-graph-card.c +70 −73
  446. sound/soc/generic/audio-graph-card2-custom-sample.dtsi +7 −0
  447. sound/soc/generic/audio-graph-card2.c +13 −1
  448. sound/soc/generic/simple-card-utils.c +19 −4
  449. sound/soc/generic/simple-card.c +62 −4
  450. sound/soc/hisilicon/hi6210-i2s.c +1 −1
  451. sound/soc/img/img-i2s-in.c +7 −7
  452. sound/soc/img/img-i2s-out.c +7 −7
  453. sound/soc/img/img-parallel-out.c +7 −7
  454. sound/soc/img/img-spdif-in.c +6 −6
  455. sound/soc/img/img-spdif-out.c +6 −6
  456. sound/soc/intel/atom/sst-mfld-platform-pcm.c +1 −1
  457. sound/soc/intel/atom/sst/sst.c +10 −4
  458. sound/soc/intel/atom/sst/sst.h +2 −5
  459. sound/soc/intel/atom/sst/sst_pci.c +2 −2
  460. sound/soc/intel/atom/sst/sst_stream.c +7 −6
  461. sound/soc/intel/avs/board_selection.c +21 −5
  462. sound/soc/intel/avs/boards/Kconfig +20 −0
  463. sound/soc/intel/avs/boards/Makefile +4 −0
  464. sound/soc/intel/avs/boards/da7219.c +30 −4
  465. sound/soc/intel/avs/boards/es8336.c +315 −0
  466. sound/soc/intel/avs/boards/rt5663.c +254 −0
  467. sound/soc/intel/avs/boards/rt5682.c +40 −27
  468. sound/soc/intel/avs/core.c +8 −8
  469. sound/soc/intel/avs/probes.c +7 −3
  470. sound/soc/intel/avs/topology.c +3 −3
  471. sound/soc/intel/boards/Kconfig +6 −4
  472. sound/soc/intel/boards/Makefile +1 −1
  473. sound/soc/intel/boards/bdw_rt286.c +6 −0
  474. sound/soc/intel/boards/bxt_da7219_max98357a.c +7 −0
  475. sound/soc/intel/boards/bytcr_wm5102.c +7 −0
  476. sound/soc/intel/boards/kbl_da7219_max98357a.c +7 −0
  477. sound/soc/intel/boards/kbl_da7219_max98927.c +7 −0
  478. sound/soc/intel/boards/sof_da7219_max98373.c +10 −0
  479. sound/soc/intel/boards/sof_es8336.c +10 −0
  480. sound/soc/intel/boards/sof_maxim_common.c +100 −70
  481. sound/soc/intel/boards/sof_maxim_common.h +9 −12
  482. sound/soc/intel/boards/sof_nau8825.c +10 −0
  483. sound/soc/intel/boards/sof_rt5682.c +135 −37
  484. sound/soc/intel/boards/sof_sdw.c +276 −332
  485. sound/soc/intel/boards/sof_sdw_common.h +7 −0
  486. sound/soc/intel/boards/sof_sdw_cs_amp.c +47 −0
  487. sound/soc/intel/boards/sof_ssp_amp.c +9 −0
  488. sound/soc/intel/catpt/pcm.c +6 −2
  489. sound/soc/intel/common/soc-acpi-intel-adl-match.c +7 −0
  490. sound/soc/intel/common/soc-acpi-intel-jsl-match.c +12 −0
  491. sound/soc/intel/common/soc-acpi-intel-mtl-match.c +52 −0
  492. sound/soc/intel/common/soc-acpi-intel-rpl-match.c +69 −0
  493. sound/soc/intel/keembay/kmb_platform.c +1 −3
  494. sound/soc/intel/skylake/skl-messages.c +8 −8
  495. sound/soc/intel/skylake/skl-pcm.c +2 −1
  496. sound/soc/intel/skylake/skl.c +10 −26
  497. sound/soc/jz4740/jz4740-i2s.c +1 −2
  498. sound/soc/loongson/loongson_card.c +1 −1
  499. sound/soc/loongson/loongson_i2s.c +8 −8
  500. sound/soc/mediatek/Kconfig +20 −0
  501. sound/soc/mediatek/Makefile +1 −0
  502. sound/soc/mediatek/common/mtk-btcvsd.c +10 −17
  503. sound/soc/mediatek/mt7986/Makefile +9 −0
  504. sound/soc/mediatek/mt7986/mt7986-afe-common.h +49 −0
  505. sound/soc/mediatek/mt7986/mt7986-afe-pcm.c +622 −0
  506. sound/soc/mediatek/mt7986/mt7986-dai-etdm.c +411 −0
  507. sound/soc/mediatek/mt7986/mt7986-reg.h +196 −0
  508. sound/soc/mediatek/mt7986/mt7986-wm8960.c +196 −0
  509. sound/soc/mediatek/mt8173/mt8173-max98090.c +1 −1
  510. sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c +18 −5
  511. sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +18 −5
  512. sound/soc/mediatek/mt8173/mt8173-rt5650.c +18 −5
  513. sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c +36 −7
  514. sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +47 −6
  515. sound/soc/mediatek/mt8186/mt8186-afe-clk.c +0 −2
  516. sound/soc/mediatek/mt8186/mt8186-afe-pcm.c +1 −3
  517. sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c +6 −0
  518. sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +6 −2
  519. sound/soc/mediatek/mt8188/mt8188-mt6359.c +16 −11
  520. sound/soc/mediatek/mt8195/mt8195-dai-etdm.c +31 −25
  521. sound/soc/meson/aiu-acodec-ctrl.c +2 −2
  522. sound/soc/meson/aiu-codec-ctrl.c +2 −2
  523. sound/soc/meson/aiu-fifo-i2s.c +3 −0
  524. sound/soc/meson/aiu-fifo-spdif.c +3 −0
  525. sound/soc/meson/aiu.c +0 −6
  526. sound/soc/meson/axg-frddr.c +2 −2
  527. sound/soc/meson/axg-pdm.c +9 −9
  528. sound/soc/meson/axg-spdifin.c +2 −2
  529. sound/soc/meson/axg-tdm-interface.c +2 −4
  530. sound/soc/meson/axg-toddr.c +2 −2
  531. sound/soc/meson/g12a-toacodec.c +2 −2
  532. sound/soc/meson/g12a-tohdmitx.c +2 −2
  533. sound/soc/pxa/mmp-sspa.c +1 −1
  534. sound/soc/pxa/pxa-ssp.c +3 −9
  535. sound/soc/pxa/pxa2xx-i2s.c +5 −12
  536. sound/soc/qcom/apq8016_sbc.c +29 −8
  537. sound/soc/qcom/lpass-apq8016.c +0 −4
  538. sound/soc/qcom/lpass-cpu.c +25 −15
  539. sound/soc/qcom/lpass-ipq806x.c +0 −1
  540. sound/soc/qcom/lpass-platform.c +7 −6
  541. sound/soc/qcom/lpass-sc7180.c +1 −4
  542. sound/soc/qcom/lpass-sc7280.c +0 −2
  543. sound/soc/qcom/lpass.h +1 −3
  544. sound/soc/qcom/qdsp6/q6afe-dai.c +48 −40
  545. sound/soc/qcom/qdsp6/q6apm.c +1 −1
  546. sound/soc/qcom/qdsp6/q6apm.h +0 −2
  547. sound/soc/qcom/qdsp6/q6asm-dai.c +5 −1
  548. sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c +0 −3
  549. sound/soc/qcom/sc7180.c +33 −7
  550. sound/soc/qcom/sc7280.c +27 −7
  551. sound/soc/qcom/sdm845.c +26 −6
  552. sound/soc/rockchip/rk3399_gru_sound.c +6 −1
  553. sound/soc/rockchip/rockchip_i2s.c +1 −1
  554. sound/soc/rockchip/rockchip_i2s_tdm.c +1 −1
  555. sound/soc/rockchip/rockchip_pdm.c +2 −2
  556. sound/soc/rockchip/rockchip_rt5645.c +17 −5
  557. sound/soc/rockchip/rockchip_spdif.c +1 −1
  558. sound/soc/samsung/aries_wm8994.c +7 −3
  559. sound/soc/samsung/i2s.c +2 −3
  560. sound/soc/samsung/littlemill.c +21 −6
  561. sound/soc/samsung/lowland.c +7 −1
  562. sound/soc/samsung/midas_wm1811.c +26 −8
  563. sound/soc/samsung/odroid.c +8 −7
  564. sound/soc/samsung/pcm.c +9 −9
  565. sound/soc/samsung/tm2_wm5110.c +7 −3
  566. sound/soc/sh/rcar/adg.c +55 −13
  567. sound/soc/sh/rcar/core.c +114 −61
  568. sound/soc/sh/rcar/rsnd.h +4 −0
  569. sound/soc/soc-acpi.c +73 −0
  570. sound/soc/soc-component.c +7 −9
  571. sound/soc/soc-compress.c +1 −0
  572. sound/soc/soc-core.c +194 −79
  573. sound/soc/soc-dai.c +36 −19
  574. sound/soc/soc-dapm.c +2 −0
  575. sound/soc/soc-generic-dmaengine-pcm.c +9 −9
  576. sound/soc/soc-jack.c +1 −1
  577. sound/soc/soc-pcm.c +2 −2
  578. sound/soc/soc-topology.c +5 −4
  579. sound/soc/sof/amd/Kconfig +19 −1
  580. sound/soc/sof/amd/Makefile +4 −1
  581. sound/soc/sof/amd/acp-common.c +4 −0
  582. sound/soc/sof/amd/acp-dsp-offset.h +8 −1
  583. sound/soc/sof/amd/acp-ipc.c +30 −0
  584. sound/soc/sof/amd/acp-loader.c +39 −3
  585. sound/soc/sof/amd/acp-probes.c +147 −0
  586. sound/soc/sof/amd/acp.c +67 −39
  587. sound/soc/sof/amd/acp.h +32 −3
  588. sound/soc/sof/amd/pci-rmb.c +2 −0
  589. sound/soc/sof/amd/pci-rn.c +2 −0
  590. sound/soc/sof/amd/pci-vangogh.c +105 −0
  591. sound/soc/sof/amd/vangogh.c +162 −0
  592. sound/soc/sof/intel/Kconfig +16 −0
  593. sound/soc/sof/intel/Makefile +3 −1
  594. sound/soc/sof/intel/cnl.c +2 −0
  595. sound/soc/sof/intel/hda-dai-ops.c +176 −3
  596. sound/soc/sof/intel/hda-dai.c +210 −1
  597. sound/soc/sof/intel/hda-mlink.c +38 −7
  598. sound/soc/sof/intel/hda-stream.c +8 −60
  599. sound/soc/sof/intel/hda.c +56 −84
  600. sound/soc/sof/intel/hda.h +21 −0
  601. sound/soc/sof/intel/icl.c +1 −0
  602. sound/soc/sof/intel/lnl.c +188 −0
  603. sound/soc/sof/intel/mtl.c +12 −11
  604. sound/soc/sof/intel/mtl.h +20 −2
  605. sound/soc/sof/intel/pci-apl.c +2 −6
  606. sound/soc/sof/intel/pci-cnl.c +5 −10
  607. sound/soc/sof/intel/pci-icl.c +4 −8
  608. sound/soc/sof/intel/pci-lnl.c +71 −0
  609. sound/soc/sof/intel/pci-mtl.c +1 −2
  610. sound/soc/sof/intel/pci-skl.c +2 −4
  611. sound/soc/sof/intel/pci-tgl.c +15 −30
  612. sound/soc/sof/intel/pci-tng.c +1 −2
  613. sound/soc/sof/intel/shim.h +1 −0
  614. sound/soc/sof/intel/tgl.c +4 −0
  615. sound/soc/sof/ipc3-dtrace.c +3 −9
  616. sound/soc/sof/ipc3-pcm.c +17 −0
  617. sound/soc/sof/ipc3.c +2 −5
  618. sound/soc/sof/ipc4-pcm.c +11 −10
  619. sound/soc/sof/ipc4-topology.c +119 −48
  620. sound/soc/sof/ipc4-topology.h +2 −2
  621. sound/soc/sof/mediatek/mt8186/mt8186.c +23 −17
  622. sound/soc/sof/sof-client-probes-ipc4.c +9 −0
  623. sound/soc/sof/sof-client-probes.c +6 −1
  624. sound/soc/sof/topology.c +27 −2
  625. sound/soc/starfive/jh7110_tdm.c +10 −11
  626. sound/soc/sti/sti_uniperif.c +5 −1
  627. sound/soc/stm/stm32_i2s.c +1 −1
  628. sound/soc/stm/stm32_sai_sub.c +15 −5
  629. sound/soc/stm/stm32_spdifrx.c +1 −1
  630. sound/soc/sunxi/sun4i-codec.c +5 −1
  631. sound/soc/sunxi/sun4i-i2s.c +9 −9
  632. sound/soc/sunxi/sun4i-spdif.c +2 −2
  633. sound/soc/sunxi/sun50i-dmic.c +1 −1
  634. sound/soc/tegra/tegra20_ac97.c +6 −7
  635. sound/soc/tegra/tegra20_i2s.c +1 −1
  636. sound/soc/tegra/tegra20_spdif.c +1 −1
  637. sound/soc/tegra/tegra210_admaif.c +6 −6
  638. sound/soc/tegra/tegra210_sfc.c +30 −1
  639. sound/soc/tegra/tegra210_sfc.h +2 −2
  640. sound/soc/tegra/tegra30_i2s.c +1 −1
  641. sound/soc/ti/davinci-evm.c +1 −12
  642. sound/soc/ti/davinci-i2s.c +11 −11
  643. sound/soc/ti/davinci-mcasp.c +13 −14
  644. sound/soc/ti/omap-dmic.c +12 −14
  645. sound/soc/ti/omap-mcbsp.c +16 −16
  646. sound/soc/ti/omap-mcpdm.c +12 −13
  647. sound/soc/uniphier/aio-cpu.c +134 −27
  648. sound/soc/uniphier/aio-ld11.c +9 −53
  649. sound/soc/uniphier/aio-pxs2.c +7 −48
  650. sound/soc/uniphier/aio.h +6 −4
  651. sound/soc/ux500/ux500_msp_dai.c +1 −1
  652. sound/sparc/amd7930.c +1 −2
  653. sound/sparc/cs4231.c +1 −1
  654. sound/sparc/dbri.c +1 −1
  655. sound/usb/bcd2000/bcd2000.c +2 −2
  656. sound/usb/endpoint.c +27 −13
  657. sound/usb/endpoint.h +0 −1
  658. sound/usb/media.c +2 −2
  659. sound/usb/midi2.c +8 −7
  660. sound/usb/stream.c +10 −1
  661. sound/xen/xen_snd_front_alsa.c +15 −49
  662. tools/testing/kunit/configs/all_tests.config +5 −0
  663. tools/testing/selftests/alsa/pcm-test.c +5 −3
Documentation/core-api/kernel-api.rst+4−2
@@ -162,8 +162,10 @@ Base 2 log and power Functions · 161 unmodified lines
162.. kernel-doc:: include/linux/log2.h162.. kernel-doc:: include/linux/log2.h
163 :internal:163 :internal:
164 164
165Integer power Functions165Integer log and power Functions
166-----------------------166-------------------------------
167
168.. kernel-doc:: include/linux/int_log.h
167 169
168.. kernel-doc:: lib/math/int_pow.c170.. kernel-doc:: lib/math/int_pow.c
169 :export:171 :export:
Documentation/devicetree/bindings/sound/amlogic,axg-sound-card.yaml+3−12
@@ -9,6 +9,9 @@ title: Amlogic AXG sound card · 8 unmodified lines
9maintainers:9maintainers:
10 - Jerome Brunet <jbrunet@baylibre.com>10 - Jerome Brunet <jbrunet@baylibre.com>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 const: amlogic,axg-sound-card17 const: amlogic,axg-sound-card
@@ -17,23 +20,12 @@ properties: · 2 unmodified lines
17 $ref: /schemas/types.yaml#/definitions/phandle-array20 $ref: /schemas/types.yaml#/definitions/phandle-array
18 description: list of auxiliary devices21 description: list of auxiliary devices
19 22
20 audio-routing:
21 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
22 description:
23 A list of the connections between audio components. Each entry is a
24 pair of strings, the first being the connection's sink, the second
25 being the connection's source.
26
27 audio-widgets:23 audio-widgets:
28 $ref: /schemas/types.yaml#/definitions/non-unique-string-array24 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
29 description:25 description:
30 A list off component DAPM widget. Each entry is a pair of strings,26 A list off component DAPM widget. Each entry is a pair of strings,
31 the first being the widget type, the second being the widget name27 the first being the widget type, the second being the widget name
32 28
33 model:
34 $ref: /schemas/types.yaml#/definitions/string
35 description: User specified audio sound card name
36
37patternProperties:29patternProperties:
38 "^dai-link-[0-9]+$":30 "^dai-link-[0-9]+$":
39 type: object31 type: object
@@ -108,7 +100,6 @@ patternProperties: · 68 unmodified lines
108 - sound-dai100 - sound-dai
109 101
110required:102required:
111 - model
112 - dai-link-0103 - dai-link-0
113 104
114unevaluatedProperties: false105unevaluatedProperties: false
Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml+4−13
@@ -9,6 +9,9 @@ title: Amlogic GX sound card · 8 unmodified lines
9maintainers:9maintainers:
10 - Jerome Brunet <jbrunet@baylibre.com>10 - Jerome Brunet <jbrunet@baylibre.com>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 items:17 items:
@@ -18,14 +21,6 @@ properties: · 3 unmodified lines
18 $ref: /schemas/types.yaml#/definitions/phandle-array21 $ref: /schemas/types.yaml#/definitions/phandle-array
19 description: list of auxiliary devices22 description: list of auxiliary devices
20 23
21 audio-routing:
22 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
23 minItems: 2
24 description: |-
25 A list of the connections between audio components. Each entry is a
26 pair of strings, the first being the connection's sink, the second
27 being the connection's source.
28
29 audio-widgets:24 audio-widgets:
30 $ref: /schemas/types.yaml#/definitions/non-unique-string-array25 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
31 minItems: 226 minItems: 2
@@ -33,10 +28,6 @@ properties: · 1 unmodified line
33 A list off component DAPM widget. Each entry is a pair of strings,28 A list off component DAPM widget. Each entry is a pair of strings,
34 the first being the widget type, the second being the widget name29 the first being the widget type, the second being the widget name
35 30
36 model:
37 $ref: /schemas/types.yaml#/definitions/string
38 description: User specified audio sound card name
39
40patternProperties:31patternProperties:
41 "^dai-link-[0-9]+$":32 "^dai-link-[0-9]+$":
42 type: object33 type: object
@@ -86,7 +77,7 @@ required: · 43 unmodified lines
86 - model77 - model
87 - dai-link-078 - dai-link-0
88 79
89additionalProperties: false80unevaluatedProperties: false
90 81
91examples:82examples:
92 - |83 - |
Documentation/devicetree/bindings/sound/audio-iio-aux.yaml+64−0
@@ -0,0 +1,64 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/audio-iio-aux.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Audio IIO auxiliary
8
9maintainers:
10 - Herve Codina <herve.codina@bootlin.com>
11
12description:
13 Auxiliary device based on Industrial I/O device channels
14
15allOf:
16 - $ref: dai-common.yaml#
17
18properties:
19 compatible:
20 const: audio-iio-aux
21
22 io-channels:
23 description:
24 Industrial I/O device channels used
25
26 io-channel-names:
27 description:
28 Industrial I/O channel names related to io-channels.
29 These names are used to provides sound controls, widgets and routes names.
30
31 snd-control-invert-range:
32 $ref: /schemas/types.yaml#/definitions/uint32-array
33 description: |
34 A list of 0/1 flags defining whether or not the related channel is
35 inverted
36 items:
37 enum: [0, 1]
38 default: 0
39 description: |
40 Invert the sound control value compared to the IIO channel raw value.
41 - 1: The related sound control value is inverted meaning that the
42 minimum sound control value correspond to the maximum IIO channel
43 raw value and the maximum sound control value correspond to the
44 minimum IIO channel raw value.
45 - 0: The related sound control value is not inverted meaning that the
46 minimum (resp maximum) sound control value correspond to the
47 minimum (resp maximum) IIO channel raw value.
48
49required:
50 - compatible
51 - io-channels
52 - io-channel-names
53
54unevaluatedProperties: false
55
56examples:
57 - |
58 iio-aux {
59 compatible = "audio-iio-aux";
60 io-channels = <&iio 0>, <&iio 1>, <&iio 2>, <&iio 3>;
61 io-channel-names = "CH0", "CH1", "CH2", "CH3";
62 /* Invert CH1 and CH2 */
63 snd-control-invert-range = <0 1 1 0>;
64 };
Documentation/devicetree/bindings/sound/awinic,aw88395.yaml+3−1
@@ -19,7 +19,9 @@ allOf: · 18 unmodified lines
19 19
20properties:20properties:
21 compatible:21 compatible:
22 const: awinic,aw8839522 enum:
23 - awinic,aw88395
24 - awinic,aw88261
23 25
24 reg:26 reg:
25 maxItems: 127 maxItems: 1
Documentation/devicetree/bindings/sound/fsl,rpmsg.yaml+5−13
@@ -17,6 +17,9 @@ description: | · 16 unmodified lines
17 such as SAI, MICFIL, .etc through building rpmsg channels between17 such as SAI, MICFIL, .etc through building rpmsg channels between
18 Cortex-A and Cortex-M.18 Cortex-A and Cortex-M.
19 19
20allOf:
21 - $ref: sound-card-common.yaml#
22
20properties:23properties:
21 compatible:24 compatible:
22 enum:25 enum:
@@ -25,10 +28,7 @@ properties: · 2 unmodified lines
25 - fsl,imx8mm-rpmsg-audio28 - fsl,imx8mm-rpmsg-audio
26 - fsl,imx8mp-rpmsg-audio29 - fsl,imx8mp-rpmsg-audio
27 - fsl,imx8ulp-rpmsg-audio30 - fsl,imx8ulp-rpmsg-audio
28 31 - fsl,imx93-rpmsg-audio
29 model:
30 $ref: /schemas/types.yaml#/definitions/string
31 description: User specified audio sound card name
32 32
33 clocks:33 clocks:
34 items:34 items:
@@ -65,13 +65,6 @@ properties: · 30 unmodified lines
65 $ref: /schemas/types.yaml#/definitions/phandle65 $ref: /schemas/types.yaml#/definitions/phandle
66 description: The phandle to a node of audio codec66 description: The phandle to a node of audio codec
67 67
68 audio-routing:
69 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
70 description: |
71 A list of the connections between audio components. Each entry is a
72 pair of strings, the first being the connection's sink, the second
73 being the connection's source.
74
75 fsl,enable-lpa:68 fsl,enable-lpa:
76 $ref: /schemas/types.yaml#/definitions/flag69 $ref: /schemas/types.yaml#/definitions/flag
77 description: enable low power audio path.70 description: enable low power audio path.
@@ -100,9 +93,8 @@ properties: · 22 unmodified lines
100 93
101required:94required:
102 - compatible95 - compatible
103 - model
104 96
105additionalProperties: false97unevaluatedProperties: false
106 98
107examples:99examples:
108 - |100 - |
Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml+4−13
@@ -13,23 +13,15 @@ maintainers: · 12 unmodified lines
13description:13description:
14 This binding describes the SC7180 sound card which uses LPASS for audio.14 This binding describes the SC7180 sound card which uses LPASS for audio.
15 15
16allOf:
17 - $ref: sound-card-common.yaml#
18
16properties:19properties:
17 compatible:20 compatible:
18 enum:21 enum:
19 - google,sc7180-trogdor22 - google,sc7180-trogdor
20 - google,sc7180-coachz23 - google,sc7180-coachz
21 24
22 audio-routing:
23 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
24 description:
25 A list of the connections between audio components. Each entry is a
26 pair of strings, the first being the connection's sink, the second
27 being the connection's source.
28
29 model:
30 $ref: /schemas/types.yaml#/definitions/string
31 description: User specified audio sound card name
32
33 "#address-cells":25 "#address-cells":
34 const: 126 const: 1
35 27
@@ -86,11 +78,10 @@ patternProperties: · 50 unmodified lines
86 78
87required:79required:
88 - compatible80 - compatible
89 - model
90 - "#address-cells"81 - "#address-cells"
91 - "#size-cells"82 - "#size-cells"
92 83
93additionalProperties: false84unevaluatedProperties: false
94 85
95examples:86examples:
96 87
Documentation/devicetree/bindings/sound/google,sc7280-herobrine.yaml+4−13
@@ -13,22 +13,14 @@ maintainers: · 12 unmodified lines
13description:13description:
14 This binding describes the SC7280 sound card which uses LPASS for audio.14 This binding describes the SC7280 sound card which uses LPASS for audio.
15 15
16allOf:
17 - $ref: sound-card-common.yaml#
18
16properties:19properties:
17 compatible:20 compatible:
18 enum:21 enum:
19 - google,sc7280-herobrine22 - google,sc7280-herobrine
20 23
21 audio-routing:
22 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
23 description:
24 A list of the connections between audio components. Each entry is a
25 pair of strings, the first being the connection's sink, the second
26 being the connection's source.
27
28 model:
29 $ref: /schemas/types.yaml#/definitions/string
30 description: User specified audio sound card name
31
32 "#address-cells":24 "#address-cells":
33 const: 125 const: 1
34 26
@@ -97,11 +89,10 @@ patternProperties: · 62 unmodified lines
97 89
98required:90required:
99 - compatible91 - compatible
100 - model
101 - "#address-cells"92 - "#address-cells"
102 - "#size-cells"93 - "#size-cells"
103 94
104additionalProperties: false95unevaluatedProperties: false
105 96
106examples:97examples:
107 98
Documentation/devicetree/bindings/sound/gtm601.txt+0−19
@@ -1,19 +0,0 @@
1GTM601 UMTS modem audio interface CODEC
2
3This device has no configuration interface. The sample rate and channels are
4based on the compatible string
5 "option,gtm601" = 8kHz mono
6 "broadmobi,bm818" = 48KHz stereo
7
8Required properties:
9
10 - compatible : one of
11 "option,gtm601"
12 "broadmobi,bm818"
13
14
15Example:
16
17codec: gtm601_codec {
18 compatible = "option,gtm601";
19};
Documentation/devicetree/bindings/sound/imx-audio-card.yaml+4−14
@@ -9,23 +9,14 @@ title: NXP i.MX audio sound card. · 8 unmodified lines
9maintainers:9maintainers:
10 - Shengjiu Wang <shengjiu.wang@nxp.com>10 - Shengjiu Wang <shengjiu.wang@nxp.com>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 enum:17 enum:
15 - fsl,imx-audio-card18 - fsl,imx-audio-card
16 19
17 model:
18 $ref: /schemas/types.yaml#/definitions/string
19 description: User specified audio sound card name
20
21 audio-routing:
22 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
23 description:
24 A list of the connections between audio components. Each entry is a
25 pair of strings, the first being the connection's sink, the second
26 being the connection's source. Valid names could be power supplies,
27 MicBias of codec and the jacks on the board.
28
29patternProperties:20patternProperties:
30 ".*-dai-link$":21 ".*-dai-link$":
31 description:22 description:
@@ -84,9 +75,8 @@ patternProperties: · 52 unmodified lines
84 75
85required:76required:
86 - compatible77 - compatible
87 - model
88 78
89additionalProperties: false79unevaluatedProperties: false
90 80
91examples:81examples:
92 - |82 - |
Documentation/devicetree/bindings/sound/max9892x.txt+0−44
@@ -1,44 +0,0 @@
1Maxim Integrated MAX98925/MAX98926/MAX98927 Speaker Amplifier
2
3This device supports I2C.
4
5Required properties:
6
7 - compatible : should be one of the following
8 - "maxim,max98925"
9 - "maxim,max98926"
10 - "maxim,max98927"
11
12 - vmon-slot-no : slot number used to send voltage information
13 or in inteleave mode this will be used as
14 interleave slot.
15 MAX98925/MAX98926 slot range : 0 ~ 30, Default : 0
16 MAX98927 slot range : 0 ~ 15, Default : 0
17
18 - imon-slot-no : slot number used to send current information
19 MAX98925/MAX98926 slot range : 0 ~ 30, Default : 0
20 MAX98927 slot range : 0 ~ 15, Default : 0
21
22 - interleave-mode : When using two MAX9892X in a system it is
23 possible to create ADC data that that will
24 overflow the frame size. Digital Audio Interleave
25 mode provides a means to output VMON and IMON data
26 from two devices on a single DOUT line when running
27 smaller frames sizes such as 32 BCLKS per LRCLK or
28 48 BCLKS per LRCLK.
29 Range : 0 (off), 1 (on), Default : 0
30
31 - reg : the I2C address of the device for I2C
32
33Optional properties:
34 - reset-gpios : GPIO to reset the device
35
36Example:
37
38codec: max98927@3a {
39 compatible = "maxim,max98927";
40 vmon-slot-no = <0>;
41 imon-slot-no = <1>;
42 interleave-mode = <0>;
43 reg = <0x3a>;
44};
Documentation/devicetree/bindings/sound/maxim,max98925.yaml+98−0
@@ -0,0 +1,98 @@
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,max98925.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Maxim Integrated MAX98925/MAX98926/MAX98927 speaker amplifier
8
9maintainers:
10 - Ryan Lee <ryans.lee@maximintegrated.com>
11
12properties:
13 compatible:
14 enum:
15 - maxim,max98925
16 - maxim,max98926
17 - maxim,max98927
18
19 reg:
20 maxItems: 1
21
22 reset-gpios:
23 maxItems: 1
24
25 '#sound-dai-cells':
26 const: 0
27
28 vmon-slot-no:
29 $ref: /schemas/types.yaml#/definitions/uint32
30 minimum: 0
31 maximum: 30
32 default: 0
33 description:
34 Slot number used to send voltage information or in inteleave mode this
35 will be used as interleave slot.
36
37 imon-slot-no:
38 $ref: /schemas/types.yaml#/definitions/uint32
39 minimum: 0
40 maximum: 30
41 default: 0
42 description:
43 Slot number used to send current information.
44
45 maxim,interleave-mode:
46 type: boolean
47 description:
48 When using two MAX9892X in a system it is possible to create ADC data
49 that will overflow the frame size. When enabled, the Digital Audio
50 Interleave mode provides a means to output VMON and IMON data from two
51 devices on a single DOUT line when running smaller frames sizes such as
52 32 BCLKS per LRCLK or 48 BCLKS per LRCLK.
53
54required:
55 - compatible
56 - reg
57
58allOf:
59 - $ref: dai-common.yaml#
60 - if:
61 properties:
62 compatible:
63 contains:
64 enum:
65 - maxim,max98927
66 then:
67 properties:
68 vmon-slot-no:
69 minimum: 0
70 maximum: 15
71
72 imon-slot-no:
73 minimum: 0
74 maximum: 15
75
76additionalProperties: false
77
78examples:
79 - |
80 i2c {
81 #address-cells = <1>;
82 #size-cells = <0>;
83
84 #include <dt-bindings/gpio/gpio.h>
85 audio-codec@3a {
86 compatible = "maxim,max98927";
87 reg = <0x3a>;
88 #sound-dai-cells = <0>;
89
90 pinctrl-0 = <&speaker_default>;
91 pinctrl-names = "default";
92
93 reset-gpios = <&tlmm 69 GPIO_ACTIVE_LOW>;
94
95 vmon-slot-no = <1>;
96 imon-slot-no = <0>;
97 };
98 };
Documentation/devicetree/bindings/sound/mediatek,mt7986-afe.yaml+160−0
@@ -0,0 +1,160 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/mediatek,mt7986-afe.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: MediaTek AFE PCM controller for MT7986
8
9maintainers:
10 - Maso Huang <maso.huang@mediatek.com>
11
12properties:
13 compatible:
14 oneOf:
15 - const: mediatek,mt7986-afe
16 - items:
17 - enum:
18 - mediatek,mt7981-afe
19 - mediatek,mt7988-afe
20 - const: mediatek,mt7986-afe
21
22 reg:
23 maxItems: 1
24
25 interrupts:
26 maxItems: 1
27
28 clocks:
29 minItems: 5
30 items:
31 - description: audio bus clock
32 - description: audio 26M clock
33 - description: audio intbus clock
34 - description: audio hopping clock
35 - description: audio pll clock
36 - description: mux for pcm_mck
37 - description: audio i2s/pcm mck
38
39 clock-names:
40 minItems: 5
41 items:
42 - const: bus_ck
43 - const: 26m_ck
44 - const: l_ck
45 - const: aud_ck
46 - const: eg2_ck
47 - const: sel
48 - const: i2s_m
49
50required:
51 - compatible
52 - reg
53 - interrupts
54 - clocks
55 - clock-names
56
57allOf:
58 - if:
59 properties:
60 compatible:
61 contains:
62 const: mediatek,mt7986-afe
63 then:
64 properties:
65 clocks:
66 items:
67 - description: audio bus clock
68 - description: audio 26M clock
69 - description: audio intbus clock
70 - description: audio hopping clock
71 - description: audio pll clock
72 clock-names:
73 items:
74 - const: bus_ck
75 - const: 26m_ck
76 - const: l_ck
77 - const: aud_ck
78 - const: eg2_ck
79
80 - if:
81 properties:
82 compatible:
83 contains:
84 const: mediatek,mt7981-afe
85 then:
86 properties:
87 clocks:
88 items:
89 - description: audio bus clock
90 - description: audio 26M clock
91 - description: audio intbus clock
92 - description: audio hopping clock
93 - description: audio pll clock
94 - description: mux for pcm_mck
95 clock-names:
96 items:
97 - const: bus_ck
98 - const: 26m_ck
99 - const: l_ck
100 - const: aud_ck
101 - const: eg2_ck
102 - const: sel
103
104 - if:
105 properties:
106 compatible:
107 contains:
108 const: mediatek,mt7988-afe
109 then:
110 properties:
111 clocks:
112 items:
113 - description: audio bus clock
114 - description: audio 26M clock
115 - description: audio intbus clock
116 - description: audio hopping clock
117 - description: audio pll clock
118 - description: mux for pcm_mck
119 - description: audio i2s/pcm mck
120 clock-names:
121 items:
122 - const: bus_ck
123 - const: 26m_ck
124 - const: l_ck
125 - const: aud_ck
126 - const: eg2_ck
127 - const: sel
128 - const: i2s_m
129
130additionalProperties: false
131
132examples:
133 - |
134 #include <dt-bindings/interrupt-controller/arm-gic.h>
135 #include <dt-bindings/interrupt-controller/irq.h>
136 #include <dt-bindings/clock/mt7986-clk.h>
137
138 afe@11210000 {
139 compatible = "mediatek,mt7986-afe";
140 reg = <0x11210000 0x9000>;
141 interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
142 clocks = <&infracfg_ao CLK_INFRA_AUD_BUS_CK>,
143 <&infracfg_ao CLK_INFRA_AUD_26M_CK>,
144 <&infracfg_ao CLK_INFRA_AUD_L_CK>,
145 <&infracfg_ao CLK_INFRA_AUD_AUD_CK>,
146 <&infracfg_ao CLK_INFRA_AUD_EG2_CK>;
147 clock-names = "bus_ck",
148 "26m_ck",
149 "l_ck",
150 "aud_ck",
151 "eg2_ck";
152 assigned-clocks = <&topckgen CLK_TOP_A1SYS_SEL>,
153 <&topckgen CLK_TOP_AUD_L_SEL>,
154 <&topckgen CLK_TOP_A_TUNER_SEL>;
155 assigned-clock-parents = <&topckgen CLK_TOP_APLL2_D4>,
156 <&apmixedsys CLK_APMIXED_APLL2>,
157 <&topckgen CLK_TOP_APLL2_D4>;
158 };
159
160...
Documentation/devicetree/bindings/sound/mediatek,mt7986-wm8960.yaml+67−0
@@ -0,0 +1,67 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/mediatek,mt7986-wm8960.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: MediaTek MT7986 sound card with WM8960 codec
8
9maintainers:
10 - Maso Huang <maso.huang@mediatek.com>
11
12allOf:
13 - $ref: sound-card-common.yaml#
14
15properties:
16 compatible:
17 const: mediatek,mt7986-wm8960-sound
18
19 platform:
20 type: object
21 additionalProperties: false
22 properties:
23 sound-dai:
24 description: The phandle of MT7986 platform.
25 maxItems: 1
26 required:
27 - sound-dai
28
29 codec:
30 type: object
31 additionalProperties: false
32 properties:
33 sound-dai:
34 description: The phandle of wm8960 codec.
35 maxItems: 1
36 required:
37 - sound-dai
38
39unevaluatedProperties: false
40
41required:
42 - compatible
43 - audio-routing
44 - platform
45 - codec
46
47examples:
48 - |
49 sound {
50 compatible = "mediatek,mt7986-wm8960-sound";
51 model = "mt7986-wm8960";
52 audio-routing =
53 "Headphone", "HP_L",
54 "Headphone", "HP_R",
55 "LINPUT1", "AMIC",
56 "RINPUT1", "AMIC";
57
58 platform {
59 sound-dai = <&afe>;
60 };
61
62 codec {
63 sound-dai = <&wm8960>;
64 };
65 };
66
67...
Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml+7−0
@@ -25,6 +25,12 @@ properties: · 24 unmodified lines
25 reset-names:25 reset-names:
26 const: audiosys26 const: audiosys
27 27
28 memory-region:
29 maxItems: 1
30 description: |
31 Shared memory region for AFE memif. A "shared-dma-pool".
32 See ../reserved-memory/reserved-memory.yaml for details.
33
28 mediatek,topckgen:34 mediatek,topckgen:
29 $ref: /schemas/types.yaml#/definitions/phandle35 $ref: /schemas/types.yaml#/definitions/phandle
30 description: The phandle of the mediatek topckgen controller36 description: The phandle of the mediatek topckgen controller
@@ -176,6 +182,7 @@ examples: · 145 unmodified lines
176 interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;182 interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
177 resets = <&watchdog 14>;183 resets = <&watchdog 14>;
178 reset-names = "audiosys";184 reset-names = "audiosys";
185 memory-region = <&snd_dma_mem_reserved>;
179 mediatek,topckgen = <&topckgen>;186 mediatek,topckgen = <&topckgen>;
180 mediatek,infracfg = <&infracfg_ao>;187 mediatek,infracfg = <&infracfg_ao>;
181 power-domains = <&spm 13>; //MT8188_POWER_DOMAIN_AUDIO188 power-domains = <&spm 13>; //MT8188_POWER_DOMAIN_AUDIO
Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml+7−10
@@ -9,23 +9,19 @@ title: MediaTek MT8188 ASoC sound card · 8 unmodified lines
9maintainers:9maintainers:
10 - Trevor Wu <trevor.wu@mediatek.com>10 - Trevor Wu <trevor.wu@mediatek.com>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 enum:17 enum:
15 - mediatek,mt8188-mt6359-evb18 - mediatek,mt8188-mt6359-evb
16 - mediatek,mt8188-nau882519 - mediatek,mt8188-nau8825
17 20
18 model:
19 $ref: /schemas/types.yaml#/definitions/string
20 description: User specified audio sound card name
21
22 audio-routing:21 audio-routing:
23 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
24 description:22 description:
25 A list of the connections between audio components. Each entry is a23 Valid names could be the input or output widgets of audio components,
26 sink/source pair of strings. Valid names could be the input or output24 power supplies, MicBias of codec and the software switch.
27 widgets of audio components, power supplies, MicBias of codec and the
28 software switch.
29 25
30 mediatek,platform:26 mediatek,platform:
31 $ref: /schemas/types.yaml#/definitions/phandle27 $ref: /schemas/types.yaml#/definitions/phandle
@@ -86,7 +82,7 @@ patternProperties: · 54 unmodified lines
86 required:82 required:
87 - link-name83 - link-name
88 84
89additionalProperties: false85unevaluatedProperties: false
90 86
91required:87required:
92 - compatible88 - compatible
@@ -96,6 +92,7 @@ examples: · 3 unmodified lines
96 - |92 - |
97 sound {93 sound {
98 compatible = "mediatek,mt8188-mt6359-evb";94 compatible = "mediatek,mt8188-mt6359-evb";
95 model = "MT6359-EVB";
99 mediatek,platform = <&afe>;96 mediatek,platform = <&afe>;
100 pinctrl-names = "default";97 pinctrl-names = "default";
101 pinctrl-0 = <&aud_pins_default>;98 pinctrl-0 = <&aud_pins_default>;
Documentation/devicetree/bindings/sound/nau8821.txt+0−55
@@ -1,55 +0,0 @@
1Nuvoton NAU88L21 audio codec
2
3This device supports I2C only.
4
5Required properties:
6 - compatible : Must be "nuvoton,nau8821"
7
8 - reg : the I2C address of the device. This is either 0x1B (CSB=0) or 0x54 (CSB=1).
9
10Optional properties:
11 - nuvoton,jkdet-enable: Enable jack detection via JKDET pin.
12 - nuvoton,jkdet-pull-enable: Enable JKDET pin pull. If set - pin pull enabled,
13 otherwise pin in high impedance state.
14 - nuvoton,jkdet-pull-up: Pull-up JKDET pin. If set then JKDET pin is pull up, otherwise pull down.
15 - nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
16
17 - nuvoton,vref-impedance: VREF Impedance selection
18 0 - Open
19 1 - 25 kOhm
20 2 - 125 kOhm
21 3 - 2.5 kOhm
22
23 - nuvoton,micbias-voltage: Micbias voltage level.
24 0 - VDDA
25 1 - VDDA
26 2 - VDDA * 1.1
27 3 - VDDA * 1.2
28 4 - VDDA * 1.3
29 5 - VDDA * 1.4
30 6 - VDDA * 1.53
31 7 - VDDA * 1.53
32
33 - nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
34 - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
35
36 - nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock.
37 - nuvoton,key_enable: Headset button detection switch.
38
39Example:
40
41 headset: nau8821@1b {
42 compatible = "nuvoton,nau8821";
43 reg = <0x1b>;
44 interrupt-parent = <&gpio>;
45 interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
46 nuvoton,jkdet-enable;
47 nuvoton,jkdet-pull-enable;
48 nuvoton,jkdet-pull-up;
49 nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
50 nuvoton,vref-impedance = <2>;
51 nuvoton,micbias-voltage = <6>;
52 nuvoton,jack-insert-debounce = <7>;
53 nuvoton,jack-eject-debounce = <7>;
54 nuvoton,dmic-clk-threshold = 3072000;
55 };
Documentation/devicetree/bindings/sound/nuvoton,nau8821.yaml+132−0
@@ -0,0 +1,132 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/nuvoton,nau8821.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: NAU88L21 audio codec
8
9maintainers:
10 - Seven Lee <wtli@nuvoton.com>
11
12allOf:
13 - $ref: dai-common.yaml#
14
15properties:
16 compatible:
17 const: nuvoton,nau8821
18
19 reg:
20 maxItems: 1
21
22 interrupts:
23 maxItems: 1
24
25 nuvoton,jkdet-enable:
26 description: Enable jack detection via JKDET pin.
27 type: boolean
28
29 nuvoton,jkdet-pull-enable:
30 description: Enable JKDET pin pull. If set - pin pull enabled,
31 otherwise pin in high impedance state.
32 type: boolean
33
34 nuvoton,jkdet-pull-up:
35 description: Pull-up JKDET pin. If set then JKDET pin is pull up,
36 otherwise pull down.
37 type: boolean
38
39 nuvoton,key-enable:
40 description: handles key press detection.
41 type: boolean
42
43 nuvoton,jkdet-polarity:
44 description: JKDET pin polarity.
45 $ref: /schemas/types.yaml#/definitions/uint32
46 enum:
47 - 0 # active high
48 - 1 # active low
49 default: 1
50
51 nuvoton,micbias-voltage:
52 description: MICBIAS output level select.
53 $ref: /schemas/types.yaml#/definitions/uint32
54 enum:
55 - 0 # VDDA
56 - 1 # VDDA * 1
57 - 2 # VDDA * 1.1
58 - 3 # VDDA * 1.2
59 - 4 # VDDA * 1.3
60 - 5 # VDDA * 1.4
61 - 6 # VDDA * 1.53
62 - 7 # VDDA * 1.53
63 default: 6
64
65 nuvoton,vref-impedance:
66 description: VMID Tie-off impedance select.
67 $ref: /schemas/types.yaml#/definitions/uint32
68 enum:
69 - 0 # open
70 - 1 # 25KOhms
71 - 2 # 125KOhms
72 - 3 # 2.5KOhms
73 default: 2
74
75 nuvoton,jack-insert-debounce:
76 description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
77 $ref: /schemas/types.yaml#/definitions/uint32
78 maximum: 7
79 default: 7
80
81 nuvoton,jack-eject-debounce:
82 description: number from 0 to 7 that sets debounce time to 2^(n+2)ms.
83 $ref: /schemas/types.yaml#/definitions/uint32
84 maximum: 7
85 default: 0
86
87 nuvoton,dmic-clk-threshold:
88 description: DMIC clock speed expected value. Unit is Hz.
89 $ref: /schemas/types.yaml#/definitions/uint32
90 default: 3072000
91
92 nuvoton,left-input-single-end:
93 description: Enable left input with single-ended settings if set.
94 For the headset mic application, the single-ended control is
95 just limited to the left adc for design demand.
96 type: boolean
97
98 '#sound-dai-cells':
99 const: 0
100
101required:
102 - compatible
103 - reg
104
105unevaluatedProperties: false
106
107examples:
108 - |
109 #include <dt-bindings/gpio/gpio.h>
110 #include <dt-bindings/interrupt-controller/irq.h>
111 i2c {
112 #address-cells = <1>;
113 #size-cells = <0>;
114 codec@1b {
115 compatible = "nuvoton,nau8821";
116 reg = <0x1b>;
117 interrupt-parent = <&gpio>;
118 interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
119 nuvoton,jkdet-enable;
120 nuvoton,jkdet-pull-enable;
121 nuvoton,jkdet-pull-up;
122 nuvoton,key-enable;
123 nuvoton,left-input-single-end;
124 nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
125 nuvoton,micbias-voltage = <6>;
126 nuvoton,vref-impedance = <2>;
127 nuvoton,jack-insert-debounce = <7>;
128 nuvoton,jack-eject-debounce = <0>;
129 nuvoton,dmic-clk-threshold = <3072000>;
130 #sound-dai-cells = <0>;
131 };
132 };
Documentation/devicetree/bindings/sound/nuvoton,nau8822.yaml+12−0
@@ -21,6 +21,15 @@ properties: · 20 unmodified lines
21 reg:21 reg:
22 maxItems: 122 maxItems: 1
23 23
24 "#sound-dai-cells":
25 const: 0
26
27 clocks:
28 maxItems: 1
29
30 clock-names:
31 const: mclk
32
24 nuvoton,spk-btl:33 nuvoton,spk-btl:
25 description:34 description:
26 If set, configure the two loudspeaker outputs as a Bridge Tied Load output35 If set, configure the two loudspeaker outputs as a Bridge Tied Load output
@@ -31,6 +40,9 @@ required: · 4 unmodified lines
31 - compatible40 - compatible
32 - reg41 - reg
33 42
43allOf:
44 - $ref: dai-common.yaml#
45
34additionalProperties: false46additionalProperties: false
35 47
36examples:48examples:
Documentation/devicetree/bindings/sound/option,gtm601.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/option,gtm601.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: GTM601 UMTS modem audio interface CODEC
8
9maintainers:
10 - kernel@puri.sm
11
12description: >
13 This device has no configuration interface. The sample rate and channels are
14 based on the compatible string
15
16properties:
17 compatible:
18 oneOf:
19 - description: Broadmobi BM818 (48Khz stereo)
20 items:
21 - const: broadmobi,bm818
22 - const: option,gtm601
23 - description: GTM601 (8kHz mono)
24 const: option,gtm601
25
26 '#sound-dai-cells':
27 const: 0
28
29required:
30 - compatible
31
32allOf:
33 - $ref: dai-common.yaml#
34
35additionalProperties: false
36
37examples:
38 - |
39 codec {
40 compatible = "option,gtm601";
41 #sound-dai-cells = <0>;
42 };
Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt+0−101
@@ -1,101 +0,0 @@
1msm8916 analog audio CODEC
2
3Bindings for codec Analog IP which is integrated in pmic pm8916,
4
5## Bindings for codec core on pmic:
6
7Required properties
8 - compatible = "qcom,pm8916-wcd-analog-codec";
9 - reg: represents the slave base address provided to the peripheral.
10 - interrupts: List of interrupts in given SPMI peripheral.
11 - interrupt-names: Names specified to above list of interrupts in same
12 order. List of supported interrupt names are:
13 "cdc_spk_cnp_int" - Speaker click and pop interrupt.
14 "cdc_spk_clip_int" - Speaker clip interrupt.
15 "cdc_spk_ocp_int" - Speaker over current protect interrupt.
16 "mbhc_ins_rem_det1" - jack insert removal detect interrupt 1.
17 "mbhc_but_rel_det" - button release interrupt.
18 "mbhc_but_press_det" - button press event
19 "mbhc_ins_rem_det" - jack insert removal detect interrupt.
20 "mbhc_switch_int" - multi button headset interrupt.
21 "cdc_ear_ocp_int" - Earphone over current protect interrupt.
22 "cdc_hphr_ocp_int" - Headphone R over current protect interrupt.
23 "cdc_hphl_ocp_det" - Headphone L over current protect interrupt.
24 "cdc_ear_cnp_int" - earphone cnp interrupt.
25 "cdc_hphr_cnp_int" - hphr click and pop interrupt.
26 "cdc_hphl_cnp_int" - hphl click and pop interrupt.
27
28 - clocks: Handle to mclk.
29 - clock-names: should be "mclk"
30 - vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node.
31 - vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node.
32 - vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node.
33
34Optional Properties:
35 - qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons
36 detection on headset when the mbhc is powered up
37 by internal current source, this is a low power.
38 - qcom,mbhc-vthreshold-high: Array of 5 thresold voltages in mV for 5 buttons
39 detection on headset when mbhc is powered up
40 from micbias.
41- qcom,micbias-lvl: Voltage (mV) for Mic Bias
42- qcom,hphl-jack-type-normally-open: boolean, present if hphl pin on jack is a
43 NO (Normally Open). If not specified, then
44 its assumed that hphl pin on jack is NC
45 (Normally Closed).
46- qcom,gnd-jack-type-normally-open: boolean, present if gnd pin on jack is
47 NO (Normally Open). If not specified, then
48 its assumed that gnd pin on jack is NC
49 (Normally Closed).
50- qcom,micbias1-ext-cap: boolean, present if micbias1 has external capacitor
51 connected.
52- qcom,micbias2-ext-cap: boolean, present if micbias2 has external capacitor
53 connected.
54
55Example:
56
57spmi_bus {
58 ...
59 audio-codec@f000{
60 compatible = "qcom,pm8916-wcd-analog-codec";
61 reg = <0xf000 0x200>;
62 reg-names = "pmic-codec-core";
63 clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>;
64 clock-names = "mclk";
65 qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
66 qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
67 interrupt-parent = <&spmi_bus>;
68 interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
69 <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
70 <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
71 <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
72 <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
73 <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
74 <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
75 <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
76 <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
77 <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
78 <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
79 <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
80 <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
81 <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
82 interrupt-names = "cdc_spk_cnp_int",
83 "cdc_spk_clip_int",
84 "cdc_spk_ocp_int",
85 "mbhc_ins_rem_det1",
86 "mbhc_but_rel_det",
87 "mbhc_but_press_det",
88 "mbhc_ins_rem_det",
89 "mbhc_switch_int",
90 "cdc_ear_ocp_int",
91 "cdc_hphr_ocp_int",
92 "cdc_hphl_ocp_det",
93 "cdc_ear_cnp_int",
94 "cdc_hphr_cnp_int",
95 "cdc_hphl_cnp_int";
96 vdd-cdc-io-supply = <&pm8916_l5>;
97 vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
98 vdd-micbias-supply = <&pm8916_l13>;
99 #sound-dai-cells = <1>;
100 };
101};
Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml+153−0
@@ -0,0 +1,153 @@
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,pm8916-wcd-analog-codec.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Qualcomm PM8916 WCD Analog Audio Codec
8
9maintainers:
10 - Konrad Dybcio <konradybcio@kernel.org>
11
12description:
13 The analog WCD audio codec found on Qualcomm PM8916 PMIC.
14
15properties:
16 compatible:
17 const: qcom,pm8916-wcd-analog-codec
18
19 reg:
20 maxItems: 1
21
22 interrupts:
23 maxItems: 14
24
25 interrupt-names:
26 items:
27 - const: cdc_spk_cnp_int
28 - const: cdc_spk_clip_int
29 - const: cdc_spk_ocp_int
30 - const: mbhc_ins_rem_det1
31 - const: mbhc_but_rel_det
32 - const: mbhc_but_press_det
33 - const: mbhc_ins_rem_det
34 - const: mbhc_switch_int
35 - const: cdc_ear_ocp_int
36 - const: cdc_hphr_ocp_int
37 - const: cdc_hphl_ocp_det
38 - const: cdc_ear_cnp_int
39 - const: cdc_hphr_cnp_int
40 - const: cdc_hphl_cnp_int
41
42 vdd-cdc-io-supply:
43 description: 1.8V buck supply
44
45 vdd-cdc-tx-rx-cx-supply:
46 description: 1.8V SIDO buck supply
47
48 vdd-micbias-supply:
49 description: micbias supply
50
51 qcom,mbhc-vthreshold-low:
52 $ref: /schemas/types.yaml#/definitions/uint32-array
53 description:
54 Array of 5 threshold voltages in mV for 5-button detection on
55 headset when MBHC is powered by an internal current source.
56 minItems: 5
57 maxItems: 5
58
59 qcom,mbhc-vthreshold-high:
60 $ref: /schemas/types.yaml#/definitions/uint32-array
61 description:
62 Array of 5 threshold voltages in mV for 5-button detection on
63 headset when MBHC is powered from micbias.
64 minItems: 5
65 maxItems: 5
66
67 qcom,micbias-lvl:
68 $ref: /schemas/types.yaml#/definitions/uint32
69 description:
70 Voltage (mV) for Mic Bias
71
72 qcom,hphl-jack-type-normally-open:
73 type: boolean
74 description:
75 True if the HPHL pin on the jack is NO (Normally Open), false if it's
76 NC (Normally Closed).
77
78 qcom,gnd-jack-type-normally-open:
79 type: boolean
80 description:
81 True if the GND pin on the jack is NO (Normally Open), false if it's
82 NC (Normally Closed).
83
84 qcom,micbias1-ext-cap:
85 type: boolean
86 description:
87 True if micbias1 has an external capacitor.
88
89 qcom,micbias2-ext-cap:
90 type: boolean
91 description:
92 True if micbias2 has an external capacitor.
93
94 "#sound-dai-cells":
95 const: 1
96
97required:
98 - compatible
99 - reg
100
101additionalProperties: false
102
103examples:
104 - |
105 #include <dt-bindings/interrupt-controller/irq.h>
106 #include <dt-bindings/spmi/spmi.h>
107
108 pmic@1 {
109 compatible = "qcom,pm8916", "qcom,spmi-pmic";
110 reg = <0x1 SPMI_USID>;
111 #address-cells = <1>;
112 #size-cells = <0>;
113
114 audio-codec@f000 {
115 compatible = "qcom,pm8916-wcd-analog-codec";
116 reg = <0xf000>;
117 qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
118 qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
119 interrupt-parent = <&spmi_bus>;
120 interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
121 <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
122 <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
123 <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
124 <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
125 <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
126 <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
127 <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
128 <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
129 <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
130 <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
131 <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
132 <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
133 <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
134 interrupt-names = "cdc_spk_cnp_int",
135 "cdc_spk_clip_int",
136 "cdc_spk_ocp_int",
137 "mbhc_ins_rem_det1",
138 "mbhc_but_rel_det",
139 "mbhc_but_press_det",
140 "mbhc_ins_rem_det",
141 "mbhc_switch_int",
142 "cdc_ear_ocp_int",
143 "cdc_hphr_ocp_int",
144 "cdc_hphl_ocp_det",
145 "cdc_ear_cnp_int",
146 "cdc_hphr_cnp_int",
147 "cdc_hphl_cnp_int";
148 vdd-cdc-io-supply = <&pm8916_l5>;
149 vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
150 vdd-micbias-supply = <&pm8916_l13>;
151 #sound-dai-cells = <1>;
152 };
153 };
Documentation/devicetree/bindings/sound/renesas,rsnd.yaml+31−29
@@ -9,6 +9,20 @@ title: Renesas R-Car Sound Driver · 8 unmodified lines
9maintainers:9maintainers:
10 - Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>10 - Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
11 11
12definitions:
13 port-def:
14 $ref: audio-graph-port.yaml#/definitions/port-base
15 unevaluatedProperties: false
16 patternProperties:
17 "^endpoint(@[0-9a-f]+)?":
18 $ref: audio-graph-port.yaml#/definitions/endpoint-base
19 properties:
20 playback:
21 $ref: /schemas/types.yaml#/definitions/phandle-array
22 capture:
23 $ref: /schemas/types.yaml#/definitions/phandle-array
24 unevaluatedProperties: false
25
12properties:26properties:
13 27
14 compatible:28 compatible:
@@ -77,6 +91,12 @@ properties: · 62 unmodified lines
77 it must be 1 if your system has audio_clkout0/1/2/391 it must be 1 if your system has audio_clkout0/1/2/3
78 enum: [0, 1]92 enum: [0, 1]
79 93
94 "#address-cells":
95 const: 1
96
97 "#size-cells":
98 const: 0
99
80 clock-frequency:100 clock-frequency:
81 description: for audio_clkout0/1/2/3101 description: for audio_clkout0/1/2/3
82 102
@@ -103,35 +123,9 @@ properties: · 20 unmodified lines
103 description: List of necessary clock names.123 description: List of necessary clock names.
104 # details are defined below124 # details are defined below
105 125
106 ports:126 # ports is below
107 $ref: audio-graph-port.yaml#/definitions/port-base
108 unevaluatedProperties: false
109 patternProperties:
110 '^port(@[0-9a-f]+)?$':
111 $ref: audio-graph-port.yaml#/definitions/port-base
112 unevaluatedProperties: false
113 patternProperties:
114 "^endpoint(@[0-9a-f]+)?":
115 $ref: audio-graph-port.yaml#/definitions/endpoint-base
116 properties:
117 playback:
118 $ref: /schemas/types.yaml#/definitions/phandle-array
119 capture:
120 $ref: /schemas/types.yaml#/definitions/phandle-array
121 unevaluatedProperties: false
122
123 port:127 port:
124 $ref: audio-graph-port.yaml#/definitions/port-base128 $ref: "#/definitions/port-def"
125 unevaluatedProperties: false
126 patternProperties:
127 "^endpoint(@[0-9a-f]+)?":
128 $ref: audio-graph-port.yaml#/definitions/endpoint-base
129 properties:
130 playback:
131 $ref: /schemas/types.yaml#/definitions/phandle-array
132 capture:
133 $ref: /schemas/types.yaml#/definitions/phandle-array
134 unevaluatedProperties: false
135 129
136 rcar_sound,dvc:130 rcar_sound,dvc:
137 description: DVC subnode.131 description: DVC subnode.
@@ -248,8 +242,9 @@ properties: · 110 unmodified lines
248 - interrupts242 - interrupts
249 additionalProperties: false243 additionalProperties: false
250 244
245patternProperties:
251 # For DAI base246 # For DAI base
252 rcar_sound,dai:247 'rcar_sound,dai(@[0-9a-f]+)?$':
253 description: DAI subnode.248 description: DAI subnode.
254 type: object249 type: object
255 patternProperties:250 patternProperties:
@@ -269,6 +264,13 @@ properties: · 13 unmodified lines
269 - capture264 - capture
270 additionalProperties: false265 additionalProperties: false
271 266
267 'ports(@[0-9a-f]+)?$':
268 $ref: audio-graph-port.yaml#/definitions/port-base
269 unevaluatedProperties: false
270 patternProperties:
271 '^port(@[0-9a-f]+)?$':
272 $ref: "#/definitions/port-def"
273
272required:274required:
273 - compatible275 - compatible
274 - reg276 - reg
Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml+8−8
@@ -9,6 +9,9 @@ title: Samsung Aries audio complex with WM8994 codec · 8 unmodified lines
9maintainers:9maintainers:
10 - Jonathan Bakker <xc-racer2@live.ca>10 - Jonathan Bakker <xc-racer2@live.ca>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 enum:17 enum:
@@ -17,10 +20,6 @@ properties: · 2 unmodified lines
17 # Without FM radio and modem slave20 # Without FM radio and modem slave
18 - samsung,fascinate4g-wm899421 - samsung,fascinate4g-wm8994
19 22
20 model:
21 $ref: /schemas/types.yaml#/definitions/string
22 description: The user-visible name of this sound complex.
23
24 cpu:23 cpu:
25 type: object24 type: object
26 additionalProperties: false25 additionalProperties: false
@@ -46,6 +45,7 @@ properties: · 19 unmodified lines
46 45
47 samsung,audio-routing:46 samsung,audio-routing:
48 $ref: /schemas/types.yaml#/definitions/non-unique-string-array47 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
48 deprecated: true
49 description: |49 description: |
50 List of the connections between audio50 List of the connections between audio
51 components; each entry is a pair of strings, the first being the51 components; each entry is a pair of strings, the first being the
@@ -56,6 +56,7 @@ properties: · 4 unmodified lines
56 or FM In56 or FM In
57 For samsung,fascinate4g-wm8994: HP, SPK, RCV, LINE, Main Mic,57 For samsung,fascinate4g-wm8994: HP, SPK, RCV, LINE, Main Mic,
58 or HeadsetMic58 or HeadsetMic
59 Deprecated, use audio-routing.
59 60
60 extcon:61 extcon:
61 description: Extcon phandle for dock detection62 description: Extcon phandle for dock detection
@@ -87,10 +88,9 @@ properties: · 25 unmodified lines
87 88
88required:89required:
89 - compatible90 - compatible
90 - model
91 - cpu91 - cpu
92 - codec92 - codec
93 - samsung,audio-routing93 - audio-routing
94 - extcon94 - extcon
95 - main-micbias-supply95 - main-micbias-supply
96 - headset-micbias-supply96 - headset-micbias-supply
@@ -98,7 +98,7 @@ required: · 1 unmodified line
98 - headset-detect-gpios98 - headset-detect-gpios
99 - headset-key-gpios99 - headset-key-gpios
100 100
101additionalProperties: false101unevaluatedProperties: false
102 102
103examples:103examples:
104 - |104 - |
@@ -121,7 +121,7 @@ examples: · 16 unmodified lines
121 headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_HIGH>;121 headset-detect-gpios = <&gph0 6 GPIO_ACTIVE_HIGH>;
122 headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>;122 headset-key-gpios = <&gph3 6 GPIO_ACTIVE_HIGH>;
123 123
124 samsung,audio-routing =124 audio-routing =
125 "HP", "HPOUT1L",125 "HP", "HPOUT1L",
126 "HP", "HPOUT1R",126 "HP", "HPOUT1R",
127 127
Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml+8−8
@@ -9,14 +9,13 @@ title: Samsung Midas audio complex with WM1811 codec · 8 unmodified lines
9maintainers:9maintainers:
10 - Sylwester Nawrocki <s.nawrocki@samsung.com>10 - Sylwester Nawrocki <s.nawrocki@samsung.com>
11 11
12allOf:
13 - $ref: sound-card-common.yaml#
14
12properties:15properties:
13 compatible:16 compatible:
14 const: samsung,midas-audio17 const: samsung,midas-audio
15 18
16 model:
17 $ref: /schemas/types.yaml#/definitions/string
18 description: The user-visible name of this sound complex.
19
20 cpu:19 cpu:
21 type: object20 type: object
22 additionalProperties: false21 additionalProperties: false
@@ -38,6 +37,7 @@ properties: · 15 unmodified lines
38 - sound-dai37 - sound-dai
39 38
40 samsung,audio-routing:39 samsung,audio-routing:
40 deprecated: true
41 $ref: /schemas/types.yaml#/definitions/non-unique-string-array41 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
42 description: |42 description: |
43 List of the connections between audio components; each entry is43 List of the connections between audio components; each entry is
@@ -45,6 +45,7 @@ properties: · 1 unmodified line
45 being the connection's source; valid names for sources and sinks are45 being the connection's source; valid names for sources and sinks are
46 the WM1811's pins (as documented in its binding), and the jacks46 the WM1811's pins (as documented in its binding), and the jacks
47 on the board: HP, SPK, Main Mic, Sub Mic, Headset Mic.47 on the board: HP, SPK, Main Mic, Sub Mic, Headset Mic.
48 Deprecated, use audio-routing.
48 49
49 mic-bias-supply:50 mic-bias-supply:
50 description: Supply for the micbias on the Main microphone51 description: Supply for the micbias on the Main microphone
@@ -62,14 +63,13 @@ properties: · 11 unmodified lines
62 63
63required:64required:
64 - compatible65 - compatible
65 - model
66 - cpu66 - cpu
67 - codec67 - codec
68 - samsung,audio-routing68 - audio-routing
69 - mic-bias-supply69 - mic-bias-supply
70 - submic-bias-supply70 - submic-bias-supply
71 71
72additionalProperties: false72unevaluatedProperties: false
73 73
74examples:74examples:
75 - |75 - |
@@ -84,7 +84,7 @@ examples: · 8 unmodified lines
84 mic-bias-supply = <&mic_bias_reg>;84 mic-bias-supply = <&mic_bias_reg>;
85 submic-bias-supply = <&submic_bias_reg>;85 submic-bias-supply = <&submic_bias_reg>;
86 86
87 samsung,audio-routing =87 audio-routing =
88 "HP", "HPOUT1L",88 "HP", "HPOUT1L",
89 "HP", "HPOUT1R",89 "HP", "HPOUT1R",
90 90
Documentation/devicetree/bindings/sound/samsung,odroid.yaml+7−7
@@ -10,6 +10,9 @@ maintainers: · 9 unmodified lines
10 - Krzysztof Kozlowski <krzk@kernel.org>10 - Krzysztof Kozlowski <krzk@kernel.org>
11 - Sylwester Nawrocki <s.nawrocki@samsung.com>11 - Sylwester Nawrocki <s.nawrocki@samsung.com>
12 12
13allOf:
14 - $ref: sound-card-common.yaml#
15
13properties:16properties:
14 compatible:17 compatible:
15 oneOf:18 oneOf:
@@ -24,10 +27,6 @@ properties: · 8 unmodified lines
24 - const: samsung,odroid-xu4-audio27 - const: samsung,odroid-xu4-audio
25 deprecated: true28 deprecated: true
26 29
27 model:
28 $ref: /schemas/types.yaml#/definitions/string
29 description: The user-visible name of this sound complex.
30
31 assigned-clock-parents: true30 assigned-clock-parents: true
32 assigned-clock-rates: true31 assigned-clock-rates: true
33 assigned-clocks: true32 assigned-clocks: true
@@ -52,6 +51,7 @@ properties: · 18 unmodified lines
52 51
53 samsung,audio-routing:52 samsung,audio-routing:
54 $ref: /schemas/types.yaml#/definitions/non-unique-string-array53 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
54 deprecated: true
55 description: |55 description: |
56 List of the connections between audio56 List of the connections between audio
57 components; each entry is a pair of strings, the first being the57 components; each entry is a pair of strings, the first being the
@@ -61,6 +61,7 @@ properties: · 3 unmodified lines
61 For Odroid X2: "Headphone Jack", "Mic Jack", "DMIC"61 For Odroid X2: "Headphone Jack", "Mic Jack", "DMIC"
62 For Odroid U3, XU3: "Headphone Jack", "Speakers"62 For Odroid U3, XU3: "Headphone Jack", "Speakers"
63 For Odroid XU4: no entries63 For Odroid XU4: no entries
64 Deprecated, use audio-routing.
64 65
65 samsung,audio-widgets:66 samsung,audio-widgets:
66 $ref: /schemas/types.yaml#/definitions/non-unique-string-array67 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
@@ -70,18 +71,17 @@ properties: · 3 unmodified lines
70 71
71required:72required:
72 - compatible73 - compatible
73 - model
74 - cpu74 - cpu
75 - codec75 - codec
76 76
77additionalProperties: false77unevaluatedProperties: false
78 78
79examples:79examples:
80 - |80 - |
81 sound {81 sound {
82 compatible = "hardkernel,odroid-xu3-audio";82 compatible = "hardkernel,odroid-xu3-audio";
83 model = "Odroid-XU3";83 model = "Odroid-XU3";
84 samsung,audio-routing =84 audio-routing =
85 "Headphone Jack", "HPL",85 "Headphone Jack", "HPL",
86 "Headphone Jack", "HPR",86 "Headphone Jack", "HPR",
87 "IN1", "Mic Jack",87 "IN1", "Mic Jack",
Documentation/devicetree/bindings/sound/samsung,tm2.yaml+8−8
@@ -10,6 +10,9 @@ maintainers: · 9 unmodified lines
10 - Krzysztof Kozlowski <krzk@kernel.org>10 - Krzysztof Kozlowski <krzk@kernel.org>
11 - Sylwester Nawrocki <s.nawrocki@samsung.com>11 - Sylwester Nawrocki <s.nawrocki@samsung.com>
12 12
13allOf:
14 - $ref: sound-card-common.yaml#
15
13properties:16properties:
14 compatible:17 compatible:
15 const: samsung,tm2-audio18 const: samsung,tm2-audio
@@ -32,6 +35,8 @@ properties: · 16 unmodified lines
32 being the connection's source; valid names for sources and sinks are the35 being the connection's source; valid names for sources and sinks are the
33 WM5110's and MAX98504's pins and the jacks on the board: HP, SPK, Main36 WM5110's and MAX98504's pins and the jacks on the board: HP, SPK, Main
34 Mic, Sub Mic, Third Mic, Headset Mic.37 Mic, Sub Mic, Third Mic, Headset Mic.
38 Deprecated, use audio-routing.
39 deprecated: true
35 $ref: /schemas/types.yaml#/definitions/non-unique-string-array40 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
36 41
37 i2s-controller:42 i2s-controller:
@@ -44,20 +49,15 @@ properties: · 6 unmodified lines
44 mic-bias-gpios:49 mic-bias-gpios:
45 description: GPIO pin that enables the Main Mic bias regulator.50 description: GPIO pin that enables the Main Mic bias regulator.
46 51
47 model:
48 description: The user-visible name of this sound complex.
49 $ref: /schemas/types.yaml#/definitions/string
50
51required:52required:
52 - compatible53 - compatible
53 - audio-amplifier54 - audio-amplifier
54 - audio-codec55 - audio-codec
55 - samsung,audio-routing56 - audio-routing
56 - i2s-controller57 - i2s-controller
57 - mic-bias-gpios58 - mic-bias-gpios
58 - model
59 59
60additionalProperties: false60unevaluatedProperties: false
61 61
62examples:62examples:
63 - |63 - |
@@ -70,7 +70,7 @@ examples: · 6 unmodified lines
70 audio-amplifier = <&max98504>;70 audio-amplifier = <&max98504>;
71 mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;71 mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
72 model = "wm5110";72 model = "wm5110";
73 samsung,audio-routing = "HP", "HPOUT1L",73 audio-routing = "HP", "HPOUT1L",
74 "HP", "HPOUT1R",74 "HP", "HPOUT1R",
75 "SPK", "SPKOUT",75 "SPK", "SPKOUT",
76 "SPKOUT", "HPOUT2L",76 "SPKOUT", "HPOUT2L",
Documentation/devicetree/bindings/sound/simple-card.yaml+53−0
@@ -148,6 +148,15 @@ definitions: · 147 unmodified lines
148 required:148 required:
149 - sound-dai149 - sound-dai
150 150
151 additional-devs:
152 type: object
153 description:
154 Additional devices used by the simple audio card.
155 patternProperties:
156 '^iio-aux(-.+)?$':
157 type: object
158 $ref: audio-iio-aux.yaml#
159
151properties:160properties:
152 compatible:161 compatible:
153 contains:162 contains:
@@ -187,6 +196,8 @@ properties: · 33 unmodified lines
187 $ref: "#/definitions/mclk-fs"196 $ref: "#/definitions/mclk-fs"
188 simple-audio-card,aux-devs:197 simple-audio-card,aux-devs:
189 $ref: "#/definitions/aux-devs"198 $ref: "#/definitions/aux-devs"
199 simple-audio-card,additional-devs:
200 $ref: "#/definitions/additional-devs"
190 simple-audio-card,convert-rate:201 simple-audio-card,convert-rate:
191 $ref: "#/definitions/convert-rate"202 $ref: "#/definitions/convert-rate"
192 simple-audio-card,convert-channels:203 simple-audio-card,convert-channels:
@@ -359,6 +370,48 @@ examples: · 166 unmodified lines
359 };370 };
360 };371 };
361 372
373# --------------------
374# route audio to/from a codec through an amplifier
375# designed with a potentiometer driven by IIO:
376# --------------------
377 - |
378 sound {
379 compatible = "simple-audio-card";
380
381 simple-audio-card,aux-devs = <&amp_in>, <&amp_out>;
382 simple-audio-card,routing =
383 "CODEC LEFTIN", "AMP_IN LEFT OUT",
384 "CODEC RIGHTIN", "AMP_IN RIGHT OUT",
385 "AMP_OUT LEFT IN", "CODEC LEFTOUT",
386 "AMP_OUT RIGHT IN", "CODEC RIGHTOUT";
387
388 simple-audio-card,additional-devs {
389 amp_out: iio-aux-out {
390 compatible = "audio-iio-aux";
391 io-channels = <&pot_out 0>, <&pot_out 1>;
392 io-channel-names = "LEFT", "RIGHT";
393 snd-control-invert-range = <1 1>;
394 sound-name-prefix = "AMP_OUT";
395 };
396
397 amp_in: iio_aux-in {
398 compatible = "audio-iio-aux";
399 io-channels = <&pot_in 0>, <&pot_in 1>;
400 io-channel-names = "LEFT", "RIGHT";
401 sound-name-prefix = "AMP_IN";
402 };
403 };
404
405 simple-audio-card,cpu {
406 sound-dai = <&cpu>;
407 };
408
409 simple-audio-card,codec {
410 sound-dai = <&codec>;
411 clocks = <&clocks>;
412 };
413 };
414
362# --------------------415# --------------------
363# Sampling Rate Conversion416# Sampling Rate Conversion
364# --------------------417# --------------------
Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml+105−3
@@ -17,6 +17,9 @@ properties: · 16 unmodified lines
17 - const: snps,designware-i2s17 - const: snps,designware-i2s
18 - enum:18 - enum:
19 - snps,designware-i2s19 - snps,designware-i2s
20 - starfive,jh7110-i2stx0
21 - starfive,jh7110-i2stx1
22 - starfive,jh7110-i2srx
20 23
21 reg:24 reg:
22 maxItems: 125 maxItems: 1
@@ -29,15 +32,36 @@ properties: · 6 unmodified lines
29 maxItems: 132 maxItems: 1
30 33
31 clocks:34 clocks:
32 description: Sampling rate reference clock35 items:
33 maxItems: 136 - description: Sampling rate reference clock
37 - description: APB clock
38 - description: Audio master clock
39 - description: Inner audio master clock source
40 - description: External audio master clock source
41 - description: Bit clock
42 - description: Left/right channel clock
43 - description: External bit clock
44 - description: External left/right channel clock
45 minItems: 1
34 46
35 clock-names:47 clock-names:
36 const: i2sclk48 items:
49 - const: i2sclk
50 - const: apb
51 - const: mclk
52 - const: mclk_inner
53 - const: mclk_ext
54 - const: bclk
55 - const: lrck
56 - const: bclk_ext
57 - const: lrck_ext
58 minItems: 1
37 59
38 resets:60 resets:
39 items:61 items:
40 - description: Optional controller resets62 - description: Optional controller resets
63 - description: controller reset of Sampling rate
64 minItems: 1
41 65
42 dmas:66 dmas:
43 items:67 items:
@@ -51,6 +75,17 @@ properties: · 7 unmodified lines
51 - const: rx75 - const: rx
52 minItems: 176 minItems: 1
53 77
78 starfive,syscon:
79 $ref: /schemas/types.yaml#/definitions/phandle-array
80 items:
81 - items:
82 - description: phandle to System Register Controller sys_syscon node.
83 - description: I2S-rx enabled control offset of SYS_SYSCONSAIF__SYSCFG register.
84 - description: I2S-rx enabled control mask
85 description:
86 The phandle to System Register Controller syscon node and the I2S-rx(ADC)
87 enabled control offset and mask of SYS_SYSCONSAIF__SYSCFG register.
88
54allOf:89allOf:
55 - $ref: dai-common.yaml#90 - $ref: dai-common.yaml#
56 - if:91 - if:
@@ -66,6 +101,73 @@ allOf: · 9 unmodified lines
66 properties:101 properties:
67 "#sound-dai-cells":102 "#sound-dai-cells":
68 const: 0103 const: 0
104 - if:
105 properties:
106 compatible:
107 contains:
108 const: snps,designware-i2s
109 then:
110 properties:
111 clocks:
112 maxItems: 1
113 clock-names:
114 maxItems: 1
115 resets:
116 maxItems: 1
117 else:
118 properties:
119 resets:
120 minItems: 2
121 maxItems: 2
122 - if:
123 properties:
124 compatible:
125 contains:
126 const: starfive,jh7110-i2stx0
127 then:
128 properties:
129 clocks:
130 minItems: 5
131 maxItems: 5
132 clock-names:
133 minItems: 5
134 maxItems: 5
135 required:
136 - resets
137 - if:
138 properties:
139 compatible:
140 contains:
141 const: starfive,jh7110-i2stx1
142 then:
143 properties:
144 clocks:
145 minItems: 9
146 maxItems: 9
147 clock-names:
148 minItems: 9
149 maxItems: 9
150 required:
151 - resets
152 - if:
153 properties:
154 compatible:
155 contains:
156 const: starfive,jh7110-i2srx
157 then:
158 properties:
159 clocks:
160 minItems: 9
161 maxItems: 9
162 clock-names:
163 minItems: 9
164 maxItems: 9
165 required:
166 - resets
167 - starfive,syscon
168 else:
169 properties:
170 starfive,syscon: false
69 171
70required:172required:
71 - compatible173 - compatible
Documentation/devicetree/bindings/sound/sound-card-common.yaml+27−0
@@ -0,0 +1,27 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/sound/sound-card-common.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Board Sound Card Common Properties
8
9maintainers:
10 - Mark Brown <broonie@kernel.org>
11
12properties:
13 audio-routing:
14 $ref: /schemas/types.yaml#/definitions/non-unique-string-array
15 description: |
16 A list of the connections between audio components. Each entry is a
17 pair of strings, the first being the connection's sink, the second
18 being the connection's source.
19
20 model:
21 $ref: /schemas/types.yaml#/definitions/string
22 description: User specified audio sound card name
23
24required:
25 - model
26
27additionalProperties: true
Documentation/devicetree/bindings/sound/wlf,wm8904.yaml+74−0
@@ -0,0 +1,74 @@
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,wm8904.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Wolfson WM8904/WM8912 audio codecs
8
9maintainers:
10 - patches@opensource.cirrus.com
11
12description: |
13 Pins on the device (for linking into audio routes):
14 IN1L, IN1R, IN2L, IN2R, IN3L, IN3R, HPOUTL, HPOUTR, LINEOUTL, LINEOUTR,
15 MICBIAS
16
17properties:
18 compatible:
19 enum:
20 - wlf,wm8904
21 - wlf,wm8912
22
23 reg:
24 maxItems: 1
25
26 "#sound-dai-cells":
27 const: 0
28
29 clocks:
30 maxItems: 1
31
32 clock-names:
33 const: mclk
34
35 AVDD-supply: true
36 CPVDD-supply: true
37 DBVDD-supply: true
38 DCVDD-supply: true
39 MICVDD-supply: true
40
41required:
42 - compatible
43 - reg
44 - clocks
45 - clock-names
46 - AVDD-supply
47 - CPVDD-supply
48 - DBVDD-supply
49 - DCVDD-supply
50 - MICVDD-supply
51
52allOf:
53 - $ref: dai-common.yaml#
54
55unevaluatedProperties: false
56
57examples:
58 - |
59 i2c {
60 #address-cells = <1>;
61 #size-cells = <0>;
62
63 codec@1a {
64 compatible = "wlf,wm8904";
65 reg = <0x1a>;
66 clocks = <&pck0>;
67 clock-names = "mclk";
68 AVDD-supply = <&reg_1p8v>;
69 CPVDD-supply = <&reg_1p8v>;
70 DBVDD-supply = <&reg_1p8v>;
71 DCVDD-supply = <&reg_1p8v>;
72 MICVDD-supply = <&reg_1p8v>;
73 };
74 };
Documentation/devicetree/bindings/sound/wlf,wm8960.yaml+20−0
@@ -26,6 +26,21 @@ properties: · 25 unmodified lines
26 '#sound-dai-cells':26 '#sound-dai-cells':
27 const: 027 const: 0
28 28
29 AVDD-supply:
30 description: Analogue supply.
31
32 DBVDD-supply:
33 description: Digital Buffer Supply.
34
35 DCVDD-supply:
36 description: Digital Core Supply.
37
38 SPKVDD1-supply:
39 description: Supply for speaker drivers 1.
40
41 SPKVDD2-supply:
42 description: Supply for speaker drivers 2.
43
29 wlf,capless:44 wlf,capless:
30 type: boolean45 type: boolean
31 description:46 description:
@@ -84,5 +99,10 @@ examples: · 52 unmodified lines
84 wlf,hp-cfg = <3 2 3>;99 wlf,hp-cfg = <3 2 3>;
85 wlf,gpio-cfg = <1 3>;100 wlf,gpio-cfg = <1 3>;
86 wlf,shared-lrclk;101 wlf,shared-lrclk;
102 DCVDD-supply = <&reg_audio>;
103 DBVDD-supply = <&reg_audio>;
104 AVDD-supply = <&reg_audio>;
105 SPKVDD1-supply = <&reg_audio>;
106 SPKVDD2-supply = <&reg_audio>;
87 };107 };
88 };108 };
Documentation/devicetree/bindings/sound/wm8904.txt+0−33
@@ -1,33 +0,0 @@
1WM8904 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6 - compatible: "wlf,wm8904" or "wlf,wm8912"
7 - reg: the I2C address of the device.
8 - clock-names: "mclk"
9 - clocks: reference to
10 <Documentation/devicetree/bindings/clock/clock-bindings.txt>
11
12Pins on the device (for linking into audio routes):
13
14 * IN1L
15 * IN1R
16 * IN2L
17 * IN2R
18 * IN3L
19 * IN3R
20 * HPOUTL
21 * HPOUTR
22 * LINEOUTL
23 * LINEOUTR
24 * MICBIAS
25
26Examples:
27
28codec: wm8904@1a {
29 compatible = "wlf,wm8904";
30 reg = <0x1a>;
31 clocks = <&pck0>;
32 clock-names = "mclk";
33};
Documentation/driver-api/media/dtv-common.rst+0−9
@@ -3,15 +3,6 @@ · 2 unmodified lines
3Digital TV Common functions3Digital TV Common functions
4---------------------------4---------------------------
5 5
6Math functions
7~~~~~~~~~~~~~~
8
9Provide some commonly-used math functions, usually required in order to
10estimate signal strength and signal to noise measurements in dB.
11
12.. kernel-doc:: include/media/dvb_math.h
13
14
15DVB devices6DVB devices
16~~~~~~~~~~~7~~~~~~~~~~~
17 8
Documentation/sound/cards/audigy-mixer.rst+66−131
@@ -46,157 +46,158 @@ FX-bus · 45 unmodified lines
46 46
47name='PCM Front Playback Volume',index=047name='PCM Front Playback Volume',index=0
48----------------------------------------48----------------------------------------
49This control is used to attenuate samples for left and right front PCM FX-bus49This control is used to attenuate samples from left and right front PCM FX-bus
50accumulators. ALSA uses accumulators 8 and 9 for left and right front PCM 50accumulators. ALSA uses accumulators 8 and 9 for left and right front PCM
51samples for 5.1 playback. The result samples are forwarded to the front DAC PCM 51samples for 5.1 playback. The result samples are forwarded to the front speakers.
52slots of the Philips DAC.
53 52
54name='PCM Surround Playback Volume',index=053name='PCM Surround Playback Volume',index=0
55-------------------------------------------54-------------------------------------------
56This control is used to attenuate samples for left and right surround PCM FX-bus55This control is used to attenuate samples from left and right surround PCM FX-bus
57accumulators. ALSA uses accumulators 2 and 3 for left and right surround PCM 56accumulators. ALSA uses accumulators 2 and 3 for left and right surround PCM
58samples for 5.1 playback. The result samples are forwarded to the surround DAC PCM 57samples for 5.1 playback. The result samples are forwarded to the surround (rear)
59slots of the Philips DAC.58speakers.
59
60name='PCM Side Playback Volume',index=0
61---------------------------------------
62This control is used to attenuate samples from left and right side PCM FX-bus
63accumulators. ALSA uses accumulators 14 and 15 for left and right side PCM
64samples for 7.1 playback. The result samples are forwarded to the side speakers.
60 65
61name='PCM Center Playback Volume',index=066name='PCM Center Playback Volume',index=0
62-----------------------------------------67-----------------------------------------
63This control is used to attenuate samples for center PCM FX-bus accumulator.68This control is used to attenuate samples from center PCM FX-bus accumulator.
64ALSA uses accumulator 6 for center PCM sample for 5.1 playback. The result sample69ALSA uses accumulator 6 for center PCM samples for 5.1 playback. The result
65is forwarded to the center DAC PCM slot of the Philips DAC.70samples are forwarded to the center speaker.
66 71
67name='PCM LFE Playback Volume',index=072name='PCM LFE Playback Volume',index=0
68--------------------------------------73--------------------------------------
69This control is used to attenuate sample for LFE PCM FX-bus accumulator. 74This control is used to attenuate sample for LFE PCM FX-bus accumulator.
70ALSA uses accumulator 7 for LFE PCM sample for 5.1 playback. The result sample 75ALSA uses accumulator 7 for LFE PCM samples for 5.1 playback. The result
71is forwarded to the LFE DAC PCM slot of the Philips DAC.76samples are forwarded to the subwoofer.
72 77
73name='PCM Playback Volume',index=078name='PCM Playback Volume',index=0
74----------------------------------79----------------------------------
75This control is used to attenuate samples for left and right PCM FX-bus80This control is used to attenuate samples from left and right PCM FX-bus
76accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples for81accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples for
77stereo playback. The result samples are forwarded to the front DAC PCM slots 82stereo playback. The result samples are forwarded to the front speakers.
78of the Philips DAC.
79 83
80name='PCM Capture Volume',index=084name='PCM Capture Volume',index=0
81---------------------------------85---------------------------------
82This control is used to attenuate samples for left and right PCM FX-bus86This control is used to attenuate samples from left and right PCM FX-bus
83accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.87accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples for
84The result is forwarded to the ADC capture FIFO (thus to the standard capture88stereo playback. The result is forwarded to the standard capture PCM device.
85PCM device).
86 89
87name='Music Playback Volume',index=090name='Music Playback Volume',index=0
88------------------------------------91------------------------------------
89This control is used to attenuate samples for left and right MIDI FX-bus92This control is used to attenuate samples from left and right MIDI FX-bus
90accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.93accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
91The result samples are forwarded to the front DAC PCM slots of the AC97 codec.94The result samples are forwarded to the virtual stereo mixer.
92 95
93name='Music Capture Volume',index=096name='Music Capture Volume',index=0
94-----------------------------------97-----------------------------------
95These controls are used to attenuate samples for left and right MIDI FX-bus98These controls are used to attenuate samples from left and right MIDI FX-bus
96accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.99accumulator. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
97The result is forwarded to the ADC capture FIFO (thus to the standard capture100The result is forwarded to the standard capture PCM device.
98PCM device).
99 101
100name='Mic Playback Volume',index=0102name='Mic Playback Volume',index=0
101----------------------------------103----------------------------------
102This control is used to attenuate samples for left and right Mic input.104This control is used to attenuate samples from left and right Mic input of
103For Mic input is used AC97 codec. The result samples are forwarded to 105the AC97 codec. The result samples are forwarded to the virtual stereo mixer.
104the front DAC PCM slots of the Philips DAC. Samples are forwarded to Mic
105capture FIFO (device 1 - 16bit/8KHz mono) too without volume control.
106 106
107name='Mic Capture Volume',index=0107name='Mic Capture Volume',index=0
108---------------------------------108---------------------------------
109This control is used to attenuate samples for left and right Mic input.109This control is used to attenuate samples from left and right Mic input of
110The result is forwarded to the ADC capture FIFO (thus to the standard capture110the AC97 codec. The result is forwarded to the standard capture PCM device.
111PCM device).111
112The original samples are also forwarded to the Mic capture PCM device (device 1;
11316bit/8KHz mono) without volume control.
112 114
113name='Audigy CD Playback Volume',index=0115name='Audigy CD Playback Volume',index=0
114----------------------------------------116----------------------------------------
115This control is used to attenuate samples from left and right IEC958 TTL117This control is used to attenuate samples from left and right IEC958 TTL
116digital inputs (usually used by a CDROM drive). The result samples are118digital inputs (usually used by a CDROM drive). The result samples are
117forwarded to the front DAC PCM slots of the Philips DAC.119forwarded to the virtual stereo mixer.
118 120
119name='Audigy CD Capture Volume',index=0121name='Audigy CD Capture Volume',index=0
120---------------------------------------122---------------------------------------
121This control is used to attenuate samples from left and right IEC958 TTL123This control is used to attenuate samples from left and right IEC958 TTL
122digital inputs (usually used by a CDROM drive). The result samples are124digital inputs (usually used by a CDROM drive). The result is forwarded
123forwarded to the ADC capture FIFO (thus to the standard capture PCM device).125to the standard capture PCM device.
124 126
125name='IEC958 Optical Playback Volume',index=0127name='IEC958 Optical Playback Volume',index=0
126---------------------------------------------128---------------------------------------------
127This control is used to attenuate samples from left and right IEC958 optical129This control is used to attenuate samples from left and right IEC958 optical
128digital input. The result samples are forwarded to the front DAC PCM slots130digital input. The result samples are forwarded to the virtual stereo mixer.
129of the Philips DAC.
130 131
131name='IEC958 Optical Capture Volume',index=0132name='IEC958 Optical Capture Volume',index=0
132--------------------------------------------133--------------------------------------------
133This control is used to attenuate samples from left and right IEC958 optical134This control is used to attenuate samples from left and right IEC958 optical
134digital inputs. The result samples are forwarded to the ADC capture FIFO135digital inputs. The result is forwarded to the standard capture PCM device.
135(thus to the standard capture PCM device).
136 136
137name='Line2 Playback Volume',index=0137name='Line2 Playback Volume',index=0
138------------------------------------138------------------------------------
139This control is used to attenuate samples from left and right I2S ADC139This control is used to attenuate samples from left and right I2S ADC
140inputs (on the AudigyDrive). The result samples are forwarded to the front140inputs (on the AudigyDrive). The result samples are forwarded to the virtual
141DAC PCM slots of the Philips DAC.141stereo mixer.
142 142
143name='Line2 Capture Volume',index=1143name='Line2 Capture Volume',index=1
144-----------------------------------144-----------------------------------
145This control is used to attenuate samples from left and right I2S ADC145This control is used to attenuate samples from left and right I2S ADC
146inputs (on the AudigyDrive). The result samples are forwarded to the ADC146inputs (on the AudigyDrive). The result is forwarded to the standard capture
147capture FIFO (thus to the standard capture PCM device).147PCM device.
148 148
149name='Analog Mix Playback Volume',index=0149name='Analog Mix Playback Volume',index=0
150-----------------------------------------150-----------------------------------------
151This control is used to attenuate samples from left and right I2S ADC151This control is used to attenuate samples from left and right I2S ADC
152inputs from Philips ADC. The result samples are forwarded to the front152inputs from Philips ADC. The result samples are forwarded to the virtual
153DAC PCM slots of the Philips DAC. This contains mix from analog sources153stereo mixer. This contains mix from analog sources like CD, Line In, Aux, ....
154like CD, Line In, Aux, ....
155 154
156name='Analog Mix Capture Volume',index=1155name='Analog Mix Capture Volume',index=1
157----------------------------------------156----------------------------------------
158This control is used to attenuate samples from left and right I2S ADC157This control is used to attenuate samples from left and right I2S ADC
159inputs Philips ADC. The result samples are forwarded to the ADC158inputs Philips ADC. The result is forwarded to the standard capture PCM device.
160capture FIFO (thus to the standard capture PCM device).
161 159
162name='Aux2 Playback Volume',index=0160name='Aux2 Playback Volume',index=0
163-----------------------------------161-----------------------------------
164This control is used to attenuate samples from left and right I2S ADC162This control is used to attenuate samples from left and right I2S ADC
165inputs (on the AudigyDrive). The result samples are forwarded to the front163inputs (on the AudigyDrive). The result samples are forwarded to the virtual
166DAC PCM slots of the Philips DAC.164stereo mixer.
167 165
168name='Aux2 Capture Volume',index=1166name='Aux2 Capture Volume',index=1
169----------------------------------167----------------------------------
170This control is used to attenuate samples from left and right I2S ADC168This control is used to attenuate samples from left and right I2S ADC
171inputs (on the AudigyDrive). The result samples are forwarded to the ADC169inputs (on the AudigyDrive). The result is forwarded to the standard capture
172capture FIFO (thus to the standard capture PCM device).170PCM device.
173 171
174name='Front Playback Volume',index=0172name='Front Playback Volume',index=0
175------------------------------------173------------------------------------
176All stereo signals are mixed together and mirrored to surround, center and LFE.174This control is used to attenuate samples from the virtual stereo mixer.
177This control is used to attenuate samples for left and right front speakers of175The result samples are forwarded to the front speakers.
178this mix.
179 176
180name='Surround Playback Volume',index=0177name='Surround Playback Volume',index=0
181---------------------------------------178---------------------------------------
182All stereo signals are mixed together and mirrored to surround, center and LFE.179This control is used to attenuate samples from the virtual stereo mixer.
183This control is used to attenuate samples for left and right surround speakers of180The result samples are forwarded to the surround (rear) speakers.
184this mix.181
182name='Side Playback Volume',index=0
183-----------------------------------
184This control is used to attenuate samples from the virtual stereo mixer.
185The result samples are forwarded to the side speakers.
185 186
186name='Center Playback Volume',index=0187name='Center Playback Volume',index=0
187-------------------------------------188-------------------------------------
188All stereo signals are mixed together and mirrored to surround, center and LFE.189This control is used to attenuate samples from the virtual stereo mixer.
189This control is used to attenuate sample for center speaker of this mix.190The result samples are forwarded to the center speaker.
190 191
191name='LFE Playback Volume',index=0192name='LFE Playback Volume',index=0
192----------------------------------193----------------------------------
193All stereo signals are mixed together and mirrored to surround, center and LFE.194This control is used to attenuate samples from the virtual stereo mixer.
194This control is used to attenuate sample for LFE speaker of this mix.195The result samples are forwarded to the subwoofer.
195 196
196name='Tone Control - Switch',index=0197name='Tone Control - Switch',index=0
197------------------------------------198------------------------------------
198This control turns the tone control on or off. The samples for front, rear199This control turns the tone control on or off. The samples forwarded to
199and center / LFE outputs are affected.200the speaker outputs are affected.
200 201
201name='Tone Control - Bass',index=0202name='Tone Control - Bass',index=0
202----------------------------------203----------------------------------
@@ -212,8 +213,7 @@ The closest value to pure signal is 20. · 9 unmodified lines
212 213
213name='Master Playback Volume',index=0214name='Master Playback Volume',index=0
214-------------------------------------215-------------------------------------
215This control is used to attenuate samples for front, surround, center and 216This control is used to attenuate samples forwarded to the speaker outputs.
216LFE outputs.
217 217
218name='IEC958 Optical Raw Playback Switch',index=0218name='IEC958 Optical Raw Playback Switch',index=0
219-------------------------------------------------219-------------------------------------------------
@@ -303,69 +303,4 @@ The channel mapping is following: · 83 unmodified lines
303MANUALS/PATENTS303MANUALS/PATENTS
304===============304===============
305 305
306ftp://opensource.creative.com/pub/doc306See sb-live-mixer.rst.
307-------------------------------------
308
309Note that the site is defunct, but the documents are available
310from various other locations.
311
312LM4545.pdf
313 AC97 Codec
314
315m2049.pdf
316 The EMU10K1 Digital Audio Processor
317
318hog63.ps
319 FX8010 - A DSP Chip Architecture for Audio Effects
320
321
322WIPO Patents
323------------
324
325WO 9901813 (A1)
326 Audio Effects Processor with multiple asynchronous streams
327 (Jan. 14, 1999)
328
329WO 9901814 (A1)
330 Processor with Instruction Set for Audio Effects (Jan. 14, 1999)
331
332WO 9901953 (A1)
333 Audio Effects Processor having Decoupled Instruction
334 Execution and Audio Data Sequencing (Jan. 14, 1999)
335
336
337US Patents (https://www.uspto.gov/)
338-----------------------------------
339
340US 5925841
341 Digital Sampling Instrument employing cache memory (Jul. 20, 1999)
342
343US 5928342
344 Audio Effects Processor integrated on a single chip
345 with a multiport memory onto which multiple asynchronous
346 digital sound samples can be concurrently loaded
347 (Jul. 27, 1999)
348
349US 5930158
350 Processor with Instruction Set for Audio Effects (Jul. 27, 1999)
351
352US 6032235
353 Memory initialization circuit (Tram) (Feb. 29, 2000)
354
355US 6138207
356 Interpolation looping of audio samples in cache connected to
357 system bus with prioritization and modification of bus transfers
358 in accordance with loop ends and minimum block sizes
359 (Oct. 24, 2000)
360
361US 6151670
362 Method for conserving memory storage using a
363 pool of short term memory registers
364 (Nov. 21, 2000)
365
366US 6195715
367 Interrupt control for multiple programs communicating with
368 a common interrupt by associating programs to GP registers,
369 defining interrupt register, polling GP registers, and invoking
370 callback routine associated with defined interrupt register
371 (Feb. 27, 2001)
Documentation/sound/cards/emu-mixer.rst+226−0
@@ -0,0 +1,226 @@
1==================================================
2E-MU Digital Audio System mixer / default DSP code
3==================================================
4
5This document covers the E-MU 0404/1010/1212/1616/1820 PCI/PCI-e/CardBus
6cards.
7
8These cards use regular EMU10K2 (SoundBlaster Audigy) chips, but with an
9alternative front-end geared towards semi-professional studio recording.
10
11This document is based on audigy-mixer.rst.
12
13
14Hardware compatibility
15======================
16
17The EMU10K2 chips have a very short capture FIFO, which makes recording
18unreliable if the card's PCI bus requests are not handled with the
19appropriate priority.
20This is the case on more modern motherboards, where the PCI bus is only a
21secondary peripheral, rather than the actual arbiter of device access.
22In particular, I got recording glitches during simultaneous playback on an
23Intel DP55 board (memory controller in the CPU), but had success with an
24Intel DP45 board (memory controller in the north bridge).
25
26The PCI Express variants of these cards (which have a PCI bridge on board,
27but are otherwise identical) may be less problematic.
28
29
30Driver capabilities
31===================
32
33This driver supports only 16-bit 44.1/48 kHz operation. The multi-channel
34device (see emu10k1-jack.rst) additionally supports 24-bit capture.
35
36A patchset to enhance the driver is available from `a GitHub repository
37<https://github.com/ossilator/linux/tree/ossis-emu10k1>`_.
38Its multi-channel device supports 24-bit for both playback and capture,
39and also supports full 88.2/96/176.4/192 kHz operation.
40It is not going to be upstreamed due to a fundamental disagreement about
41what constitutes a good user experience.
42
43
44Digital mixer controls
45======================
46
47Note that the controls work as attenuators: the maximum value is the neutral
48position leaving the signal unchanged. Note that if the same destination is
49mentioned in multiple controls, the signal is accumulated and can be clipped
50(set to maximal or minimal value without checking for overflow).
51
52Explanation of used abbreviations:
53
54DAC
55 digital to analog converter
56ADC
57 analog to digital converter
58LFE
59 low frequency effects (used as subwoofer signal)
60IEC958
61 S/PDIF
62FX-bus
63 the EMU10K2 chip has an effect bus containing 64 accumulators.
64 Each of the synthesizer voices can feed its output to these accumulators
65 and the DSP microcontroller can operate with the resulting sum.
66
67name='Clock Source',index=0
68---------------------------
69This control allows switching the word clock between interally generated
7044.1 or 48 kHz, or a number of external sources.
71
72Note: the sources for the 1616 CardBus card are unclear. Please report your
73findings.
74
75name='Clock Fallback',index=0
76-----------------------------
77This control determines the internal clock which the card switches to when
78the selected external clock source is/becomes invalid.
79
80name='DAC1 0202 14dB PAD',index=0, etc.
81---------------------------------------
82Output attenuation controls. Not available on 0404 cards.
83
84name='ADC1 14dB PAD 0202',index=0, etc.
85---------------------------------------
86Input attenuation controls. Not available on 0404 cards.
87
88name='Optical Output Mode',index=0
89----------------------------------
90Switches the TOSLINK output port between S/PDIF and ADAT.
91Not available on 0404 cards (fixed to S/PDIF).
92
93name='Optical Input Mode',index=0
94---------------------------------
95Switches the TOSLINK input port between S/PDIF and ADAT.
96Not available on 0404 cards (fixed to S/PDIF).
97
98name='PCM Front Playback Volume',index=0
99----------------------------------------
100This control is used to attenuate samples from left and right front PCM FX-bus
101accumulators. ALSA uses accumulators 8 and 9 for left and right front PCM
102samples for 5.1 playback. The result samples are forwarded to the DSP 0 & 1
103playback channels.
104
105name='PCM Surround Playback Volume',index=0
106-------------------------------------------
107This control is used to attenuate samples from left and right surround PCM FX-bus
108accumulators. ALSA uses accumulators 2 and 3 for left and right surround PCM
109samples for 5.1 playback. The result samples are forwarded to the DSP 2 & 3
110playback channels.
111
112name='PCM Side Playback Volume',index=0
113---------------------------------------
114This control is used to attenuate samples from left and right side PCM FX-bus
115accumulators. ALSA uses accumulators 14 and 15 for left and right side PCM
116samples for 7.1 playback. The result samples are forwarded to the DSP 6 & 7
117playback channels.
118
119name='PCM Center Playback Volume',index=0
120-----------------------------------------
121This control is used to attenuate samples from the center PCM FX-bus accumulator.
122ALSA uses accumulator 6 for center PCM samples for 5.1 playback. The result samples
123are forwarded to the DSP 4 playback channel.
124
125name='PCM LFE Playback Volume',index=0
126--------------------------------------
127This control is used to attenuate samples from the LFE PCM FX-bus accumulator.
128ALSA uses accumulator 7 for LFE PCM samples for 5.1 playback. The result samples
129are forwarded to the DSP 5 playback channel.
130
131name='PCM Playback Volume',index=0
132----------------------------------
133This control is used to attenuate samples from left and right PCM FX-bus
134accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples for
135stereo playback. The result samples are forwarded to the virtual stereo mixer.
136
137name='PCM Capture Volume',index=0
138---------------------------------
139This control is used to attenuate samples from left and right PCM FX-bus
140accumulators. ALSA uses accumulators 0 and 1 for left and right PCM.
141The result is forwarded to the standard capture PCM device.
142
143name='Music Playback Volume',index=0
144------------------------------------
145This control is used to attenuate samples from left and right MIDI FX-bus
146accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
147The result samples are forwarded to the virtual stereo mixer.
148
149name='Music Capture Volume',index=0
150-----------------------------------
151These controls are used to attenuate samples from left and right MIDI FX-bus
152accumulator. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
153The result is forwarded to the standard capture PCM device.
154
155name='Front Playback Volume',index=0
156------------------------------------
157This control is used to attenuate samples from the virtual stereo mixer.
158The result samples are forwarded to the DSP 0 & 1 playback channels.
159
160name='Surround Playback Volume',index=0
161---------------------------------------
162This control is used to attenuate samples from the virtual stereo mixer.
163The result samples are forwarded to the DSP 2 & 3 playback channels.
164
165name='Side Playback Volume',index=0
166-----------------------------------
167This control is used to attenuate samples from the virtual stereo mixer.
168The result samples are forwarded to the DSP 6 & 7 playback channels.
169
170name='Center Playback Volume',index=0
171-------------------------------------
172This control is used to attenuate samples from the virtual stereo mixer.
173The result samples are forwarded to the DSP 4 playback channel.
174
175name='LFE Playback Volume',index=0
176----------------------------------
177This control is used to attenuate samples from the virtual stereo mixer.
178The result samples are forwarded to the DSP 5 playback channel.
179
180name='Tone Control - Switch',index=0
181------------------------------------
182This control turns the tone control on or off. The samples forwarded to
183the DSP playback channels are affected.
184
185name='Tone Control - Bass',index=0
186----------------------------------
187This control sets the bass intensity. There is no neutral value!!
188When the tone control code is activated, the samples are always modified.
189The closest value to pure signal is 20.
190
191name='Tone Control - Treble',index=0
192------------------------------------
193This control sets the treble intensity. There is no neutral value!!
194When the tone control code is activated, the samples are always modified.
195The closest value to pure signal is 20.
196
197name='Master Playback Volume',index=0
198-------------------------------------
199This control is used to attenuate samples for all DSP playback channels.
200
201name='EMU Capture Volume',index=0
202----------------------------------
203This control is used to attenuate samples from the DSP 0 & 1 capture channels.
204The result is forwarded to the standard capture PCM device.
205
206name='DAC Left',index=0, etc.
207-----------------------------
208Select the source for the given physical audio output. These may be physical
209inputs, playback channels (DSP xx, specified as a decimal number), or silence.
210
211name='DSP x',index=0
212--------------------
213Select the source for the given capture channel (specified as a hexadecimal
214digit). Same options as for the physical audio outputs.
215
216
217PCM stream related controls
218===========================
219
220These controls are described in audigy-mixer.rst.
221
222
223MANUALS/PATENTS
224===============
225
226See sb-live-mixer.rst.
Documentation/sound/cards/index.rst+1−0
@@ -8,6 +8,7 @@ Card-Specific Information · 7 unmodified lines
8 cmipci8 cmipci
9 sb-live-mixer9 sb-live-mixer
10 audigy-mixer10 audigy-mixer
11 emu-mixer
11 emu10k1-jack12 emu10k1-jack
12 via82xx-mixer13 via82xx-mixer
13 audiophile-usb14 audiophile-usb
Documentation/sound/cards/sb-live-mixer.rst+12−12
@@ -61,61 +61,61 @@ FX-bus · 60 unmodified lines
61 61
62``name='Wave Playback Volume',index=0``62``name='Wave Playback Volume',index=0``
63---------------------------------------63---------------------------------------
64This control is used to attenuate samples for left and right PCM FX-bus64This control is used to attenuate samples from left and right PCM FX-bus
65accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.65accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
66The result samples are forwarded to the front DAC PCM slots of the AC97 codec.66The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
67 67
68``name='Wave Surround Playback Volume',index=0``68``name='Wave Surround Playback Volume',index=0``
69------------------------------------------------69------------------------------------------------
70This control is used to attenuate samples for left and right PCM FX-bus70This control is used to attenuate samples from left and right PCM FX-bus
71accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.71accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
72The result samples are forwarded to the rear I2S DACs. These DACs operates72The result samples are forwarded to the rear I2S DACs. These DACs operates
73separately (they are not inside the AC97 codec).73separately (they are not inside the AC97 codec).
74 74
75``name='Wave Center Playback Volume',index=0``75``name='Wave Center Playback Volume',index=0``
76----------------------------------------------76----------------------------------------------
77This control is used to attenuate samples for left and right PCM FX-bus77This control is used to attenuate samples from left and right PCM FX-bus
78accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.78accumulators. ALSA uses accumulators 0 and 1 for left and right PCM samples.
79The result is mixed to mono signal (single channel) and forwarded to79The result is mixed to mono signal (single channel) and forwarded to
80the ??rear?? right DAC PCM slot of the AC97 codec.80the ??rear?? right DAC PCM slot of the AC97 codec.
81 81
82``name='Wave LFE Playback Volume',index=0``82``name='Wave LFE Playback Volume',index=0``
83-------------------------------------------83-------------------------------------------
84This control is used to attenuate samples for left and right PCM FX-bus84This control is used to attenuate samples from left and right PCM FX-bus
85accumulators. ALSA uses accumulators 0 and 1 for left and right PCM.85accumulators. ALSA uses accumulators 0 and 1 for left and right PCM.
86The result is mixed to mono signal (single channel) and forwarded to86The result is mixed to mono signal (single channel) and forwarded to
87the ??rear?? left DAC PCM slot of the AC97 codec.87the ??rear?? left DAC PCM slot of the AC97 codec.
88 88
89``name='Wave Capture Volume',index=0``, ``name='Wave Capture Switch',index=0``89``name='Wave Capture Volume',index=0``, ``name='Wave Capture Switch',index=0``
90------------------------------------------------------------------------------90------------------------------------------------------------------------------
91These controls are used to attenuate samples for left and right PCM FX-bus91These controls are used to attenuate samples from left and right PCM FX-bus
92accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.92accumulator. ALSA uses accumulators 0 and 1 for left and right PCM.
93The result is forwarded to the ADC capture FIFO (thus to the standard capture93The result is forwarded to the ADC capture FIFO (thus to the standard capture
94PCM device).94PCM device).
95 95
96``name='Synth Playback Volume',index=0``96``name='Synth Playback Volume',index=0``
97----------------------------------------97----------------------------------------
98This control is used to attenuate samples for left and right MIDI FX-bus98This control is used to attenuate samples from left and right MIDI FX-bus
99accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.99accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
100The result samples are forwarded to the front DAC PCM slots of the AC97 codec.100The result samples are forwarded to the front DAC PCM slots of the AC97 codec.
101 101
102``name='Synth Capture Volume',index=0``, ``name='Synth Capture Switch',index=0``102``name='Synth Capture Volume',index=0``, ``name='Synth Capture Switch',index=0``
103--------------------------------------------------------------------------------103--------------------------------------------------------------------------------
104These controls are used to attenuate samples for left and right MIDI FX-bus104These controls are used to attenuate samples from left and right MIDI FX-bus
105accumulator. ALSA uses accumulators 4 and 5 for left and right PCM.105accumulator. ALSA uses accumulators 4 and 5 for left and right MIDI samples.
106The result is forwarded to the ADC capture FIFO (thus to the standard capture106The result is forwarded to the ADC capture FIFO (thus to the standard capture
107PCM device).107PCM device).
108 108
109``name='Surround Playback Volume',index=0``109``name='Surround Playback Volume',index=0``
110-------------------------------------------110-------------------------------------------
111This control is used to attenuate samples for left and right rear PCM FX-bus111This control is used to attenuate samples from left and right rear PCM FX-bus
112accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.112accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
113The result samples are forwarded to the rear I2S DACs. These DACs operate113The result samples are forwarded to the rear I2S DACs. These DACs operate
114separately (they are not inside the AC97 codec).114separately (they are not inside the AC97 codec).
115 115
116``name='Surround Capture Volume',index=0``, ``name='Surround Capture Switch',index=0``116``name='Surround Capture Volume',index=0``, ``name='Surround Capture Switch',index=0``
117--------------------------------------------------------------------------------------117--------------------------------------------------------------------------------------
118These controls are used to attenuate samples for left and right rear PCM FX-bus118These controls are used to attenuate samples from left and right rear PCM FX-bus
119accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.119accumulators. ALSA uses accumulators 2 and 3 for left and right rear PCM samples.
120The result is forwarded to the ADC capture FIFO (thus to the standard capture120The result is forwarded to the ADC capture FIFO (thus to the standard capture
121PCM device).121PCM device).
@@ -134,7 +134,7 @@ to the ??rear?? left DAC PCM slot of the AC97 codec. · 12 unmodified lines
134 134
135``name='AC97 Playback Volume',index=0``135``name='AC97 Playback Volume',index=0``
136---------------------------------------136---------------------------------------
137This control is used to attenuate samples for left and right front ADC PCM slots137This control is used to attenuate samples from left and right front ADC PCM slots
138of the AC97 codec. The result samples are forwarded to the front DAC PCM138of the AC97 codec. The result samples are forwarded to the front DAC PCM
139slots of the AC97 codec.139slots of the AC97 codec.
140 140
@@ -145,7 +145,7 @@ slots of the AC97 codec. · 4 unmodified lines
145 145
146``name='AC97 Capture Volume',index=0``146``name='AC97 Capture Volume',index=0``
147--------------------------------------147--------------------------------------
148This control is used to attenuate samples for left and right front ADC PCM slots148This control is used to attenuate samples from left and right front ADC PCM slots
149of the AC97 codec. The result is forwarded to the ADC capture FIFO (thus to149of the AC97 codec. The result is forwarded to the ADC capture FIFO (thus to
150the standard capture PCM device).150the standard capture PCM device).
151 151
Documentation/sound/designs/midi-2.0.rst+188−0
@@ -376,3 +376,191 @@ Sequencer API Extensions · 375 unmodified lines
376 name and attributes accordingly, and notifies the changes via the376 name and attributes accordingly, and notifies the changes via the
377 announcement to the ALSA sequencer system port, similarly like the377 announcement to the ALSA sequencer system port, similarly like the
378 normal port change notification.378 normal port change notification.
379
380
381MIDI2 USB Gadget Function Driver
382================================
383
384The latest kernel contains the support for USB MIDI 2.0 gadget
385function driver, which can be used for prototyping and debugging MIDI
3862.0 features.
387
388`CONFIG_USB_GADGET`, `CONFIG_USB_CONFIGFS` and
389`CONFIG_USB_CONFIGFS_F_MIDI2` need to be enabled for the MIDI2 gadget
390driver.
391
392In addition, for using a gadget driver, you need a working UDC driver.
393In the example below, we use `dummy_hcd` driver (enabled via
394`CONFIG_USB_DUMMY_HCD`) that is available on PC and VM for debugging
395purpose. There are other UDC drivers depending on the platform, and
396those can be used for a real device, instead, too.
397
398At first, on a system to run the gadget, load `libcomposite` module::
399
400 % modprobe libcomposite
401
402and you'll have `usb_gadget` subdirectory under configfs space
403(typically `/sys/kernel/config` on modern OS). Then create a gadget
404instance and add configurations there, for example::
405
406 % cd /sys/kernel/config
407 % mkdir usb_gadget/g1
408
409 % cd usb_gadget/g1
410 % mkdir configs/c.1
411 % mkdir functions/midi2.usb0
412
413 % echo 0x0004 > idProduct
414 % echo 0x17b3 > idVendor
415 % mkdir strings/0x409
416 % echo "ACME Enterprises" > strings/0x409/manufacturer
417 % echo "ACMESynth" > strings/0x409/product
418 % echo "ABCD12345" > strings/0x409/serialnumber
419
420 % mkdir configs/c.1/strings/0x409
421 % echo "Monosynth" > configs/c.1/strings/0x409/configuration
422 % echo 120 > configs/c.1/MaxPower
423
424At this point, there must be a subdirectory `ep.0`, and that is the
425configuration for a UMP Endpoint. You can fill the Endpoint
426information like::
427
428 % echo "ACMESynth" > functions/midi2.usb0/iface_name
429 % echo "ACMESynth" > functions/midi2.usb0/ep.0/ep_name
430 % echo "ABCD12345" > functions/midi2.usb0/ep.0/product_id
431 % echo 0x0123 > functions/midi2.usb0/ep.0/family
432 % echo 0x4567 > functions/midi2.usb0/ep.0/model
433 % echo 0x123456 > functions/midi2.usb0/ep.0/manufacturer
434 % echo 0x12345678 > functions/midi2.usb0/ep.0/sw_revision
435
436The default MIDI protocol can be set either 1 or 2::
437
438 % echo 2 > functions/midi2.usb0/ep.0/protocol
439
440And, you can find a subdirectory `block.0` under this Endpoint
441subdirectory. This defines the Function Block information::
442
443 % echo "Monosynth" > functions/midi2.usb0/ep.0/block.0/name
444 % echo 0 > functions/midi2.usb0/ep.0/block.0/first_group
445 % echo 1 > functions/midi2.usb0/ep.0/block.0/num_groups
446
447Finally, link the configuration and enable it::
448
449 % ln -s functions/midi2.usb0 configs/c.1
450 % echo dummy_udc.0 > UDC
451
452where `dummy_udc.0` is an example case and it differs depending on the
453system. You can find the UDC instances in `/sys/class/udc` and pass
454the found name instead::
455
456 % ls /sys/class/udc
457 dummy_udc.0
458
459Now, the MIDI 2.0 gadget device is enabled, and the gadget host
460creates a new sound card instance containing a UMP rawmidi device by
461`f_midi2` driver::
462
463 % cat /proc/asound/cards
464 ....
465 1 [Gadget ]: f_midi2 - MIDI 2.0 Gadget
466 MIDI 2.0 Gadget
467
468And on the connected host, a similar card should appear, too, but with
469the card and device names given in the configfs above::
470
471 % cat /proc/asound/cards
472 ....
473 2 [ACMESynth ]: USB-Audio - ACMESynth
474 ACME Enterprises ACMESynth at usb-dummy_hcd.0-1, high speed
475
476You can play a MIDI file on the gadget side::
477
478 % aplaymidi -p 20:1 to_host.mid
479
480and this will appear as an input from a MIDI device on the connected
481host::
482
483 % aseqdump -p 20:0 -u 2
484
485Vice versa, a playback on the connected host will work as an input on
486the gadget, too.
487
488Each Function Block may have different direction and UI-hint,
489specified via `direction` and `ui_hint` attributes.
490Passing `1` is for input-only, `2` for out-only and `3` for
491bidirectional (the default value). For example::
492
493 % echo 2 > functions/midi2.usb0/ep.0/block.0/direction
494 % echo 2 > functions/midi2.usb0/ep.0/block.0/ui_hint
495
496When you need more than one Function Blocks, you can create
497subdirectories `block.1`, `block.2`, etc dynamically, and configure
498them in the configuration procedure above before linking.
499For example, to create a second Function Block for a keyboard::
500
501 % mkdir functions/midi2.usb0/ep.0/block.1
502 % echo "Keyboard" > functions/midi2.usb0/ep.0/block.1/name
503 % echo 1 > functions/midi2.usb0/ep.0/block.1/first_group
504 % echo 1 > functions/midi2.usb0/ep.0/block.1/num_groups
505 % echo 1 > functions/midi2.usb0/ep.0/block.1/direction
506 % echo 1 > functions/midi2.usb0/ep.0/block.1/ui_hint
507
508The `block.*` subdirectories can be removed dynamically, too (except
509for `block.0` which is persistent).
510
511For assigning a Function Block for MIDI 1.0 I/O, set up in `is_midi1`
512attribute. 1 is for MIDI 1.0, and 2 is for MIDI 1.0 with low speed
513connection::
514
515 % echo 2 > functions/midi2.usb0/ep.0/block.1/is_midi1
516
517For disabling the processing of UMP Stream messages in the gadget
518driver, pass `0` to `process_ump` attribute in the top-level config::
519
520 % echo 0 > functions/midi2.usb0/process_ump
521
522The MIDI 1.0 interface at altset 0 is supported by the gadget driver,
523too. When MIDI 1.0 interface is selected by the connected host, the
524UMP I/O on the gadget is translated from/to USB MIDI 1.0 packets
525accordingly while the gadget driver keeps communicating with the
526user-space over UMP rawmidi.
527
528MIDI 1.0 ports are set up from the config in each Function Block.
529For example::
530
531 % echo 0 > functions/midi2.usb0/ep.0/block.0/midi1_first_group
532 % echo 1 > functions/midi2.usb0/ep.0/block.0/midi1_num_groups
533
534The configuration above will enable the Group 1 (the index 0) for MIDI
5351.0 interface. Note that those groups must be in the groups defined
536for the Function Block itself.
537
538The gadget driver supports more than one UMP Endpoints, too.
539Similarly like the Function Blocks, you can create a new subdirectory
540`ep.1` (but under the card top-level config) to enable a new Endpoint::
541
542 % mkdir functions/midi2.usb0/ep.1
543
544and create a new Function Block there. For example, to create 4
545Groups for the Function Block of this new Endpoint::
546
547 % mkdir functions/midi2.usb0/ep.1/block.0
548 % echo 4 > functions/midi2.usb0/ep.1/block.0/num_groups
549
550Now, you'll have 4 rawmidi devices in total: the first two are UMP
551rawmidi devices for Endpoint 0 and Endpoint 1, and other two for the
552legacy MIDI 1.0 rawmidi devices corresponding to both EP 0 and EP 1.
553
554The current altsetting on the gadget can be informed via a control
555element "Operation Mode" with `RAWMIDI` iface. e.g. you can read it
556via `amixer` program running on the gadget host like::
557
558 % amixer -c1 cget iface=RAWMIDI,name='Operation Mode'
559 ; type=INTEGER,access=r--v----,values=1,min=0,max=2,step=0
560 : values=2
561
562The value (shown in the second returned line with `: values=`)
563indicates 1 for MIDI 1.0 (altset 0), 2 for MIDI 2.0 (altset 1) and 0
564for unset.
565
566As of now, the configurations can't be changed after binding.
Documentation/sound/kernel-api/writing-an-alsa-driver.rst+19−39
@@ -2018,8 +2018,8 @@ sleeping poll threads, etc. · 2017 unmodified lines
2018 2018
2019This callback is also atomic by default.2019This callback is also atomic by default.
2020 2020
2021copy_user, copy_kernel and fill_silence ops2021copy and fill_silence ops
2022~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2022~~~~~~~~~~~~~~~~~~~~~~~~~
2023 2023
2024These callbacks are not mandatory, and can be omitted in most cases.2024These callbacks are not mandatory, and can be omitted in most cases.
2025These callbacks are used when the hardware buffer cannot be in the2025These callbacks are used when the hardware buffer cannot be in the
@@ -3444,8 +3444,8 @@ external hardware buffer in interrupts (or in tasklets, preferably). · 1418 unmodified lines
3444 3444
3445The first case works fine if the external hardware buffer is large3445The first case works fine if the external hardware buffer is large
3446enough. This method doesn't need any extra buffers and thus is more3446enough. This method doesn't need any extra buffers and thus is more
3447efficient. You need to define the ``copy_user`` and ``copy_kernel``3447efficient. You need to define the ``copy`` callback
3448callbacks for the data transfer, in addition to the ``fill_silence``3448for the data transfer, in addition to the ``fill_silence``
3449callback for playback. However, there is a drawback: it cannot be3449callback for playback. However, there is a drawback: it cannot be
3450mmapped. 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.
3451 3451
@@ -3458,22 +3458,22 @@ Another case is when the chip uses a PCI memory-map region for the · 6 unmodified lines
3458buffer instead of the host memory. In this case, mmap is available only3458buffer instead of the host memory. In this case, mmap is available only
3459on certain architectures like the Intel one. In non-mmap mode, the data3459on certain architectures like the Intel one. In non-mmap mode, the data
3460cannot 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
3461``copy_user``, ``copy_kernel`` and ``fill_silence`` callbacks as well,3461``copy`` and ``fill_silence`` callbacks as well,
3462as in the cases above. Examples are found in ``rme32.c`` and3462as in the cases above. Examples are found in ``rme32.c`` and
3463``rme96.c``.3463``rme96.c``.
3464 3464
3465The implementation of the ``copy_user``, ``copy_kernel`` and3465The implementation of the ``copy`` and
3466``silence`` callbacks depends upon whether the hardware supports3466``silence`` callbacks depends upon whether the hardware supports
3467interleaved or non-interleaved samples. The ``copy_user`` callback is3467interleaved or non-interleaved samples. The ``copy`` callback is
3468defined like below, a bit differently depending on whether the direction3468defined like below, a bit differently depending on whether the direction
3469is playback or capture::3469is playback or capture::
3470 3470
3471 static int playback_copy_user(struct snd_pcm_substream *substream,3471 static int playback_copy(struct snd_pcm_substream *substream,
3472 int channel, unsigned long pos,3472 int channel, unsigned long pos,
3473 void __user *src, unsigned long count);3473 struct iov_iter *src, unsigned long count);
3474 static int capture_copy_user(struct snd_pcm_substream *substream,3474 static int capture_copy(struct snd_pcm_substream *substream,
3475 int channel, unsigned long pos,3475 int channel, unsigned long pos,
3476 void __user *dst, unsigned long count);3476 struct iov_iter *dst, unsigned long count);
3477 3477
3478In the case of interleaved samples, the second argument (``channel``) is3478In the case of interleaved samples, the second argument (``channel``) is
3479not used. The third argument (``pos``) specifies the position in bytes.3479not used. The third argument (``pos``) specifies the position in bytes.
@@ -3490,18 +3490,17 @@ of data (``count``) at the specified pointer (``src``) to the specified · 10 unmodified lines
3490offset (``pos``) in the hardware buffer. When coded like memcpy-like3490offset (``pos``) in the hardware buffer. When coded like memcpy-like
3491way, the copy would look like::3491way, the copy would look like::
3492 3492
3493 my_memcpy_from_user(my_buffer + pos, src, count);3493 my_memcpy_from_iter(my_buffer + pos, src, count);
3494 3494
3495For the capture direction, you copy the given amount of data (``count``)3495For the capture direction, you copy the given amount of data (``count``)
3496at the specified offset (``pos``) in the hardware buffer to the3496at the specified offset (``pos``) in the hardware buffer to the
3497specified pointer (``dst``)::3497specified pointer (``dst``)::
3498 3498
3499 my_memcpy_to_user(dst, my_buffer + pos, count);3499 my_memcpy_to_iter(dst, my_buffer + pos, count);
3500 3500
3501Here the functions are named ``from_user`` and ``to_user`` because3501The given ``src`` or ``dst`` a struct iov_iter pointer containing the
3502it's the user-space buffer that is passed to these callbacks. That3502pointer and the size. Use the existing helpers to copy or access the
3503is, the callback is supposed to copy data from/to the user-space3503data as defined in ``linux/uio.h``.
3504directly to/from the hardware buffer.
3505 3504
3506Careful readers might notice that these callbacks receive the3505Careful readers might notice that these callbacks receive the
3507arguments in bytes, not in frames like other callbacks. It's because3506arguments in bytes, not in frames like other callbacks. It's because
@@ -3519,25 +3518,6 @@ the given user-space buffer, but only for the given channel. For · 11 unmodified lines
3519details, please check ``isa/gus/gus_pcm.c`` or ``pci/rme9652/rme9652.c``3518details, please check ``isa/gus/gus_pcm.c`` or ``pci/rme9652/rme9652.c``
3520as examples.3519as examples.
3521 3520
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::
3526
3527 static int playback_copy_kernel(struct snd_pcm_substream *substream,
3528 int channel, unsigned long pos,
3529 void *src, unsigned long count);
3530 static int capture_copy_kernel(struct snd_pcm_substream *substream,
3531 int channel, unsigned long pos,
3532 void *dst, unsigned long count);
3533
3534As found easily, the only difference is that the buffer pointer is
3535without a ``__user`` prefix; that is, a kernel-buffer pointer is passed
3536in the fourth argument. Correspondingly, the implementation would be
3537a version without the user-copy, such as::
3538
3539 my_memcpy(my_buffer + pos, src, count);
3540
3541Usually for the playback, another callback ``fill_silence`` is3521Usually for the playback, another callback ``fill_silence`` is
3542defined. It's implemented in a similar way as the copy callbacks3522defined. It's implemented in a similar way as the copy callbacks
3543above::3523above::
@@ -3545,10 +3525,10 @@ above:: · 1 unmodified line
3545 static int silence(struct snd_pcm_substream *substream, int channel,3525 static int silence(struct snd_pcm_substream *substream, int channel,
3546 unsigned long pos, unsigned long count);3526 unsigned long pos, unsigned long count);
3547 3527
3548The meanings of arguments are the same as in the ``copy_user`` and3528The meanings of arguments are the same as in the ``copy`` callback,
3549``copy_kernel`` callbacks, although there is no buffer pointer3529although there is no buffer pointer
3550argument. In the case of interleaved samples, the channel argument has3530argument. In the case of interleaved samples, the channel argument has
3551no meaning, as for the ``copy_*`` callbacks.3531no meaning, as for the ``copy`` callback.
3552 3532
3553The role of the ``fill_silence`` callback is to set the given amount3533The role of the ``fill_silence`` callback is to set the given amount
3554(``count``) of silence data at the specified offset (``pos``) in the3534(``count``) of silence data at the specified offset (``pos``) in the
drivers/firmware/cirrus/cs_dsp.c+2−1
@@ -978,7 +978,8 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, · 977 unmodified lines
978 ctl->alg_region.alg == alg_region->alg &&978 ctl->alg_region.alg == alg_region->alg &&
979 ctl->alg_region.type == alg_region->type) {979 ctl->alg_region.type == alg_region->type) {
980 if ((!subname && !ctl->subname) ||980 if ((!subname && !ctl->subname) ||
981 (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) {981 (subname && (ctl->subname_len == subname_len) &&
982 !strncmp(ctl->subname, subname, ctl->subname_len))) {
982 if (!ctl->enabled)983 if (!ctl->enabled)
983 ctl->enabled = 1;984 ctl->enabled = 1;
984 return 0;985 return 0;
drivers/gpu/drm/vc4/vc4_hdmi.c+5−1
@@ -2615,9 +2615,13 @@ static int vc4_hdmi_audio_cpu_dai_probe(struct snd_soc_dai *dai) · 2614 unmodified lines
2615 return 0;2615 return 0;
2616}2616}
2617 2617
2618static const struct snd_soc_dai_ops vc4_snd_dai_ops = {
2619 .probe = vc4_hdmi_audio_cpu_dai_probe,
2620};
2621
2618static struct snd_soc_dai_driver vc4_hdmi_audio_cpu_dai_drv = {2622static struct snd_soc_dai_driver vc4_hdmi_audio_cpu_dai_drv = {
2619 .name = "vc4-hdmi-cpu-dai",2623 .name = "vc4-hdmi-cpu-dai",
2620 .probe = vc4_hdmi_audio_cpu_dai_probe,2624 .ops = &vc4_snd_dai_ops,
2621 .playback = {2625 .playback = {
2622 .stream_name = "Playback",2626 .stream_name = "Playback",
2623 .channels_min = 1,2627 .channels_min = 1,
drivers/iio/inkern.c+73−13
@@ -5,9 +5,10 @@ · 4 unmodified lines
5 */5 */
6#include <linux/err.h>6#include <linux/err.h>
7#include <linux/export.h>7#include <linux/export.h>
8#include <linux/minmax.h>
9#include <linux/mutex.h>
8#include <linux/property.h>10#include <linux/property.h>
9#include <linux/slab.h>11#include <linux/slab.h>
10#include <linux/mutex.h>
11 12
12#include <linux/iio/iio.h>13#include <linux/iio/iio.h>
13#include <linux/iio/iio-opaque.h>14#include <linux/iio/iio-opaque.h>
@@ -849,15 +850,14 @@ static int iio_channel_read_max(struct iio_channel *chan, · 835 unmodified lines
849 int *val, int *val2, int *type,850 int *val, int *val2, int *type,
850 enum iio_chan_info_enum info)851 enum iio_chan_info_enum info)
851{852{
852 int unused;
853 const int *vals;853 const int *vals;
854 int length;854 int length;
855 int ret;855 int ret;
856 856
857 if (!val2)
858 val2 = &unused;
859
860 ret = iio_channel_read_avail(chan, &vals, type, &length, info);857 ret = iio_channel_read_avail(chan, &vals, type, &length, info);
858 if (ret < 0)
859 return ret;
860
861 switch (ret) {861 switch (ret) {
862 case IIO_AVAIL_RANGE:862 case IIO_AVAIL_RANGE:
863 switch (*type) {863 switch (*type) {
@@ -866,7 +866,8 @@ static int iio_channel_read_max(struct iio_channel *chan, · 2 unmodified lines
866 break;866 break;
867 default:867 default:
868 *val = vals[4];868 *val = vals[4];
869 *val2 = vals[5];869 if (val2)
870 *val2 = vals[5];
870 }871 }
871 return 0;872 return 0;
872 873
@@ -875,20 +876,16 @@ static int iio_channel_read_max(struct iio_channel *chan, · 2 unmodified lines
875 return -EINVAL;876 return -EINVAL;
876 switch (*type) {877 switch (*type) {
877 case IIO_VAL_INT:878 case IIO_VAL_INT:
878 *val = vals[--length];879 *val = max_array(vals, length);
879 while (length) {
880 if (vals[--length] > *val)
881 *val = vals[length];
882 }
883 break;880 break;
884 default:881 default:
885 /* FIXME: learn about max for other iio values */882 /* TODO: learn about max for other iio values */
886 return -EINVAL;883 return -EINVAL;
887 }884 }
888 return 0;885 return 0;
889 886
890 default:887 default:
891 return ret;888 return -EINVAL;
892 }889 }
893}890}
894 891
@@ -912,6 +909,69 @@ err_unlock: · 17 unmodified lines
912}909}
913EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);910EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);
914 911
912static int iio_channel_read_min(struct iio_channel *chan,
913 int *val, int *val2, int *type,
914 enum iio_chan_info_enum info)
915{
916 const int *vals;
917 int length;
918 int ret;
919
920 ret = iio_channel_read_avail(chan, &vals, type, &length, info);
921 if (ret < 0)
922 return ret;
923
924 switch (ret) {
925 case IIO_AVAIL_RANGE:
926 switch (*type) {
927 case IIO_VAL_INT:
928 *val = vals[0];
929 break;
930 default:
931 *val = vals[0];
932 if (val2)
933 *val2 = vals[1];
934 }
935 return 0;
936
937 case IIO_AVAIL_LIST:
938 if (length <= 0)
939 return -EINVAL;
940 switch (*type) {
941 case IIO_VAL_INT:
942 *val = min_array(vals, length);
943 break;
944 default:
945 /* TODO: learn about min for other iio values */
946 return -EINVAL;
947 }
948 return 0;
949
950 default:
951 return -EINVAL;
952 }
953}
954
955int iio_read_min_channel_raw(struct iio_channel *chan, int *val)
956{
957 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
958 int ret;
959 int type;
960
961 mutex_lock(&iio_dev_opaque->info_exist_lock);
962 if (!chan->indio_dev->info) {
963 ret = -ENODEV;
964 goto err_unlock;
965 }
966
967 ret = iio_channel_read_min(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
968err_unlock:
969 mutex_unlock(&iio_dev_opaque->info_exist_lock);
970
971 return ret;
972}
973EXPORT_SYMBOL_GPL(iio_read_min_channel_raw);
974
915int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)975int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
916{976{
917 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);977 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
drivers/media/dvb-core/Makefile+1−1
@@ -8,6 +8,6 @@ dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o · 7 unmodified lines
8 8
9dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \9dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
10 dvb_ca_en50221.o dvb_frontend.o \10 dvb_ca_en50221.o dvb_frontend.o \
11 $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o11 $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y)
12 12
13obj-$(CONFIG_DVB_CORE) += dvb-core.o13obj-$(CONFIG_DVB_CORE) += dvb-core.o
drivers/media/dvb-frontends/af9013_priv.h+1−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
12#define AF9013_PRIV_H12#define AF9013_PRIV_H
13 13
14#include <media/dvb_frontend.h>14#include <media/dvb_frontend.h>
15#include <media/dvb_math.h>15#include <linux/int_log.h>
16#include "af9013.h"16#include "af9013.h"
17#include <linux/firmware.h>17#include <linux/firmware.h>
18#include <linux/i2c-mux.h>18#include <linux/i2c-mux.h>
drivers/media/dvb-frontends/af9033_priv.h+1−1
@@ -14,7 +14,7 @@ · 13 unmodified lines
14#include <linux/math64.h>14#include <linux/math64.h>
15#include <linux/regmap.h>15#include <linux/regmap.h>
16#include <linux/kernel.h>16#include <linux/kernel.h>
17#include <media/dvb_math.h>17#include <linux/int_log.h>
18 18
19struct reg_val {19struct reg_val {
20 u32 reg;20 u32 reg;
drivers/media/dvb-frontends/cxd2820r_priv.h+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11 11
12#include <linux/dvb/version.h>12#include <linux/dvb/version.h>
13#include <media/dvb_frontend.h>13#include <media/dvb_frontend.h>
14#include <media/dvb_math.h>14#include <linux/int_log.h>
15#include "cxd2820r.h"15#include "cxd2820r.h"
16#include <linux/gpio/driver.h> /* For gpio_chip */16#include <linux/gpio/driver.h> /* For gpio_chip */
17#include <linux/math64.h>17#include <linux/math64.h>
drivers/media/dvb-frontends/cxd2841er.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
22#include <linux/dynamic_debug.h>22#include <linux/dynamic_debug.h>
23#include <linux/kernel.h>23#include <linux/kernel.h>
24 24
25#include <media/dvb_math.h>25#include <linux/int_log.h>
26#include <media/dvb_frontend.h>26#include <media/dvb_frontend.h>
27#include "cxd2841er.h"27#include "cxd2841er.h"
28#include "cxd2841er_priv.h"28#include "cxd2841er_priv.h"
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11#include "cxd2880_tnrdmd_dvbt2.h"11#include "cxd2880_tnrdmd_dvbt2.h"
12#include "cxd2880_tnrdmd_dvbt2_mon.h"12#include "cxd2880_tnrdmd_dvbt2_mon.h"
13 13
14#include <media/dvb_math.h>14#include <linux/int_log.h>
15 15
16static const int ref_dbm_1000[4][8] = {16static const int ref_dbm_1000[4][8] = {
17 {-96000, -95000, -94000, -93000, -92000, -92000, -98000, -97000},17 {-96000, -95000, -94000, -93000, -92000, -92000, -98000, -97000},
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11#include "cxd2880_tnrdmd_dvbt.h"11#include "cxd2880_tnrdmd_dvbt.h"
12#include "cxd2880_tnrdmd_dvbt_mon.h"12#include "cxd2880_tnrdmd_dvbt_mon.h"
13 13
14#include <media/dvb_math.h>14#include <linux/int_log.h>
15 15
16static const int ref_dbm_1000[3][5] = {16static const int ref_dbm_1000[3][5] = {
17 {-93000, -91000, -90000, -89000, -88000},17 {-93000, -91000, -90000, -89000, -88000},
drivers/media/dvb-frontends/cxd2880/cxd2880_top.c+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11#include <linux/spi/spi.h>11#include <linux/spi/spi.h>
12 12
13#include <media/dvb_frontend.h>13#include <media/dvb_frontend.h>
14#include <media/dvb_math.h>14#include <linux/int_log.h>
15 15
16#include "cxd2880.h"16#include "cxd2880.h"
17#include "cxd2880_tnrdmd_mon.h"17#include "cxd2880_tnrdmd_mon.h"
drivers/media/dvb-frontends/dib7000p.c+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
13#include <linux/mutex.h>13#include <linux/mutex.h>
14#include <asm/div64.h>14#include <asm/div64.h>
15 15
16#include <media/dvb_math.h>16#include <linux/int_log.h>
17#include <media/dvb_frontend.h>17#include <media/dvb_frontend.h>
18 18
19#include "dib7000p.h"19#include "dib7000p.h"
drivers/media/dvb-frontends/dib8000.c+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
13#include <linux/mutex.h>13#include <linux/mutex.h>
14#include <asm/div64.h>14#include <asm/div64.h>
15 15
16#include <media/dvb_math.h>16#include <linux/int_log.h>
17 17
18#include <media/dvb_frontend.h>18#include <media/dvb_frontend.h>
19 19
drivers/media/dvb-frontends/dib9000.c+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
11#include <linux/i2c.h>11#include <linux/i2c.h>
12#include <linux/mutex.h>12#include <linux/mutex.h>
13 13
14#include <media/dvb_math.h>14#include <linux/int_log.h>
15#include <media/dvb_frontend.h>15#include <media/dvb_frontend.h>
16 16
17#include "dib9000.h"17#include "dib9000.h"
drivers/media/dvb-frontends/drxk_hard.c+1−1
@@ -20,7 +20,7 @@ · 19 unmodified lines
20#include <media/dvb_frontend.h>20#include <media/dvb_frontend.h>
21#include "drxk.h"21#include "drxk.h"
22#include "drxk_hard.h"22#include "drxk_hard.h"
23#include <media/dvb_math.h>23#include <linux/int_log.h>
24 24
25static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);25static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
26static int power_down_qam(struct drxk_state *state);26static int power_down_qam(struct drxk_state *state);
drivers/media/dvb-frontends/lgdt3305.c+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
10#include <asm/div64.h>10#include <asm/div64.h>
11#include <linux/dvb/frontend.h>11#include <linux/dvb/frontend.h>
12#include <linux/slab.h>12#include <linux/slab.h>
13#include <media/dvb_math.h>13#include <linux/int_log.h>
14#include "lgdt3305.h"14#include "lgdt3305.h"
15 15
16static int debug;16static int debug;
drivers/media/dvb-frontends/lgdt3306a.c+1−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
12#include <asm/div64.h>12#include <asm/div64.h>
13#include <linux/kernel.h>13#include <linux/kernel.h>
14#include <linux/dvb/frontend.h>14#include <linux/dvb/frontend.h>
15#include <media/dvb_math.h>15#include <linux/int_log.h>
16#include "lgdt3306a.h"16#include "lgdt3306a.h"
17#include <linux/i2c-mux.h>17#include <linux/i2c-mux.h>
18 18
drivers/media/dvb-frontends/lgdt330x.c+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include <asm/byteorder.h>28#include <asm/byteorder.h>
29 29
30#include <media/dvb_frontend.h>30#include <media/dvb_frontend.h>
31#include <media/dvb_math.h>31#include <linux/int_log.h>
32#include "lgdt330x_priv.h"32#include "lgdt330x_priv.h"
33#include "lgdt330x.h"33#include "lgdt330x.h"
34 34
drivers/media/dvb-frontends/m88ds3103_priv.h+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
10 10
11#include <media/dvb_frontend.h>11#include <media/dvb_frontend.h>
12#include "m88ds3103.h"12#include "m88ds3103.h"
13#include <media/dvb_math.h>13#include <linux/int_log.h>
14#include <linux/firmware.h>14#include <linux/firmware.h>
15#include <linux/i2c-mux.h>15#include <linux/i2c-mux.h>
16#include <linux/regmap.h>16#include <linux/regmap.h>
drivers/media/dvb-frontends/mn88443x.c+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
10#include <linux/gpio/consumer.h>10#include <linux/gpio/consumer.h>
11#include <linux/of_device.h>11#include <linux/of_device.h>
12#include <linux/regmap.h>12#include <linux/regmap.h>
13#include <media/dvb_math.h>13#include <linux/int_log.h>
14 14
15#include "mn88443x.h"15#include "mn88443x.h"
16 16
drivers/media/dvb-frontends/mn88472_priv.h+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
9#define MN88472_PRIV_H9#define MN88472_PRIV_H
10 10
11#include <media/dvb_frontend.h>11#include <media/dvb_frontend.h>
12#include <media/dvb_math.h>12#include <linux/int_log.h>
13#include "mn88472.h"13#include "mn88472.h"
14#include <linux/firmware.h>14#include <linux/firmware.h>
15#include <linux/regmap.h>15#include <linux/regmap.h>
drivers/media/dvb-frontends/mn88473_priv.h+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
9#define MN88473_PRIV_H9#define MN88473_PRIV_H
10 10
11#include <media/dvb_frontend.h>11#include <media/dvb_frontend.h>
12#include <media/dvb_math.h>12#include <linux/int_log.h>
13#include "mn88473.h"13#include "mn88473.h"
14#include <linux/math64.h>14#include <linux/math64.h>
15#include <linux/firmware.h>15#include <linux/firmware.h>
drivers/media/dvb-frontends/or51132.c+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
27#include <linux/slab.h>27#include <linux/slab.h>
28#include <asm/byteorder.h>28#include <asm/byteorder.h>
29 29
30#include <media/dvb_math.h>30#include <linux/int_log.h>
31#include <media/dvb_frontend.h>31#include <media/dvb_frontend.h>
32#include "or51132.h"32#include "or51132.h"
33 33
drivers/media/dvb-frontends/or51211.c+1−1
@@ -26,7 +26,7 @@ · 25 unmodified lines
26#include <linux/slab.h>26#include <linux/slab.h>
27#include <asm/byteorder.h>27#include <asm/byteorder.h>
28 28
29#include <media/dvb_math.h>29#include <linux/int_log.h>
30#include <media/dvb_frontend.h>30#include <media/dvb_frontend.h>
31#include "or51211.h"31#include "or51211.h"
32 32
drivers/media/dvb-frontends/rtl2830_priv.h+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
9#define RTL2830_PRIV_H9#define RTL2830_PRIV_H
10 10
11#include <media/dvb_frontend.h>11#include <media/dvb_frontend.h>
12#include <media/dvb_math.h>12#include <linux/int_log.h>
13#include "rtl2830.h"13#include "rtl2830.h"
14#include <linux/i2c-mux.h>14#include <linux/i2c-mux.h>
15#include <linux/math64.h>15#include <linux/math64.h>
drivers/media/dvb-frontends/rtl2832_priv.h+1−1
@@ -14,7 +14,7 @@ · 13 unmodified lines
14#include <linux/bitops.h>14#include <linux/bitops.h>
15 15
16#include <media/dvb_frontend.h>16#include <media/dvb_frontend.h>
17#include <media/dvb_math.h>17#include <linux/int_log.h>
18#include "rtl2832.h"18#include "rtl2832.h"
19 19
20struct rtl2832_dev {20struct rtl2832_dev {
drivers/media/dvb-frontends/si2165.c+1−1
@@ -19,7 +19,7 @@ · 18 unmodified lines
19#include <linux/regmap.h>19#include <linux/regmap.h>
20 20
21#include <media/dvb_frontend.h>21#include <media/dvb_frontend.h>
22#include <media/dvb_math.h>22#include <linux/int_log.h>
23#include "si2165_priv.h"23#include "si2165_priv.h"
24#include "si2165.h"24#include "si2165.h"
25 25
drivers/media/dvb-frontends/stv0367.c+1−1
@@ -15,7 +15,7 @@ · 14 unmodified lines
15#include <linux/slab.h>15#include <linux/slab.h>
16#include <linux/i2c.h>16#include <linux/i2c.h>
17 17
18#include <media/dvb_math.h>18#include <linux/int_log.h>
19 19
20#include "stv0367.h"20#include "stv0367.h"
21#include "stv0367_defs.h"21#include "stv0367_defs.h"
drivers/media/dvb-frontends/tc90522.c+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
21#include <linux/kernel.h>21#include <linux/kernel.h>
22#include <linux/math64.h>22#include <linux/math64.h>
23#include <linux/dvb/frontend.h>23#include <linux/dvb/frontend.h>
24#include <media/dvb_math.h>24#include <linux/int_log.h>
25#include "tc90522.h"25#include "tc90522.h"
26 26
27#define TC90522_I2C_THRU_REG 0xfe27#define TC90522_I2C_THRU_REG 0xfe
drivers/media/dvb-frontends/tda10048.c+1−1
@@ -16,7 +16,7 @@ · 15 unmodified lines
16#include <linux/math64.h>16#include <linux/math64.h>
17#include <asm/div64.h>17#include <asm/div64.h>
18#include <media/dvb_frontend.h>18#include <media/dvb_frontend.h>
19#include <media/dvb_math.h>19#include <linux/int_log.h>
20#include "tda10048.h"20#include "tda10048.h"
21 21
22#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"22#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
drivers/media/pci/solo6x10/solo6x10-g723.c+6−33
@@ -204,9 +204,9 @@ static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) · 203 unmodified lines
204 return idx * G723_FRAMES_PER_PAGE;204 return idx * G723_FRAMES_PER_PAGE;
205}205}
206 206
207static int snd_solo_pcm_copy_user(struct snd_pcm_substream *ss, int channel,207static int snd_solo_pcm_copy(struct snd_pcm_substream *ss, int channel,
208 unsigned long pos, void __user *dst,208 unsigned long pos, struct iov_iter *dst,
209 unsigned long count)209 unsigned long count)
210{210{
211 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);211 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
212 struct solo_dev *solo_dev = solo_pcm->solo_dev;212 struct solo_dev *solo_dev = solo_pcm->solo_dev;
@@ -223,35 +223,9 @@ static int snd_solo_pcm_copy_user(struct snd_pcm_substream *ss, int channel, · 10 unmodified lines
223 if (err)223 if (err)
224 return err;224 return err;
225 225
226 if (copy_to_user(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES))226 if (copy_to_iter(solo_pcm->g723_buf, G723_PERIOD_BYTES, dst) !=
227 G723_PERIOD_BYTES)
227 return -EFAULT;228 return -EFAULT;
228 dst += G723_PERIOD_BYTES;
229 }
230
231 return 0;
232}
233
234static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel,
235 unsigned long pos, void *dst,
236 unsigned long count)
237{
238 struct solo_snd_pcm *solo_pcm = snd_pcm_substream_chip(ss);
239 struct solo_dev *solo_dev = solo_pcm->solo_dev;
240 int err, i;
241
242 for (i = 0; i < (count / G723_FRAMES_PER_PAGE); i++) {
243 int page = (pos / G723_FRAMES_PER_PAGE) + i;
244
245 err = solo_p2m_dma_t(solo_dev, 0, solo_pcm->g723_dma,
246 SOLO_G723_EXT_ADDR(solo_dev) +
247 (page * G723_PERIOD_BLOCK) +
248 (ss->number * G723_PERIOD_BYTES),
249 G723_PERIOD_BYTES, 0, 0);
250 if (err)
251 return err;
252
253 memcpy(dst, solo_pcm->g723_buf, G723_PERIOD_BYTES);
254 dst += G723_PERIOD_BYTES;
255 }229 }
256 230
257 return 0;231 return 0;
@@ -263,8 +237,7 @@ static const struct snd_pcm_ops snd_solo_pcm_ops = { · 5 unmodified lines
263 .prepare = snd_solo_pcm_prepare,237 .prepare = snd_solo_pcm_prepare,
264 .trigger = snd_solo_pcm_trigger,238 .trigger = snd_solo_pcm_trigger,
265 .pointer = snd_solo_pcm_pointer,239 .pointer = snd_solo_pcm_pointer,
266 .copy_user = snd_solo_pcm_copy_user,240 .copy = snd_solo_pcm_copy,
267 .copy_kernel = snd_solo_pcm_copy_kernel,
268};241};
269 242
270static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol,243static int snd_solo_capture_volume_info(struct snd_kcontrol *kcontrol,
drivers/staging/greybus/audio_codec.c+7−11
@@ -807,7 +807,6 @@ int gbaudio_register_module(struct gbaudio_module_info *module) · 806 unmodified lines
807{807{
808 int ret;808 int ret;
809 struct snd_soc_component *comp;809 struct snd_soc_component *comp;
810 struct snd_card *card;
811 struct gbaudio_jack *jack = NULL;810 struct gbaudio_jack *jack = NULL;
812 811
813 if (!gbcodec) {812 if (!gbcodec) {
@@ -816,21 +815,20 @@ int gbaudio_register_module(struct gbaudio_module_info *module) · 2 unmodified lines
816 }815 }
817 816
818 comp = gbcodec->component;817 comp = gbcodec->component;
819 card = comp->card->snd_card;
820 818
821 down_write(&card->controls_rwsem);819 mutex_lock(&gbcodec->register_mutex);
822 820
823 if (module->num_dais) {821 if (module->num_dais) {
824 dev_err(gbcodec->dev,822 dev_err(gbcodec->dev,
825 "%d:DAIs not supported via gbcodec driver\n",823 "%d:DAIs not supported via gbcodec driver\n",
826 module->num_dais);824 module->num_dais);
827 up_write(&card->controls_rwsem);825 mutex_unlock(&gbcodec->register_mutex);
828 return -EINVAL;826 return -EINVAL;
829 }827 }
830 828
831 ret = gbaudio_init_jack(module, comp->card);829 ret = gbaudio_init_jack(module, comp->card);
832 if (ret) {830 if (ret) {
833 up_write(&card->controls_rwsem);831 mutex_unlock(&gbcodec->register_mutex);
834 return ret;832 return ret;
835 }833 }
836 834
@@ -867,7 +865,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module) · 30 unmodified lines
867 ret = snd_soc_dapm_new_widgets(comp->card);865 ret = snd_soc_dapm_new_widgets(comp->card);
868 dev_dbg(comp->dev, "Registered %s module\n", module->name);866 dev_dbg(comp->dev, "Registered %s module\n", module->name);
869 867
870 up_write(&card->controls_rwsem);868 mutex_unlock(&gbcodec->register_mutex);
871 return ret;869 return ret;
872}870}
873EXPORT_SYMBOL(gbaudio_register_module);871EXPORT_SYMBOL(gbaudio_register_module);
@@ -935,13 +933,12 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module) · 61 unmodified lines
935void gbaudio_unregister_module(struct gbaudio_module_info *module)933void gbaudio_unregister_module(struct gbaudio_module_info *module)
936{934{
937 struct snd_soc_component *comp = gbcodec->component;935 struct snd_soc_component *comp = gbcodec->component;
938 struct snd_card *card = comp->card->snd_card;
939 struct gbaudio_jack *jack, *n;936 struct gbaudio_jack *jack, *n;
940 int mask;937 int mask;
941 938
942 dev_dbg(comp->dev, "Unregister %s module\n", module->name);939 dev_dbg(comp->dev, "Unregister %s module\n", module->name);
943 940
944 down_write(&card->controls_rwsem);941 mutex_lock(&gbcodec->register_mutex);
945 mutex_lock(&gbcodec->lock);942 mutex_lock(&gbcodec->lock);
946 gbaudio_codec_cleanup(module);943 gbaudio_codec_cleanup(module);
947 list_del(&module->list);944 list_del(&module->list);
@@ -978,10 +975,8 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) · 30 unmodified lines
978 dev_dbg(comp->dev, "Removing %d controls\n",975 dev_dbg(comp->dev, "Removing %d controls\n",
979 module->num_controls);976 module->num_controls);
980 /* release control semaphore */977 /* release control semaphore */
981 up_write(&card->controls_rwsem);
982 gbaudio_remove_component_controls(comp, module->controls,978 gbaudio_remove_component_controls(comp, module->controls,
983 module->num_controls);979 module->num_controls);
984 down_write(&card->controls_rwsem);
985 }980 }
986 if (module->dapm_widgets) {981 if (module->dapm_widgets) {
987 dev_dbg(comp->dev, "Removing %d widgets\n",982 dev_dbg(comp->dev, "Removing %d widgets\n",
@@ -992,7 +987,7 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) · 4 unmodified lines
992 987
993 dev_dbg(comp->dev, "Unregistered %s module\n", module->name);988 dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
994 989
995 up_write(&card->controls_rwsem);990 mutex_unlock(&gbcodec->register_mutex);
996}991}
997EXPORT_SYMBOL(gbaudio_unregister_module);992EXPORT_SYMBOL(gbaudio_unregister_module);
998 993
@@ -1012,6 +1007,7 @@ static int gbcodec_probe(struct snd_soc_component *comp) · 13 unmodified lines
1012 info->dev = comp->dev;1007 info->dev = comp->dev;
1013 INIT_LIST_HEAD(&info->module_list);1008 INIT_LIST_HEAD(&info->module_list);
1014 mutex_init(&info->lock);1009 mutex_init(&info->lock);
1010 mutex_init(&info->register_mutex);
1015 INIT_LIST_HEAD(&info->dai_list);1011 INIT_LIST_HEAD(&info->dai_list);
1016 1012
1017 /* init dai_list used to maintain runtime stream info */1013 /* init dai_list used to maintain runtime stream info */
drivers/staging/greybus/audio_codec.h+1−0
@@ -71,6 +71,7 @@ struct gbaudio_codec_info { · 70 unmodified lines
71 /* to maintain runtime stream params for each DAI */71 /* to maintain runtime stream params for each DAI */
72 struct list_head dai_list;72 struct list_head dai_list;
73 struct mutex lock;73 struct mutex lock;
74 struct mutex register_mutex;
74};75};
75 76
76struct gbaudio_widget {77struct gbaudio_widget {
drivers/staging/greybus/audio_helper.c+4−16
@@ -149,7 +149,6 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev, · 148 unmodified lines
149 for (i = 0; i < num_controls; i++) {149 for (i = 0; i < num_controls; i++) {
150 const struct snd_kcontrol_new *control = &controls[i];150 const struct snd_kcontrol_new *control = &controls[i];
151 struct snd_ctl_elem_id id;151 struct snd_ctl_elem_id id;
152 struct snd_kcontrol *kctl;
153 152
154 if (prefix)153 if (prefix)
155 snprintf(id.name, sizeof(id.name), "%s %s", prefix,154 snprintf(id.name, sizeof(id.name), "%s %s", prefix,
@@ -161,17 +160,10 @@ static int gbaudio_remove_controls(struct snd_card *card, struct device *dev, · 5 unmodified lines
161 id.device = control->device;160 id.device = control->device;
162 id.subdevice = control->subdevice;161 id.subdevice = control->subdevice;
163 id.index = control->index;162 id.index = control->index;
164 kctl = snd_ctl_find_id(card, &id);163 err = snd_ctl_remove_id(card, &id);
165 if (!kctl) {164 if (err < 0)
166 dev_err(dev, "Failed to find %s\n", control->name);
167 continue;
168 }
169 err = snd_ctl_remove(card, kctl);
170 if (err < 0) {
171 dev_err(dev, "%d: Failed to remove %s\n", err,165 dev_err(dev, "%d: Failed to remove %s\n", err,
172 control->name);166 control->name);
173 continue;
174 }
175 }167 }
176 return 0;168 return 0;
177}169}
@@ -181,11 +173,7 @@ int gbaudio_remove_component_controls(struct snd_soc_component *component, · 3 unmodified lines
181 unsigned int num_controls)173 unsigned int num_controls)
182{174{
183 struct snd_card *card = component->card->snd_card;175 struct snd_card *card = component->card->snd_card;
184 int err;
185 176
186 down_write(&card->controls_rwsem);177 return gbaudio_remove_controls(card, component->dev, controls,
187 err = gbaudio_remove_controls(card, component->dev, controls,178 num_controls, component->name_prefix);
188 num_controls, component->name_prefix);
189 up_write(&card->controls_rwsem);
190 return err;
191}179}
include/linux/device.h+26−0
@@ -349,6 +349,7 @@ unsigned long devm_get_free_pages(struct device *dev, · 348 unmodified lines
349 gfp_t gfp_mask, unsigned int order);349 gfp_t gfp_mask, unsigned int order);
350void devm_free_pages(struct device *dev, unsigned long addr);350void devm_free_pages(struct device *dev, unsigned long addr);
351 351
352#ifdef CONFIG_HAS_IOMEM
352void __iomem *devm_ioremap_resource(struct device *dev,353void __iomem *devm_ioremap_resource(struct device *dev,
353 const struct resource *res);354 const struct resource *res);
354void __iomem *devm_ioremap_resource_wc(struct device *dev,355void __iomem *devm_ioremap_resource_wc(struct device *dev,
@@ -357,6 +358,31 @@ void __iomem *devm_ioremap_resource_wc(struct device *dev, · 2 unmodified lines
357void __iomem *devm_of_iomap(struct device *dev,358void __iomem *devm_of_iomap(struct device *dev,
358 struct device_node *node, int index,359 struct device_node *node, int index,
359 resource_size_t *size);360 resource_size_t *size);
361#else
362
363static inline
364void __iomem *devm_ioremap_resource(struct device *dev,
365 const struct resource *res)
366{
367 return ERR_PTR(-EINVAL);
368}
369
370static inline
371void __iomem *devm_ioremap_resource_wc(struct device *dev,
372 const struct resource *res)
373{
374 return ERR_PTR(-EINVAL);
375}
376
377static inline
378void __iomem *devm_of_iomap(struct device *dev,
379 struct device_node *node, int index,
380 resource_size_t *size)
381{
382 return ERR_PTR(-EINVAL);
383}
384
385#endif
360 386
361/* allows to add/remove a custom action to devres stack */387/* allows to add/remove a custom action to devres stack */
362void devm_remove_action(struct device *dev, void (*action)(void *), void *data);388void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
include/linux/firmware/imx/dsp.h+0−6
@@ -37,17 +37,11 @@ struct imx_dsp_ipc { · 36 unmodified lines
37 37
38static inline void imx_dsp_set_data(struct imx_dsp_ipc *ipc, void *data)38static inline void imx_dsp_set_data(struct imx_dsp_ipc *ipc, void *data)
39{39{
40 if (!ipc)
41 return;
42
43 ipc->private_data = data;40 ipc->private_data = data;
44}41}
45 42
46static inline void *imx_dsp_get_data(struct imx_dsp_ipc *ipc)43static inline void *imx_dsp_get_data(struct imx_dsp_ipc *ipc)
47{44{
48 if (!ipc)
49 return NULL;
50
51 return ipc->private_data;45 return ipc->private_data;
52}46}
53 47
include/linux/firmware/mediatek/mtk-adsp-ipc.h+0−6
@@ -46,17 +46,11 @@ struct mtk_adsp_ipc { · 45 unmodified lines
46 46
47static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)47static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
48{48{
49 if (!ipc)
50 return;
51
52 ipc->private_data = data;49 ipc->private_data = data;
53}50}
54 51
55static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)52static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
56{53{
57 if (!ipc)
58 return NULL;
59
60 return ipc->private_data;54 return ipc->private_data;
61}55}
62 56
include/linux/iio/consumer.h+27−10
@@ -201,8 +201,9 @@ struct iio_dev · 200 unmodified lines
201 * @chan: The channel being queried.201 * @chan: The channel being queried.
202 * @val: Value read back.202 * @val: Value read back.
203 *203 *
204 * Note raw reads from iio channels are in adc counts and hence204 * Note, if standard units are required, raw reads from iio channels
205 * scale will need to be applied if standard units required.205 * need the offset (default 0) and scale (default 1) to be applied
206 * as (raw + offset) * scale.
206 */207 */
207int iio_read_channel_raw(struct iio_channel *chan,208int iio_read_channel_raw(struct iio_channel *chan,
208 int *val);209 int *val);
@@ -212,8 +213,9 @@ int iio_read_channel_raw(struct iio_channel *chan, · 3 unmodified lines
212 * @chan: The channel being queried.213 * @chan: The channel being queried.
213 * @val: Value read back.214 * @val: Value read back.
214 *215 *
215 * Note raw reads from iio channels are in adc counts and hence216 * Note, if standard units are required, raw reads from iio channels
216 * scale will need to be applied if standard units required.217 * need the offset (default 0) and scale (default 1) to be applied
218 * as (raw + offset) * scale.
217 *219 *
218 * In opposit to the normal iio_read_channel_raw this function220 * In opposit to the normal iio_read_channel_raw this function
219 * returns the average of multiple reads.221 * returns the average of multiple reads.
@@ -281,8 +283,9 @@ int iio_read_channel_attribute(struct iio_channel *chan, int *val, · 61 unmodified lines
281 * @chan: The channel being queried.283 * @chan: The channel being queried.
282 * @val: Value being written.284 * @val: Value being written.
283 *285 *
284 * Note raw writes to iio channels are in dac counts and hence286 * Note that for raw writes to iio channels, if the value provided is
285 * scale will need to be applied if standard units required.287 * in standard units, the affect of the scale and offset must be removed
288 * as (value / scale) - offset.
286 */289 */
287int iio_write_channel_raw(struct iio_channel *chan, int val);290int iio_write_channel_raw(struct iio_channel *chan, int val);
288 291
@@ -292,11 +295,24 @@ int iio_write_channel_raw(struct iio_channel *chan, int val); · 3 unmodified lines
292 * @chan: The channel being queried.295 * @chan: The channel being queried.
293 * @val: Value read back.296 * @val: Value read back.
294 *297 *
295 * Note raw reads from iio channels are in adc counts and hence298 * Note, if standard units are required, raw reads from iio channels
296 * scale will need to be applied if standard units are required.299 * need the offset (default 0) and scale (default 1) to be applied
300 * as (raw + offset) * scale.
297 */301 */
298int iio_read_max_channel_raw(struct iio_channel *chan, int *val);302int iio_read_max_channel_raw(struct iio_channel *chan, int *val);
299 303
304/**
305 * iio_read_min_channel_raw() - read minimum available raw value from a given
306 * channel, i.e. the minimum possible value.
307 * @chan: The channel being queried.
308 * @val: Value read back.
309 *
310 * Note, if standard units are required, raw reads from iio channels
311 * need the offset (default 0) and scale (default 1) to be applied
312 * as (raw + offset) * scale.
313 */
314int iio_read_min_channel_raw(struct iio_channel *chan, int *val);
315
300/**316/**
301 * iio_read_avail_channel_raw() - read available raw values from a given channel317 * iio_read_avail_channel_raw() - read available raw values from a given channel
302 * @chan: The channel being queried.318 * @chan: The channel being queried.
@@ -308,8 +324,9 @@ int iio_read_max_channel_raw(struct iio_channel *chan, int *val); · 5 unmodified lines
308 * For ranges, three vals are always returned; min, step and max.324 * For ranges, three vals are always returned; min, step and max.
309 * For lists, all the possible values are enumerated.325 * For lists, all the possible values are enumerated.
310 *326 *
311 * Note raw available values from iio channels are in adc counts and327 * Note, if standard units are required, raw available values from iio
312 * hence scale will need to be applied if standard units are required.328 * channels need the offset (default 0) and scale (default 1) to be applied
329 * as (raw + offset) * scale.
313 */330 */
314int iio_read_avail_channel_raw(struct iio_channel *chan,331int iio_read_avail_channel_raw(struct iio_channel *chan,
315 const int **vals, int *length);332 const int **vals, int *length);
include/linux/int_log.hrenamed from include/media/dvb_math.h+4−14
@@ -1,22 +1,12 @@
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
1/*2/*
2 * dvb-math provides some complex fixed-point math3 * Provides fixed-point logarithm operations.
3 * operations shared between the dvb related stuff
4 *4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 */6 */
17 7
18#ifndef __DVB_MATH_H8#ifndef __LINUX_INT_LOG_H
19#define __DVB_MATH_H9#define __LINUX_INT_LOG_H
20 10
21#include <linux/types.h>11#include <linux/types.h>
22 12
include/linux/minmax.h+64−0
@@ -134,6 +134,70 @@ · 133 unmodified lines
134 */134 */
135#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)135#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)
136 136
137/*
138 * Remove a const qualifier from integer types
139 * _Generic(foo, type-name: association, ..., default: association) performs a
140 * comparison against the foo type (not the qualified type).
141 * Do not use the const keyword in the type-name as it will not match the
142 * unqualified type of foo.
143 */
144#define __unconst_integer_type_cases(type) \
145 unsigned type: (unsigned type)0, \
146 signed type: (signed type)0
147
148#define __unconst_integer_typeof(x) typeof( \
149 _Generic((x), \
150 char: (char)0, \
151 __unconst_integer_type_cases(char), \
152 __unconst_integer_type_cases(short), \
153 __unconst_integer_type_cases(int), \
154 __unconst_integer_type_cases(long), \
155 __unconst_integer_type_cases(long long), \
156 default: (x)))
157
158/*
159 * Do not check the array parameter using __must_be_array().
160 * In the following legit use-case where the "array" passed is a simple pointer,
161 * __must_be_array() will return a failure.
162 * --- 8< ---
163 * int *buff
164 * ...
165 * min = min_array(buff, nb_items);
166 * --- 8< ---
167 *
168 * The first typeof(&(array)[0]) is needed in order to support arrays of both
169 * 'int *buff' and 'int buff[N]' types.
170 *
171 * The array can be an array of const items.
172 * typeof() keeps the const qualifier. Use __unconst_integer_typeof() in order
173 * to discard the const qualifier for the __element variable.
174 */
175#define __minmax_array(op, array, len) ({ \
176 typeof(&(array)[0]) __array = (array); \
177 typeof(len) __len = (len); \
178 __unconst_integer_typeof(__array[0]) __element = __array[--__len]; \
179 while (__len--) \
180 __element = op(__element, __array[__len]); \
181 __element; })
182
183/**
184 * min_array - return minimum of values present in an array
185 * @array: array
186 * @len: array length
187 *
188 * Note that @len must not be zero (empty array).
189 */
190#define min_array(array, len) __minmax_array(min, array, len)
191
192/**
193 * max_array - return maximum of values present in an array
194 * @array: array
195 * @len: array length
196 *
197 * Note that @len must not be zero (empty array).
198 */
199#define max_array(array, len) __minmax_array(max, array, len)
200
137/**201/**
138 * clamp_t - return a value clamped to a given range using a given type202 * clamp_t - return a value clamped to a given range using a given type
139 * @type: the type of variable to use203 * @type: the type of variable to use
include/linux/pci_ids.h+90−16
@@ -2646,6 +2646,7 @@ · 2645 unmodified lines
2646 2646
2647#define PCI_VENDOR_ID_INTEL 0x80862647#define PCI_VENDOR_ID_INTEL 0x8086
2648#define PCI_DEVICE_ID_INTEL_EESSC 0x00082648#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
2649#define PCI_DEVICE_ID_INTEL_HDA_CML_LP 0x02c8
2649#define PCI_DEVICE_ID_INTEL_PXHD_0 0x03202650#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
2650#define PCI_DEVICE_ID_INTEL_PXHD_1 0x03212651#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321
2651#define PCI_DEVICE_ID_INTEL_PXH_0 0x03292652#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
@@ -2661,8 +2662,10 @@ · 9 unmodified lines
2661#define PCI_DEVICE_ID_INTEL_82424 0x04832662#define PCI_DEVICE_ID_INTEL_82424 0x0483
2662#define PCI_DEVICE_ID_INTEL_82378 0x04842663#define PCI_DEVICE_ID_INTEL_82378 0x0484
2663#define PCI_DEVICE_ID_INTEL_82425 0x04862664#define PCI_DEVICE_ID_INTEL_82425 0x0486
2665#define PCI_DEVICE_ID_INTEL_HDA_CML_H 0x06c8
2664#define PCI_DEVICE_ID_INTEL_MRST_SD0 0x08072666#define PCI_DEVICE_ID_INTEL_MRST_SD0 0x0807
2665#define PCI_DEVICE_ID_INTEL_MRST_SD1 0x08082667#define PCI_DEVICE_ID_INTEL_MRST_SD1 0x0808
2668#define PCI_DEVICE_ID_INTEL_HDA_OAKTRAIL 0x080a
2666#define PCI_DEVICE_ID_INTEL_MFD_SD 0x08202669#define PCI_DEVICE_ID_INTEL_MFD_SD 0x0820
2667#define PCI_DEVICE_ID_INTEL_MFD_SDIO1 0x08212670#define PCI_DEVICE_ID_INTEL_MFD_SDIO1 0x0821
2668#define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x08222671#define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x0822
@@ -2672,15 +2675,19 @@ · 3 unmodified lines
2672#define PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB 0x095e2675#define PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB 0x095e
2673#define PCI_DEVICE_ID_INTEL_I960 0x09602676#define PCI_DEVICE_ID_INTEL_I960 0x0960
2674#define PCI_DEVICE_ID_INTEL_I960RM 0x09622677#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
2678#define PCI_DEVICE_ID_INTEL_HDA_HSW_0 0x0a0c
2679#define PCI_DEVICE_ID_INTEL_HDA_HSW_2 0x0c0c
2675#define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c602680#define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60
2681#define PCI_DEVICE_ID_INTEL_HDA_HSW_3 0x0d0c
2682#define PCI_DEVICE_ID_INTEL_HDA_BYT 0x0f04
2683#define PCI_DEVICE_ID_INTEL_SST_BYT 0x0f28
2676#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x10622684#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
2677#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x10852685#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085
2678#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108f2686#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108f
2679#define PCI_DEVICE_ID_INTEL_82815_MC 0x11302687#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
2680#define PCI_DEVICE_ID_INTEL_82815_CGC 0x11322688#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
2689#define PCI_DEVICE_ID_INTEL_SST_TNG 0x119a
2681#define PCI_DEVICE_ID_INTEL_82092AA_0 0x12212690#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
2682#define PCI_DEVICE_ID_INTEL_7505_0 0x2550
2683#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
2684#define PCI_DEVICE_ID_INTEL_82437 0x122d2691#define PCI_DEVICE_ID_INTEL_82437 0x122d
2685#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e2692#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
2686#define PCI_DEVICE_ID_INTEL_82371FB_1 0x12302693#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
@@ -2706,20 +2713,26 @@ · 19 unmodified lines
2706#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE 0x15762713#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE 0x1576
2707#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI 0x15772714#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI 0x1577
2708#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE 0x15782715#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE 0x1578
2716#define PCI_DEVICE_ID_INTEL_HDA_BDW 0x160c
2709#define PCI_DEVICE_ID_INTEL_80960_RP 0x19602717#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960
2710#define PCI_DEVICE_ID_INTEL_QAT_C3XXX 0x19e22718#define PCI_DEVICE_ID_INTEL_QAT_C3XXX 0x19e2
2711#define PCI_DEVICE_ID_INTEL_QAT_C3XXX_VF 0x19e32719#define PCI_DEVICE_ID_INTEL_QAT_C3XXX_VF 0x19e3
2712#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a212720#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21
2713#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a302721#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
2714#define PCI_DEVICE_ID_INTEL_IOAT 0x1a382722#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38
2723#define PCI_DEVICE_ID_INTEL_HDA_CPT 0x1c20
2715#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c412724#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41
2716#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f2725#define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f
2726#define PCI_DEVICE_ID_INTEL_HDA_PBG 0x1d20
2717#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d402727#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40
2718#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d412728#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41
2729#define PCI_DEVICE_ID_INTEL_HDA_PPT 0x1e20
2719#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e312730#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI 0x1e31
2720#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e402731#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e40
2721#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f2732#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f
2722#define PCI_DEVICE_ID_INTEL_VMD_201D 0x201d2733#define PCI_DEVICE_ID_INTEL_VMD_201D 0x201d
2734#define PCI_DEVICE_ID_INTEL_HDA_BSW 0x2284
2735#define PCI_DEVICE_ID_INTEL_SST_BSW 0x22a8
2723#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x23102736#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN 0x2310
2724#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f2737#define PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX 0x231f
2725#define PCI_DEVICE_ID_INTEL_82801AA_0 0x24102738#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
@@ -2774,6 +2787,8 @@ · 48 unmodified lines
2774#define PCI_DEVICE_ID_INTEL_82850_HB 0x25302787#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530
2775#define PCI_DEVICE_ID_INTEL_82860_HB 0x25312788#define PCI_DEVICE_ID_INTEL_82860_HB 0x2531
2776#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c2789#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c
2790#define PCI_DEVICE_ID_INTEL_7505_0 0x2550
2791#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
2777#define PCI_DEVICE_ID_INTEL_82845G_HB 0x25602792#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560
2778#define PCI_DEVICE_ID_INTEL_82845G_IG 0x25622793#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562
2779#define PCI_DEVICE_ID_INTEL_82865_HB 0x25702794#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
@@ -2795,12 +2810,14 @@ · 15 unmodified lines
2795#define PCI_DEVICE_ID_INTEL_ICH6_0 0x26402810#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640
2796#define PCI_DEVICE_ID_INTEL_ICH6_1 0x26412811#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641
2797#define PCI_DEVICE_ID_INTEL_ICH6_2 0x26422812#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642
2813#define PCI_DEVICE_ID_INTEL_HDA_ICH6 0x2668
2798#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a2814#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a
2799#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d2815#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d
2800#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e2816#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
2801#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f2817#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f
2802#define PCI_DEVICE_ID_INTEL_ESB2_0 0x26702818#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670
2803#define PCI_DEVICE_ID_INTEL_ESB2_14 0x26982819#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
2820#define PCI_DEVICE_ID_INTEL_HDA_ESB2 0x269a
2804#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b2821#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b
2805#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e2822#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e
2806#define PCI_DEVICE_ID_INTEL_82945G_HB 0x27702823#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770
@@ -2808,11 +2825,12 @@ · 1 unmodified line
2808#define PCI_DEVICE_ID_INTEL_3000_HB 0x27782825#define PCI_DEVICE_ID_INTEL_3000_HB 0x2778
2809#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27a02826#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27a0
2810#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27a22827#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27a2
2828#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
2811#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b82829#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
2812#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b92830#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
2813#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
2814#define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc2831#define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc
2815#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd2832#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
2833#define PCI_DEVICE_ID_INTEL_HDA_ICH7 0x27d8
2816#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da2834#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da
2817#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd2835#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
2818#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de2836#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
@@ -2823,17 +2841,20 @@ · 4 unmodified lines
2823#define PCI_DEVICE_ID_INTEL_ICH8_3 0x28142841#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814
2824#define PCI_DEVICE_ID_INTEL_ICH8_4 0x28152842#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815
2825#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e2843#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e
2844#define PCI_DEVICE_ID_INTEL_HDA_ICH8 0x284b
2826#define PCI_DEVICE_ID_INTEL_ICH8_6 0x28502845#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850
2827#define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c02846#define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c0
2828#define PCI_DEVICE_ID_INTEL_ICH9_0 0x29102847#define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910
2829#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917
2830#define PCI_DEVICE_ID_INTEL_ICH9_2 0x29122848#define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912
2831#define PCI_DEVICE_ID_INTEL_ICH9_3 0x29132849#define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913
2832#define PCI_DEVICE_ID_INTEL_ICH9_4 0x29142850#define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914
2833#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
2834#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
2835#define PCI_DEVICE_ID_INTEL_ICH9_7 0x29162851#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
2852#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917
2836#define PCI_DEVICE_ID_INTEL_ICH9_8 0x29182853#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
2854#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
2855#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
2856#define PCI_DEVICE_ID_INTEL_HDA_ICH9_0 0x293e
2857#define PCI_DEVICE_ID_INTEL_HDA_ICH9_1 0x293f
2837#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c182858#define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18
2838#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c192859#define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19
2839#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a2860#define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a
@@ -2850,8 +2871,8 @@ · 10 unmodified lines
2850#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c312871#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR 0x2c31
2851#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c322872#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK 0x2c32
2852#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c332873#define PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC 0x2c33
2853#define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41
2854#define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c402874#define PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT 0x2c40
2875#define PCI_DEVICE_ID_INTEL_I7_NONCORE 0x2c41
2855#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c502876#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE 0x2c50
2856#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c512877#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT 0x2c51
2857#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2 0x2c702878#define PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2 0x2c70
@@ -2885,6 +2906,7 @@ · 27 unmodified lines
2885#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db12906#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2 0x2db1
2886#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db22907#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2 0x2db2
2887#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db32908#define PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2 0x2db3
2909#define PCI_DEVICE_ID_INTEL_HDA_GML 0x3198
2888#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x33402910#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
2889#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x34292911#define PCI_DEVICE_ID_INTEL_IOAT_TBG4 0x3429
2890#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a2912#define PCI_DEVICE_ID_INTEL_IOAT_TBG5 0x342a
@@ -2895,12 +2917,13 @@ · 4 unmodified lines
2895#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x34312917#define PCI_DEVICE_ID_INTEL_IOAT_TBG1 0x3431
2896#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x34322918#define PCI_DEVICE_ID_INTEL_IOAT_TBG2 0x3432
2897#define PCI_DEVICE_ID_INTEL_IOAT_TBG3 0x34332919#define PCI_DEVICE_ID_INTEL_IOAT_TBG3 0x3433
2920#define PCI_DEVICE_ID_INTEL_HDA_ICL_LP 0x34c8
2898#define PCI_DEVICE_ID_INTEL_82830_HB 0x35752921#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
2899#define PCI_DEVICE_ID_INTEL_82830_CGC 0x35772922#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
2900#define PCI_DEVICE_ID_INTEL_82854_HB 0x358c
2901#define PCI_DEVICE_ID_INTEL_82854_IG 0x358e
2902#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x35802923#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
2903#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x35822924#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
2925#define PCI_DEVICE_ID_INTEL_82854_HB 0x358c
2926#define PCI_DEVICE_ID_INTEL_82854_IG 0x358e
2904#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x35902927#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590
2905#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x35922928#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x3592
2906#define PCI_DEVICE_ID_INTEL_MCH_PA 0x35952929#define PCI_DEVICE_ID_INTEL_MCH_PA 0x3595
@@ -2910,11 +2933,11 @@ · 3 unmodified lines
2910#define PCI_DEVICE_ID_INTEL_MCH_PC 0x35992933#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
2911#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a2934#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
2912#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e2935#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
2936#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
2937#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c
2913#define PCI_DEVICE_ID_INTEL_I7300_MCH_ERR 0x360c2938#define PCI_DEVICE_ID_INTEL_I7300_MCH_ERR 0x360c
2914#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB0 0x360f2939#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB0 0x360f
2915#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB1 0x36102940#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB1 0x3610
2916#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
2917#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c
2918#define PCI_DEVICE_ID_INTEL_IOAT_JSF0 0x37102941#define PCI_DEVICE_ID_INTEL_IOAT_JSF0 0x3710
2919#define PCI_DEVICE_ID_INTEL_IOAT_JSF1 0x37112942#define PCI_DEVICE_ID_INTEL_IOAT_JSF1 0x3711
2920#define PCI_DEVICE_ID_INTEL_IOAT_JSF2 0x37122943#define PCI_DEVICE_ID_INTEL_IOAT_JSF2 0x3712
@@ -2927,14 +2950,19 @@ · 6 unmodified lines
2927#define PCI_DEVICE_ID_INTEL_IOAT_JSF9 0x37192950#define PCI_DEVICE_ID_INTEL_IOAT_JSF9 0x3719
2928#define PCI_DEVICE_ID_INTEL_QAT_C62X 0x37c82951#define PCI_DEVICE_ID_INTEL_QAT_C62X 0x37c8
2929#define PCI_DEVICE_ID_INTEL_QAT_C62X_VF 0x37c92952#define PCI_DEVICE_ID_INTEL_QAT_C62X_VF 0x37c9
2953#define PCI_DEVICE_ID_INTEL_HDA_ICL_N 0x38c8
2930#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a142954#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14
2931#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a162955#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16
2932#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a182956#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18
2933#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a2957#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a
2934#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a302958#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30
2959#define PCI_DEVICE_ID_INTEL_HDA_ICH10_0 0x3a3e
2935#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a602960#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60
2961#define PCI_DEVICE_ID_INTEL_HDA_ICH10_1 0x3a6e
2936#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b002962#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00
2937#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f2963#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f
2964#define PCI_DEVICE_ID_INTEL_HDA_5_3400_SERIES_0 0x3b56
2965#define PCI_DEVICE_ID_INTEL_HDA_5_3400_SERIES_1 0x3b57
2938#define PCI_DEVICE_ID_INTEL_IOAT_SNB0 0x3c202966#define PCI_DEVICE_ID_INTEL_IOAT_SNB0 0x3c20
2939#define PCI_DEVICE_ID_INTEL_IOAT_SNB1 0x3c212967#define PCI_DEVICE_ID_INTEL_IOAT_SNB1 0x3c21
2940#define PCI_DEVICE_ID_INTEL_IOAT_SNB2 0x3c222968#define PCI_DEVICE_ID_INTEL_IOAT_SNB2 0x3c22
@@ -2945,16 +2973,12 @@ · 4 unmodified lines
2945#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c272973#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27
2946#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e2974#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e
2947#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f2975#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f
2948#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46
2949#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0
2950#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1
2951#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4
2952#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5
2953#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c412976#define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41
2954#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c422977#define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42
2955#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c432978#define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43
2956#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c442979#define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44
2957#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c452980#define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45
2981#define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46
2958#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS 0x3c71 /* 15.1 */2982#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_RAS 0x3c71 /* 15.1 */
2959#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_ERR0 0x3c72 /* 16.2 */2983#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_ERR0 0x3c72 /* 16.2 */
2960#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_ERR1 0x3c73 /* 16.3 */2984#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_ERR1 0x3c73 /* 16.3 */
@@ -2966,17 +2990,40 @@ · 5 unmodified lines
2966#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1 0x3cab /* 15.3 */2990#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD1 0x3cab /* 15.3 */
2967#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2 0x3cac /* 15.4 */2991#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD2 0x3cac /* 15.4 */
2968#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3 0x3cad /* 15.5 */2992#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_TAD3 0x3cad /* 15.5 */
2993#define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0
2994#define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1
2995#define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4
2996#define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5
2969#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO 0x3cb8 /* 17.0 */2997#define PCI_DEVICE_ID_INTEL_SBRIDGE_IMC_DDRIO 0x3cb8 /* 17.0 */
2970#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce02998#define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0
2971#define PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0 0x3cf4 /* 12.6 */2999#define PCI_DEVICE_ID_INTEL_SBRIDGE_SAD0 0x3cf4 /* 12.6 */
2972#define PCI_DEVICE_ID_INTEL_SBRIDGE_BR 0x3cf5 /* 13.6 */3000#define PCI_DEVICE_ID_INTEL_SBRIDGE_BR 0x3cf5 /* 13.6 */
2973#define PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1 0x3cf6 /* 12.7 */3001#define PCI_DEVICE_ID_INTEL_SBRIDGE_SAD1 0x3cf6 /* 12.7 */
3002#define PCI_DEVICE_ID_INTEL_HDA_ICL_H 0x3dc8
2974#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f3003#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
2975#define PCI_DEVICE_ID_INTEL_5400_ERR 0x40303004#define PCI_DEVICE_ID_INTEL_5400_ERR 0x4030
2976#define PCI_DEVICE_ID_INTEL_5400_FBD0 0x40353005#define PCI_DEVICE_ID_INTEL_5400_FBD0 0x4035
2977#define PCI_DEVICE_ID_INTEL_5400_FBD1 0x40363006#define PCI_DEVICE_ID_INTEL_5400_FBD1 0x4036
3007#define PCI_DEVICE_ID_INTEL_HDA_TGL_H 0x43c8
3008#define PCI_DEVICE_ID_INTEL_HDA_DG1 0x490d
3009#define PCI_DEVICE_ID_INTEL_HDA_EHL_0 0x4b55
3010#define PCI_DEVICE_ID_INTEL_HDA_EHL_3 0x4b58
3011#define PCI_DEVICE_ID_INTEL_HDA_JSL_N 0x4dc8
3012#define PCI_DEVICE_ID_INTEL_HDA_DG2_0 0x4f90
3013#define PCI_DEVICE_ID_INTEL_HDA_DG2_1 0x4f91
3014#define PCI_DEVICE_ID_INTEL_HDA_DG2_2 0x4f92
2978#define PCI_DEVICE_ID_INTEL_EP80579_0 0x50313015#define PCI_DEVICE_ID_INTEL_EP80579_0 0x5031
2979#define PCI_DEVICE_ID_INTEL_EP80579_1 0x50323016#define PCI_DEVICE_ID_INTEL_EP80579_1 0x5032
3017#define PCI_DEVICE_ID_INTEL_HDA_ADL_P 0x51c8
3018#define PCI_DEVICE_ID_INTEL_HDA_ADL_PS 0x51c9
3019#define PCI_DEVICE_ID_INTEL_HDA_RPL_P_0 0x51ca
3020#define PCI_DEVICE_ID_INTEL_HDA_RPL_P_1 0x51cb
3021#define PCI_DEVICE_ID_INTEL_HDA_ADL_M 0x51cc
3022#define PCI_DEVICE_ID_INTEL_HDA_ADL_PX 0x51cd
3023#define PCI_DEVICE_ID_INTEL_HDA_RPL_M 0x51ce
3024#define PCI_DEVICE_ID_INTEL_HDA_RPL_PX 0x51cf
3025#define PCI_DEVICE_ID_INTEL_HDA_ADL_N 0x54c8
3026#define PCI_DEVICE_ID_INTEL_HDA_APL 0x5a98
2980#define PCI_DEVICE_ID_INTEL_5100_16 0x65f03027#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
2981#define PCI_DEVICE_ID_INTEL_5100_19 0x65f33028#define PCI_DEVICE_ID_INTEL_5100_19 0x65f3
2982#define PCI_DEVICE_ID_INTEL_5100_21 0x65f53029#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
@@ -3010,8 +3057,13 @@ · 27 unmodified lines
3010#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a03057#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
3011#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a23058#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
3012#define PCI_DEVICE_ID_INTEL_82372FB_1 0x76013059#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
3060#define PCI_DEVICE_ID_INTEL_HDA_RPL_S 0x7a50
3061#define PCI_DEVICE_ID_INTEL_HDA_ADL_S 0x7ad0
3062#define PCI_DEVICE_ID_INTEL_HDA_MTL 0x7e28
3063#define PCI_DEVICE_ID_INTEL_HDA_ARL_S 0x7f50
3013#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x81193064#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
3014#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a3065#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
3066#define PCI_DEVICE_ID_INTEL_HDA_POULSBO 0x811b
3015#define PCI_DEVICE_ID_INTEL_E6XX_CU 0x81833067#define PCI_DEVICE_ID_INTEL_E6XX_CU 0x8183
3016#define PCI_DEVICE_ID_INTEL_ITC_LPC 0x81863068#define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186
3017#define PCI_DEVICE_ID_INTEL_82454GX 0x84c43069#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
@@ -3020,9 +3072,31 @@ · 2 unmodified lines
3020#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb3072#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
3021#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea3073#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea
3022#define PCI_DEVICE_ID_INTEL_IXP4XX 0x85003074#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
3075#define PCI_DEVICE_ID_INTEL_HDA_LPT 0x8c20
3076#define PCI_DEVICE_ID_INTEL_HDA_9_SERIES 0x8ca0
3077#define PCI_DEVICE_ID_INTEL_HDA_WBG_0 0x8d20
3078#define PCI_DEVICE_ID_INTEL_HDA_WBG_1 0x8d21
3023#define PCI_DEVICE_ID_INTEL_IXP2800 0x90043079#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
3080#define PCI_DEVICE_ID_INTEL_HDA_LKF 0x98c8
3024#define PCI_DEVICE_ID_INTEL_VMD_9A0B 0x9a0b3081#define PCI_DEVICE_ID_INTEL_VMD_9A0B 0x9a0b
3082#define PCI_DEVICE_ID_INTEL_HDA_LPT_LP_0 0x9c20
3083#define PCI_DEVICE_ID_INTEL_HDA_LPT_LP_1 0x9c21
3084#define PCI_DEVICE_ID_INTEL_HDA_WPT_LP 0x9ca0
3085#define PCI_DEVICE_ID_INTEL_HDA_SKL_LP 0x9d70
3086#define PCI_DEVICE_ID_INTEL_HDA_KBL_LP 0x9d71
3087#define PCI_DEVICE_ID_INTEL_HDA_CNL_LP 0x9dc8
3088#define PCI_DEVICE_ID_INTEL_HDA_TGL_LP 0xa0c8
3089#define PCI_DEVICE_ID_INTEL_HDA_SKL 0xa170
3090#define PCI_DEVICE_ID_INTEL_HDA_KBL 0xa171
3091#define PCI_DEVICE_ID_INTEL_HDA_LBG_0 0xa1f0
3092#define PCI_DEVICE_ID_INTEL_HDA_LBG_1 0xa270
3093#define PCI_DEVICE_ID_INTEL_HDA_KBL_H 0xa2f0
3094#define PCI_DEVICE_ID_INTEL_HDA_CNL_H 0xa348
3095#define PCI_DEVICE_ID_INTEL_HDA_CML_S 0xa3f0
3096#define PCI_DEVICE_ID_INTEL_HDA_LNL_P 0xa828
3025#define PCI_DEVICE_ID_INTEL_S21152BB 0xb1523097#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
3098#define PCI_DEVICE_ID_INTEL_HDA_CML_R 0xf0c8
3099#define PCI_DEVICE_ID_INTEL_HDA_RKL_S 0xf1c8
3026 3100
3027#define PCI_VENDOR_ID_WANGXUN 0x80883101#define PCI_VENDOR_ID_WANGXUN 0x8088
3028 3102
include/linux/platform_device.h+28−0
@@ -63,6 +63,8 @@ extern struct resource *platform_get_mem_or_io(struct platform_device *, · 62 unmodified lines
63extern struct device *63extern struct device *
64platform_find_device_by_driver(struct device *start,64platform_find_device_by_driver(struct device *start,
65 const struct device_driver *drv);65 const struct device_driver *drv);
66
67#ifdef CONFIG_HAS_IOMEM
66extern void __iomem *68extern void __iomem *
67devm_platform_get_and_ioremap_resource(struct platform_device *pdev,69devm_platform_get_and_ioremap_resource(struct platform_device *pdev,
68 unsigned int index, struct resource **res);70 unsigned int index, struct resource **res);
@@ -72,6 +74,32 @@ devm_platform_ioremap_resource(struct platform_device *pdev, · 3 unmodified lines
72extern void __iomem *74extern void __iomem *
73devm_platform_ioremap_resource_byname(struct platform_device *pdev,75devm_platform_ioremap_resource_byname(struct platform_device *pdev,
74 const char *name);76 const char *name);
77#else
78
79static inline void __iomem *
80devm_platform_get_and_ioremap_resource(struct platform_device *pdev,
81 unsigned int index, struct resource **res)
82{
83 return ERR_PTR(-EINVAL);
84}
85
86
87static inline void __iomem *
88devm_platform_ioremap_resource(struct platform_device *pdev,
89 unsigned int index)
90{
91 return ERR_PTR(-EINVAL);
92}
93
94static inline void __iomem *
95devm_platform_ioremap_resource_byname(struct platform_device *pdev,
96 const char *name)
97{
98 return ERR_PTR(-EINVAL);
99}
100
101#endif
102
75extern int platform_get_irq(struct platform_device *, unsigned int);103extern int platform_get_irq(struct platform_device *, unsigned int);
76extern int platform_get_irq_optional(struct platform_device *, unsigned int);104extern int platform_get_irq_optional(struct platform_device *, unsigned int);
77extern int platform_irq_count(struct platform_device *);105extern int platform_irq_count(struct platform_device *);
include/linux/soundwire/sdw.h+5−0
@@ -486,6 +486,11 @@ struct sdw_slave_id { · 485 unmodified lines
486 __u8 sdw_version:4;486 __u8 sdw_version:4;
487};487};
488 488
489struct sdw_extended_slave_id {
490 int link_id;
491 struct sdw_slave_id id;
492};
493
489/*494/*
490 * Helper macros to extract the MIPI-defined IDs495 * Helper macros to extract the MIPI-defined IDs
491 *496 *
include/linux/soundwire/sdw_intel.h+1−6
@@ -264,11 +264,6 @@ struct sdw_intel_link_dev; · 263 unmodified lines
264 */264 */
265#define SDW_INTEL_CLK_STOP_BUS_RESET BIT(3)265#define SDW_INTEL_CLK_STOP_BUS_RESET BIT(3)
266 266
267struct sdw_intel_slave_id {
268 int link_id;
269 struct sdw_slave_id id;
270};
271
272struct hdac_bus;267struct hdac_bus;
273 268
274/**269/**
@@ -298,7 +293,7 @@ struct sdw_intel_ctx { · 23 unmodified lines
298 int num_slaves;293 int num_slaves;
299 acpi_handle handle;294 acpi_handle handle;
300 struct sdw_intel_link_dev **ldev;295 struct sdw_intel_link_dev **ldev;
301 struct sdw_intel_slave_id *ids;296 struct sdw_extended_slave_id *ids;
302 struct list_head link_list;297 struct list_head link_list;
303 struct mutex shim_lock; /* lock for access to shared SHIM registers */298 struct mutex shim_lock; /* lock for access to shared SHIM registers */
304 u32 shim_mask;299 u32 shim_mask;
include/sound/compress_driver.h+1−1
@@ -148,7 +148,7 @@ struct snd_compr_ops { · 147 unmodified lines
148 */148 */
149struct snd_compr {149struct snd_compr {
150 const char *name;150 const char *name;
151 struct device dev;151 struct device *dev;
152 struct snd_compr_ops *ops;152 struct snd_compr_ops *ops;
153 void *private_data;153 void *private_data;
154 struct snd_card *card;154 struct snd_card *card;
include/sound/control.h+29−2
@@ -140,8 +140,32 @@ int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); · 139 unmodified lines
140int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);140int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
141void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);141void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
142int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);142int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
143struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);143struct snd_kcontrol *snd_ctl_find_numid_locked(struct snd_card *card, unsigned int numid);
144struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);144struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid);
145struct snd_kcontrol *snd_ctl_find_id_locked(struct snd_card *card, const struct snd_ctl_elem_id *id);
146struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, const struct snd_ctl_elem_id *id);
147
148/**
149 * snd_ctl_find_id_mixer - find the control instance with the given name string
150 * @card: the card instance
151 * @name: the name string
152 *
153 * Finds the control instance with the given name and
154 * @SNDRV_CTL_ELEM_IFACE_MIXER. Other fields are set to zero.
155 *
156 * This is merely a wrapper to snd_ctl_find_id().
157 *
158 * Return: The pointer of the instance if found, or %NULL if not.
159 */
160static inline struct snd_kcontrol *
161snd_ctl_find_id_mixer(struct snd_card *card, const char *name)
162{
163 struct snd_ctl_elem_id id = {};
164
165 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
166 strscpy(id.name, name, sizeof(id.name));
167 return snd_ctl_find_id(card, &id);
168}
145 169
146int snd_ctl_create(struct snd_card *card);170int snd_ctl_create(struct snd_card *card);
147 171
@@ -238,6 +262,9 @@ snd_ctl_add_follower(struct snd_kcontrol *master, struct snd_kcontrol *follower) · 90 unmodified lines
238 return _snd_ctl_add_follower(master, follower, 0);262 return _snd_ctl_add_follower(master, follower, 0);
239}263}
240 264
265int snd_ctl_add_followers(struct snd_card *card, struct snd_kcontrol *master,
266 const char * const *list);
267
241/**268/**
242 * snd_ctl_add_follower_uncached - Add a virtual follower control269 * snd_ctl_add_follower_uncached - Add a virtual follower control
243 * @master: vmaster element270 * @master: vmaster element
include/sound/core.h+2−2
@@ -96,7 +96,7 @@ struct snd_card { · 95 unmodified lines
96 private data */96 private data */
97 struct list_head devices; /* devices */97 struct list_head devices; /* devices */
98 98
99 struct device ctl_dev; /* control device */99 struct device *ctl_dev; /* control device */
100 unsigned int last_numid; /* last used numeric ID */100 unsigned int last_numid; /* last used numeric ID */
101 struct rw_semaphore controls_rwsem; /* controls lock (list and values) */101 struct rw_semaphore controls_rwsem; /* controls lock (list and values) */
102 rwlock_t ctl_files_rwlock; /* ctl_files list lock */102 rwlock_t ctl_files_rwlock; /* ctl_files list lock */
@@ -239,7 +239,7 @@ extern struct dentry *sound_debugfs_root; · 136 unmodified lines
239 239
240void snd_request_card(int card);240void snd_request_card(int card);
241 241
242void snd_device_initialize(struct device *dev, struct snd_card *card);242int snd_device_alloc(struct device **dev_p, struct snd_card *card);
243 243
244int snd_register_device(int type, struct snd_card *card, int dev,244int snd_register_device(int type, struct snd_card *card, int dev,
245 const struct file_operations *f_ops,245 const struct file_operations *f_ops,
include/sound/cs35l41.h+3−2
@@ -829,6 +829,7 @@ enum cs35l41_cspl_mbox_cmd { · 828 unmodified lines
829 CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,829 CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,
830 CSPL_MBOX_CMD_HIBERNATE = 5,830 CSPL_MBOX_CMD_HIBERNATE = 5,
831 CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,831 CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,
832 CSPL_MBOX_CMD_SPK_OUT_ENABLE = 7,
832 CSPL_MBOX_CMD_UNKNOWN_CMD = -1,833 CSPL_MBOX_CMD_UNKNOWN_CMD = -1,
833 CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,834 CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
834};835};
@@ -901,7 +902,7 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap); · 66 unmodified lines
901int cs35l41_init_boost(struct device *dev, struct regmap *regmap,902int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
902 struct cs35l41_hw_cfg *hw_cfg);903 struct cs35l41_hw_cfg *hw_cfg);
903bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);904bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
904int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,905int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type,
905 struct completion *pll_lock);906 int enable, struct completion *pll_lock, bool firmware_running);
906 907
907#endif /* __CS35L41_H */908#endif /* __CS35L41_H */
include/sound/cs35l56.h+27−2
@@ -252,15 +252,40 @@ · 251 unmodified lines
252#define CS35L56_NUM_BULK_SUPPLIES 3252#define CS35L56_NUM_BULK_SUPPLIES 3
253#define CS35L56_NUM_DSP_REGIONS 5253#define CS35L56_NUM_DSP_REGIONS 5
254 254
255struct cs35l56_base {
256 struct device *dev;
257 struct regmap *regmap;
258 int irq;
259 struct mutex irq_lock;
260 u8 rev;
261 bool init_done;
262 bool fw_patched;
263 bool secured;
264 bool can_hibernate;
265 struct gpio_desc *reset_gpio;
266};
267
255extern struct regmap_config cs35l56_regmap_i2c;268extern struct regmap_config cs35l56_regmap_i2c;
256extern struct regmap_config cs35l56_regmap_spi;269extern struct regmap_config cs35l56_regmap_spi;
257extern struct regmap_config cs35l56_regmap_sdw;270extern struct regmap_config cs35l56_regmap_sdw;
258 271
259extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
260extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];272extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
261extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];273extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
262 274
263void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap);275int cs35l56_set_patch(struct cs35l56_base *cs35l56_base);
276int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command);
277int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base);
278int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base);
279void cs35l56_wait_control_port_ready(void);
280void cs35l56_wait_min_reset_pulse(void);
281void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire);
282int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq);
283irqreturn_t cs35l56_irq(int irq, void *data);
284int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base);
285int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
286int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);
287void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
288int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
264int cs35l56_get_bclk_freq_id(unsigned int freq);289int cs35l56_get_bclk_freq_id(unsigned int freq);
265void cs35l56_fill_supply_names(struct regulator_bulk_data *data);290void cs35l56_fill_supply_names(struct regulator_bulk_data *data);
266 291
include/sound/cs42l43.h+17−0
@@ -0,0 +1,17 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * CS42L43 CODEC driver external data
4 *
5 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and
6 * Cirrus Logic International Semiconductor Ltd.
7 */
8
9#ifndef CS42L43_ASOC_EXT_H
10#define CS42L43_ASOC_EXT_H
11
12#define CS42L43_SYSCLK 0
13
14#define CS42L43_SYSCLK_MCLK 0
15#define CS42L43_SYSCLK_SDW 1
16
17#endif /* CS42L43_ASOC_EXT_H */
include/sound/designware_i2s.h+3−0
@@ -21,6 +21,8 @@ struct i2s_clk_config_data { · 20 unmodified lines
21 u32 sample_rate;21 u32 sample_rate;
22};22};
23 23
24struct dw_i2s_dev;
25
24struct i2s_platform_data {26struct i2s_platform_data {
25 #define DWC_I2S_PLAY (1 << 0)27 #define DWC_I2S_PLAY (1 << 0)
26 #define DWC_I2S_RECORD (1 << 1)28 #define DWC_I2S_RECORD (1 << 1)
@@ -42,6 +44,7 @@ struct i2s_platform_data { · 15 unmodified lines
42 void *capture_dma_data;44 void *capture_dma_data;
43 bool (*filter)(struct dma_chan *chan, void *slave);45 bool (*filter)(struct dma_chan *chan, void *slave);
44 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);46 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
47 int (*i2s_pd_init)(struct dw_i2s_dev *dev);
45};48};
46 49
47struct i2s_dma_data {50struct i2s_dma_data {
include/sound/dmaengine_pcm.h+1−1
@@ -142,7 +142,7 @@ struct snd_dmaengine_pcm_config { · 141 unmodified lines
142 struct snd_pcm_substream *substream);142 struct snd_pcm_substream *substream);
143 int (*process)(struct snd_pcm_substream *substream,143 int (*process)(struct snd_pcm_substream *substream,
144 int channel, unsigned long hwoff,144 int channel, unsigned long hwoff,
145 void *buf, unsigned long bytes);145 struct iov_iter *buf, unsigned long bytes);
146 dma_filter_fn compat_filter_fn;146 dma_filter_fn compat_filter_fn;
147 struct device *dma_dev;147 struct device *dma_dev;
148 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];148 const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
include/sound/emu10k1.h+14−6
@@ -902,6 +902,11 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM · 901 unmodified lines
902#define A_TTDA 0x7a /* Tank Table DMA Address */902#define A_TTDA 0x7a /* Tank Table DMA Address */
903#define A_TTDD 0x7b /* Tank Table DMA Data */903#define A_TTDD 0x7b /* Tank Table DMA Data */
904 904
905// In A_FXRT1 & A_FXRT2, the 0x80 bit of each byte completely disables the
906// filter (CVCF_CURRENTFILTER) for the corresponding channel. There is no
907// effect on the volume (CVCF_CURRENTVOLUME) or the interpolator's filter
908// (CCCA_INTERPROM_MASK).
909
905#define A_FXRT2 0x7c910#define A_FXRT2 0x7c
906#define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */911#define A_FXRT_CHANNELE 0x0000003f /* Effects send bus number for channel's effects send E */
907#define A_FXRT_CHANNELF 0x00003f00 /* Effects send bus number for channel's effects send F */912#define A_FXRT_CHANNELF 0x00003f00 /* Effects send bus number for channel's effects send F */
@@ -914,8 +919,6 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM · 6 unmodified lines
914#define A_FXSENDAMOUNT_G_MASK 0x0000FF00919#define A_FXSENDAMOUNT_G_MASK 0x0000FF00
915#define A_FXSENDAMOUNT_H_MASK 0x000000FF920#define A_FXSENDAMOUNT_H_MASK 0x000000FF
916 921
917/* 0x7c, 0x7e "high bit is used for filtering" */
918
919/* The send amounts for this one are the same as used with the emu10k1 */922/* The send amounts for this one are the same as used with the emu10k1 */
920#define A_FXRT1 0x7e923#define A_FXRT1 0x7e
921#define A_FXRT_CHANNELA 0x0000003f924#define A_FXRT_CHANNELA 0x0000003f
@@ -992,6 +995,9 @@ SUB_REG_NC(A_EHC, A_I2S_CAPTURE_RATE, 0x00000e00) /* This sets the capture PCM · 70 unmodified lines
992#define EMU_HANA_WCLOCK_4X 0x10995#define EMU_HANA_WCLOCK_4X 0x10
993#define EMU_HANA_WCLOCK_MULT_RESERVED 0x18996#define EMU_HANA_WCLOCK_MULT_RESERVED 0x18
994 997
998// If the selected external clock source is/becomes invalid or incompatible
999// with the clock multiplier, the clock source is reset to this value, and
1000// a WCLK_CHANGED interrupt is raised.
995#define EMU_HANA_DEFCLOCK 0x06 /* 000000x 1 bits Default Word Clock */1001#define EMU_HANA_DEFCLOCK 0x06 /* 000000x 1 bits Default Word Clock */
996#define EMU_HANA_DEFCLOCK_48K 0x001002#define EMU_HANA_DEFCLOCK_48K 0x00
997#define EMU_HANA_DEFCLOCK_44_1K 0x011003#define EMU_HANA_DEFCLOCK_44_1K 0x01
@@ -1523,10 +1529,10 @@ struct snd_emu10k1_pcm_mixer { · 525 unmodified lines
1523((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)1529((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
1524 1530
1525#define snd_emu10k1_compose_audigy_fxrt1(route) \1531#define snd_emu10k1_compose_audigy_fxrt1(route) \
1526((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 24))1532((unsigned int)route[0] | ((unsigned int)route[1] << 8) | ((unsigned int)route[2] << 16) | ((unsigned int)route[3] << 24) | 0x80808080)
1527 1533
1528#define snd_emu10k1_compose_audigy_fxrt2(route) \1534#define snd_emu10k1_compose_audigy_fxrt2(route) \
1529((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24))1535((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24) | 0x80808080)
1530 1536
1531#define snd_emu10k1_compose_audigy_sendamounts(vol) \1537#define snd_emu10k1_compose_audigy_sendamounts(vol) \
1532(((unsigned int)vol[4] << 24) | ((unsigned int)vol[5] << 16) | ((unsigned int)vol[6] << 8) | (unsigned int)vol[7])1538(((unsigned int)vol[4] << 24) | ((unsigned int)vol[5] << 16) | ((unsigned int)vol[6] << 8) | (unsigned int)vol[7])
@@ -1678,8 +1684,8 @@ struct snd_emu1010 { · 145 unmodified lines
1678 unsigned int clock_fallback;1684 unsigned int clock_fallback;
1679 unsigned int optical_in; /* 0:SPDIF, 1:ADAT */1685 unsigned int optical_in; /* 0:SPDIF, 1:ADAT */
1680 unsigned int optical_out; /* 0:SPDIF, 1:ADAT */1686 unsigned int optical_out; /* 0:SPDIF, 1:ADAT */
1681 struct delayed_work firmware_work;1687 struct work_struct firmware_work;
1682 u32 last_reg;1688 struct work_struct clock_work;
1683};1689};
1684 1690
1685struct snd_emu10k1 {1691struct snd_emu10k1 {
@@ -1754,6 +1760,7 @@ struct snd_emu10k1 { · 68 unmodified lines
1754 struct snd_kcontrol *ctl_efx_send_routing;1760 struct snd_kcontrol *ctl_efx_send_routing;
1755 struct snd_kcontrol *ctl_efx_send_volume;1761 struct snd_kcontrol *ctl_efx_send_volume;
1756 struct snd_kcontrol *ctl_efx_attn;1762 struct snd_kcontrol *ctl_efx_attn;
1763 struct snd_kcontrol *ctl_clock_source;
1757 1764
1758 void (*hwvol_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1765 void (*hwvol_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
1759 void (*capture_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1766 void (*capture_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
@@ -1761,6 +1768,7 @@ struct snd_emu10k1 { · 1 unmodified line
1761 void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1768 void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
1762 void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);1769 void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
1763 void (*dsp_interrupt)(struct snd_emu10k1 *emu);1770 void (*dsp_interrupt)(struct snd_emu10k1 *emu);
1771 void (*gpio_interrupt)(struct snd_emu10k1 *emu);
1764 void (*p16v_interrupt)(struct snd_emu10k1 *emu);1772 void (*p16v_interrupt)(struct snd_emu10k1 *emu);
1765 1773
1766 struct snd_pcm_substream *pcm_capture_substream;1774 struct snd_pcm_substream *pcm_capture_substream;
include/sound/hda-mlink.h+4−0
@@ -42,6 +42,7 @@ int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, i · 41 unmodified lines
42int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink);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);43int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
44 44
45int hdac_bus_eml_sdw_get_lsdiid_unlocked(struct hdac_bus *bus, int sublink, u16 *lsdiid);
45int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);46int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
46 47
47int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,48int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
@@ -145,6 +146,9 @@ hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink) { return 0 · 97 unmodified lines
145static inline int146static inline int
146hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }147hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return 0; }
147 148
149static inline int
150hdac_bus_eml_sdw_get_lsdiid_unlocked(struct hdac_bus *bus, int sublink, u16 *lsdiid) { return 0; }
151
148static inline int152static inline int
149hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }153hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
150 154
include/sound/hda_codec.h+0−3
@@ -18,9 +18,6 @@ · 17 unmodified lines
18#include <sound/hda_verbs.h>18#include <sound/hda_verbs.h>
19#include <sound/hda_regmap.h>19#include <sound/hda_regmap.h>
20 20
21#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
22#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
23
24/*21/*
25 * Structures22 * Structures
26 */23 */
include/sound/hdaudio.h+26−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/io.h>11#include <linux/io.h>
12#include <linux/io-64-nonatomic-lo-hi.h>12#include <linux/io-64-nonatomic-lo-hi.h>
13#include <linux/iopoll.h>13#include <linux/iopoll.h>
14#include <linux/pci.h>
14#include <linux/pm_runtime.h>15#include <linux/pm_runtime.h>
15#include <linux/timecounter.h>16#include <linux/timecounter.h>
16#include <sound/core.h>17#include <sound/core.h>
@@ -704,4 +705,29 @@ static inline unsigned int snd_array_index(struct snd_array *array, void *ptr) · 687 unmodified lines
704 for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \705 for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \
705 (ptr) = snd_array_elem(array, ++(idx)))706 (ptr) = snd_array_elem(array, ++(idx)))
706 707
708/*
709 * Device matching
710 */
711
712#define HDA_CONTROLLER_IS_HSW(pci) (pci_match_id((struct pci_device_id []){ \
713 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_HSW_0) }, \
714 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_HSW_2) }, \
715 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_HSW_3) }, \
716 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_BDW) }, \
717 { } \
718 }, pci))
719
720#define HDA_CONTROLLER_IS_APL(pci) (pci_match_id((struct pci_device_id []){ \
721 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_APL) }, \
722 { } \
723 }, pci))
724
725#define HDA_CONTROLLER_IN_GPU(pci) (pci_match_id((struct pci_device_id []){ \
726 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_DG1) }, \
727 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_DG2_0) }, \
728 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_DG2_1) }, \
729 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HDA_DG2_2) }, \
730 { } \
731 }, pci) || HDA_CONTROLLER_IS_HSW(pci))
732
707#endif /* __SOUND_HDAUDIO_H */733#endif /* __SOUND_HDAUDIO_H */
include/sound/hwdep.h+1−1
@@ -53,7 +53,7 @@ struct snd_hwdep { · 52 unmodified lines
53 wait_queue_head_t open_wait;53 wait_queue_head_t open_wait;
54 void *private_data;54 void *private_data;
55 void (*private_free) (struct snd_hwdep *hwdep);55 void (*private_free) (struct snd_hwdep *hwdep);
56 struct device dev;56 struct device *dev;
57 57
58 struct mutex open_mutex;58 struct mutex open_mutex;
59 int used; /* reference counter */59 int used; /* reference counter */
include/sound/info.h+0−2
@@ -118,8 +118,6 @@ struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card, · 117 unmodified lines
118 const char *name,118 const char *name,
119 struct snd_info_entry *parent);119 struct snd_info_entry *parent);
120void snd_info_free_entry(struct snd_info_entry *entry);120void snd_info_free_entry(struct snd_info_entry *entry);
121int snd_info_store_text(struct snd_info_entry *entry);
122int snd_info_restore_text(struct snd_info_entry *entry);
123 121
124int snd_info_card_create(struct snd_card *card);122int snd_info_card_create(struct snd_card *card);
125int snd_info_card_register(struct snd_card *card);123int snd_info_card_register(struct snd_card *card);
include/sound/l3.h+0−28
@@ -1,28 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _L3_H_
3#define _L3_H_ 1
4
5struct l3_pins {
6 void (*setdat)(struct l3_pins *, int);
7 void (*setclk)(struct l3_pins *, int);
8 void (*setmode)(struct l3_pins *, int);
9
10 int gpio_data;
11 int gpio_clk;
12 int gpio_mode;
13 int use_gpios;
14
15 int data_hold;
16 int data_setup;
17 int clock_high;
18 int mode_hold;
19 int mode;
20 int mode_setup;
21};
22
23struct device;
24
25int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
26int l3_set_gpio_ops(struct device *dev, struct l3_pins *adap);
27
28#endif
include/sound/pcm.h+9−6
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/bitops.h>16#include <linux/bitops.h>
17#include <linux/pm_qos.h>17#include <linux/pm_qos.h>
18#include <linux/refcount.h>18#include <linux/refcount.h>
19#include <linux/uio.h>
19 20
20#define snd_pcm_substream_chip(substream) ((substream)->private_data)21#define snd_pcm_substream_chip(substream) ((substream)->private_data)
21#define snd_pcm_chip(pcm) ((pcm)->private_data)22#define snd_pcm_chip(pcm) ((pcm)->private_data)
@@ -68,11 +69,8 @@ struct snd_pcm_ops { · 46 unmodified lines
68 struct snd_pcm_audio_tstamp_report *audio_tstamp_report);69 struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
69 int (*fill_silence)(struct snd_pcm_substream *substream, int channel,70 int (*fill_silence)(struct snd_pcm_substream *substream, int channel,
70 unsigned long pos, unsigned long bytes);71 unsigned long pos, unsigned long bytes);
71 int (*copy_user)(struct snd_pcm_substream *substream, int channel,72 int (*copy)(struct snd_pcm_substream *substream, int channel,
72 unsigned long pos, void __user *buf,73 unsigned long pos, struct iov_iter *iter, unsigned long bytes);
73 unsigned long bytes);
74 int (*copy_kernel)(struct snd_pcm_substream *substream, int channel,
75 unsigned long pos, void *buf, unsigned long bytes);
76 struct page *(*page)(struct snd_pcm_substream *substream,74 struct page *(*page)(struct snd_pcm_substream *substream,
77 unsigned long offset);75 unsigned long offset);
78 int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);76 int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
@@ -510,7 +508,7 @@ struct snd_pcm_str { · 431 unmodified lines
510#endif508#endif
511#endif509#endif
512 struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */510 struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
513 struct device dev;511 struct device *dev;
514};512};
515 513
516struct snd_pcm {514struct snd_pcm {
@@ -1556,6 +1554,11 @@ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) · 1039 unmodified lines
1556#define pcm_dbg(pcm, fmt, args...) \1554#define pcm_dbg(pcm, fmt, args...) \
1557 dev_dbg((pcm)->card->dev, fmt, ##args)1555 dev_dbg((pcm)->card->dev, fmt, ##args)
1558 1556
1557/* helpers for copying between iov_iter and iomem */
1558int copy_to_iter_fromio(struct iov_iter *itert, const void __iomem *src,
1559 size_t count);
1560int copy_from_iter_toio(void __iomem *dst, struct iov_iter *iter, size_t count);
1561
1559struct snd_pcm_status64 {1562struct snd_pcm_status64 {
1560 snd_pcm_state_t state; /* stream state */1563 snd_pcm_state_t state; /* stream state */
1561 u8 rsvd[4];1564 u8 rsvd[4];
include/sound/rawmidi.h+1−1
@@ -135,7 +135,7 @@ struct snd_rawmidi { · 134 unmodified lines
135 struct mutex open_mutex;135 struct mutex open_mutex;
136 wait_queue_head_t open_wait;136 wait_queue_head_t open_wait;
137 137
138 struct device dev;138 struct device *dev;
139 139
140 struct snd_info_entry *proc_entry;140 struct snd_info_entry *proc_entry;
141 141
include/sound/rt5665.h+0−2
@@ -31,8 +31,6 @@ struct rt5665_platform_data { · 30 unmodified lines
31 bool in3_diff;31 bool in3_diff;
32 bool in4_diff;32 bool in4_diff;
33 33
34 int ldo1_en; /* GPIO for LDO1_EN */
35
36 enum rt5665_dmic1_data_pin dmic1_data_pin;34 enum rt5665_dmic1_data_pin dmic1_data_pin;
37 enum rt5665_dmic2_data_pin dmic2_data_pin;35 enum rt5665_dmic2_data_pin dmic2_data_pin;
38 enum rt5665_jd_src jd_src;36 enum rt5665_jd_src jd_src;
include/sound/rt5668.h+0−3
@@ -25,9 +25,6 @@ enum rt5668_jd_src { · 24 unmodified lines
25};25};
26 26
27struct rt5668_platform_data {27struct rt5668_platform_data {
28
29 int ldo1_en; /* GPIO for LDO1_EN */
30
31 enum rt5668_dmic1_data_pin dmic1_data_pin;28 enum rt5668_dmic1_data_pin dmic1_data_pin;
32 enum rt5668_dmic1_clk_pin dmic1_clk_pin;29 enum rt5668_dmic1_clk_pin dmic1_clk_pin;
33 enum rt5668_jd_src jd_src;30 enum rt5668_jd_src jd_src;
include/sound/rt5682.h+0−3
@@ -31,9 +31,6 @@ enum rt5682_dai_clks { · 30 unmodified lines
31};31};
32 32
33struct rt5682_platform_data {33struct rt5682_platform_data {
34
35 int ldo1_en; /* GPIO for LDO1_EN */
36
37 enum rt5682_dmic1_data_pin dmic1_data_pin;34 enum rt5682_dmic1_data_pin dmic1_data_pin;
38 enum rt5682_dmic1_clk_pin dmic1_clk_pin;35 enum rt5682_dmic1_clk_pin dmic1_clk_pin;
39 enum rt5682_jd_src jd_src;36 enum rt5682_jd_src jd_src;
include/sound/rt5682s.h+0−3
@@ -32,9 +32,6 @@ enum rt5682s_dai_clks { · 31 unmodified lines
32};32};
33 33
34struct rt5682s_platform_data {34struct rt5682s_platform_data {
35
36 int ldo1_en; /* GPIO for LDO1_EN */
37
38 enum rt5682s_dmic1_data_pin dmic1_data_pin;35 enum rt5682s_dmic1_data_pin dmic1_data_pin;
39 enum rt5682s_dmic1_clk_pin dmic1_clk_pin;36 enum rt5682s_dmic1_clk_pin dmic1_clk_pin;
40 enum rt5682s_jd_src jd_src;37 enum rt5682s_jd_src jd_src;
include/sound/simple_card_utils.h+2−3
@@ -192,9 +192,8 @@ int asoc_simple_remove(struct platform_device *pdev); · 191 unmodified lines
192 192
193int asoc_graph_card_probe(struct snd_soc_card *card);193int asoc_graph_card_probe(struct snd_soc_card *card);
194int asoc_graph_is_ports0(struct device_node *port);194int asoc_graph_is_ports0(struct device_node *port);
195int asoc_graph_parse_dai(struct device_node *ep,195int asoc_graph_parse_dai(struct device *dev, struct device_node *ep,
196 struct snd_soc_dai_link_component *dlc,196 struct snd_soc_dai_link_component *dlc, int *is_single_link);
197 int *is_single_link);
198 197
199#ifdef DEBUG198#ifdef DEBUG
200static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,199static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
include/sound/soc-acpi.h+7−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/stddef.h>9#include <linux/stddef.h>
10#include <linux/acpi.h>10#include <linux/acpi.h>
11#include <linux/mod_devicetable.h>11#include <linux/mod_devicetable.h>
12#include <linux/soundwire/sdw.h>
12 13
13struct snd_soc_acpi_package_context {14struct snd_soc_acpi_package_context {
14 char *name; /* package name */15 char *name; /* package name */
@@ -150,6 +151,7 @@ struct snd_soc_acpi_link_adr { · 135 unmodified lines
150 * all firmware/topology related fields.151 * all firmware/topology related fields.
151 *152 *
152 * @id: ACPI ID (usually the codec's) used to find a matching machine driver.153 * @id: ACPI ID (usually the codec's) used to find a matching machine driver.
154 * @uid: ACPI Unique ID, can be used to disambiguate matches.
153 * @comp_ids: list of compatible audio codecs using the same machine driver,155 * @comp_ids: list of compatible audio codecs using the same machine driver,
154 * firmware and topology156 * firmware and topology
155 * @link_mask: describes required board layout, e.g. for SoundWire.157 * @link_mask: describes required board layout, e.g. for SoundWire.
@@ -208,4 +210,9 @@ static inline bool snd_soc_acpi_sof_parent(struct device *dev) · 52 unmodified lines
208 !strncmp(dev->parent->driver->name, "sof-audio-acpi", strlen("sof-audio-acpi"));210 !strncmp(dev->parent->driver->name, "sof-audio-acpi", strlen("sof-audio-acpi"));
209}211}
210 212
213bool snd_soc_acpi_sdw_link_slaves_found(struct device *dev,
214 const struct snd_soc_acpi_link_adr *link,
215 struct sdw_extended_slave_id *ids,
216 int num_slaves);
217
211#endif218#endif
include/sound/soc-component.h+7−7
@@ -137,10 +137,10 @@ struct snd_soc_component_driver { · 136 unmodified lines
137 struct timespec64 *audio_ts,137 struct timespec64 *audio_ts,
138 struct snd_pcm_audio_tstamp_config *audio_tstamp_config,138 struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
139 struct snd_pcm_audio_tstamp_report *audio_tstamp_report);139 struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
140 int (*copy_user)(struct snd_soc_component *component,140 int (*copy)(struct snd_soc_component *component,
141 struct snd_pcm_substream *substream, int channel,141 struct snd_pcm_substream *substream, int channel,
142 unsigned long pos, void __user *buf,142 unsigned long pos, struct iov_iter *buf,
143 unsigned long bytes);143 unsigned long bytes);
144 struct page *(*page)(struct snd_soc_component *component,144 struct page *(*page)(struct snd_soc_component *component,
145 struct snd_pcm_substream *substream,145 struct snd_pcm_substream *substream,
146 unsigned long offset);146 unsigned long offset);
@@ -509,9 +509,9 @@ int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream); · 362 unmodified lines
509int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,509int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
510 unsigned int cmd, void *arg);510 unsigned int cmd, void *arg);
511int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);511int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);
512int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,512int snd_soc_pcm_component_copy(struct snd_pcm_substream *substream,
513 int channel, unsigned long pos,513 int channel, unsigned long pos,
514 void __user *buf, unsigned long bytes);514 struct iov_iter *buf, unsigned long bytes);
515struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,515struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
516 unsigned long offset);516 unsigned long offset);
517int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,517int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
include/sound/soc-dai.h+16−13
@@ -271,7 +271,18 @@ int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai, · 270 unmodified lines
271 struct snd_compr_stream *cstream,271 struct snd_compr_stream *cstream,
272 struct snd_compr_metadata *metadata);272 struct snd_compr_metadata *metadata);
273 273
274const char *snd_soc_dai_name_get(struct snd_soc_dai *dai);
275
274struct snd_soc_dai_ops {276struct snd_soc_dai_ops {
277 /* DAI driver callbacks */
278 int (*probe)(struct snd_soc_dai *dai);
279 int (*remove)(struct snd_soc_dai *dai);
280 /* compress dai */
281 int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
282 /* Optional Callback used at pcm creation*/
283 int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
284 struct snd_soc_dai *dai);
285
275 /*286 /*
276 * DAI clocking configuration, all optional.287 * DAI clocking configuration, all optional.
277 * Called by soc_card drivers, normally in their hw_params.288 * Called by soc_card drivers, normally in their hw_params.
@@ -353,6 +364,10 @@ struct snd_soc_dai_ops { · 75 unmodified lines
353 u64 *auto_selectable_formats;364 u64 *auto_selectable_formats;
354 int num_auto_selectable_formats;365 int num_auto_selectable_formats;
355 366
367 /* probe ordering - for components with runtime dependencies */
368 int probe_order;
369 int remove_order;
370
356 /* bit field */371 /* bit field */
357 unsigned int no_capture_mute:1;372 unsigned int no_capture_mute:1;
358};373};
@@ -397,15 +412,7 @@ struct snd_soc_dai_driver { · 38 unmodified lines
397 unsigned int id;412 unsigned int id;
398 unsigned int base;413 unsigned int base;
399 struct snd_soc_dobj dobj;414 struct snd_soc_dobj dobj;
400 415 struct of_phandle_args *dai_args;
401 /* DAI driver callbacks */
402 int (*probe)(struct snd_soc_dai *dai);
403 int (*remove)(struct snd_soc_dai *dai);
404 /* compress dai */
405 int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
406 /* Optional Callback used at pcm creation*/
407 int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
408 struct snd_soc_dai *dai);
409 416
410 /* ops */417 /* ops */
411 const struct snd_soc_dai_ops *ops;418 const struct snd_soc_dai_ops *ops;
@@ -417,10 +424,6 @@ struct snd_soc_dai_driver { · 5 unmodified lines
417 unsigned int symmetric_rate:1;424 unsigned int symmetric_rate:1;
418 unsigned int symmetric_channels:1;425 unsigned int symmetric_channels:1;
419 unsigned int symmetric_sample_bits:1;426 unsigned int symmetric_sample_bits:1;
420
421 /* probe ordering - for components with runtime dependencies */
422 int probe_order;
423 int remove_order;
424};427};
425 428
426/* for Playback/Capture */429/* for Playback/Capture */
include/sound/soc-dapm.h+93−46
@@ -42,36 +42,45 @@ struct soc_enum; · 41 unmodified lines
42 42
43/* codec domain */43/* codec domain */
44#define SND_SOC_DAPM_VMID(wname) \44#define SND_SOC_DAPM_VMID(wname) \
45{ .id = snd_soc_dapm_vmid, .name = wname, .kcontrol_news = NULL, \45(struct snd_soc_dapm_widget) { \
46 .id = snd_soc_dapm_vmid, .name = wname, .kcontrol_news = NULL, \
46 .num_kcontrols = 0}47 .num_kcontrols = 0}
47 48
48/* platform domain */49/* platform domain */
49#define SND_SOC_DAPM_SIGGEN(wname) \50#define SND_SOC_DAPM_SIGGEN(wname) \
50{ .id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \51(struct snd_soc_dapm_widget) { \
52 .id = snd_soc_dapm_siggen, .name = wname, .kcontrol_news = NULL, \
51 .num_kcontrols = 0, .reg = SND_SOC_NOPM }53 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
52#define SND_SOC_DAPM_SINK(wname) \54#define SND_SOC_DAPM_SINK(wname) \
53{ .id = snd_soc_dapm_sink, .name = wname, .kcontrol_news = NULL, \55(struct snd_soc_dapm_widget) { \
56 .id = snd_soc_dapm_sink, .name = wname, .kcontrol_news = NULL, \
54 .num_kcontrols = 0, .reg = SND_SOC_NOPM }57 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
55#define SND_SOC_DAPM_INPUT(wname) \58#define SND_SOC_DAPM_INPUT(wname) \
56{ .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \59(struct snd_soc_dapm_widget) { \
60 .id = snd_soc_dapm_input, .name = wname, .kcontrol_news = NULL, \
57 .num_kcontrols = 0, .reg = SND_SOC_NOPM }61 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
58#define SND_SOC_DAPM_OUTPUT(wname) \62#define SND_SOC_DAPM_OUTPUT(wname) \
59{ .id = snd_soc_dapm_output, .name = wname, .kcontrol_news = NULL, \63(struct snd_soc_dapm_widget) { \
64 .id = snd_soc_dapm_output, .name = wname, .kcontrol_news = NULL, \
60 .num_kcontrols = 0, .reg = SND_SOC_NOPM }65 .num_kcontrols = 0, .reg = SND_SOC_NOPM }
61#define SND_SOC_DAPM_MIC(wname, wevent) \66#define SND_SOC_DAPM_MIC(wname, wevent) \
62{ .id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \67(struct snd_soc_dapm_widget) { \
68 .id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \
63 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \69 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
64 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}70 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
65#define SND_SOC_DAPM_HP(wname, wevent) \71#define SND_SOC_DAPM_HP(wname, wevent) \
66{ .id = snd_soc_dapm_hp, .name = wname, .kcontrol_news = NULL, \72(struct snd_soc_dapm_widget) { \
73 .id = snd_soc_dapm_hp, .name = wname, .kcontrol_news = NULL, \
67 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \74 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
68 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}75 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
69#define SND_SOC_DAPM_SPK(wname, wevent) \76#define SND_SOC_DAPM_SPK(wname, wevent) \
70{ .id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \77(struct snd_soc_dapm_widget) { \
78 .id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
71 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \79 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
72 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}80 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
73#define SND_SOC_DAPM_LINE(wname, wevent) \81#define SND_SOC_DAPM_LINE(wname, wevent) \
74{ .id = snd_soc_dapm_line, .name = wname, .kcontrol_news = NULL, \82(struct snd_soc_dapm_widget) { \
83 .id = snd_soc_dapm_line, .name = wname, .kcontrol_news = NULL, \
75 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \84 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
76 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}85 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD}
77 86
@@ -82,93 +91,110 @@ struct soc_enum; · 4 unmodified lines
82/* path domain */91/* path domain */
83#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\92#define SND_SOC_DAPM_PGA(wname, wreg, wshift, winvert,\
84 wcontrols, wncontrols) \93 wcontrols, wncontrols) \
85{ .id = snd_soc_dapm_pga, .name = wname, \94(struct snd_soc_dapm_widget) { \
95 .id = snd_soc_dapm_pga, .name = wname, \
86 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \96 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
87 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}97 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
88#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\98#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\
89 wcontrols, wncontrols) \99 wcontrols, wncontrols) \
90{ .id = snd_soc_dapm_out_drv, .name = wname, \100(struct snd_soc_dapm_widget) { \
101 .id = snd_soc_dapm_out_drv, .name = wname, \
91 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \102 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
92 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}103 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
93#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \104#define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \
94 wcontrols, wncontrols)\105 wcontrols, wncontrols)\
95{ .id = snd_soc_dapm_mixer, .name = wname, \106(struct snd_soc_dapm_widget) { \
107 .id = snd_soc_dapm_mixer, .name = wname, \
96 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \108 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
97 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}109 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
98#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \110#define SND_SOC_DAPM_MIXER_NAMED_CTL(wname, wreg, wshift, winvert, \
99 wcontrols, wncontrols)\111 wcontrols, wncontrols)\
100{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \112(struct snd_soc_dapm_widget) { \
113 .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
101 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \114 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
102 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}115 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols}
103/* DEPRECATED: use SND_SOC_DAPM_SUPPLY */116/* DEPRECATED: use SND_SOC_DAPM_SUPPLY */
104#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \117#define SND_SOC_DAPM_MICBIAS(wname, wreg, wshift, winvert) \
105{ .id = snd_soc_dapm_micbias, .name = wname, \118(struct snd_soc_dapm_widget) { \
119 .id = snd_soc_dapm_micbias, .name = wname, \
106 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \120 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
107 .kcontrol_news = NULL, .num_kcontrols = 0}121 .kcontrol_news = NULL, .num_kcontrols = 0}
108#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \122#define SND_SOC_DAPM_SWITCH(wname, wreg, wshift, winvert, wcontrols) \
109{ .id = snd_soc_dapm_switch, .name = wname, \123(struct snd_soc_dapm_widget) { \
124 .id = snd_soc_dapm_switch, .name = wname, \
110 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \125 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
111 .kcontrol_news = wcontrols, .num_kcontrols = 1}126 .kcontrol_news = wcontrols, .num_kcontrols = 1}
112#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \127#define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \
113{ .id = snd_soc_dapm_mux, .name = wname, \128(struct snd_soc_dapm_widget) { \
129 .id = snd_soc_dapm_mux, .name = wname, \
114 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \130 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
115 .kcontrol_news = wcontrols, .num_kcontrols = 1}131 .kcontrol_news = wcontrols, .num_kcontrols = 1}
116#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \132#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \
117{ .id = snd_soc_dapm_demux, .name = wname, \133(struct snd_soc_dapm_widget) { \
134 .id = snd_soc_dapm_demux, .name = wname, \
118 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \135 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
119 .kcontrol_news = wcontrols, .num_kcontrols = 1}136 .kcontrol_news = wcontrols, .num_kcontrols = 1}
120 137
121/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */138/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
122#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\139#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
123 wcontrols) \140 wcontrols) \
124{ .id = snd_soc_dapm_pga, .name = wname, \141(struct snd_soc_dapm_widget) { \
142 .id = snd_soc_dapm_pga, .name = wname, \
125 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \143 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
126 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}144 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
127#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \145#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
128 wcontrols)\146 wcontrols)\
129{ .id = snd_soc_dapm_mixer, .name = wname, \147(struct snd_soc_dapm_widget) { \
148 .id = snd_soc_dapm_mixer, .name = wname, \
130 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \149 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
131 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}150 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
132#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \151#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
133 wcontrols)\152 wcontrols)\
134{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \153(struct snd_soc_dapm_widget) { \
154 .id = snd_soc_dapm_mixer_named_ctl, .name = wname, \
135 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \155 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
136 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}156 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
137 157
138/* path domain with event - event handler must return 0 for success */158/* path domain with event - event handler must return 0 for success */
139#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \159#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
140 wncontrols, wevent, wflags) \160 wncontrols, wevent, wflags) \
141{ .id = snd_soc_dapm_pga, .name = wname, \161(struct snd_soc_dapm_widget) { \
162 .id = snd_soc_dapm_pga, .name = wname, \
142 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \163 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
143 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \164 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
144 .event = wevent, .event_flags = wflags}165 .event = wevent, .event_flags = wflags}
145#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \166#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \
146 wncontrols, wevent, wflags) \167 wncontrols, wevent, wflags) \
147{ .id = snd_soc_dapm_out_drv, .name = wname, \168(struct snd_soc_dapm_widget) { \
169 .id = snd_soc_dapm_out_drv, .name = wname, \
148 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \170 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
149 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \171 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
150 .event = wevent, .event_flags = wflags}172 .event = wevent, .event_flags = wflags}
151#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \173#define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \
152 wncontrols, wevent, wflags) \174 wncontrols, wevent, wflags) \
153{ .id = snd_soc_dapm_mixer, .name = wname, \175(struct snd_soc_dapm_widget) { \
176 .id = snd_soc_dapm_mixer, .name = wname, \
154 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \177 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
155 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \178 .kcontrol_news = wcontrols, .num_kcontrols = wncontrols, \
156 .event = wevent, .event_flags = wflags}179 .event = wevent, .event_flags = wflags}
157#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \180#define SND_SOC_DAPM_MIXER_NAMED_CTL_E(wname, wreg, wshift, winvert, \
158 wcontrols, wncontrols, wevent, wflags) \181 wcontrols, wncontrols, wevent, wflags) \
159{ .id = snd_soc_dapm_mixer, .name = wname, \182(struct snd_soc_dapm_widget) { \
183 .id = snd_soc_dapm_mixer, .name = wname, \
160 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \184 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
161 .kcontrol_news = wcontrols, \185 .kcontrol_news = wcontrols, \
162 .num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags}186 .num_kcontrols = wncontrols, .event = wevent, .event_flags = wflags}
163#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \187#define SND_SOC_DAPM_SWITCH_E(wname, wreg, wshift, winvert, wcontrols, \
164 wevent, wflags) \188 wevent, wflags) \
165{ .id = snd_soc_dapm_switch, .name = wname, \189(struct snd_soc_dapm_widget) { \
190 .id = snd_soc_dapm_switch, .name = wname, \
166 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \191 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
167 .kcontrol_news = wcontrols, .num_kcontrols = 1, \192 .kcontrol_news = wcontrols, .num_kcontrols = 1, \
168 .event = wevent, .event_flags = wflags}193 .event = wevent, .event_flags = wflags}
169#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \194#define SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, \
170 wevent, wflags) \195 wevent, wflags) \
171{ .id = snd_soc_dapm_mux, .name = wname, \196(struct snd_soc_dapm_widget) { \
197 .id = snd_soc_dapm_mux, .name = wname, \
172 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \198 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
173 .kcontrol_news = wcontrols, .num_kcontrols = 1, \199 .kcontrol_news = wcontrols, .num_kcontrols = 1, \
174 .event = wevent, .event_flags = wflags}200 .event = wevent, .event_flags = wflags}
@@ -176,101 +202,121 @@ struct soc_enum; · 1 unmodified line
176/* additional sequencing control within an event type */202/* additional sequencing control within an event type */
177#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \203#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \
178 wevent, wflags) \204 wevent, wflags) \
179{ .id = snd_soc_dapm_pga, .name = wname, \205(struct snd_soc_dapm_widget) { \
206 .id = snd_soc_dapm_pga, .name = wname, \
180 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \207 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
181 .event = wevent, .event_flags = wflags, \208 .event = wevent, .event_flags = wflags, \
182 .subseq = wsubseq}209 .subseq = wsubseq}
183#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \210#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
184 wflags) \211 wflags) \
185{ .id = snd_soc_dapm_supply, .name = wname, \212(struct snd_soc_dapm_widget) { \
213 .id = snd_soc_dapm_supply, .name = wname, \
186 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \214 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
187 .event = wevent, .event_flags = wflags, .subseq = wsubseq}215 .event = wevent, .event_flags = wflags, .subseq = wsubseq}
188 216
189/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */217/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
190#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \218#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
191 wevent, wflags) \219 wevent, wflags) \
192{ .id = snd_soc_dapm_pga, .name = wname, \220(struct snd_soc_dapm_widget) { \
221 .id = snd_soc_dapm_pga, .name = wname, \
193 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \222 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
194 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \223 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
195 .event = wevent, .event_flags = wflags}224 .event = wevent, .event_flags = wflags}
196#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \225#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
197 wevent, wflags) \226 wevent, wflags) \
198{ .id = snd_soc_dapm_mixer, .name = wname, \227(struct snd_soc_dapm_widget) { \
228 .id = snd_soc_dapm_mixer, .name = wname, \
199 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \229 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
200 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \230 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
201 .event = wevent, .event_flags = wflags}231 .event = wevent, .event_flags = wflags}
202#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \232#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
203 wcontrols, wevent, wflags) \233 wcontrols, wevent, wflags) \
204{ .id = snd_soc_dapm_mixer, .name = wname, \234(struct snd_soc_dapm_widget) { \
235 .id = snd_soc_dapm_mixer, .name = wname, \
205 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \236 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
206 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \237 .kcontrol_news = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
207 .event = wevent, .event_flags = wflags}238 .event = wevent, .event_flags = wflags}
208 239
209/* events that are pre and post DAPM */240/* events that are pre and post DAPM */
210#define SND_SOC_DAPM_PRE(wname, wevent) \241#define SND_SOC_DAPM_PRE(wname, wevent) \
211{ .id = snd_soc_dapm_pre, .name = wname, .kcontrol_news = NULL, \242(struct snd_soc_dapm_widget) { \
243 .id = snd_soc_dapm_pre, .name = wname, .kcontrol_news = NULL, \
212 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \244 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
213 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}245 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD}
214#define SND_SOC_DAPM_POST(wname, wevent) \246#define SND_SOC_DAPM_POST(wname, wevent) \
215{ .id = snd_soc_dapm_post, .name = wname, .kcontrol_news = NULL, \247(struct snd_soc_dapm_widget) { \
248 .id = snd_soc_dapm_post, .name = wname, .kcontrol_news = NULL, \
216 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \249 .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \
217 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}250 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
218 251
219/* stream domain */252/* stream domain */
220#define SND_SOC_DAPM_AIF_IN(wname, stname, wchan, wreg, wshift, winvert) \253#define SND_SOC_DAPM_AIF_IN(wname, stname, wchan, wreg, wshift, winvert) \
221{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \254(struct snd_soc_dapm_widget) { \
255 .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
222 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }256 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
223#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wchan, wreg, wshift, winvert, \257#define SND_SOC_DAPM_AIF_IN_E(wname, stname, wchan, wreg, wshift, winvert, \
224 wevent, wflags) \258 wevent, wflags) \
225{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \259(struct snd_soc_dapm_widget) { \
260 .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
226 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \261 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
227 .event = wevent, .event_flags = wflags }262 .event = wevent, .event_flags = wflags }
228#define SND_SOC_DAPM_AIF_OUT(wname, stname, wchan, wreg, wshift, winvert) \263#define SND_SOC_DAPM_AIF_OUT(wname, stname, wchan, wreg, wshift, winvert) \
229{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \264(struct snd_soc_dapm_widget) { \
265 .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
230 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }266 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
231#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wchan, wreg, wshift, winvert, \267#define SND_SOC_DAPM_AIF_OUT_E(wname, stname, wchan, wreg, wshift, winvert, \
232 wevent, wflags) \268 wevent, wflags) \
233{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \269(struct snd_soc_dapm_widget) { \
270 .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
234 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \271 .channel = wchan, SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
235 .event = wevent, .event_flags = wflags }272 .event = wevent, .event_flags = wflags }
236#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \273#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
237{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, \274(struct snd_soc_dapm_widget) { \
275 .id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
238 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) }276 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert) }
239#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \277#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \
240 wevent, wflags) \278 wevent, wflags) \
241{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, \279(struct snd_soc_dapm_widget) { \
280 .id = snd_soc_dapm_dac, .name = wname, .sname = stname, \
242 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \281 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
243 .event = wevent, .event_flags = wflags}282 .event = wevent, .event_flags = wflags}
244 283
245#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \284#define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \
246{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, \285(struct snd_soc_dapm_widget) { \
286 .id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
247 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }287 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), }
248#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \288#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \
249 wevent, wflags) \289 wevent, wflags) \
250{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, \290(struct snd_soc_dapm_widget) { \
291 .id = snd_soc_dapm_adc, .name = wname, .sname = stname, \
251 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \292 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
252 .event = wevent, .event_flags = wflags}293 .event = wevent, .event_flags = wflags}
253#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \294#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \
254{ .id = snd_soc_dapm_clock_supply, .name = wname, \295(struct snd_soc_dapm_widget) { \
296 .id = snd_soc_dapm_clock_supply, .name = wname, \
255 .reg = SND_SOC_NOPM, .event = dapm_clock_event, \297 .reg = SND_SOC_NOPM, .event = dapm_clock_event, \
256 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }298 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
257 299
258/* generic widgets */300/* generic widgets */
259#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \301#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
260{ .id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \302(struct snd_soc_dapm_widget) { \
303 .id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
261 .reg = wreg, .shift = wshift, .mask = wmask, \304 .reg = wreg, .shift = wshift, .mask = wmask, \
262 .on_val = won_val, .off_val = woff_val, }305 .on_val = won_val, .off_val = woff_val, }
263#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \306#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
264{ .id = snd_soc_dapm_supply, .name = wname, \307(struct snd_soc_dapm_widget) { \
308 .id = snd_soc_dapm_supply, .name = wname, \
265 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \309 SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
266 .event = wevent, .event_flags = wflags}310 .event = wevent, .event_flags = wflags}
267#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags) \311#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags) \
268{ .id = snd_soc_dapm_regulator_supply, .name = wname, \312(struct snd_soc_dapm_widget) { \
313 .id = snd_soc_dapm_regulator_supply, .name = wname, \
269 .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \314 .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
270 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \315 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
271 .on_val = wflags}316 .on_val = wflags}
272#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \317#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \
273{ .id = snd_soc_dapm_pinctrl, .name = wname, \318(struct snd_soc_dapm_widget) { \
319 .id = snd_soc_dapm_pinctrl, .name = wname, \
274 .priv = (&(struct snd_soc_dapm_pinctrl_priv) \320 .priv = (&(struct snd_soc_dapm_pinctrl_priv) \
275 { .active_state = active, .sleep_state = sleep,}), \321 { .active_state = active, .sleep_state = sleep,}), \
276 .reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \322 .reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \
@@ -604,6 +650,7 @@ struct snd_soc_dapm_widget { · 327 unmodified lines
604 unsigned char power_checked:1; /* power checked this run */650 unsigned char power_checked:1; /* power checked this run */
605 unsigned char is_supply:1; /* Widget is a supply type widget */651 unsigned char is_supply:1; /* Widget is a supply type widget */
606 unsigned char is_ep:2; /* Widget is a endpoint type widget */652 unsigned char is_ep:2; /* Widget is a endpoint type widget */
653 unsigned char no_wname_in_kcontrol_name:1; /* No widget name prefix in kcontrol name */
607 int subseq; /* sort within widget type */654 int subseq; /* sort within widget type */
608 655
609 int (*power_check)(struct snd_soc_dapm_widget *w);656 int (*power_check)(struct snd_soc_dapm_widget *w);
include/sound/soc.h+6−0
@@ -651,6 +651,7 @@ struct snd_soc_dai_link_component { · 650 unmodified lines
651 const char *name;651 const char *name;
652 struct device_node *of_node;652 struct device_node *of_node;
653 const char *dai_name;653 const char *dai_name;
654 struct of_phandle_args *dai_args;
654};655};
655 656
656struct snd_soc_dai_link_codec_ch_map {657struct snd_soc_dai_link_codec_ch_map {
@@ -1335,6 +1336,11 @@ int snd_soc_add_pcm_runtimes(struct snd_soc_card *card, · 678 unmodified lines
1335void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,1336void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
1336 struct snd_soc_pcm_runtime *rtd);1337 struct snd_soc_pcm_runtime *rtd);
1337 1338
1339void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platforms,
1340 struct snd_soc_dai_link_component *cpus);
1341struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,
1342 struct of_phandle_args *args);
1343struct snd_soc_dai *snd_soc_get_dai_via_args(struct of_phandle_args *dai_args);
1338struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,1344struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
1339 struct snd_soc_dai_driver *dai_drv,1345 struct snd_soc_dai_driver *dai_drv,
1340 bool legacy_dai_naming);1346 bool legacy_dai_naming);
include/sound/sof/topology.h+2−2
@@ -26,9 +26,9 @@ enum sof_comp_type { · 25 unmodified lines
26 SOF_COMP_MIXER,26 SOF_COMP_MIXER,
27 SOF_COMP_MUX,27 SOF_COMP_MUX,
28 SOF_COMP_SRC,28 SOF_COMP_SRC,
29 SOF_COMP_SPLITTER,29 SOF_COMP_DEPRECATED0, /* Formerly SOF_COMP_SPLITTER */
30 SOF_COMP_TONE,30 SOF_COMP_TONE,
31 SOF_COMP_SWITCH,31 SOF_COMP_DEPRECATED1, /* Formerly SOF_COMP_SWITCH */
32 SOF_COMP_BUFFER,32 SOF_COMP_BUFFER,
33 SOF_COMP_EQ_IIR,33 SOF_COMP_EQ_IIR,
34 SOF_COMP_EQ_FIR,34 SOF_COMP_EQ_FIR,
include/sound/uda134x.h+0−24
@@ -1,24 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * uda134x.h -- UDA134x ALSA SoC Codec driver
4 *
5 * Copyright 2007 Dension Audio Systems Ltd.
6 * Author: Zoltan Devai
7 */
8
9#ifndef _UDA134X_H
10#define _UDA134X_H
11
12#include <sound/l3.h>
13
14struct uda134x_platform_data {
15 struct l3_pins l3;
16 void (*power) (int);
17 int model;
18#define UDA134X_UDA1340 1
19#define UDA134X_UDA1341 2
20#define UDA134X_UDA1344 3
21#define UDA134X_UDA1345 4
22};
23
24#endif /* _UDA134X_H */
include/sound/ump.h+1−0
@@ -45,6 +45,7 @@ struct snd_ump_endpoint { · 44 unmodified lines
45 spinlock_t legacy_locks[2];45 spinlock_t legacy_locks[2];
46 struct snd_rawmidi *legacy_rmidi;46 struct snd_rawmidi *legacy_rmidi;
47 struct snd_rawmidi_substream *legacy_substreams[2][SNDRV_UMP_MAX_GROUPS];47 struct snd_rawmidi_substream *legacy_substreams[2][SNDRV_UMP_MAX_GROUPS];
48 unsigned char legacy_mapping[SNDRV_UMP_MAX_GROUPS];
48 49
49 /* for legacy output; need to open the actual substream unlike input */50 /* for legacy output; need to open the actual substream unlike input */
50 int legacy_out_opens;51 int legacy_out_opens;
include/uapi/sound/sof/tokens.h+5−1
@@ -99,7 +99,11 @@ · 98 unmodified lines
99#define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 41499#define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 414
100#define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415100#define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415
101#define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416101#define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416
102 102/*
103 * The token value is copied to the dapm_widget's
104 * no_wname_in_kcontrol_name.
105 */
106#define SOF_TKN_COMP_NO_WNAME_IN_KCONTROL_NAME 417
103 107
104/* SSP */108/* SSP */
105#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500109#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
lib/iov_iter.c+1−0
@@ -1557,6 +1557,7 @@ int import_ubuf(int rw, void __user *buf, size_t len, struct iov_iter *i) · 1556 unmodified lines
1557 iov_iter_ubuf(i, rw, buf, len);1557 iov_iter_ubuf(i, rw, buf, len);
1558 return 0;1558 return 0;
1559}1559}
1560EXPORT_SYMBOL_GPL(import_ubuf);
1560 1561
1561/**1562/**
1562 * iov_iter_restore() - Restore a &struct iov_iter to the same state as when1563 * iov_iter_restore() - Restore a &struct iov_iter to the same state as when
lib/math/Makefile+1−1
@@ -1,5 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += div64.o gcd.o lcm.o int_pow.o int_sqrt.o reciprocal_div.o2obj-y += div64.o gcd.o lcm.o int_log.o int_pow.o int_sqrt.o reciprocal_div.o
3 3
4obj-$(CONFIG_CORDIC) += cordic.o4obj-$(CONFIG_CORDIC) += cordic.o
5obj-$(CONFIG_PRIME_NUMBERS) += prime_numbers.o5obj-$(CONFIG_PRIME_NUMBERS) += prime_numbers.o
lib/math/int_log.crenamed from drivers/media/dvb-core/dvb_math.c+9−17
@@ -1,25 +1,17 @@
1// SPDX-License-Identifier: LGPL-2.1-or-later
1/*2/*
2 * dvb-math provides some complex fixed-point math3 * Provides fixed-point logarithm operations.
3 * operations shared between the dvb related stuff
4 *4 *
5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)5 * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 */6 */
17 7
18#include <linux/bitops.h>8#include <linux/bitops.h>
9#include <linux/export.h>
10#include <linux/int_log.h>
19#include <linux/kernel.h>11#include <linux/kernel.h>
20#include <linux/module.h>12#include <linux/types.h>
13
21#include <asm/bug.h>14#include <asm/bug.h>
22#include <media/dvb_math.h>
23 15
24static const unsigned short logtable[256] = {16static const unsigned short logtable[256] = {
25 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,17 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
@@ -53,7 +45,7 @@ static const unsigned short logtable[256] = { · 27 unmodified lines
53 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,45 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
54 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,46 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
55 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,47 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
56 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff4748 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47,
57};49};
58 50
59unsigned int intlog2(u32 value)51unsigned int intlog2(u32 value)
@@ -90,7 +82,7 @@ unsigned int intlog2(u32 value) · 30 unmodified lines
90 * so we would use the entry 0x1882 * so we would use the entry 0x18
91 */83 */
92 significand = value << (31 - msb);84 significand = value << (31 - msb);
93 logentry = (significand >> 23) & 0xff;85 logentry = (significand >> 23) % ARRAY_SIZE(logtable);
94 86
95 /**87 /**
96 * last step we do is interpolation because of the88 * last step we do is interpolation because of the
@@ -108,7 +100,7 @@ unsigned int intlog2(u32 value) · 11 unmodified lines
108 * logtable_next is 256100 * logtable_next is 256
109 */101 */
110 interpolation = ((significand & 0x7fffff) *102 interpolation = ((significand & 0x7fffff) *
111 ((logtable[(logentry + 1) & 0xff] -103 ((logtable[(logentry + 1) % ARRAY_SIZE(logtable)] -
112 logtable[logentry]) & 0xffff)) >> 15;104 logtable[logentry]) & 0xffff)) >> 15;
113 105
114 /* now we return the result */106 /* now we return the result */
sound/Kconfig+0−4
@@ -39,8 +39,6 @@ config SOUND_OSS_CORE_PRECLAIM · 38 unmodified lines
39 39
40source "sound/oss/dmasound/Kconfig"40source "sound/oss/dmasound/Kconfig"
41 41
42if !UML
43
44menuconfig SND42menuconfig SND
45 tristate "Advanced Linux Sound Architecture"43 tristate "Advanced Linux Sound Architecture"
46 help44 help
@@ -103,8 +101,6 @@ source "sound/virtio/Kconfig" · 56 unmodified lines
103 101
104endif # SND102endif # SND
105 103
106endif # !UML
107
108endif # SOUND104endif # SOUND
109 105
110config AC97_BUS106config AC97_BUS
sound/ac97/bus.c+1−1
@@ -462,7 +462,7 @@ static ssize_t vendor_id_show(struct device *dev, · 461 unmodified lines
462 462
463 return sysfs_emit(buf, "%08x", codec->vendor_id);463 return sysfs_emit(buf, "%08x", codec->vendor_id);
464}464}
465DEVICE_ATTR_RO(vendor_id);465static DEVICE_ATTR_RO(vendor_id);
466 466
467static struct attribute *ac97_dev_attrs[] = {467static struct attribute *ac97_dev_attrs[] = {
468 &dev_attr_vendor_id.attr,468 &dev_attr_vendor_id.attr,
sound/aoa/soundbus/i2sbus/pcm.c+2−2
@@ -972,7 +972,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, · 971 unmodified lines
972 goto out_put_ci_module;972 goto out_put_ci_module;
973 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,973 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
974 &i2sbus_playback_ops);974 &i2sbus_playback_ops);
975 dev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].dev.parent =975 dev->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].dev->parent =
976 &dev->ofdev.dev;976 &dev->ofdev.dev;
977 i2sdev->out.created = 1;977 i2sdev->out.created = 1;
978 }978 }
@@ -989,7 +989,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, · 10 unmodified lines
989 goto out_put_ci_module;989 goto out_put_ci_module;
990 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,990 snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
991 &i2sbus_record_ops);991 &i2sbus_record_ops);
992 dev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].dev.parent =992 dev->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].dev->parent =
993 &dev->ofdev.dev;993 &dev->ofdev.dev;
994 i2sdev->in.created = 1;994 i2sdev->in.created = 1;
995 }995 }
sound/atmel/ac97c.c+1−2
@@ -12,13 +12,12 @@ · 11 unmodified lines
12#include <linux/gpio/consumer.h>12#include <linux/gpio/consumer.h>
13#include <linux/init.h>13#include <linux/init.h>
14#include <linux/interrupt.h>14#include <linux/interrupt.h>
15#include <linux/mod_devicetable.h>
15#include <linux/module.h>16#include <linux/module.h>
16#include <linux/platform_device.h>17#include <linux/platform_device.h>
17#include <linux/mutex.h>18#include <linux/mutex.h>
18#include <linux/types.h>19#include <linux/types.h>
19#include <linux/io.h>20#include <linux/io.h>
20#include <linux/of.h>
21#include <linux/of_device.h>
22 21
23#include <sound/core.h>22#include <sound/core.h>
24#include <sound/initval.h>23#include <sound/initval.h>
sound/core/compress_offload.c+10−6
@@ -546,7 +546,7 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, · 545 unmodified lines
546 if (stream->runtime->dma_buffer_p) {546 if (stream->runtime->dma_buffer_p) {
547 547
548 if (buffer_size > stream->runtime->dma_buffer_p->bytes)548 if (buffer_size > stream->runtime->dma_buffer_p->bytes)
549 dev_err(&stream->device->dev,549 dev_err(stream->device->dev,
550 "Not enough DMA buffer");550 "Not enough DMA buffer");
551 else551 else
552 buffer = stream->runtime->dma_buffer_p->area;552 buffer = stream->runtime->dma_buffer_p->area;
@@ -1070,7 +1070,7 @@ static int snd_compress_dev_register(struct snd_device *device) · 517 unmodified lines
1070 /* register compressed device */1070 /* register compressed device */
1071 ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,1071 ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,
1072 compr->card, compr->device,1072 compr->card, compr->device,
1073 &snd_compr_file_ops, compr, &compr->dev);1073 &snd_compr_file_ops, compr, compr->dev);
1074 if (ret < 0) {1074 if (ret < 0) {
1075 pr_err("snd_register_device failed %d\n", ret);1075 pr_err("snd_register_device failed %d\n", ret);
1076 return ret;1076 return ret;
@@ -1084,7 +1084,7 @@ static int snd_compress_dev_disconnect(struct snd_device *device) · 7 unmodified lines
1084 struct snd_compr *compr;1084 struct snd_compr *compr;
1085 1085
1086 compr = device->device_data;1086 compr = device->device_data;
1087 snd_unregister_device(&compr->dev);1087 snd_unregister_device(compr->dev);
1088 return 0;1088 return 0;
1089}1089}
1090 1090
@@ -1158,7 +1158,7 @@ static int snd_compress_dev_free(struct snd_device *device) · 67 unmodified lines
1158 1158
1159 compr = device->device_data;1159 compr = device->device_data;
1160 snd_compress_proc_done(compr);1160 snd_compress_proc_done(compr);
1161 put_device(&compr->dev);1161 put_device(compr->dev);
1162 return 0;1162 return 0;
1163}1163}
1164 1164
@@ -1189,12 +1189,16 @@ int snd_compress_new(struct snd_card *card, int device, · 24 unmodified lines
1189 1189
1190 snd_compress_set_id(compr, id);1190 snd_compress_set_id(compr, id);
1191 1191
1192 snd_device_initialize(&compr->dev, card);1192 ret = snd_device_alloc(&compr->dev, card);
1193 dev_set_name(&compr->dev, "comprC%iD%i", card->number, device);1193 if (ret)
1194 return ret;
1195 dev_set_name(compr->dev, "comprC%iD%i", card->number, device);
1194 1196
1195 ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);1197 ret = snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
1196 if (ret == 0)1198 if (ret == 0)
1197 snd_compress_proc_init(compr);1199 snd_compress_proc_init(compr);
1200 else
1201 put_device(compr->dev);
1198 1202
1199 return ret;1203 return ret;
1200}1204}
sound/core/control.c+108−32
@@ -39,6 +39,9 @@ static LIST_HEAD(snd_control_compat_ioctls); · 38 unmodified lines
39#endif39#endif
40static struct snd_ctl_layer_ops *snd_ctl_layer;40static struct snd_ctl_layer_ops *snd_ctl_layer;
41 41
42static int snd_ctl_remove_locked(struct snd_card *card,
43 struct snd_kcontrol *kcontrol);
44
42static int snd_ctl_open(struct inode *inode, struct file *file)45static int snd_ctl_open(struct inode *inode, struct file *file)
43{46{
44 unsigned long flags;47 unsigned long flags;
@@ -466,11 +469,13 @@ static int __snd_ctl_add_replace(struct snd_card *card, · 421 unmodified lines
466 struct snd_kcontrol *old;469 struct snd_kcontrol *old;
467 int err;470 int err;
468 471
472 lockdep_assert_held_write(&card->controls_rwsem);
473
469 id = kcontrol->id;474 id = kcontrol->id;
470 if (id.index > UINT_MAX - kcontrol->count)475 if (id.index > UINT_MAX - kcontrol->count)
471 return -EINVAL;476 return -EINVAL;
472 477
473 old = snd_ctl_find_id(card, &id);478 old = snd_ctl_find_id_locked(card, &id);
474 if (!old) {479 if (!old) {
475 if (mode == CTL_REPLACE)480 if (mode == CTL_REPLACE)
476 return -EINVAL;481 return -EINVAL;
@@ -483,7 +488,7 @@ static int __snd_ctl_add_replace(struct snd_card *card, · 6 unmodified lines
483 return -EBUSY;488 return -EBUSY;
484 }489 }
485 490
486 err = snd_ctl_remove(card, old);491 err = snd_ctl_remove_locked(card, old);
487 if (err < 0)492 if (err < 0)
488 return err;493 return err;
489 }494 }
@@ -575,6 +580,8 @@ static int __snd_ctl_remove(struct snd_card *card, · 85 unmodified lines
575{580{
576 unsigned int idx;581 unsigned int idx;
577 582
583 lockdep_assert_held_write(&card->controls_rwsem);
584
578 if (snd_BUG_ON(!card || !kcontrol))585 if (snd_BUG_ON(!card || !kcontrol))
579 return -EINVAL;586 return -EINVAL;
580 list_del(&kcontrol->list);587 list_del(&kcontrol->list);
@@ -589,20 +596,32 @@ static int __snd_ctl_remove(struct snd_card *card, · 8 unmodified lines
589 return 0;596 return 0;
590}597}
591 598
599static inline int snd_ctl_remove_locked(struct snd_card *card,
600 struct snd_kcontrol *kcontrol)
601{
602 return __snd_ctl_remove(card, kcontrol, true);
603}
604
592/**605/**
593 * snd_ctl_remove - remove the control from the card and release it606 * snd_ctl_remove - remove the control from the card and release it
594 * @card: the card instance607 * @card: the card instance
595 * @kcontrol: the control instance to remove608 * @kcontrol: the control instance to remove
596 *609 *
597 * Removes the control from the card and then releases the instance.610 * Removes the control from the card and then releases the instance.
598 * You don't need to call snd_ctl_free_one(). You must be in611 * You don't need to call snd_ctl_free_one().
599 * the write lock - down_write(&card->controls_rwsem).
600 *612 *
601 * Return: 0 if successful, or a negative error code on failure.613 * Return: 0 if successful, or a negative error code on failure.
614 *
615 * Note that this function takes card->controls_rwsem lock internally.
602 */616 */
603int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)617int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
604{618{
605 return __snd_ctl_remove(card, kcontrol, true);619 int ret;
620
621 down_write(&card->controls_rwsem);
622 ret = snd_ctl_remove_locked(card, kcontrol);
623 up_write(&card->controls_rwsem);
624 return ret;
606}625}
607EXPORT_SYMBOL(snd_ctl_remove);626EXPORT_SYMBOL(snd_ctl_remove);
608 627
@@ -622,12 +641,12 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) · 13 unmodified lines
622 int ret;641 int ret;
623 642
624 down_write(&card->controls_rwsem);643 down_write(&card->controls_rwsem);
625 kctl = snd_ctl_find_id(card, id);644 kctl = snd_ctl_find_id_locked(card, id);
626 if (kctl == NULL) {645 if (kctl == NULL) {
627 up_write(&card->controls_rwsem);646 up_write(&card->controls_rwsem);
628 return -ENOENT;647 return -ENOENT;
629 }648 }
630 ret = snd_ctl_remove(card, kctl);649 ret = snd_ctl_remove_locked(card, kctl);
631 up_write(&card->controls_rwsem);650 up_write(&card->controls_rwsem);
632 return ret;651 return ret;
633}652}
@@ -651,7 +670,7 @@ static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, · 17 unmodified lines
651 int idx, ret;670 int idx, ret;
652 671
653 down_write(&card->controls_rwsem);672 down_write(&card->controls_rwsem);
654 kctl = snd_ctl_find_id(card, id);673 kctl = snd_ctl_find_id_locked(card, id);
655 if (kctl == NULL) {674 if (kctl == NULL) {
656 ret = -ENOENT;675 ret = -ENOENT;
657 goto error;676 goto error;
@@ -665,7 +684,7 @@ static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file, · 7 unmodified lines
665 ret = -EBUSY;684 ret = -EBUSY;
666 goto error;685 goto error;
667 }686 }
668 ret = snd_ctl_remove(card, kctl);687 ret = snd_ctl_remove_locked(card, kctl);
669error:688error:
670 up_write(&card->controls_rwsem);689 up_write(&card->controls_rwsem);
671 return ret;690 return ret;
@@ -692,7 +711,7 @@ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, · 20 unmodified lines
692 int ret;711 int ret;
693 712
694 down_write(&card->controls_rwsem);713 down_write(&card->controls_rwsem);
695 kctl = snd_ctl_find_id(card, id);714 kctl = snd_ctl_find_id_locked(card, id);
696 if (kctl == NULL) {715 if (kctl == NULL) {
697 ret = -ENOENT;716 ret = -ENOENT;
698 goto unlock;717 goto unlock;
@@ -746,7 +765,7 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, · 47 unmodified lines
746 int saved_numid;765 int saved_numid;
747 766
748 down_write(&card->controls_rwsem);767 down_write(&card->controls_rwsem);
749 kctl = snd_ctl_find_id(card, src_id);768 kctl = snd_ctl_find_id_locked(card, src_id);
750 if (kctl == NULL) {769 if (kctl == NULL) {
751 up_write(&card->controls_rwsem);770 up_write(&card->controls_rwsem);
752 return -ENOENT;771 return -ENOENT;
@@ -769,11 +788,12 @@ EXPORT_SYMBOL(snd_ctl_rename_id); · 16 unmodified lines
769 *788 *
770 * Renames the specified control on the card to the new name.789 * Renames the specified control on the card to the new name.
771 *790 *
772 * Make sure to take the control write lock - down_write(&card->controls_rwsem).791 * Note that this function takes card->controls_rwsem lock internally.
773 */792 */
774void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,793void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,
775 const char *name)794 const char *name)
776{795{
796 down_write(&card->controls_rwsem);
777 remove_hash_entries(card, kctl);797 remove_hash_entries(card, kctl);
778 798
779 if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)799 if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)
@@ -781,6 +801,7 @@ void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, · 1 unmodified line
781 name, kctl->id.name);801 name, kctl->id.name);
782 802
783 add_hash_entries(card, kctl);803 add_hash_entries(card, kctl);
804 up_write(&card->controls_rwsem);
784}805}
785EXPORT_SYMBOL(snd_ctl_rename);806EXPORT_SYMBOL(snd_ctl_rename);
786 807
@@ -799,7 +820,7 @@ snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) · 12 unmodified lines
799#endif /* !CONFIG_SND_CTL_FAST_LOOKUP */820#endif /* !CONFIG_SND_CTL_FAST_LOOKUP */
800 821
801/**822/**
802 * snd_ctl_find_numid - find the control instance with the given number-id823 * snd_ctl_find_numid_locked - find the control instance with the given number-id
803 * @card: the card instance824 * @card: the card instance
804 * @numid: the number-id to search825 * @numid: the number-id to search
805 *826 *
@@ -809,22 +830,46 @@ snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) · 3 unmodified lines
809 * (if the race condition can happen).830 * (if the race condition can happen).
810 *831 *
811 * Return: The pointer of the instance if found, or %NULL if not.832 * Return: The pointer of the instance if found, or %NULL if not.
812 *
813 */833 */
814struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid)834struct snd_kcontrol *
835snd_ctl_find_numid_locked(struct snd_card *card, unsigned int numid)
815{836{
816 if (snd_BUG_ON(!card || !numid))837 if (snd_BUG_ON(!card || !numid))
817 return NULL;838 return NULL;
839 lockdep_assert_held(&card->controls_rwsem);
818#ifdef CONFIG_SND_CTL_FAST_LOOKUP840#ifdef CONFIG_SND_CTL_FAST_LOOKUP
819 return xa_load(&card->ctl_numids, numid);841 return xa_load(&card->ctl_numids, numid);
820#else842#else
821 return snd_ctl_find_numid_slow(card, numid);843 return snd_ctl_find_numid_slow(card, numid);
822#endif844#endif
823}845}
846EXPORT_SYMBOL(snd_ctl_find_numid_locked);
847
848/**
849 * snd_ctl_find_numid - find the control instance with the given number-id
850 * @card: the card instance
851 * @numid: the number-id to search
852 *
853 * Finds the control instance with the given number-id from the card.
854 *
855 * Return: The pointer of the instance if found, or %NULL if not.
856 *
857 * Note that this function takes card->controls_rwsem lock internally.
858 */
859struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card,
860 unsigned int numid)
861{
862 struct snd_kcontrol *kctl;
863
864 down_read(&card->controls_rwsem);
865 kctl = snd_ctl_find_numid_locked(card, numid);
866 up_read(&card->controls_rwsem);
867 return kctl;
868}
824EXPORT_SYMBOL(snd_ctl_find_numid);869EXPORT_SYMBOL(snd_ctl_find_numid);
825 870
826/**871/**
827 * snd_ctl_find_id - find the control instance with the given id872 * snd_ctl_find_id_locked - find the control instance with the given id
828 * @card: the card instance873 * @card: the card instance
829 * @id: the id to search874 * @id: the id to search
830 *875 *
@@ -834,17 +879,17 @@ EXPORT_SYMBOL(snd_ctl_find_numid); · 3 unmodified lines
834 * (if the race condition can happen).879 * (if the race condition can happen).
835 *880 *
836 * Return: The pointer of the instance if found, or %NULL if not.881 * Return: The pointer of the instance if found, or %NULL if not.
837 *
838 */882 */
839struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,883struct snd_kcontrol *snd_ctl_find_id_locked(struct snd_card *card,
840 struct snd_ctl_elem_id *id)884 const struct snd_ctl_elem_id *id)
841{885{
842 struct snd_kcontrol *kctl;886 struct snd_kcontrol *kctl;
843 887
844 if (snd_BUG_ON(!card || !id))888 if (snd_BUG_ON(!card || !id))
845 return NULL;889 return NULL;
890 lockdep_assert_held(&card->controls_rwsem);
846 if (id->numid != 0)891 if (id->numid != 0)
847 return snd_ctl_find_numid(card, id->numid);892 return snd_ctl_find_numid_locked(card, id->numid);
848#ifdef CONFIG_SND_CTL_FAST_LOOKUP893#ifdef CONFIG_SND_CTL_FAST_LOOKUP
849 kctl = xa_load(&card->ctl_hash, get_ctl_id_hash(id));894 kctl = xa_load(&card->ctl_hash, get_ctl_id_hash(id));
850 if (kctl && elem_id_matches(kctl, id))895 if (kctl && elem_id_matches(kctl, id))
@@ -859,6 +904,29 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, · 8 unmodified lines
859 904
860 return NULL;905 return NULL;
861}906}
907EXPORT_SYMBOL(snd_ctl_find_id_locked);
908
909/**
910 * snd_ctl_find_id - find the control instance with the given id
911 * @card: the card instance
912 * @id: the id to search
913 *
914 * Finds the control instance with the given id from the card.
915 *
916 * Return: The pointer of the instance if found, or %NULL if not.
917 *
918 * Note that this function takes card->controls_rwsem lock internally.
919 */
920struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
921 const struct snd_ctl_elem_id *id)
922{
923 struct snd_kcontrol *kctl;
924
925 down_read(&card->controls_rwsem);
926 kctl = snd_ctl_find_id_locked(card, id);
927 up_read(&card->controls_rwsem);
928 return kctl;
929}
862EXPORT_SYMBOL(snd_ctl_find_id);930EXPORT_SYMBOL(snd_ctl_find_id);
863 931
864static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,932static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
@@ -1173,7 +1241,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl, · 308 unmodified lines
1173 int result;1241 int result;
1174 1242
1175 down_read(&card->controls_rwsem);1243 down_read(&card->controls_rwsem);
1176 kctl = snd_ctl_find_id(card, &info->id);1244 kctl = snd_ctl_find_id_locked(card, &info->id);
1177 if (kctl == NULL)1245 if (kctl == NULL)
1178 result = -ENOENT;1246 result = -ENOENT;
1179 else1247 else
@@ -1212,7 +1280,7 @@ static int snd_ctl_elem_read(struct snd_card *card, · 32 unmodified lines
1212 int ret;1280 int ret;
1213 1281
1214 down_read(&card->controls_rwsem);1282 down_read(&card->controls_rwsem);
1215 kctl = snd_ctl_find_id(card, &control->id);1283 kctl = snd_ctl_find_id_locked(card, &control->id);
1216 if (kctl == NULL) {1284 if (kctl == NULL) {
1217 ret = -ENOENT;1285 ret = -ENOENT;
1218 goto unlock;1286 goto unlock;
@@ -1289,7 +1357,7 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, · 70 unmodified lines
1289 int result;1357 int result;
1290 1358
1291 down_write(&card->controls_rwsem);1359 down_write(&card->controls_rwsem);
1292 kctl = snd_ctl_find_id(card, &control->id);1360 kctl = snd_ctl_find_id_locked(card, &control->id);
1293 if (kctl == NULL) {1361 if (kctl == NULL) {
1294 up_write(&card->controls_rwsem);1362 up_write(&card->controls_rwsem);
1295 return -ENOENT;1363 return -ENOENT;
@@ -1370,7 +1438,7 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file, · 74 unmodified lines
1370 if (copy_from_user(&id, _id, sizeof(id)))1438 if (copy_from_user(&id, _id, sizeof(id)))
1371 return -EFAULT;1439 return -EFAULT;
1372 down_write(&card->controls_rwsem);1440 down_write(&card->controls_rwsem);
1373 kctl = snd_ctl_find_id(card, &id);1441 kctl = snd_ctl_find_id_locked(card, &id);
1374 if (kctl == NULL) {1442 if (kctl == NULL) {
1375 result = -ENOENT;1443 result = -ENOENT;
1376 } else {1444 } else {
@@ -1398,7 +1466,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file, · 21 unmodified lines
1398 if (copy_from_user(&id, _id, sizeof(id)))1466 if (copy_from_user(&id, _id, sizeof(id)))
1399 return -EFAULT;1467 return -EFAULT;
1400 down_write(&card->controls_rwsem);1468 down_write(&card->controls_rwsem);
1401 kctl = snd_ctl_find_id(card, &id);1469 kctl = snd_ctl_find_id_locked(card, &id);
1402 if (kctl == NULL) {1470 if (kctl == NULL) {
1403 result = -ENOENT;1471 result = -ENOENT;
1404 } else {1472 } else {
@@ -1507,6 +1575,8 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf, · 102 unmodified lines
1507 int i;1575 int i;
1508 int change;1576 int change;
1509 1577
1578 lockdep_assert_held_write(&ue->card->controls_rwsem);
1579
1510 if (size > 1024 * 128) /* sane value */1580 if (size > 1024 * 128) /* sane value */
1511 return -EINVAL;1581 return -EINVAL;
1512 1582
@@ -1583,6 +1653,8 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue) · 70 unmodified lines
1583 unsigned int i;1653 unsigned int i;
1584 const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;1654 const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
1585 1655
1656 lockdep_assert_held_write(&ue->card->controls_rwsem);
1657
1586 buf_len = ue->info.value.enumerated.names_length;1658 buf_len = ue->info.value.enumerated.names_length;
1587 if (buf_len > 64 * 1024)1659 if (buf_len > 64 * 1024)
1588 return -EINVAL;1660 return -EINVAL;
@@ -1887,6 +1959,8 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, · 298 unmodified lines
1887 struct snd_ctl_elem_id id;1959 struct snd_ctl_elem_id id;
1888 struct snd_kcontrol_volatile *vd;1960 struct snd_kcontrol_volatile *vd;
1889 1961
1962 lockdep_assert_held(&file->card->controls_rwsem);
1963
1890 if (copy_from_user(&header, buf, sizeof(header)))1964 if (copy_from_user(&header, buf, sizeof(header)))
1891 return -EFAULT;1965 return -EFAULT;
1892 1966
@@ -1900,7 +1974,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, · 7 unmodified lines
1900 container_size = header.length;1974 container_size = header.length;
1901 container = buf->tlv;1975 container = buf->tlv;
1902 1976
1903 kctl = snd_ctl_find_numid(file->card, header.numid);1977 kctl = snd_ctl_find_numid_locked(file->card, header.numid);
1904 if (kctl == NULL)1978 if (kctl == NULL)
1905 return -ENOENT;1979 return -ENOENT;
1906 1980
@@ -2315,7 +2389,7 @@ static int snd_ctl_dev_register(struct snd_device *device) · 408 unmodified lines
2315 int err;2389 int err;
2316 2390
2317 err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,2391 err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
2318 &snd_ctl_f_ops, card, &card->ctl_dev);2392 &snd_ctl_f_ops, card, card->ctl_dev);
2319 if (err < 0)2393 if (err < 0)
2320 return err;2394 return err;
2321 down_read(&card->controls_rwsem);2395 down_read(&card->controls_rwsem);
@@ -2351,7 +2425,7 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) · 29 unmodified lines
2351 up_read(&snd_ctl_layer_rwsem);2425 up_read(&snd_ctl_layer_rwsem);
2352 up_read(&card->controls_rwsem);2426 up_read(&card->controls_rwsem);
2353 2427
2354 return snd_unregister_device(&card->ctl_dev);2428 return snd_unregister_device(card->ctl_dev);
2355}2429}
2356 2430
2357/*2431/*
@@ -2373,7 +2447,7 @@ static int snd_ctl_dev_free(struct snd_device *device) · 15 unmodified lines
2373 xa_destroy(&card->ctl_hash);2447 xa_destroy(&card->ctl_hash);
2374#endif2448#endif
2375 up_write(&card->controls_rwsem);2449 up_write(&card->controls_rwsem);
2376 put_device(&card->ctl_dev);2450 put_device(card->ctl_dev);
2377 return 0;2451 return 0;
2378}2452}
2379 2453
@@ -2395,12 +2469,14 @@ int snd_ctl_create(struct snd_card *card) · 15 unmodified lines
2395 if (snd_BUG_ON(card->number < 0 || card->number >= SNDRV_CARDS))2469 if (snd_BUG_ON(card->number < 0 || card->number >= SNDRV_CARDS))
2396 return -ENXIO;2470 return -ENXIO;
2397 2471
2398 snd_device_initialize(&card->ctl_dev, card);2472 err = snd_device_alloc(&card->ctl_dev, card);
2399 dev_set_name(&card->ctl_dev, "controlC%d", card->number);2473 if (err < 0)
2474 return err;
2475 dev_set_name(card->ctl_dev, "controlC%d", card->number);
2400 2476
2401 err = snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);2477 err = snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
2402 if (err < 0)2478 if (err < 0)
2403 put_device(&card->ctl_dev);2479 put_device(card->ctl_dev);
2404 return err;2480 return err;
2405}2481}
2406 2482
sound/core/control_compat.c+1−1
@@ -173,7 +173,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, · 172 unmodified lines
173 int err;173 int err;
174 174
175 down_read(&card->controls_rwsem);175 down_read(&card->controls_rwsem);
176 kctl = snd_ctl_find_id(card, id);176 kctl = snd_ctl_find_id_locked(card, id);
177 if (! kctl) {177 if (! kctl) {
178 up_read(&card->controls_rwsem);178 up_read(&card->controls_rwsem);
179 return -ENOENT;179 return -ENOENT;
sound/core/control_led.c+3−3
@@ -251,7 +251,7 @@ static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id, · 250 unmodified lines
251 card = snd_card_ref(card_number);251 card = snd_card_ref(card_number);
252 if (card) {252 if (card) {
253 down_write(&card->controls_rwsem);253 down_write(&card->controls_rwsem);
254 kctl = snd_ctl_find_id(card, id);254 kctl = snd_ctl_find_id_locked(card, id);
255 if (kctl) {255 if (kctl) {
256 ioff = snd_ctl_get_ioff(kctl, id);256 ioff = snd_ctl_get_ioff(kctl, id);
257 vd = &kctl->vd[ioff];257 vd = &kctl->vd[ioff];
@@ -688,7 +688,7 @@ static void snd_ctl_led_sysfs_add(struct snd_card *card) · 430 unmodified lines
688 goto cerr;688 goto cerr;
689 led->cards[card->number] = led_card;689 led->cards[card->number] = led_card;
690 snprintf(link_name, sizeof(link_name), "led-%s", led->name);690 snprintf(link_name, sizeof(link_name), "led-%s", led->name);
691 WARN(sysfs_create_link(&card->ctl_dev.kobj, &led_card->dev.kobj, link_name),691 WARN(sysfs_create_link(&card->ctl_dev->kobj, &led_card->dev.kobj, link_name),
692 "can't create symlink to controlC%i device\n", card->number);692 "can't create symlink to controlC%i device\n", card->number);
693 WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"),693 WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"),
694 "can't create symlink to card%i\n", card->number);694 "can't create symlink to card%i\n", card->number);
@@ -714,7 +714,7 @@ static void snd_ctl_led_sysfs_remove(struct snd_card *card) · 19 unmodified lines
714 if (!led_card)714 if (!led_card)
715 continue;715 continue;
716 snprintf(link_name, sizeof(link_name), "led-%s", led->name);716 snprintf(link_name, sizeof(link_name), "led-%s", led->name);
717 sysfs_remove_link(&card->ctl_dev.kobj, link_name);717 sysfs_remove_link(&card->ctl_dev->kobj, link_name);
718 sysfs_remove_link(&led_card->dev.kobj, "card");718 sysfs_remove_link(&led_card->dev.kobj, "card");
719 device_unregister(&led_card->dev);719 device_unregister(&led_card->dev);
720 led->cards[card->number] = NULL;720 led->cards[card->number] = NULL;
sound/core/hwdep.c+21−17
@@ -338,9 +338,14 @@ static const struct file_operations snd_hwdep_f_ops = · 337 unmodified lines
338 .mmap = snd_hwdep_mmap,338 .mmap = snd_hwdep_mmap,
339};339};
340 340
341static void release_hwdep_device(struct device *dev)341static void snd_hwdep_free(struct snd_hwdep *hwdep)
342{342{
343 kfree(container_of(dev, struct snd_hwdep, dev));343 if (!hwdep)
344 return;
345 if (hwdep->private_free)
346 hwdep->private_free(hwdep);
347 put_device(hwdep->dev);
348 kfree(hwdep);
344}349}
345 350
346/**351/**
@@ -382,16 +387,20 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, · 35 unmodified lines
382 if (id)387 if (id)
383 strscpy(hwdep->id, id, sizeof(hwdep->id));388 strscpy(hwdep->id, id, sizeof(hwdep->id));
384 389
385 snd_device_initialize(&hwdep->dev, card);390 err = snd_device_alloc(&hwdep->dev, card);
386 hwdep->dev.release = release_hwdep_device;391 if (err < 0) {
387 dev_set_name(&hwdep->dev, "hwC%iD%i", card->number, device);392 snd_hwdep_free(hwdep);
393 return err;
394 }
395
396 dev_set_name(hwdep->dev, "hwC%iD%i", card->number, device);
388#ifdef CONFIG_SND_OSSEMUL397#ifdef CONFIG_SND_OSSEMUL
389 hwdep->oss_type = -1;398 hwdep->oss_type = -1;
390#endif399#endif
391 400
392 err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops);401 err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops);
393 if (err < 0) {402 if (err < 0) {
394 put_device(&hwdep->dev);403 snd_hwdep_free(hwdep);
395 return err;404 return err;
396 }405 }
397 406
@@ -403,12 +412,7 @@ EXPORT_SYMBOL(snd_hwdep_new); · 5 unmodified lines
403 412
404static int snd_hwdep_dev_free(struct snd_device *device)413static int snd_hwdep_dev_free(struct snd_device *device)
405{414{
406 struct snd_hwdep *hwdep = device->device_data;415 snd_hwdep_free(device->device_data);
407 if (!hwdep)
408 return 0;
409 if (hwdep->private_free)
410 hwdep->private_free(hwdep);
411 put_device(&hwdep->dev);
412 return 0;416 return 0;
413}417}
414 418
@@ -426,9 +430,9 @@ static int snd_hwdep_dev_register(struct snd_device *device) · 11 unmodified lines
426 list_add_tail(&hwdep->list, &snd_hwdep_devices);430 list_add_tail(&hwdep->list, &snd_hwdep_devices);
427 err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,431 err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
428 hwdep->card, hwdep->device,432 hwdep->card, hwdep->device,
429 &snd_hwdep_f_ops, hwdep, &hwdep->dev);433 &snd_hwdep_f_ops, hwdep, hwdep->dev);
430 if (err < 0) {434 if (err < 0) {
431 dev_err(&hwdep->dev, "unable to register\n");435 dev_err(hwdep->dev, "unable to register\n");
432 list_del(&hwdep->list);436 list_del(&hwdep->list);
433 mutex_unlock(&register_mutex);437 mutex_unlock(&register_mutex);
434 return err;438 return err;
@@ -439,12 +443,12 @@ static int snd_hwdep_dev_register(struct snd_device *device) · 4 unmodified lines
439 if (hwdep->oss_type >= 0) {443 if (hwdep->oss_type >= 0) {
440 if (hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM &&444 if (hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM &&
441 hwdep->device)445 hwdep->device)
442 dev_warn(&hwdep->dev,446 dev_warn(hwdep->dev,
443 "only hwdep device 0 can be registered as OSS direct FM device!\n");447 "only hwdep device 0 can be registered as OSS direct FM device!\n");
444 else if (snd_register_oss_device(hwdep->oss_type,448 else if (snd_register_oss_device(hwdep->oss_type,
445 card, hwdep->device,449 card, hwdep->device,
446 &snd_hwdep_f_ops, hwdep) < 0)450 &snd_hwdep_f_ops, hwdep) < 0)
447 dev_warn(&hwdep->dev,451 dev_warn(hwdep->dev,
448 "unable to register OSS compatibility device\n");452 "unable to register OSS compatibility device\n");
449 else453 else
450 hwdep->ossreg = 1;454 hwdep->ossreg = 1;
@@ -471,7 +475,7 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) · 20 unmodified lines
471 if (hwdep->ossreg)475 if (hwdep->ossreg)
472 snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);476 snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
473#endif477#endif
474 snd_unregister_device(&hwdep->dev);478 snd_unregister_device(hwdep->dev);
475 list_del_init(&hwdep->list);479 list_del_init(&hwdep->list);
476 mutex_unlock(&hwdep->open_mutex);480 mutex_unlock(&hwdep->open_mutex);
477 mutex_unlock(&register_mutex);481 mutex_unlock(&register_mutex);
sound/core/init.c+18−10
@@ -111,28 +111,36 @@ static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int), · 110 unmodified lines
111 return mask; /* unchanged */111 return mask; /* unchanged */
112}112}
113 113
114/* the default release callback set in snd_device_initialize() below;114/* the default release callback set in snd_device_alloc() */
115 * this is just NOP for now, as almost all jobs are already done in115static void default_release_alloc(struct device *dev)
116 * dev_free callback of snd_device chain instead.
117 */
118static void default_release(struct device *dev)
119{116{
117 kfree(dev);
120}118}
121 119
122/**120/**
123 * snd_device_initialize - Initialize struct device for sound devices121 * snd_device_alloc - Allocate and initialize struct device for sound devices
124 * @dev: device to initialize122 * @dev_p: pointer to store the allocated device
125 * @card: card to assign, optional123 * @card: card to assign, optional
124 *
125 * For releasing the allocated device, call put_device().
126 */126 */
127void snd_device_initialize(struct device *dev, struct snd_card *card)127int snd_device_alloc(struct device **dev_p, struct snd_card *card)
128{128{
129 struct device *dev;
130
131 *dev_p = NULL;
132 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
133 if (!dev)
134 return -ENOMEM;
129 device_initialize(dev);135 device_initialize(dev);
130 if (card)136 if (card)
131 dev->parent = &card->card_dev;137 dev->parent = &card->card_dev;
132 dev->class = &sound_class;138 dev->class = &sound_class;
133 dev->release = default_release;139 dev->release = default_release_alloc;
140 *dev_p = dev;
141 return 0;
134}142}
135EXPORT_SYMBOL_GPL(snd_device_initialize);143EXPORT_SYMBOL_GPL(snd_device_alloc);
136 144
137static int snd_card_init(struct snd_card *card, struct device *parent,145static int snd_card_init(struct snd_card *card, struct device *parent,
138 int idx, const char *xid, struct module *module,146 int idx, const char *xid, struct module *module,
sound/core/jack.c+0−2
@@ -66,12 +66,10 @@ static int snd_jack_dev_free(struct snd_device *device) · 65 unmodified lines
66 struct snd_card *card = device->card;66 struct snd_card *card = device->card;
67 struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;67 struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
68 68
69 down_write(&card->controls_rwsem);
70 list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {69 list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {
71 list_del_init(&jack_kctl->list);70 list_del_init(&jack_kctl->list);
72 snd_ctl_remove(card, jack_kctl->kctl);71 snd_ctl_remove(card, jack_kctl->kctl);
73 }72 }
74 up_write(&card->controls_rwsem);
75 73
76 if (jack->private_free)74 if (jack->private_free)
77 jack->private_free(jack);75 jack->private_free(jack);
sound/core/memory.c+48−8
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/io.h>9#include <linux/io.h>
10#include <linux/uaccess.h>10#include <linux/uaccess.h>
11#include <sound/core.h>11#include <sound/core.h>
12#include <sound/pcm.h>
12 13
13/**14/**
14 * copy_to_user_fromio - copy data from mmio-space to user-space15 * copy_to_user_fromio - copy data from mmio-space to user-space
@@ -21,9 +22,30 @@ · 6 unmodified lines
21 * Return: Zero if successful, or non-zero on failure.22 * Return: Zero if successful, or non-zero on failure.
22 */23 */
23int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)24int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
25{
26 struct iov_iter iter;
27
28 if (import_ubuf(ITER_DEST, dst, count, &iter))
29 return -EFAULT;
30 return copy_to_iter_fromio(&iter, (const void __iomem *)src, count);
31}
32EXPORT_SYMBOL(copy_to_user_fromio);
33
34/**
35 * copy_to_iter_fromio - copy data from mmio-space to iov_iter
36 * @dst: the destination iov_iter
37 * @src: the source pointer on mmio
38 * @count: the data size to copy in bytes
39 *
40 * Copies the data from mmio-space to iov_iter.
41 *
42 * Return: Zero if successful, or non-zero on failure.
43 */
44int copy_to_iter_fromio(struct iov_iter *dst, const void __iomem *src,
45 size_t count)
24{46{
25#if defined(__i386__) || defined(CONFIG_SPARC32)47#if defined(__i386__) || defined(CONFIG_SPARC32)
26 return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0;48 return copy_to_iter((const void __force *)src, count, dst) == count ? 0 : -EFAULT;
27#else49#else
28 char buf[256];50 char buf[256];
29 while (count) {51 while (count) {
@@ -31,16 +53,15 @@ int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size · 1 unmodified line
31 if (c > sizeof(buf))53 if (c > sizeof(buf))
32 c = sizeof(buf);54 c = sizeof(buf);
33 memcpy_fromio(buf, (void __iomem *)src, c);55 memcpy_fromio(buf, (void __iomem *)src, c);
34 if (copy_to_user(dst, buf, c))56 if (copy_to_iter(buf, c, dst) != c)
35 return -EFAULT;57 return -EFAULT;
36 count -= c;58 count -= c;
37 dst += c;
38 src += c;59 src += c;
39 }60 }
40 return 0;61 return 0;
41#endif62#endif
42}63}
43EXPORT_SYMBOL(copy_to_user_fromio);64EXPORT_SYMBOL(copy_to_iter_fromio);
44 65
45/**66/**
46 * copy_from_user_toio - copy data from user-space to mmio-space67 * copy_from_user_toio - copy data from user-space to mmio-space
@@ -53,23 +74,42 @@ EXPORT_SYMBOL(copy_to_user_fromio); · 6 unmodified lines
53 * Return: Zero if successful, or non-zero on failure.74 * Return: Zero if successful, or non-zero on failure.
54 */75 */
55int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)76int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
77{
78 struct iov_iter iter;
79
80 if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter))
81 return -EFAULT;
82 return copy_from_iter_toio((void __iomem *)dst, &iter, count);
83}
84EXPORT_SYMBOL(copy_from_user_toio);
85
86/**
87 * copy_from_iter_toio - copy data from iov_iter to mmio-space
88 * @dst: the destination pointer on mmio-space
89 * @src: the source iov_iter
90 * @count: the data size to copy in bytes
91 *
92 * Copies the data from iov_iter to mmio-space.
93 *
94 * Return: Zero if successful, or non-zero on failure.
95 */
96int copy_from_iter_toio(void __iomem *dst, struct iov_iter *src, size_t count)
56{97{
57#if defined(__i386__) || defined(CONFIG_SPARC32)98#if defined(__i386__) || defined(CONFIG_SPARC32)
58 return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0;99 return copy_from_iter((void __force *)dst, count, src) == count ? 0 : -EFAULT;
59#else100#else
60 char buf[256];101 char buf[256];
61 while (count) {102 while (count) {
62 size_t c = count;103 size_t c = count;
63 if (c > sizeof(buf))104 if (c > sizeof(buf))
64 c = sizeof(buf);105 c = sizeof(buf);
65 if (copy_from_user(buf, src, c))106 if (copy_from_iter(buf, c, src) != c)
66 return -EFAULT;107 return -EFAULT;
67 memcpy_toio(dst, buf, c);108 memcpy_toio(dst, buf, c);
68 count -= c;109 count -= c;
69 dst += c;110 dst += c;
70 src += c;
71 }111 }
72 return 0;112 return 0;
73#endif113#endif
74}114}
75EXPORT_SYMBOL(copy_from_user_toio);115EXPORT_SYMBOL(copy_from_iter_toio);
sound/core/oss/mixer_oss.c+5−5
@@ -524,7 +524,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c · 523 unmodified lines
524 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;524 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
525 strscpy(id.name, name, sizeof(id.name));525 strscpy(id.name, name, sizeof(id.name));
526 id.index = index;526 id.index = index;
527 return snd_ctl_find_id(card, &id);527 return snd_ctl_find_id_locked(card, &id);
528}528}
529 529
530static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,530static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
@@ -540,7 +540,7 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer, · 9 unmodified lines
540 if (numid == ID_UNKNOWN)540 if (numid == ID_UNKNOWN)
541 return;541 return;
542 down_read(&card->controls_rwsem);542 down_read(&card->controls_rwsem);
543 kctl = snd_ctl_find_numid(card, numid);543 kctl = snd_ctl_find_numid_locked(card, numid);
544 if (!kctl) {544 if (!kctl) {
545 up_read(&card->controls_rwsem);545 up_read(&card->controls_rwsem);
546 return;546 return;
@@ -579,7 +579,7 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer, · 32 unmodified lines
579 if (numid == ID_UNKNOWN)579 if (numid == ID_UNKNOWN)
580 return;580 return;
581 down_read(&card->controls_rwsem);581 down_read(&card->controls_rwsem);
582 kctl = snd_ctl_find_numid(card, numid);582 kctl = snd_ctl_find_numid_locked(card, numid);
583 if (!kctl) {583 if (!kctl) {
584 up_read(&card->controls_rwsem);584 up_read(&card->controls_rwsem);
585 return;585 return;
@@ -645,7 +645,7 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer, · 59 unmodified lines
645 if (numid == ID_UNKNOWN)645 if (numid == ID_UNKNOWN)
646 return;646 return;
647 down_read(&card->controls_rwsem);647 down_read(&card->controls_rwsem);
648 kctl = snd_ctl_find_numid(card, numid);648 kctl = snd_ctl_find_numid_locked(card, numid);
649 if (!kctl) {649 if (!kctl) {
650 up_read(&card->controls_rwsem);650 up_read(&card->controls_rwsem);
651 return;651 return;
@@ -688,7 +688,7 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer, · 36 unmodified lines
688 if (numid == ID_UNKNOWN)688 if (numid == ID_UNKNOWN)
689 return;689 return;
690 down_read(&card->controls_rwsem);690 down_read(&card->controls_rwsem);
691 kctl = snd_ctl_find_numid(card, numid);691 kctl = snd_ctl_find_numid_locked(card, numid);
692 if (!kctl) {692 if (!kctl) {
693 up_read(&card->controls_rwsem);693 up_read(&card->controls_rwsem);
694 return;694 return;
sound/core/pcm.c+13−11
@@ -604,7 +604,7 @@ static const struct attribute_group *pcm_dev_attr_groups[]; · 603 unmodified lines
604#ifdef CONFIG_PM_SLEEP604#ifdef CONFIG_PM_SLEEP
605static int do_pcm_suspend(struct device *dev)605static int do_pcm_suspend(struct device *dev)
606{606{
607 struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);607 struct snd_pcm_str *pstr = dev_get_drvdata(dev);
608 608
609 if (!pstr->pcm->no_device_suspend)609 if (!pstr->pcm->no_device_suspend)
610 snd_pcm_suspend_all(pstr->pcm);610 snd_pcm_suspend_all(pstr->pcm);
@@ -650,11 +650,14 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) · 39 unmodified lines
650 if (!substream_count)650 if (!substream_count)
651 return 0;651 return 0;
652 652
653 snd_device_initialize(&pstr->dev, pcm->card);653 err = snd_device_alloc(&pstr->dev, pcm->card);
654 pstr->dev.groups = pcm_dev_attr_groups;654 if (err < 0)
655 pstr->dev.type = &pcm_dev_type;655 return err;
656 dev_set_name(&pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,656 dev_set_name(pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
657 stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');657 stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
658 pstr->dev->groups = pcm_dev_attr_groups;
659 pstr->dev->type = &pcm_dev_type;
660 dev_set_drvdata(pstr->dev, pstr);
658 661
659 if (!pcm->internal) {662 if (!pcm->internal) {
660 err = snd_pcm_stream_proc_init(pstr);663 err = snd_pcm_stream_proc_init(pstr);
@@ -814,9 +817,7 @@ static void free_chmap(struct snd_pcm_str *pstr) · 153 unmodified lines
814 if (pstr->chmap_kctl) {817 if (pstr->chmap_kctl) {
815 struct snd_card *card = pstr->pcm->card;818 struct snd_card *card = pstr->pcm->card;
816 819
817 down_write(&card->controls_rwsem);
818 snd_ctl_remove(card, pstr->chmap_kctl);820 snd_ctl_remove(card, pstr->chmap_kctl);
819 up_write(&card->controls_rwsem);
820 pstr->chmap_kctl = NULL;821 pstr->chmap_kctl = NULL;
821 }822 }
822}823}
@@ -847,7 +848,7 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr) · 24 unmodified lines
847#endif848#endif
848 free_chmap(pstr);849 free_chmap(pstr);
849 if (pstr->substream_count)850 if (pstr->substream_count)
850 put_device(&pstr->dev);851 put_device(pstr->dev);
851}852}
852 853
853#if IS_ENABLED(CONFIG_SND_PCM_OSS)854#if IS_ENABLED(CONFIG_SND_PCM_OSS)
@@ -1017,7 +1018,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) · 163 unmodified lines
1017static ssize_t pcm_class_show(struct device *dev,1018static ssize_t pcm_class_show(struct device *dev,
1018 struct device_attribute *attr, char *buf)1019 struct device_attribute *attr, char *buf)
1019{1020{
1020 struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);1021 struct snd_pcm_str *pstr = dev_get_drvdata(dev);
1021 struct snd_pcm *pcm = pstr->pcm;1022 struct snd_pcm *pcm = pstr->pcm;
1022 const char *str;1023 const char *str;
1023 static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {1024 static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
@@ -1078,7 +1079,7 @@ static int snd_pcm_dev_register(struct snd_device *device) · 54 unmodified lines
1078 /* register pcm */1079 /* register pcm */
1079 err = snd_register_device(devtype, pcm->card, pcm->device,1080 err = snd_register_device(devtype, pcm->card, pcm->device,
1080 &snd_pcm_f_ops[cidx], pcm,1081 &snd_pcm_f_ops[cidx], pcm,
1081 &pcm->streams[cidx].dev);1082 pcm->streams[cidx].dev);
1082 if (err < 0) {1083 if (err < 0) {
1083 list_del_init(&pcm->list);1084 list_del_init(&pcm->list);
1084 goto unlock;1085 goto unlock;
@@ -1125,7 +1126,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) · 40 unmodified lines
1125 1126
1126 pcm_call_notify(pcm, n_disconnect);1127 pcm_call_notify(pcm, n_disconnect);
1127 for (cidx = 0; cidx < 2; cidx++) {1128 for (cidx = 0; cidx < 2; cidx++) {
1128 snd_unregister_device(&pcm->streams[cidx].dev);1129 if (pcm->streams[cidx].dev)
1130 snd_unregister_device(pcm->streams[cidx].dev);
1129 free_chmap(&pcm->streams[cidx]);1131 free_chmap(&pcm->streams[cidx]);
1130 }1132 }
1131 mutex_unlock(&pcm->open_mutex);1133 mutex_unlock(&pcm->open_mutex);
sound/core/pcm_compat.c+6−2
@@ -253,10 +253,14 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, · 252 unmodified lines
253 goto error;253 goto error;
254 }254 }
255 255
256 if (refine)256 if (refine) {
257 err = snd_pcm_hw_refine(substream, data);257 err = snd_pcm_hw_refine(substream, data);
258 else258 if (err < 0)
259 goto error;
260 err = fixup_unreferenced_params(substream, data);
261 } else {
259 err = snd_pcm_hw_params(substream, data);262 err = snd_pcm_hw_params(substream, data);
263 }
260 if (err < 0)264 if (err < 0)
261 goto error;265 goto error;
262 if (copy_to_user(data32, data, sizeof(*data32)) ||266 if (copy_to_user(data32, data, sizeof(*data32)) ||
sound/core/pcm_lib.c+51−44
@@ -1973,10 +1973,11 @@ static int wait_for_avail(struct snd_pcm_substream *substream, · 1972 unmodified lines
1973 1973
1974typedef int (*pcm_transfer_f)(struct snd_pcm_substream *substream,1974typedef int (*pcm_transfer_f)(struct snd_pcm_substream *substream,
1975 int channel, unsigned long hwoff,1975 int channel, unsigned long hwoff,
1976 void *buf, unsigned long bytes);1976 struct iov_iter *iter, unsigned long bytes);
1977 1977
1978typedef int (*pcm_copy_f)(struct snd_pcm_substream *, snd_pcm_uframes_t, void *,1978typedef int (*pcm_copy_f)(struct snd_pcm_substream *, snd_pcm_uframes_t, void *,
1979 snd_pcm_uframes_t, snd_pcm_uframes_t, pcm_transfer_f);1979 snd_pcm_uframes_t, snd_pcm_uframes_t, pcm_transfer_f,
1980 bool);
1980 1981
1981/* calculate the target DMA-buffer position to be written/read */1982/* calculate the target DMA-buffer position to be written/read */
1982static void *get_dma_ptr(struct snd_pcm_runtime *runtime,1983static void *get_dma_ptr(struct snd_pcm_runtime *runtime,
@@ -1986,32 +1987,24 @@ static void *get_dma_ptr(struct snd_pcm_runtime *runtime, · 3 unmodified lines
1986 channel * (runtime->dma_bytes / runtime->channels);1987 channel * (runtime->dma_bytes / runtime->channels);
1987}1988}
1988 1989
1989/* default copy_user ops for write; used for both interleaved and non- modes */1990/* default copy ops for write; used for both interleaved and non- modes */
1990static int default_write_copy(struct snd_pcm_substream *substream,1991static int default_write_copy(struct snd_pcm_substream *substream,
1991 int channel, unsigned long hwoff,1992 int channel, unsigned long hwoff,
1992 void *buf, unsigned long bytes)1993 struct iov_iter *iter, unsigned long bytes)
1993{1994{
1994 if (copy_from_user(get_dma_ptr(substream->runtime, channel, hwoff),1995 if (!copy_from_iter(get_dma_ptr(substream->runtime, channel, hwoff),
1995 (void __user *)buf, bytes))1996 bytes, iter))
1996 return -EFAULT;1997 return -EFAULT;
1997 return 0;1998 return 0;
1998}1999}
1999 2000
2000/* default copy_kernel ops for write */
2001static int default_write_copy_kernel(struct snd_pcm_substream *substream,
2002 int channel, unsigned long hwoff,
2003 void *buf, unsigned long bytes)
2004{
2005 memcpy(get_dma_ptr(substream->runtime, channel, hwoff), buf, bytes);
2006 return 0;
2007}
2008
2009/* fill silence instead of copy data; called as a transfer helper2001/* fill silence instead of copy data; called as a transfer helper
2010 * from __snd_pcm_lib_write() or directly from noninterleaved_copy() when2002 * from __snd_pcm_lib_write() or directly from noninterleaved_copy() when
2011 * a NULL buffer is passed2003 * a NULL buffer is passed
2012 */2004 */
2013static int fill_silence(struct snd_pcm_substream *substream, int channel,2005static int fill_silence(struct snd_pcm_substream *substream, int channel,
2014 unsigned long hwoff, void *buf, unsigned long bytes)2006 unsigned long hwoff, struct iov_iter *iter,
2007 unsigned long bytes)
2015{2008{
2016 struct snd_pcm_runtime *runtime = substream->runtime;2009 struct snd_pcm_runtime *runtime = substream->runtime;
2017 2010
@@ -2027,25 +2020,41 @@ static int fill_silence(struct snd_pcm_substream *substream, int channel, · 9 unmodified lines
2027 return 0;2020 return 0;
2028}2021}
2029 2022
2030/* default copy_user ops for read; used for both interleaved and non- modes */2023/* default copy ops for read; used for both interleaved and non- modes */
2031static int default_read_copy(struct snd_pcm_substream *substream,2024static int default_read_copy(struct snd_pcm_substream *substream,
2032 int channel, unsigned long hwoff,2025 int channel, unsigned long hwoff,
2033 void *buf, unsigned long bytes)2026 struct iov_iter *iter, unsigned long bytes)
2034{2027{
2035 if (copy_to_user((void __user *)buf,2028 if (!copy_to_iter(get_dma_ptr(substream->runtime, channel, hwoff),
2036 get_dma_ptr(substream->runtime, channel, hwoff),2029 bytes, iter))
2037 bytes))
2038 return -EFAULT;2030 return -EFAULT;
2039 return 0;2031 return 0;
2040}2032}
2041 2033
2042/* default copy_kernel ops for read */2034/* call transfer with the filled iov_iter */
2043static int default_read_copy_kernel(struct snd_pcm_substream *substream,2035static int do_transfer(struct snd_pcm_substream *substream, int c,
2044 int channel, unsigned long hwoff,2036 unsigned long hwoff, void *data, unsigned long bytes,
2045 void *buf, unsigned long bytes)2037 pcm_transfer_f transfer, bool in_kernel)
2046{2038{
2047 memcpy(buf, get_dma_ptr(substream->runtime, channel, hwoff), bytes);2039 struct iov_iter iter;
2048 return 0;2040 int err, type;
2041
2042 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2043 type = ITER_SOURCE;
2044 else
2045 type = ITER_DEST;
2046
2047 if (in_kernel) {
2048 struct kvec kvec = { data, bytes };
2049
2050 iov_iter_kvec(&iter, type, &kvec, 1, bytes);
2051 return transfer(substream, c, hwoff, &iter, bytes);
2052 }
2053
2054 err = import_ubuf(type, (__force void __user *)data, bytes, &iter);
2055 if (err)
2056 return err;
2057 return transfer(substream, c, hwoff, &iter, bytes);
2049}2058}
2050 2059
2051/* call transfer function with the converted pointers and sizes;2060/* call transfer function with the converted pointers and sizes;
@@ -2055,7 +2064,8 @@ static int interleaved_copy(struct snd_pcm_substream *substream, · 3 unmodified lines
2055 snd_pcm_uframes_t hwoff, void *data,2064 snd_pcm_uframes_t hwoff, void *data,
2056 snd_pcm_uframes_t off,2065 snd_pcm_uframes_t off,
2057 snd_pcm_uframes_t frames,2066 snd_pcm_uframes_t frames,
2058 pcm_transfer_f transfer)2067 pcm_transfer_f transfer,
2068 bool in_kernel)
2059{2069{
2060 struct snd_pcm_runtime *runtime = substream->runtime;2070 struct snd_pcm_runtime *runtime = substream->runtime;
2061 2071
@@ -2063,7 +2073,9 @@ static int interleaved_copy(struct snd_pcm_substream *substream, · 1 unmodified line
2063 hwoff = frames_to_bytes(runtime, hwoff);2073 hwoff = frames_to_bytes(runtime, hwoff);
2064 off = frames_to_bytes(runtime, off);2074 off = frames_to_bytes(runtime, off);
2065 frames = frames_to_bytes(runtime, frames);2075 frames = frames_to_bytes(runtime, frames);
2066 return transfer(substream, 0, hwoff, data + off, frames);2076
2077 return do_transfer(substream, 0, hwoff, data + off, frames, transfer,
2078 in_kernel);
2067}2079}
2068 2080
2069/* call transfer function with the converted pointers and sizes for each2081/* call transfer function with the converted pointers and sizes for each
@@ -2073,7 +2085,8 @@ static int noninterleaved_copy(struct snd_pcm_substream *substream, · 3 unmodified lines
2073 snd_pcm_uframes_t hwoff, void *data,2085 snd_pcm_uframes_t hwoff, void *data,
2074 snd_pcm_uframes_t off,2086 snd_pcm_uframes_t off,
2075 snd_pcm_uframes_t frames,2087 snd_pcm_uframes_t frames,
2076 pcm_transfer_f transfer)2088 pcm_transfer_f transfer,
2089 bool in_kernel)
2077{2090{
2078 struct snd_pcm_runtime *runtime = substream->runtime;2091 struct snd_pcm_runtime *runtime = substream->runtime;
2079 int channels = runtime->channels;2092 int channels = runtime->channels;
@@ -2091,8 +2104,8 @@ static int noninterleaved_copy(struct snd_pcm_substream *substream, · 11 unmodified lines
2091 if (!data || !*bufs)2104 if (!data || !*bufs)
2092 err = fill_silence(substream, c, hwoff, NULL, frames);2105 err = fill_silence(substream, c, hwoff, NULL, frames);
2093 else2106 else
2094 err = transfer(substream, c, hwoff, *bufs + off,2107 err = do_transfer(substream, c, hwoff, *bufs + off,
2095 frames);2108 frames, transfer, in_kernel);
2096 if (err < 0)2109 if (err < 0)
2097 return err;2110 return err;
2098 }2111 }
@@ -2108,10 +2121,10 @@ static int fill_silence_frames(struct snd_pcm_substream *substream, · 9 unmodified lines
2108 if (substream->runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||2121 if (substream->runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
2109 substream->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)2122 substream->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED)
2110 return interleaved_copy(substream, off, NULL, 0, frames,2123 return interleaved_copy(substream, off, NULL, 0, frames,
2111 fill_silence);2124 fill_silence, true);
2112 else2125 else
2113 return noninterleaved_copy(substream, off, NULL, 0, frames,2126 return noninterleaved_copy(substream, off, NULL, 0, frames,
2114 fill_silence);2127 fill_silence, true);
2115}2128}
2116 2129
2117/* sanity-check for read/write methods */2130/* sanity-check for read/write methods */
@@ -2121,7 +2134,7 @@ static int pcm_sanity_check(struct snd_pcm_substream *substream) · 3 unmodified lines
2121 if (PCM_RUNTIME_CHECK(substream))2134 if (PCM_RUNTIME_CHECK(substream))
2122 return -ENXIO;2135 return -ENXIO;
2123 runtime = substream->runtime;2136 runtime = substream->runtime;
2124 if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area))2137 if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area))
2125 return -EINVAL;2138 return -EINVAL;
2126 if (runtime->state == SNDRV_PCM_STATE_OPEN)2139 if (runtime->state == SNDRV_PCM_STATE_OPEN)
2127 return -EBADFD;2140 return -EBADFD;
@@ -2226,15 +2239,9 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, · 98 unmodified lines
2226 transfer = fill_silence;2239 transfer = fill_silence;
2227 else2240 else
2228 return -EINVAL;2241 return -EINVAL;
2229 } else if (in_kernel) {
2230 if (substream->ops->copy_kernel)
2231 transfer = substream->ops->copy_kernel;
2232 else
2233 transfer = is_playback ?
2234 default_write_copy_kernel : default_read_copy_kernel;
2235 } else {2242 } else {
2236 if (substream->ops->copy_user)2243 if (substream->ops->copy)
2237 transfer = (pcm_transfer_f)substream->ops->copy_user;2244 transfer = substream->ops->copy;
2238 else2245 else
2239 transfer = is_playback ?2246 transfer = is_playback ?
2240 default_write_copy : default_read_copy;2247 default_write_copy : default_read_copy;
@@ -2307,7 +2314,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream, · 66 unmodified lines
2307 if (!is_playback)2314 if (!is_playback)
2308 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU);2315 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU);
2309 err = writer(substream, appl_ofs, data, offset, frames,2316 err = writer(substream, appl_ofs, data, offset, frames,
2310 transfer);2317 transfer, in_kernel);
2311 if (is_playback)2318 if (is_playback)
2312 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);2319 snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
2313 snd_pcm_stream_lock_irq(substream);2320 snd_pcm_stream_lock_irq(substream);
sound/core/pcm_native.c+1−1
@@ -809,7 +809,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, · 808 unmodified lines
809 runtime->boundary *= 2;809 runtime->boundary *= 2;
810 810
811 /* clear the buffer for avoiding possible kernel info leaks */811 /* clear the buffer for avoiding possible kernel info leaks */
812 if (runtime->dma_area && !substream->ops->copy_user) {812 if (runtime->dma_area && !substream->ops->copy) {
813 size_t size = runtime->dma_bytes;813 size_t size = runtime->dma_bytes;
814 814
815 if (runtime->info & SNDRV_PCM_INFO_MMAP)815 if (runtime->info & SNDRV_PCM_INFO_MMAP)
sound/core/rawmidi.c+13−16
@@ -44,11 +44,11 @@ static LIST_HEAD(snd_rawmidi_devices); · 43 unmodified lines
44static DEFINE_MUTEX(register_mutex);44static DEFINE_MUTEX(register_mutex);
45 45
46#define rmidi_err(rmidi, fmt, args...) \46#define rmidi_err(rmidi, fmt, args...) \
47 dev_err(&(rmidi)->dev, fmt, ##args)47 dev_err((rmidi)->dev, fmt, ##args)
48#define rmidi_warn(rmidi, fmt, args...) \48#define rmidi_warn(rmidi, fmt, args...) \
49 dev_warn(&(rmidi)->dev, fmt, ##args)49 dev_warn((rmidi)->dev, fmt, ##args)
50#define rmidi_dbg(rmidi, fmt, args...) \50#define rmidi_dbg(rmidi, fmt, args...) \
51 dev_dbg(&(rmidi)->dev, fmt, ##args)51 dev_dbg((rmidi)->dev, fmt, ##args)
52 52
53struct snd_rawmidi_status32 {53struct snd_rawmidi_status32 {
54 s32 stream;54 s32 stream;
@@ -1877,11 +1877,6 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, · 1822 unmodified lines
1877 return 0;1877 return 0;
1878}1878}
1879 1879
1880static void release_rawmidi_device(struct device *dev)
1881{
1882 kfree(container_of(dev, struct snd_rawmidi, dev));
1883}
1884
1885/* used for both rawmidi and ump */1880/* used for both rawmidi and ump */
1886int snd_rawmidi_init(struct snd_rawmidi *rmidi,1881int snd_rawmidi_init(struct snd_rawmidi *rmidi,
1887 struct snd_card *card, char *id, int device,1882 struct snd_card *card, char *id, int device,
@@ -1906,12 +1901,13 @@ int snd_rawmidi_init(struct snd_rawmidi *rmidi, · 18 unmodified lines
1906 if (id != NULL)1901 if (id != NULL)
1907 strscpy(rmidi->id, id, sizeof(rmidi->id));1902 strscpy(rmidi->id, id, sizeof(rmidi->id));
1908 1903
1909 snd_device_initialize(&rmidi->dev, card);1904 err = snd_device_alloc(&rmidi->dev, card);
1910 rmidi->dev.release = release_rawmidi_device;1905 if (err < 0)
1906 return err;
1911 if (rawmidi_is_ump(rmidi))1907 if (rawmidi_is_ump(rmidi))
1912 dev_set_name(&rmidi->dev, "umpC%iD%i", card->number, device);1908 dev_set_name(rmidi->dev, "umpC%iD%i", card->number, device);
1913 else1909 else
1914 dev_set_name(&rmidi->dev, "midiC%iD%i", card->number, device);1910 dev_set_name(rmidi->dev, "midiC%iD%i", card->number, device);
1915 1911
1916 err = snd_rawmidi_alloc_substreams(rmidi,1912 err = snd_rawmidi_alloc_substreams(rmidi,
1917 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],1913 &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
@@ -1996,7 +1992,8 @@ int snd_rawmidi_free(struct snd_rawmidi *rmidi) · 78 unmodified lines
1996 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);1992 snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
1997 if (rmidi->private_free)1993 if (rmidi->private_free)
1998 rmidi->private_free(rmidi);1994 rmidi->private_free(rmidi);
1999 put_device(&rmidi->dev);1995 put_device(rmidi->dev);
1996 kfree(rmidi);
2000 return 0;1997 return 0;
2001}1998}
2002EXPORT_SYMBOL_GPL(snd_rawmidi_free);1999EXPORT_SYMBOL_GPL(snd_rawmidi_free);
@@ -2038,7 +2035,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) · 35 unmodified lines
2038 2035
2039 err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,2036 err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
2040 rmidi->card, rmidi->device,2037 rmidi->card, rmidi->device,
2041 &snd_rawmidi_f_ops, rmidi, &rmidi->dev);2038 &snd_rawmidi_f_ops, rmidi, rmidi->dev);
2042 if (err < 0) {2039 if (err < 0) {
2043 rmidi_err(rmidi, "unable to register\n");2040 rmidi_err(rmidi, "unable to register\n");
2044 goto error;2041 goto error;
@@ -2103,7 +2100,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) · 58 unmodified lines
2103 return 0;2100 return 0;
2104 2101
2105 error_unregister:2102 error_unregister:
2106 snd_unregister_device(&rmidi->dev);2103 snd_unregister_device(rmidi->dev);
2107 error:2104 error:
2108 mutex_lock(&register_mutex);2105 mutex_lock(&register_mutex);
2109 list_del(&rmidi->list);2106 list_del(&rmidi->list);
@@ -2142,7 +2139,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) · 32 unmodified lines
2142 rmidi->ossreg = 0;2139 rmidi->ossreg = 0;
2143 }2140 }
2144#endif /* CONFIG_SND_OSSEMUL */2141#endif /* CONFIG_SND_OSSEMUL */
2145 snd_unregister_device(&rmidi->dev);2142 snd_unregister_device(rmidi->dev);
2146 mutex_unlock(&rmidi->open_mutex);2143 mutex_unlock(&rmidi->open_mutex);
2147 mutex_unlock(&register_mutex);2144 mutex_unlock(&register_mutex);
2148 return 0;2145 return 0;
sound/core/seq/seq_clientmgr.c+9−7
@@ -2721,7 +2721,7 @@ static const struct file_operations snd_seq_f_ops = · 2720 unmodified lines
2721 .compat_ioctl = snd_seq_ioctl_compat,2721 .compat_ioctl = snd_seq_ioctl_compat,
2722};2722};
2723 2723
2724static struct device seq_dev;2724static struct device *seq_dev;
2725 2725
2726/* 2726/*
2727 * register sequencer device 2727 * register sequencer device
@@ -2730,15 +2730,17 @@ int __init snd_sequencer_device_init(void) · 2 unmodified lines
2730{2730{
2731 int err;2731 int err;
2732 2732
2733 snd_device_initialize(&seq_dev, NULL);2733 err = snd_device_alloc(&seq_dev, NULL);
2734 dev_set_name(&seq_dev, "seq");2734 if (err < 0)
2735 return err;
2736 dev_set_name(seq_dev, "seq");
2735 2737
2736 mutex_lock(&register_mutex);2738 mutex_lock(&register_mutex);
2737 err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,2739 err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
2738 &snd_seq_f_ops, NULL, &seq_dev);2740 &snd_seq_f_ops, NULL, seq_dev);
2739 mutex_unlock(&register_mutex);2741 mutex_unlock(&register_mutex);
2740 if (err < 0) {2742 if (err < 0) {
2741 put_device(&seq_dev);2743 put_device(seq_dev);
2742 return err;2744 return err;
2743 }2745 }
2744 2746
@@ -2752,6 +2754,6 @@ int __init snd_sequencer_device_init(void) · 7 unmodified lines
2752 */2754 */
2753void snd_sequencer_device_done(void)2755void snd_sequencer_device_done(void)
2754{2756{
2755 snd_unregister_device(&seq_dev);2757 snd_unregister_device(seq_dev);
2756 put_device(&seq_dev);2758 put_device(seq_dev);
2757}2759}
sound/core/timer.c+9−7
@@ -2301,7 +2301,7 @@ static void snd_timer_free_all(void) · 2300 unmodified lines
2301 snd_timer_free(timer);2301 snd_timer_free(timer);
2302}2302}
2303 2303
2304static struct device timer_dev;2304static struct device *timer_dev;
2305 2305
2306/*2306/*
2307 * ENTRY functions2307 * ENTRY functions
@@ -2311,8 +2311,10 @@ static int __init alsa_timer_init(void) · 3 unmodified lines
2311{2311{
2312 int err;2312 int err;
2313 2313
2314 snd_device_initialize(&timer_dev, NULL);2314 err = snd_device_alloc(&timer_dev, NULL);
2315 dev_set_name(&timer_dev, "timer");2315 if (err < 0)
2316 return err;
2317 dev_set_name(timer_dev, "timer");
2316 2318
2317#ifdef SNDRV_OSS_INFO_DEV_TIMERS2319#ifdef SNDRV_OSS_INFO_DEV_TIMERS
2318 snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,2320 snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
@@ -2326,7 +2328,7 @@ static int __init alsa_timer_init(void) · 7 unmodified lines
2326 }2328 }
2327 2329
2328 err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,2330 err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
2329 &snd_timer_f_ops, NULL, &timer_dev);2331 &snd_timer_f_ops, NULL, timer_dev);
2330 if (err < 0) {2332 if (err < 0) {
2331 pr_err("ALSA: unable to register timer device (%i)\n", err);2333 pr_err("ALSA: unable to register timer device (%i)\n", err);
2332 snd_timer_free_all();2334 snd_timer_free_all();
@@ -2337,15 +2339,15 @@ static int __init alsa_timer_init(void) · 4 unmodified lines
2337 return 0;2339 return 0;
2338 2340
2339put_timer:2341put_timer:
2340 put_device(&timer_dev);2342 put_device(timer_dev);
2341 return err;2343 return err;
2342}2344}
2343 2345
2344static void __exit alsa_timer_exit(void)2346static void __exit alsa_timer_exit(void)
2345{2347{
2346 snd_unregister_device(&timer_dev);2348 snd_unregister_device(timer_dev);
2347 snd_timer_free_all();2349 snd_timer_free_all();
2348 put_device(&timer_dev);2350 put_device(timer_dev);
2349 snd_timer_proc_done();2351 snd_timer_proc_done();
2350#ifdef SNDRV_OSS_INFO_DEV_TIMERS2352#ifdef SNDRV_OSS_INFO_DEV_TIMERS
2351 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);2353 snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
sound/core/ump.c+57−9
@@ -13,10 +13,10 @@ · 12 unmodified lines
13#include <sound/ump.h>13#include <sound/ump.h>
14#include <sound/ump_convert.h>14#include <sound/ump_convert.h>
15 15
16#define ump_err(ump, fmt, args...) dev_err(&(ump)->core.dev, fmt, ##args)16#define ump_err(ump, fmt, args...) dev_err((ump)->core.dev, fmt, ##args)
17#define ump_warn(ump, fmt, args...) dev_warn(&(ump)->core.dev, fmt, ##args)17#define ump_warn(ump, fmt, args...) dev_warn((ump)->core.dev, fmt, ##args)
18#define ump_info(ump, fmt, args...) dev_info(&(ump)->core.dev, fmt, ##args)18#define ump_info(ump, fmt, args...) dev_info((ump)->core.dev, fmt, ##args)
19#define ump_dbg(ump, fmt, args...) dev_dbg(&(ump)->core.dev, fmt, ##args)19#define ump_dbg(ump, fmt, args...) dev_dbg((ump)->core.dev, fmt, ##args)
20 20
21static int snd_ump_dev_register(struct snd_rawmidi *rmidi);21static int snd_ump_dev_register(struct snd_rawmidi *rmidi);
22static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi);22static int snd_ump_dev_unregister(struct snd_rawmidi *rmidi);
@@ -984,7 +984,7 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream) · 961 unmodified lines
984{984{
985 struct snd_ump_endpoint *ump = substream->rmidi->private_data;985 struct snd_ump_endpoint *ump = substream->rmidi->private_data;
986 int dir = substream->stream;986 int dir = substream->stream;
987 int group = substream->number;987 int group = ump->legacy_mapping[substream->number];
988 int err;988 int err;
989 989
990 mutex_lock(&ump->open_mutex);990 mutex_lock(&ump->open_mutex);
@@ -1016,7 +1016,7 @@ static int snd_ump_legacy_close(struct snd_rawmidi_substream *substream) · 25 unmodified lines
1016{1016{
1017 struct snd_ump_endpoint *ump = substream->rmidi->private_data;1017 struct snd_ump_endpoint *ump = substream->rmidi->private_data;
1018 int dir = substream->stream;1018 int dir = substream->stream;
1019 int group = substream->number;1019 int group = ump->legacy_mapping[substream->number];
1020 1020
1021 mutex_lock(&ump->open_mutex);1021 mutex_lock(&ump->open_mutex);
1022 spin_lock_irq(&ump->legacy_locks[dir]);1022 spin_lock_irq(&ump->legacy_locks[dir]);
@@ -1123,21 +1123,62 @@ static void process_legacy_input(struct snd_ump_endpoint *ump, const u32 *src, · 100 unmodified lines
1123 spin_unlock_irqrestore(&ump->legacy_locks[dir], flags);1123 spin_unlock_irqrestore(&ump->legacy_locks[dir], flags);
1124}1124}
1125 1125
1126/* Fill ump->legacy_mapping[] for groups to be used for legacy rawmidi */
1127static int fill_legacy_mapping(struct snd_ump_endpoint *ump)
1128{
1129 struct snd_ump_block *fb;
1130 unsigned int group_maps = 0;
1131 int i, num;
1132
1133 if (ump->info.flags & SNDRV_UMP_EP_INFO_STATIC_BLOCKS) {
1134 list_for_each_entry(fb, &ump->block_list, list) {
1135 for (i = 0; i < fb->info.num_groups; i++)
1136 group_maps |= 1U << (fb->info.first_group + i);
1137 }
1138 if (!group_maps)
1139 ump_info(ump, "No UMP Group is found in FB\n");
1140 }
1141
1142 /* use all groups for non-static case */
1143 if (!group_maps)
1144 group_maps = (1U << SNDRV_UMP_MAX_GROUPS) - 1;
1145
1146 num = 0;
1147 for (i = 0; i < SNDRV_UMP_MAX_GROUPS; i++)
1148 if (group_maps & (1U << i))
1149 ump->legacy_mapping[num++] = i;
1150
1151 return num;
1152}
1153
1154static void fill_substream_names(struct snd_ump_endpoint *ump,
1155 struct snd_rawmidi *rmidi, int dir)
1156{
1157 struct snd_rawmidi_substream *s;
1158
1159 list_for_each_entry(s, &rmidi->streams[dir].substreams, list)
1160 snprintf(s->name, sizeof(s->name), "Group %d (%.16s)",
1161 ump->legacy_mapping[s->number] + 1, ump->info.name);
1162}
1163
1126int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,1164int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump,
1127 char *id, int device)1165 char *id, int device)
1128{1166{
1129 struct snd_rawmidi *rmidi;1167 struct snd_rawmidi *rmidi;
1130 bool input, output;1168 bool input, output;
1131 int err;1169 int err, num;
1132 1170
1133 ump->out_cvts = kcalloc(16, sizeof(*ump->out_cvts), GFP_KERNEL);1171 ump->out_cvts = kcalloc(SNDRV_UMP_MAX_GROUPS,
1172 sizeof(*ump->out_cvts), GFP_KERNEL);
1134 if (!ump->out_cvts)1173 if (!ump->out_cvts)
1135 return -ENOMEM;1174 return -ENOMEM;
1136 1175
1176 num = fill_legacy_mapping(ump);
1177
1137 input = ump->core.info_flags & SNDRV_RAWMIDI_INFO_INPUT;1178 input = ump->core.info_flags & SNDRV_RAWMIDI_INFO_INPUT;
1138 output = ump->core.info_flags & SNDRV_RAWMIDI_INFO_OUTPUT;1179 output = ump->core.info_flags & SNDRV_RAWMIDI_INFO_OUTPUT;
1139 err = snd_rawmidi_new(ump->core.card, id, device,1180 err = snd_rawmidi_new(ump->core.card, id, device,
1140 output ? 16 : 0, input ? 16 : 0,1181 output ? num : 0, input ? num : 0,
1141 &rmidi);1182 &rmidi);
1142 if (err < 0) {1183 if (err < 0) {
1143 kfree(ump->out_cvts);1184 kfree(ump->out_cvts);
@@ -1150,10 +1191,17 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, · 6 unmodified lines
1150 if (output)1191 if (output)
1151 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,1192 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
1152 &snd_ump_legacy_output_ops);1193 &snd_ump_legacy_output_ops);
1194 snprintf(rmidi->name, sizeof(rmidi->name), "%.68s (MIDI 1.0)",
1195 ump->info.name);
1153 rmidi->info_flags = ump->core.info_flags & ~SNDRV_RAWMIDI_INFO_UMP;1196 rmidi->info_flags = ump->core.info_flags & ~SNDRV_RAWMIDI_INFO_UMP;
1154 rmidi->ops = &snd_ump_legacy_ops;1197 rmidi->ops = &snd_ump_legacy_ops;
1155 rmidi->private_data = ump;1198 rmidi->private_data = ump;
1156 ump->legacy_rmidi = rmidi;1199 ump->legacy_rmidi = rmidi;
1200 if (input)
1201 fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
1202 if (output)
1203 fill_substream_names(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
1204
1157 ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id);1205 ump_dbg(ump, "Created a legacy rawmidi #%d (%s)\n", device, id);
1158 return 0;1206 return 0;
1159}1207}
sound/core/vmaster.c+28−0
@@ -280,6 +280,34 @@ int _snd_ctl_add_follower(struct snd_kcontrol *master, · 279 unmodified lines
280}280}
281EXPORT_SYMBOL(_snd_ctl_add_follower);281EXPORT_SYMBOL(_snd_ctl_add_follower);
282 282
283/**
284 * snd_ctl_add_followers - add multiple followers to vmaster
285 * @card: card instance
286 * @master: the target vmaster kcontrol object
287 * @list: NULL-terminated list of name strings of followers to be added
288 *
289 * Adds the multiple follower kcontrols with the given names.
290 * Returns 0 for success or a negative error code.
291 */
292int snd_ctl_add_followers(struct snd_card *card, struct snd_kcontrol *master,
293 const char * const *list)
294{
295 struct snd_kcontrol *follower;
296 int err;
297
298 for (; *list; list++) {
299 follower = snd_ctl_find_id_mixer(card, *list);
300 if (follower) {
301 err = snd_ctl_add_follower(master, follower);
302 if (err < 0)
303 return err;
304 }
305 }
306
307 return 0;
308}
309EXPORT_SYMBOL_GPL(snd_ctl_add_followers);
310
283/*311/*
284 * ctl callbacks for master controls312 * ctl callbacks for master controls
285 */313 */
sound/drivers/Kconfig+1−0
@@ -111,6 +111,7 @@ config SND_ALOOP · 110 unmodified lines
111 111
112config SND_PCMTEST112config SND_PCMTEST
113 tristate "Virtual PCM test driver"113 tristate "Virtual PCM test driver"
114 depends on DEBUG_FS
114 select SND_PCM115 select SND_PCM
115 help116 help
116 Say 'Y' or 'M' to include support for the Virtual PCM test driver.117 Say 'Y' or 'M' to include support for the Virtual PCM test driver.
sound/drivers/dummy.c+2−10
@@ -626,14 +626,7 @@ static int alloc_fake_buffer(void) · 625 unmodified lines
626 626
627static int dummy_pcm_copy(struct snd_pcm_substream *substream,627static int dummy_pcm_copy(struct snd_pcm_substream *substream,
628 int channel, unsigned long pos,628 int channel, unsigned long pos,
629 void __user *dst, unsigned long bytes)629 struct iov_iter *iter, unsigned long bytes)
630{
631 return 0; /* do nothing */
632}
633
634static int dummy_pcm_copy_kernel(struct snd_pcm_substream *substream,
635 int channel, unsigned long pos,
636 void *dst, unsigned long bytes)
637{630{
638 return 0; /* do nothing */631 return 0; /* do nothing */
639}632}
@@ -667,8 +660,7 @@ static const struct snd_pcm_ops dummy_pcm_ops_no_buf = { · 27 unmodified lines
667 .prepare = dummy_pcm_prepare,660 .prepare = dummy_pcm_prepare,
668 .trigger = dummy_pcm_trigger,661 .trigger = dummy_pcm_trigger,
669 .pointer = dummy_pcm_pointer,662 .pointer = dummy_pcm_pointer,
670 .copy_user = dummy_pcm_copy,663 .copy = dummy_pcm_copy,
671 .copy_kernel = dummy_pcm_copy_kernel,
672 .fill_silence = dummy_pcm_silence,664 .fill_silence = dummy_pcm_silence,
673 .page = dummy_pcm_page,665 .page = dummy_pcm_page,
674};666};
sound/drivers/pcmtest.c+70−32
@@ -41,8 +41,6 @@ · 40 unmodified lines
41#include <linux/debugfs.h>41#include <linux/debugfs.h>
42#include <linux/delay.h>42#include <linux/delay.h>
43 43
44#define DEVNAME "pcmtestd"
45#define CARD_NAME "pcm-test-card"
46#define TIMER_PER_SEC 544#define TIMER_PER_SEC 5
47#define TIMER_INTERVAL (HZ / TIMER_PER_SEC)45#define TIMER_INTERVAL (HZ / TIMER_PER_SEC)
48#define DELAY_JIFFIES HZ46#define DELAY_JIFFIES HZ
@@ -65,6 +63,7 @@ static int inject_delay; · 16 unmodified lines
65static bool inject_hwpars_err;63static bool inject_hwpars_err;
66static bool inject_prepare_err;64static bool inject_prepare_err;
67static bool inject_trigger_err;65static bool inject_trigger_err;
66static bool inject_open_err;
68 67
69static short fill_mode = FILL_MODE_PAT;68static short fill_mode = FILL_MODE_PAT;
70 69
@@ -73,11 +72,11 @@ static u8 ioctl_reset_test; · 2 unmodified lines
73static struct dentry *driver_debug_dir;72static struct dentry *driver_debug_dir;
74 73
75module_param(index, int, 0444);74module_param(index, int, 0444);
76MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard");75MODULE_PARM_DESC(index, "Index value for pcmtest soundcard");
77module_param(id, charp, 0444);76module_param(id, charp, 0444);
78MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard");77MODULE_PARM_DESC(id, "ID string for pcmtest soundcard");
79module_param(enable, bool, 0444);78module_param(enable, bool, 0444);
80MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");79MODULE_PARM_DESC(enable, "Enable pcmtest soundcard.");
81module_param(fill_mode, short, 0600);80module_param(fill_mode, short, 0600);
82MODULE_PARM_DESC(fill_mode, "Buffer fill mode: rand(0) or pattern(1)");81MODULE_PARM_DESC(fill_mode, "Buffer fill mode: rand(0) or pattern(1)");
83module_param(inject_delay, int, 0600);82module_param(inject_delay, int, 0600);
@@ -88,6 +87,8 @@ module_param(inject_prepare_err, bool, 0600); · 4 unmodified lines
88MODULE_PARM_DESC(inject_prepare_err, "Inject EINVAL error in the 'prepare' callback");87MODULE_PARM_DESC(inject_prepare_err, "Inject EINVAL error in the 'prepare' callback");
89module_param(inject_trigger_err, bool, 0600);88module_param(inject_trigger_err, bool, 0600);
90MODULE_PARM_DESC(inject_trigger_err, "Inject EINVAL error in the 'trigger' callback");89MODULE_PARM_DESC(inject_trigger_err, "Inject EINVAL error in the 'trigger' callback");
90module_param(inject_open_err, bool, 0600);
91MODULE_PARM_DESC(inject_open_err, "Inject EBUSY error in the 'open' callback");
91 92
92struct pcmtst {93struct pcmtst {
93 struct snd_pcm *pcm;94 struct snd_pcm *pcm;
@@ -107,6 +108,7 @@ struct pcmtst_buf_iter { · 13 unmodified lines
107 size_t total_bytes; // Total bytes read/written108 size_t total_bytes; // Total bytes read/written
108 size_t chan_block; // Bytes in one channel buffer when non-interleaved109 size_t chan_block; // Bytes in one channel buffer when non-interleaved
109 struct snd_pcm_substream *substream;110 struct snd_pcm_substream *substream;
111 bool suspend; // We need to pause timer without shutting it down
110 struct timer_list timer_instance;112 struct timer_list timer_instance;
111};113};
112 114
@@ -114,7 +116,8 @@ static struct snd_pcm_hardware snd_pcmtst_hw = { · 1 unmodified line
114 .info = (SNDRV_PCM_INFO_INTERLEAVED |116 .info = (SNDRV_PCM_INFO_INTERLEAVED |
115 SNDRV_PCM_INFO_BLOCK_TRANSFER |117 SNDRV_PCM_INFO_BLOCK_TRANSFER |
116 SNDRV_PCM_INFO_NONINTERLEAVED |118 SNDRV_PCM_INFO_NONINTERLEAVED |
117 SNDRV_PCM_INFO_MMAP_VALID),119 SNDRV_PCM_INFO_MMAP_VALID |
120 SNDRV_PCM_INFO_PAUSE),
118 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,121 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
119 .rates = SNDRV_PCM_RATE_8000_48000,122 .rates = SNDRV_PCM_RATE_8000_48000,
120 .rate_min = 8000,123 .rate_min = 8000,
@@ -140,7 +143,8 @@ static inline void inc_buf_pos(struct pcmtst_buf_iter *v_iter, size_t by, size_t · 19 unmodified lines
140{143{
141 v_iter->total_bytes += by;144 v_iter->total_bytes += by;
142 v_iter->buf_pos += by;145 v_iter->buf_pos += by;
143 v_iter->buf_pos %= bytes;146 if (v_iter->buf_pos >= bytes)
147 v_iter->buf_pos %= bytes;
144}148}
145 149
146/*150/*
@@ -196,10 +200,10 @@ static void check_buf_block_ni(struct pcmtst_buf_iter *v_iter, struct snd_pcm_ru · 49 unmodified lines
196 u8 current_byte;200 u8 current_byte;
197 201
198 for (i = 0; i < v_iter->b_rw; i++) {202 for (i = 0; i < v_iter->b_rw; i++) {
199 current_byte = runtime->dma_area[buf_pos_n(v_iter, channels, i % channels)];203 ch_num = i % channels;
204 current_byte = runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)];
200 if (!current_byte)205 if (!current_byte)
201 break;206 break;
202 ch_num = i % channels;
203 if (current_byte != patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)207 if (current_byte != patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
204 % patt_bufs[ch_num].len]) {208 % patt_bufs[ch_num].len]) {
205 v_iter->is_buf_corrupted = true;209 v_iter->is_buf_corrupted = true;
@@ -225,7 +229,7 @@ static void check_buf_block(struct pcmtst_buf_iter *v_iter, struct snd_pcm_runti · 19 unmodified lines
225 229
226/*230/*
227 * Fill buffer in the non-interleaved mode. The order of samples is C0, ..., C0, C1, ..., C1, C2...231 * Fill buffer in the non-interleaved mode. The order of samples is C0, ..., C0, C1, ..., C1, C2...
228 * The channel buffers lay in the DMA buffer continuously (see default copy_user and copy_kernel232 * The channel buffers lay in the DMA buffer continuously (see default copy
229 * handlers in the pcm_lib.c file).233 * handlers in the pcm_lib.c file).
230 *234 *
231 * Here we increment the DMA buffer position every time we write a byte to any channel 'buffer'.235 * Here we increment the DMA buffer position every time we write a byte to any channel 'buffer'.
@@ -239,7 +243,7 @@ static void fill_block_pattern_n(struct pcmtst_buf_iter *v_iter, struct snd_pcm_ · 7 unmodified lines
239 243
240 for (i = 0; i < v_iter->b_rw; i++) {244 for (i = 0; i < v_iter->b_rw; i++) {
241 ch_num = i % channels;245 ch_num = i % channels;
242 runtime->dma_area[buf_pos_n(v_iter, channels, i % channels)] =246 runtime->dma_area[buf_pos_n(v_iter, channels, ch_num)] =
243 patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)247 patt_bufs[ch_num].buf[(v_iter->total_bytes / channels)
244 % patt_bufs[ch_num].len];248 % patt_bufs[ch_num].len];
245 inc_buf_pos(v_iter, 1, runtime->dma_bytes);249 inc_buf_pos(v_iter, 1, runtime->dma_bytes);
@@ -344,6 +348,9 @@ static void timer_timeout(struct timer_list *data) · 98 unmodified lines
344 v_iter = from_timer(v_iter, data, timer_instance);348 v_iter = from_timer(v_iter, data, timer_instance);
345 substream = v_iter->substream;349 substream = v_iter->substream;
346 350
351 if (v_iter->suspend)
352 return;
353
347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !v_iter->is_buf_corrupted)354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !v_iter->is_buf_corrupted)
348 check_buf_block(v_iter, substream->runtime);355 check_buf_block(v_iter, substream->runtime);
349 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)356 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -356,7 +363,9 @@ static void timer_timeout(struct timer_list *data) · 6 unmodified lines
356 v_iter->period_pos %= v_iter->period_bytes;363 v_iter->period_pos %= v_iter->period_bytes;
357 snd_pcm_period_elapsed(substream);364 snd_pcm_period_elapsed(substream);
358 }365 }
359 mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);366
367 if (!v_iter->suspend)
368 mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL + inject_delay);
360}369}
361 370
362static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)371static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream)
@@ -364,23 +373,22 @@ static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream) · 1 unmodified line
364 struct snd_pcm_runtime *runtime = substream->runtime;373 struct snd_pcm_runtime *runtime = substream->runtime;
365 struct pcmtst_buf_iter *v_iter;374 struct pcmtst_buf_iter *v_iter;
366 375
376 if (inject_open_err)
377 return -EBUSY;
378
367 v_iter = kzalloc(sizeof(*v_iter), GFP_KERNEL);379 v_iter = kzalloc(sizeof(*v_iter), GFP_KERNEL);
368 if (!v_iter)380 if (!v_iter)
369 return -ENOMEM;381 return -ENOMEM;
370 382
383 v_iter->substream = substream;
371 runtime->hw = snd_pcmtst_hw;384 runtime->hw = snd_pcmtst_hw;
372 runtime->private_data = v_iter;385 runtime->private_data = v_iter;
373 v_iter->substream = substream;
374 v_iter->buf_pos = 0;
375 v_iter->is_buf_corrupted = false;
376 v_iter->period_pos = 0;
377 v_iter->total_bytes = 0;
378 386
379 playback_capture_test = 0;387 playback_capture_test = 0;
380 ioctl_reset_test = 0;388 ioctl_reset_test = 0;
381 389
382 timer_setup(&v_iter->timer_instance, timer_timeout, 0);390 timer_setup(&v_iter->timer_instance, timer_timeout, 0);
383 mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);391
384 return 0;392 return 0;
385}393}
386 394
@@ -395,26 +403,40 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream) · 8 unmodified lines
395 return 0;403 return 0;
396}404}
397 405
406static inline void reset_buf_iterator(struct pcmtst_buf_iter *v_iter)
407{
408 v_iter->buf_pos = 0;
409 v_iter->is_buf_corrupted = false;
410 v_iter->period_pos = 0;
411 v_iter->total_bytes = 0;
412}
413
414static inline void start_pcmtest_timer(struct pcmtst_buf_iter *v_iter)
415{
416 v_iter->suspend = false;
417 mod_timer(&v_iter->timer_instance, jiffies + TIMER_INTERVAL);
418}
419
398static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)420static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
399{421{
400 struct snd_pcm_runtime *runtime = substream->runtime;422 struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
401 struct pcmtst_buf_iter *v_iter = runtime->private_data;
402 423
403 if (inject_trigger_err)424 if (inject_trigger_err)
404 return -EINVAL;425 return -EINVAL;
405 426 switch (cmd) {
406 v_iter->sample_bytes = runtime->sample_bits / 8;427 case SNDRV_PCM_TRIGGER_START:
407 v_iter->period_bytes = frames_to_bytes(runtime, runtime->period_size);428 reset_buf_iterator(v_iter);
408 if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ||429 start_pcmtest_timer(v_iter);
409 runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) {430 break;
410 v_iter->chan_block = runtime->dma_bytes / runtime->channels;431 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
411 v_iter->interleaved = false;432 start_pcmtest_timer(v_iter);
412 } else {433 break;
413 v_iter->interleaved = true;434 case SNDRV_PCM_TRIGGER_STOP:
435 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
436 // We can't call timer_shutdown_sync here, as it is forbidden to sleep here
437 v_iter->suspend = true;
438 break;
414 }439 }
415 // We want to record RATE * ch_cnt samples per sec, it is rate * sample_bytes * ch_cnt bytes
416 v_iter->s_rw_ch = runtime->rate / TIMER_PER_SEC;
417 v_iter->b_rw = v_iter->s_rw_ch * v_iter->sample_bytes * runtime->channels;
418 440
419 return 0;441 return 0;
420}442}
@@ -446,8 +468,24 @@ static void pcmtst_pdev_release(struct device *dev) · 25 unmodified lines
446 468
447static int snd_pcmtst_pcm_prepare(struct snd_pcm_substream *substream)469static int snd_pcmtst_pcm_prepare(struct snd_pcm_substream *substream)
448{470{
471 struct snd_pcm_runtime *runtime = substream->runtime;
472 struct pcmtst_buf_iter *v_iter = runtime->private_data;
473
449 if (inject_prepare_err)474 if (inject_prepare_err)
450 return -EINVAL;475 return -EINVAL;
476
477 v_iter->sample_bytes = samples_to_bytes(runtime, 1);
478 v_iter->period_bytes = snd_pcm_lib_period_bytes(substream);
479 v_iter->interleaved = true;
480 if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ||
481 runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED) {
482 v_iter->chan_block = snd_pcm_lib_buffer_bytes(substream) / runtime->channels;
483 v_iter->interleaved = false;
484 }
485 // We want to record RATE * ch_cnt samples per sec, it is rate * sample_bytes * ch_cnt bytes
486 v_iter->s_rw_ch = runtime->rate / TIMER_PER_SEC;
487 v_iter->b_rw = v_iter->s_rw_ch * v_iter->sample_bytes * runtime->channels;
488
451 return 0;489 return 0;
452}490}
453 491
sound/drivers/serial-generic.c+2−2
@@ -16,7 +16,7 @@ · 15 unmodified lines
16#include <linux/io.h>16#include <linux/io.h>
17#include <linux/ioport.h>17#include <linux/ioport.h>
18#include <linux/module.h>18#include <linux/module.h>
19#include <linux/of_device.h>19#include <linux/of.h>
20#include <linux/serdev.h>20#include <linux/serdev.h>
21#include <linux/serial_reg.h>21#include <linux/serial_reg.h>
22#include <linux/slab.h>22#include <linux/slab.h>
@@ -366,7 +366,7 @@ MODULE_DEVICE_TABLE(of, snd_serial_generic_dt_ids); · 343 unmodified lines
366static struct serdev_device_driver snd_serial_generic_driver = {366static struct serdev_device_driver snd_serial_generic_driver = {
367 .driver = {367 .driver = {
368 .name = "snd-serial-generic",368 .name = "snd-serial-generic",
369 .of_match_table = of_match_ptr(snd_serial_generic_dt_ids),369 .of_match_table = snd_serial_generic_dt_ids,
370 },370 },
371 .probe = snd_serial_generic_probe,371 .probe = snd_serial_generic_probe,
372};372};
sound/firewire/dice/Makefile+1−1
@@ -2,5 +2,5 @@ · 1 unmodified line
2snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \2snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
3 dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \3 dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
4 dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o \4 dice-alesis.o dice-extension.o dice-mytek.o dice-presonus.o \
5 dice-harman.o dice-focusrite.o5 dice-harman.o dice-focusrite.o dice-weiss.o
6obj-$(CONFIG_SND_DICE) += snd-dice.o6obj-$(CONFIG_SND_DICE) += snd-dice.o
sound/firewire/dice/dice-weiss.c+104−0
@@ -0,0 +1,104 @@
1// SPDX-License-Identifier: GPL-2.0
2// dice-weiss.c - a part of driver for DICE based devices
3//
4// Copyright (c) 2023 Rolf Anderegg and Michele Perrone
5
6#include "dice.h"
7
8struct dice_weiss_spec {
9 unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
10 unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
11};
12
13// Weiss DAC202: 192kHz 2-channel DAC
14static const struct dice_weiss_spec dac202 = {
15 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
16 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
17};
18
19// Weiss MAN301: 192kHz 2-channel music archive network player
20static const struct dice_weiss_spec man301 = {
21 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
22 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
23};
24
25// Weiss INT202: 192kHz unidirectional 2-channel digital Firewire nterface
26static const struct dice_weiss_spec int202 = {
27 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
28 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
29};
30
31// Weiss INT203: 192kHz bidirectional 2-channel digital Firewire nterface
32static const struct dice_weiss_spec int203 = {
33 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
34 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
35};
36
37// Weiss ADC2: 192kHz A/D converter with microphone preamps and line nputs
38static const struct dice_weiss_spec adc2 = {
39 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
40 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
41};
42
43// Weiss DAC2/Minerva: 192kHz 2-channel DAC
44static const struct dice_weiss_spec dac2_minerva = {
45 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
46 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
47};
48
49// Weiss Vesta: 192kHz 2-channel Firewire to AES/EBU interface
50static const struct dice_weiss_spec vesta = {
51 .tx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
52 .rx_pcm_chs = {{2, 2, 2}, {0, 0, 0} },
53};
54
55// Weiss AFI1: 192kHz 24-channel Firewire to ADAT or AES/EBU interface
56static const struct dice_weiss_spec afi1 = {
57 .tx_pcm_chs = {{24, 16, 8}, {0, 0, 0} },
58 .rx_pcm_chs = {{24, 16, 8}, {0, 0, 0} },
59};
60
61int snd_dice_detect_weiss_formats(struct snd_dice *dice)
62{
63 static const struct {
64 u32 model_id;
65 const struct dice_weiss_spec *spec;
66 } *entry, entries[] = {
67 {0x000007, &dac202},
68 {0x000008, &dac202}, // Maya edition: same audio I/O as DAC202.
69 {0x000006, &int202},
70 {0x00000a, &int203},
71 {0x00000b, &man301},
72 {0x000001, &adc2},
73 {0x000003, &dac2_minerva},
74 {0x000002, &vesta},
75 {0x000004, &afi1},
76 };
77 struct fw_csr_iterator it;
78 int key, val, model_id;
79 int i;
80
81 model_id = 0;
82 fw_csr_iterator_init(&it, dice->unit->directory);
83 while (fw_csr_iterator_next(&it, &key, &val)) {
84 if (key == CSR_MODEL) {
85 model_id = val;
86 break;
87 }
88 }
89
90 for (i = 0; i < ARRAY_SIZE(entries); ++i) {
91 entry = entries + i;
92 if (entry->model_id == model_id)
93 break;
94 }
95 if (i == ARRAY_SIZE(entries))
96 return -ENODEV;
97
98 memcpy(dice->tx_pcm_chs, entry->spec->tx_pcm_chs,
99 MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
100 memcpy(dice->rx_pcm_chs, entry->spec->rx_pcm_chs,
101 MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
102
103 return 0;
104}
sound/firewire/dice/dice.c+63−0
@@ -392,6 +392,69 @@ static const struct ieee1394_device_id dice_id_table[] = { · 391 unmodified lines
392 .model_id = 0x0000de,392 .model_id = 0x0000de,
393 .driver_data = (kernel_ulong_t)snd_dice_detect_focusrite_pro40_tcd3070_formats,393 .driver_data = (kernel_ulong_t)snd_dice_detect_focusrite_pro40_tcd3070_formats,
394 },394 },
395 // Weiss DAC202: 192kHz 2-channel DAC
396 {
397 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
398 .vendor_id = OUI_WEISS,
399 .model_id = 0x000007,
400 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
401 },
402 // Weiss DAC202: 192kHz 2-channel DAC (Maya edition)
403 {
404 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
405 .vendor_id = OUI_WEISS,
406 .model_id = 0x000008,
407 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
408 },
409 // Weiss MAN301: 192kHz 2-channel music archive network player
410 {
411 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
412 .vendor_id = OUI_WEISS,
413 .model_id = 0x00000b,
414 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
415 },
416 // Weiss INT202: 192kHz unidirectional 2-channel digital Firewire face
417 {
418 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
419 .vendor_id = OUI_WEISS,
420 .model_id = 0x000006,
421 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
422 },
423 // Weiss INT203: 192kHz bidirectional 2-channel digital Firewire face
424 {
425 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
426 .vendor_id = OUI_WEISS,
427 .model_id = 0x00000a,
428 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
429 },
430 // Weiss ADC2: 192kHz A/D converter with microphone preamps and inputs
431 {
432 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
433 .vendor_id = OUI_WEISS,
434 .model_id = 0x000001,
435 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
436 },
437 // Weiss DAC2/Minerva: 192kHz 2-channel DAC
438 {
439 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
440 .vendor_id = OUI_WEISS,
441 .model_id = 0x000003,
442 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
443 },
444 // Weiss Vesta: 192kHz 2-channel Firewire to AES/EBU interface
445 {
446 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
447 .vendor_id = OUI_WEISS,
448 .model_id = 0x000002,
449 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
450 },
451 // Weiss AFI1: 192kHz 24-channel Firewire to ADAT or AES/EBU face
452 {
453 .match_flags = IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID,
454 .vendor_id = OUI_WEISS,
455 .model_id = 0x000004,
456 .driver_data = (kernel_ulong_t)snd_dice_detect_weiss_formats,
457 },
395 {458 {
396 .match_flags = IEEE1394_MATCH_VERSION,459 .match_flags = IEEE1394_MATCH_VERSION,
397 .version = DICE_INTERFACE,460 .version = DICE_INTERFACE,
sound/firewire/dice/dice.h+1−0
@@ -232,5 +232,6 @@ int snd_dice_detect_mytek_formats(struct snd_dice *dice); · 231 unmodified lines
232int snd_dice_detect_presonus_formats(struct snd_dice *dice);232int snd_dice_detect_presonus_formats(struct snd_dice *dice);
233int snd_dice_detect_harman_formats(struct snd_dice *dice);233int snd_dice_detect_harman_formats(struct snd_dice *dice);
234int snd_dice_detect_focusrite_pro40_tcd3070_formats(struct snd_dice *dice);234int snd_dice_detect_focusrite_pro40_tcd3070_formats(struct snd_dice *dice);
235int snd_dice_detect_weiss_formats(struct snd_dice *dice);
235 236
236#endif237#endif
sound/hda/hdac_i915.c+11−10
@@ -11,11 +11,6 @@ · 10 unmodified lines
11#include <sound/hda_i915.h>11#include <sound/hda_i915.h>
12#include <sound/hda_register.h>12#include <sound/hda_register.h>
13 13
14#define IS_HSW_CONTROLLER(pci) (((pci)->device == 0x0a0c) || \
15 ((pci)->device == 0x0c0c) || \
16 ((pci)->device == 0x0d0c) || \
17 ((pci)->device == 0x160c))
18
19/**14/**
20 * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW15 * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
21 * @bus: HDA core bus16 * @bus: HDA core bus
@@ -39,7 +34,7 @@ void snd_hdac_i915_set_bclk(struct hdac_bus *bus) · 17 unmodified lines
39 34
40 if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)35 if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
41 return; /* only for i915 binding */36 return; /* only for i915 binding */
42 if (!IS_HSW_CONTROLLER(pci))37 if (!HDA_CONTROLLER_IS_HSW(pci))
43 return; /* only HSW/BDW */38 return; /* only HSW/BDW */
44 39
45 cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);40 cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
@@ -80,14 +75,20 @@ static bool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac) · 34 unmodified lines
80 if (bus_a == bus_b)75 if (bus_a == bus_b)
81 return true;76 return true;
82 77
83 /*
84 * on i915 discrete GPUs with embedded HDA audio, the two
85 * devices are connected via 2nd level PCI bridge
86 */
87 bus_a = bus_a->parent;78 bus_a = bus_a->parent;
88 bus_b = bus_b->parent;79 bus_b = bus_b->parent;
80
81 /* connected via parent bus (may be NULL!) */
82 if (bus_a == bus_b)
83 return true;
84
89 if (!bus_a || !bus_b)85 if (!bus_a || !bus_b)
90 return false;86 return false;
87
88 /*
89 * on i915 discrete GPUs with embedded HDA audio, the two
90 * devices are connected via 2nd level PCI bridge
91 */
91 bus_a = bus_a->parent;92 bus_a = bus_a->parent;
92 bus_b = bus_b->parent;93 bus_b = bus_b->parent;
93 if (bus_a && bus_a == bus_b)94 if (bus_a && bus_a == bus_b)
sound/hda/intel-dsp-config.c+119−75
@@ -50,14 +50,7 @@ static const struct config_entry config_table[] = { · 49 unmodified lines
50#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)50#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD)
51 {51 {
52 .flags = FLAG_SOF,52 .flags = FLAG_SOF,
53 .device = 0x119a,53 .device = PCI_DEVICE_ID_INTEL_SST_TNG,
54 },
55#endif
56/* Broxton-T */
57#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
58 {
59 .flags = FLAG_SOF,
60 .device = 0x1a98,
61 },54 },
62#endif55#endif
63/*56/*
@@ -68,7 +61,7 @@ static const struct config_entry config_table[] = { · 4 unmodified lines
68#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)61#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
69 {62 {
70 .flags = FLAG_SOF,63 .flags = FLAG_SOF,
71 .device = 0x5a98,64 .device = PCI_DEVICE_ID_INTEL_HDA_APL,
72 .dmi_table = (const struct dmi_system_id []) {65 .dmi_table = (const struct dmi_system_id []) {
73 {66 {
74 .ident = "Up Squared",67 .ident = "Up Squared",
@@ -82,14 +75,14 @@ static const struct config_entry config_table[] = { · 7 unmodified lines
82 },75 },
83 {76 {
84 .flags = FLAG_SOF,77 .flags = FLAG_SOF,
85 .device = 0x5a98,78 .device = PCI_DEVICE_ID_INTEL_HDA_APL,
86 .codec_hid = &essx_83x6,79 .codec_hid = &essx_83x6,
87 },80 },
88#endif81#endif
89#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)82#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
90 {83 {
91 .flags = FLAG_SST,84 .flags = FLAG_SST,
92 .device = 0x5a98,85 .device = PCI_DEVICE_ID_INTEL_HDA_APL,
93 .dmi_table = (const struct dmi_system_id []) {86 .dmi_table = (const struct dmi_system_id []) {
94 {87 {
95 .ident = "Google Chromebooks",88 .ident = "Google Chromebooks",
@@ -110,7 +103,7 @@ static const struct config_entry config_table[] = { · 14 unmodified lines
110#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)103#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
111 {104 {
112 .flags = FLAG_SST,105 .flags = FLAG_SST,
113 .device = 0x9d70,106 .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
114 .dmi_table = (const struct dmi_system_id []) {107 .dmi_table = (const struct dmi_system_id []) {
115 {108 {
116 .ident = "Google Chromebooks",109 .ident = "Google Chromebooks",
@@ -123,14 +116,14 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
123 },116 },
124 {117 {
125 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,118 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
126 .device = 0x9d70,119 .device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
127 },120 },
128#endif121#endif
129/* Kabylake-LP */122/* Kabylake-LP */
130#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)123#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
131 {124 {
132 .flags = FLAG_SST,125 .flags = FLAG_SST,
133 .device = 0x9d71,126 .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
134 .dmi_table = (const struct dmi_system_id []) {127 .dmi_table = (const struct dmi_system_id []) {
135 {128 {
136 .ident = "Google Chromebooks",129 .ident = "Google Chromebooks",
@@ -143,7 +136,7 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
143 },136 },
144 {137 {
145 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,138 .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
146 .device = 0x9d71,139 .device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
147 },140 },
148#endif141#endif
149 142
@@ -155,7 +148,7 @@ static const struct config_entry config_table[] = { · 5 unmodified lines
155#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)148#if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE)
156 {149 {
157 .flags = FLAG_SOF,150 .flags = FLAG_SOF,
158 .device = 0x3198,151 .device = PCI_DEVICE_ID_INTEL_HDA_GML,
159 .dmi_table = (const struct dmi_system_id []) {152 .dmi_table = (const struct dmi_system_id []) {
160 {153 {
161 .ident = "Google Chromebooks",154 .ident = "Google Chromebooks",
@@ -168,16 +161,16 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
168 },161 },
169 {162 {
170 .flags = FLAG_SOF,163 .flags = FLAG_SOF,
171 .device = 0x3198,164 .device = PCI_DEVICE_ID_INTEL_HDA_GML,
172 .codec_hid = &essx_83x6,165 .codec_hid = &essx_83x6,
173 },166 },
174#endif167#endif
175 168
176/*169/*
177 * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake use legacy170 * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake,
178 * HDAudio driver except for Google Chromebooks and when DMICs are171 * RaptorLake use legacy HDAudio driver except for Google Chromebooks
179 * present. Two cases are required since Coreboot does not expose NHLT172 * and when DMICs are present. Two cases are required since Coreboot
180 * tables.173 * does not expose NHLT tables.
181 *174 *
182 * When the Chromebook quirk is not present, it's based on information175 * When the Chromebook quirk is not present, it's based on information
183 * that no such device exists. When the quirk is present, it could be176 * that no such device exists. When the quirk is present, it could be
@@ -188,7 +181,7 @@ static const struct config_entry config_table[] = { · 4 unmodified lines
188#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)181#if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE)
189 {182 {
190 .flags = FLAG_SOF,183 .flags = FLAG_SOF,
191 .device = 0x9dc8,184 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
192 .dmi_table = (const struct dmi_system_id []) {185 .dmi_table = (const struct dmi_system_id []) {
193 {186 {
194 .ident = "Google Chromebooks",187 .ident = "Google Chromebooks",
@@ -207,12 +200,12 @@ static const struct config_entry config_table[] = { · 12 unmodified lines
207 },200 },
208 {201 {
209 .flags = FLAG_SOF,202 .flags = FLAG_SOF,
210 .device = 0x09dc8,203 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
211 .codec_hid = &essx_83x6,204 .codec_hid = &essx_83x6,
212 },205 },
213 {206 {
214 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,207 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
215 .device = 0x9dc8,208 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
216 },209 },
217#endif210#endif
218 211
@@ -220,7 +213,7 @@ static const struct config_entry config_table[] = { · 1 unmodified line
220#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)213#if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE)
221 {214 {
222 .flags = FLAG_SOF,215 .flags = FLAG_SOF,
223 .device = 0xa348,216 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
224 .dmi_table = (const struct dmi_system_id []) {217 .dmi_table = (const struct dmi_system_id []) {
225 {218 {
226 .ident = "Google Chromebooks",219 .ident = "Google Chromebooks",
@@ -233,7 +226,7 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
233 },226 },
234 {227 {
235 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,228 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
236 .device = 0xa348,229 .device = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
237 },230 },
238#endif231#endif
239 232
@@ -241,7 +234,7 @@ static const struct config_entry config_table[] = { · 1 unmodified line
241/* Cometlake-LP */234/* Cometlake-LP */
242 {235 {
243 .flags = FLAG_SOF,236 .flags = FLAG_SOF,
244 .device = 0x02c8,237 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
245 .dmi_table = (const struct dmi_system_id []) {238 .dmi_table = (const struct dmi_system_id []) {
246 {239 {
247 .ident = "Google Chromebooks",240 .ident = "Google Chromebooks",
@@ -267,17 +260,17 @@ static const struct config_entry config_table[] = { · 19 unmodified lines
267 },260 },
268 {261 {
269 .flags = FLAG_SOF,262 .flags = FLAG_SOF,
270 .device = 0x02c8,263 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
271 .codec_hid = &essx_83x6,264 .codec_hid = &essx_83x6,
272 },265 },
273 {266 {
274 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,267 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
275 .device = 0x02c8,268 .device = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
276 },269 },
277/* Cometlake-H */270/* Cometlake-H */
278 {271 {
279 .flags = FLAG_SOF,272 .flags = FLAG_SOF,
280 .device = 0x06c8,273 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
281 .dmi_table = (const struct dmi_system_id []) {274 .dmi_table = (const struct dmi_system_id []) {
282 {275 {
283 .matches = {276 .matches = {
@@ -296,12 +289,12 @@ static const struct config_entry config_table[] = { · 12 unmodified lines
296 },289 },
297 {290 {
298 .flags = FLAG_SOF,291 .flags = FLAG_SOF,
299 .device = 0x06c8,292 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
300 .codec_hid = &essx_83x6,293 .codec_hid = &essx_83x6,
301 },294 },
302 {295 {
303 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,296 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
304 .device = 0x06c8,297 .device = PCI_DEVICE_ID_INTEL_HDA_CML_H,
305 },298 },
306#endif299#endif
307 300
@@ -309,7 +302,7 @@ static const struct config_entry config_table[] = { · 1 unmodified line
309#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)302#if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE)
310 {303 {
311 .flags = FLAG_SOF,304 .flags = FLAG_SOF,
312 .device = 0x34c8,305 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
313 .dmi_table = (const struct dmi_system_id []) {306 .dmi_table = (const struct dmi_system_id []) {
314 {307 {
315 .ident = "Google Chromebooks",308 .ident = "Google Chromebooks",
@@ -322,12 +315,12 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
322 },315 },
323 {316 {
324 .flags = FLAG_SOF,317 .flags = FLAG_SOF,
325 .device = 0x34c8,318 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
326 .codec_hid = &essx_83x6,319 .codec_hid = &essx_83x6,
327 },320 },
328 {321 {
329 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,322 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
330 .device = 0x34c8,323 .device = PCI_DEVICE_ID_INTEL_HDA_ICL_LP,
331 },324 },
332#endif325#endif
333 326
@@ -335,7 +328,7 @@ static const struct config_entry config_table[] = { · 1 unmodified line
335#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)328#if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
336 {329 {
337 .flags = FLAG_SOF,330 .flags = FLAG_SOF,
338 .device = 0x4dc8,331 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
339 .dmi_table = (const struct dmi_system_id []) {332 .dmi_table = (const struct dmi_system_id []) {
340 {333 {
341 .ident = "Google Chromebooks",334 .ident = "Google Chromebooks",
@@ -348,12 +341,12 @@ static const struct config_entry config_table[] = { · 6 unmodified lines
348 },341 },
349 {342 {
350 .flags = FLAG_SOF,343 .flags = FLAG_SOF,
351 .device = 0x4dc8,344 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
352 .codec_hid = &essx_83x6,345 .codec_hid = &essx_83x6,
353 },346 },
354 {347 {
355 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,348 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
356 .device = 0x4dc8,349 .device = PCI_DEVICE_ID_INTEL_HDA_JSL_N,
357 },350 },
358#endif351#endif
359 352
@@ -361,7 +354,7 @@ static const struct config_entry config_table[] = { · 1 unmodified line
361#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)354#if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE)
362 {355 {
363 .flags = FLAG_SOF,356 .flags = FLAG_SOF,
364 .device = 0xa0c8,357 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
365 .dmi_table = (const struct dmi_system_id []) {358 .dmi_table = (const struct dmi_system_id []) {
366 {359 {
367 .ident = "Google Chromebooks",360 .ident = "Google Chromebooks",
@@ -380,16 +373,16 @@ static const struct config_entry config_table[] = { · 12 unmodified lines
380 },373 },
381 {374 {
382 .flags = FLAG_SOF,375 .flags = FLAG_SOF,
383 .device = 0xa0c8,376 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
384 .codec_hid = &essx_83x6,377 .codec_hid = &essx_83x6,
385 },378 },
386 {379 {
387 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,380 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
388 .device = 0xa0c8,381 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_LP,
389 },382 },
390 {383 {
391 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,384 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
392 .device = 0x43c8,385 .device = PCI_DEVICE_ID_INTEL_HDA_TGL_H,
393 },386 },
394#endif387#endif
395 388
@@ -397,78 +390,121 @@ static const struct config_entry config_table[] = { · 1 unmodified line
397#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)390#if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE)
398 {391 {
399 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,392 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
400 .device = 0x4b55,393 .device = PCI_DEVICE_ID_INTEL_HDA_EHL_0,
401 },394 },
402 {395 {
403 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,396 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
404 .device = 0x4b58,397 .device = PCI_DEVICE_ID_INTEL_HDA_EHL_3,
405 },398 },
406#endif399#endif
407 400
408/* Alder Lake */401/* Alder Lake / Raptor Lake */
409#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)402#if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE)
410 /* Alderlake-S */
411 {403 {
412 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,404 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
413 .device = 0x7ad0,405 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_S,
414 },406 },
415 /* RaptorLake-S */
416 {407 {
417 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,408 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
418 .device = 0x7a50,409 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_S,
419 },410 },
420 /* Alderlake-P */
421 {411 {
422 .flags = FLAG_SOF,412 .flags = FLAG_SOF,
423 .device = 0x51c8,413 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
414 .dmi_table = (const struct dmi_system_id []) {
415 {
416 .ident = "Google Chromebooks",
417 .matches = {
418 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
419 }
420 },
421 {}
422 }
423 },
424 {
425 .flags = FLAG_SOF,
426 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
424 .codec_hid = &essx_83x6,427 .codec_hid = &essx_83x6,
425 },428 },
426 {429 {
427 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,430 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
428 .device = 0x51c8,431 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_P,
429 },432 },
430 {433 {
431 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,434 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
432 .device = 0x51cd,435 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PX,
433 },436 },
434 /* Alderlake-PS */
435 {437 {
436 .flags = FLAG_SOF,438 .flags = FLAG_SOF,
437 .device = 0x51c9,439 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
438 .codec_hid = &essx_83x6,440 .codec_hid = &essx_83x6,
439 },441 },
440 {442 {
441 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,443 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
442 .device = 0x51c9,444 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_PS,
443 },445 },
444 /* Alderlake-M */
445 {446 {
446 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,447 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
447 .device = 0x51cc,448 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_M,
449 },
450 {
451 .flags = FLAG_SOF,
452 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
453 .dmi_table = (const struct dmi_system_id []) {
454 {
455 .ident = "Google Chromebooks",
456 .matches = {
457 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
458 }
459 },
460 {}
461 }
448 },462 },
449 /* Alderlake-N */
450 {463 {
451 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,464 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
452 .device = 0x54c8,465 .device = PCI_DEVICE_ID_INTEL_HDA_ADL_N,
466 },
467 {
468 .flags = FLAG_SOF,
469 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
470 .dmi_table = (const struct dmi_system_id []) {
471 {
472 .ident = "Google Chromebooks",
473 .matches = {
474 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
475 }
476 },
477 {}
478 }
453 },479 },
454 /* RaptorLake-P */
455 {480 {
456 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,481 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
457 .device = 0x51ca,482 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_0,
483 },
484 {
485 .flags = FLAG_SOF,
486 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
487 .dmi_table = (const struct dmi_system_id []) {
488 {
489 .ident = "Google Chromebooks",
490 .matches = {
491 DMI_MATCH(DMI_SYS_VENDOR, "Google"),
492 }
493 },
494 {}
495 }
458 },496 },
459 {497 {
460 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,498 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
461 .device = 0x51cb,499 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_P_1,
462 },500 },
463 /* RaptorLake-M */
464 {501 {
465 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,502 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
466 .device = 0x51ce,503 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_M,
467 },504 },
468 /* RaptorLake-PX */
469 {505 {
470 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,506 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
471 .device = 0x51cf,507 .device = PCI_DEVICE_ID_INTEL_HDA_RPL_PX,
472 },508 },
473#endif509#endif
474 510
@@ -477,10 +513,18 @@ static const struct config_entry config_table[] = { · 2 unmodified lines
477 /* Meteorlake-P */513 /* Meteorlake-P */
478 {514 {
479 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,515 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
480 .device = 0x7e28,516 .device = PCI_DEVICE_ID_INTEL_HDA_MTL,
481 },517 },
482#endif518#endif
483 519
520/* Lunar Lake */
521#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE)
522 /* Lunarlake-P */
523 {
524 .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
525 .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P,
526 },
527#endif
484};528};
485 529
486static const struct config_entry *snd_intel_dsp_find_config530static const struct config_entry *snd_intel_dsp_find_config
@@ -549,7 +593,7 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci) · 62 unmodified lines
549 const struct config_entry *cfg;593 const struct config_entry *cfg;
550 594
551 /* Intel vendor only */595 /* Intel vendor only */
552 if (pci->vendor != 0x8086)596 if (pci->vendor != PCI_VENDOR_ID_INTEL)
553 return SND_INTEL_DSP_DRIVER_ANY;597 return SND_INTEL_DSP_DRIVER_ANY;
554 598
555 /*599 /*
@@ -557,12 +601,12 @@ int snd_intel_dsp_driver_probe(struct pci_dev *pci) · 1 unmodified line
557 * for HDMI/DP support, ignore kernel parameter601 * for HDMI/DP support, ignore kernel parameter
558 */602 */
559 switch (pci->device) {603 switch (pci->device) {
560 case 0x160c: /* Broadwell */604 case PCI_DEVICE_ID_INTEL_HDA_BDW:
561 case 0x0a0c: /* Haswell */605 case PCI_DEVICE_ID_INTEL_HDA_HSW_0:
562 case 0x0c0c:606 case PCI_DEVICE_ID_INTEL_HDA_HSW_2:
563 case 0x0d0c:607 case PCI_DEVICE_ID_INTEL_HDA_HSW_3:
564 case 0x0f04: /* Baytrail */608 case PCI_DEVICE_ID_INTEL_HDA_BYT:
565 case 0x2284: /* Braswell */609 case PCI_DEVICE_ID_INTEL_HDA_BSW:
566 return SND_INTEL_DSP_DRIVER_ANY;610 return SND_INTEL_DSP_DRIVER_ANY;
567 }611 }
568 612
sound/isa/gus/gus_pcm.c+3−20
@@ -369,7 +369,7 @@ static int playback_copy_ack(struct snd_pcm_substream *substream, · 368 unmodified lines
369 369
370static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,370static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
371 int voice, unsigned long pos,371 int voice, unsigned long pos,
372 void __user *src, unsigned long count)372 struct iov_iter *src, unsigned long count)
373{373{
374 struct snd_pcm_runtime *runtime = substream->runtime;374 struct snd_pcm_runtime *runtime = substream->runtime;
375 struct gus_pcm_private *pcmp = runtime->private_data;375 struct gus_pcm_private *pcmp = runtime->private_data;
@@ -379,27 +379,11 @@ static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream, · 3 unmodified lines
379 bpos = get_bpos(pcmp, voice, pos, len);379 bpos = get_bpos(pcmp, voice, pos, len);
380 if (bpos < 0)380 if (bpos < 0)
381 return pos;381 return pos;
382 if (copy_from_user(runtime->dma_area + bpos, src, len))382 if (copy_from_iter(runtime->dma_area + bpos, len, src) != len)
383 return -EFAULT;383 return -EFAULT;
384 return playback_copy_ack(substream, bpos, len);384 return playback_copy_ack(substream, bpos, len);
385}385}
386 386
387static int snd_gf1_pcm_playback_copy_kernel(struct snd_pcm_substream *substream,
388 int voice, unsigned long pos,
389 void *src, unsigned long count)
390{
391 struct snd_pcm_runtime *runtime = substream->runtime;
392 struct gus_pcm_private *pcmp = runtime->private_data;
393 unsigned int len = count;
394 int bpos;
395
396 bpos = get_bpos(pcmp, voice, pos, len);
397 if (bpos < 0)
398 return pos;
399 memcpy(runtime->dma_area + bpos, src, len);
400 return playback_copy_ack(substream, bpos, len);
401}
402
403static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,387static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
404 int voice, unsigned long pos,388 int voice, unsigned long pos,
405 unsigned long count)389 unsigned long count)
@@ -830,8 +814,7 @@ static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = { · 424 unmodified lines
830 .prepare = snd_gf1_pcm_playback_prepare,814 .prepare = snd_gf1_pcm_playback_prepare,
831 .trigger = snd_gf1_pcm_playback_trigger,815 .trigger = snd_gf1_pcm_playback_trigger,
832 .pointer = snd_gf1_pcm_playback_pointer,816 .pointer = snd_gf1_pcm_playback_pointer,
833 .copy_user = snd_gf1_pcm_playback_copy,817 .copy = snd_gf1_pcm_playback_copy,
834 .copy_kernel = snd_gf1_pcm_playback_copy_kernel,
835 .fill_silence = snd_gf1_pcm_playback_silence,818 .fill_silence = snd_gf1_pcm_playback_silence,
836};819};
837 820
sound/isa/sb/emu8000.c+0−2
@@ -1040,10 +1040,8 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu) · 1039 unmodified lines
1040 1040
1041__error:1041__error:
1042 for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {1042 for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1043 down_write(&card->controls_rwsem);
1044 if (emu->controls[i])1043 if (emu->controls[i])
1045 snd_ctl_remove(card, emu->controls[i]);1044 snd_ctl_remove(card, emu->controls[i]);
1046 up_write(&card->controls_rwsem);
1047 }1045 }
1048 return err;1046 return err;
1049}1047}
sound/isa/sb/emu8000_pcm.c+16−58
@@ -409,39 +409,25 @@ do { \ · 408 unmodified lines
409 return -EAGAIN;\409 return -EAGAIN;\
410} while (0)410} while (0)
411 411
412enum {412#define GET_VAL(sval, iter) \
413 COPY_USER, COPY_KERNEL, FILL_SILENCE,
414};
415
416#define GET_VAL(sval, buf, mode) \
417 do { \413 do { \
418 switch (mode) { \414 if (!iter) \
419 case FILL_SILENCE: \
420 sval = 0; \415 sval = 0; \
421 break; \416 else if (copy_from_iter(&sval, 2, iter) != 2) \
422 case COPY_KERNEL: \417 return -EFAULT; \
423 sval = *buf++; \
424 break; \
425 default: \
426 if (get_user(sval, (unsigned short __user *)buf)) \
427 return -EFAULT; \
428 buf++; \
429 break; \
430 } \
431 } while (0)418 } while (0)
432 419
433#ifdef USE_NONINTERLEAVE420#ifdef USE_NONINTERLEAVE
434 421
435#define LOOP_WRITE(rec, offset, _buf, count, mode) \422#define LOOP_WRITE(rec, offset, iter, count) \
436 do { \423 do { \
437 struct snd_emu8000 *emu = (rec)->emu; \424 struct snd_emu8000 *emu = (rec)->emu; \
438 unsigned short *buf = (__force unsigned short *)(_buf); \
439 snd_emu8000_write_wait(emu, 1); \425 snd_emu8000_write_wait(emu, 1); \
440 EMU8000_SMALW_WRITE(emu, offset); \426 EMU8000_SMALW_WRITE(emu, offset); \
441 while (count > 0) { \427 while (count > 0) { \
442 unsigned short sval; \428 unsigned short sval; \
443 CHECK_SCHEDULER(); \429 CHECK_SCHEDULER(); \
444 GET_VAL(sval, buf, mode); \430 GET_VAL(sval, iter); \
445 EMU8000_SMLD_WRITE(emu, sval); \431 EMU8000_SMLD_WRITE(emu, sval); \
446 count--; \432 count--; \
447 } \433 } \
@@ -450,27 +436,14 @@ enum { · 2 unmodified lines
450/* copy one channel block */436/* copy one channel block */
451static int emu8k_pcm_copy(struct snd_pcm_substream *subs,437static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
452 int voice, unsigned long pos,438 int voice, unsigned long pos,
453 void __user *src, unsigned long count)439 struct iov_iter *src, unsigned long count)
454{440{
455 struct snd_emu8k_pcm *rec = subs->runtime->private_data;441 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
456 442
457 /* convert to word unit */443 /* convert to word unit */
458 pos = (pos << 1) + rec->loop_start[voice];444 pos = (pos << 1) + rec->loop_start[voice];
459 count <<= 1;445 count <<= 1;
460 LOOP_WRITE(rec, pos, src, count, COPY_USER);446 LOOP_WRITE(rec, pos, src, count);
461 return 0;
462}
463
464static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
465 int voice, unsigned long pos,
466 void *src, unsigned long count)
467{
468 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
469
470 /* convert to word unit */
471 pos = (pos << 1) + rec->loop_start[voice];
472 count <<= 1;
473 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);
474 return 0;447 return 0;
475}448}
476 449
@@ -483,16 +456,15 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs, · 6 unmodified lines
483 /* convert to word unit */456 /* convert to word unit */
484 pos = (pos << 1) + rec->loop_start[voice];457 pos = (pos << 1) + rec->loop_start[voice];
485 count <<= 1;458 count <<= 1;
486 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);459 LOOP_WRITE(rec, pos, USER_SOCKPTR(NULL), count);
487 return 0;460 return 0;
488}461}
489 462
490#else /* interleave */463#else /* interleave */
491 464
492#define LOOP_WRITE(rec, pos, _buf, count, mode) \465#define LOOP_WRITE(rec, pos, iter, count) \
493 do { \466 do { \
494 struct snd_emu8000 *emu = rec->emu; \467 struct snd_emu8000 *emu = rec->emu; \
495 unsigned short *buf = (__force unsigned short *)(_buf); \
496 snd_emu8000_write_wait(emu, 1); \468 snd_emu8000_write_wait(emu, 1); \
497 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \469 EMU8000_SMALW_WRITE(emu, pos + rec->loop_start[0]); \
498 if (rec->voices > 1) \470 if (rec->voices > 1) \
@@ -500,11 +472,11 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs, · 1 unmodified line
500 while (count > 0) { \472 while (count > 0) { \
501 unsigned short sval; \473 unsigned short sval; \
502 CHECK_SCHEDULER(); \474 CHECK_SCHEDULER(); \
503 GET_VAL(sval, buf, mode); \475 GET_VAL(sval, iter); \
504 EMU8000_SMLD_WRITE(emu, sval); \476 EMU8000_SMLD_WRITE(emu, sval); \
505 if (rec->voices > 1) { \477 if (rec->voices > 1) { \
506 CHECK_SCHEDULER(); \478 CHECK_SCHEDULER(); \
507 GET_VAL(sval, buf, mode); \479 GET_VAL(sval, iter); \
508 EMU8000_SMRD_WRITE(emu, sval); \480 EMU8000_SMRD_WRITE(emu, sval); \
509 } \481 } \
510 count--; \482 count--; \
@@ -518,27 +490,14 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs, · 7 unmodified lines
518 */490 */
519static int emu8k_pcm_copy(struct snd_pcm_substream *subs,491static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
520 int voice, unsigned long pos,492 int voice, unsigned long pos,
521 void __user *src, unsigned long count)493 struct iov_iter *src, unsigned long count)
522{
523 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
524
525 /* convert to frames */
526 pos = bytes_to_frames(subs->runtime, pos);
527 count = bytes_to_frames(subs->runtime, count);
528 LOOP_WRITE(rec, pos, src, count, COPY_USER);
529 return 0;
530}
531
532static int emu8k_pcm_copy_kernel(struct snd_pcm_substream *subs,
533 int voice, unsigned long pos,
534 void *src, unsigned long count)
535{494{
536 struct snd_emu8k_pcm *rec = subs->runtime->private_data;495 struct snd_emu8k_pcm *rec = subs->runtime->private_data;
537 496
538 /* convert to frames */497 /* convert to frames */
539 pos = bytes_to_frames(subs->runtime, pos);498 pos = bytes_to_frames(subs->runtime, pos);
540 count = bytes_to_frames(subs->runtime, count);499 count = bytes_to_frames(subs->runtime, count);
541 LOOP_WRITE(rec, pos, src, count, COPY_KERNEL);500 LOOP_WRITE(rec, pos, src, count);
542 return 0;501 return 0;
543}502}
544 503
@@ -550,7 +509,7 @@ static int emu8k_pcm_silence(struct snd_pcm_substream *subs, · 5 unmodified lines
550 /* convert to frames */509 /* convert to frames */
551 pos = bytes_to_frames(subs->runtime, pos);510 pos = bytes_to_frames(subs->runtime, pos);
552 count = bytes_to_frames(subs->runtime, count);511 count = bytes_to_frames(subs->runtime, count);
553 LOOP_WRITE(rec, pos, NULL, count, FILL_SILENCE);512 LOOP_WRITE(rec, pos, NULL, count);
554 return 0;513 return 0;
555}514}
556#endif515#endif
@@ -666,8 +625,7 @@ static const struct snd_pcm_ops emu8k_pcm_ops = { · 109 unmodified lines
666 .prepare = emu8k_pcm_prepare,625 .prepare = emu8k_pcm_prepare,
667 .trigger = emu8k_pcm_trigger,626 .trigger = emu8k_pcm_trigger,
668 .pointer = emu8k_pcm_pointer,627 .pointer = emu8k_pcm_pointer,
669 .copy_user = emu8k_pcm_copy,628 .copy = emu8k_pcm_copy,
670 .copy_kernel = emu8k_pcm_copy_kernel,
671 .fill_silence = emu8k_pcm_silence,629 .fill_silence = emu8k_pcm_silence,
672};630};
673 631
sound/isa/sb/sb16_csp.c+0−2
@@ -1080,7 +1080,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) · 1079 unmodified lines
1080 1080
1081 card = p->chip->card; 1081 card = p->chip->card;
1082 1082
1083 down_write(&card->controls_rwsem);
1084 if (p->qsound_switch) {1083 if (p->qsound_switch) {
1085 snd_ctl_remove(card, p->qsound_switch);1084 snd_ctl_remove(card, p->qsound_switch);
1086 p->qsound_switch = NULL;1085 p->qsound_switch = NULL;
@@ -1089,7 +1088,6 @@ static void snd_sb_qsound_destroy(struct snd_sb_csp * p) · 2 unmodified lines
1089 snd_ctl_remove(card, p->qsound_space);1088 snd_ctl_remove(card, p->qsound_space);
1090 p->qsound_space = NULL;1089 p->qsound_space = NULL;
1091 }1090 }
1092 up_write(&card->controls_rwsem);
1093 1091
1094 /* cancel pending transfer of QSound parameters */1092 /* cancel pending transfer of QSound parameters */
1095 spin_lock_irqsave (&p->q_lock, flags);1093 spin_lock_irqsave (&p->q_lock, flags);
sound/pci/ac97/ac97_codec.c+2−3
@@ -2069,10 +2069,9 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, · 2068 unmodified lines
2069 .dev_disconnect = snd_ac97_dev_disconnect,2069 .dev_disconnect = snd_ac97_dev_disconnect,
2070 };2070 };
2071 2071
2072 if (!rac97)2072 if (snd_BUG_ON(!bus || !template || !rac97))
2073 return -EINVAL;
2074 if (snd_BUG_ON(!bus || !template))
2075 return -EINVAL;2073 return -EINVAL;
2074 *rac97 = NULL;
2076 if (snd_BUG_ON(template->num >= 4))2075 if (snd_BUG_ON(template->num >= 4))
2077 return -EINVAL;2076 return -EINVAL;
2078 if (bus->codec[template->num])2077 if (bus->codec[template->num])
sound/pci/ac97/ac97_patch.c+2−20
@@ -3431,11 +3431,7 @@ static const char * const follower_sws_vt1616[] = { · 3430 unmodified lines
3431static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,3431static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
3432 const char *name)3432 const char *name)
3433{3433{
3434 struct snd_ctl_elem_id id;3434 return snd_ctl_find_id_mixer(ac97->bus->card, name);
3435 memset(&id, 0, sizeof(id));
3436 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
3437 strcpy(id.name, name);
3438 return snd_ctl_find_id(ac97->bus->card, &id);
3439}3435}
3440 3436
3441/* create a virtual master control and add followers */3437/* create a virtual master control and add followers */
@@ -3444,7 +3440,6 @@ static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, · 2 unmodified lines
3444 const char * const *followers)3440 const char * const *followers)
3445{3441{
3446 struct snd_kcontrol *kctl;3442 struct snd_kcontrol *kctl;
3447 const char * const *s;
3448 int err;3443 int err;
3449 3444
3450 kctl = snd_ctl_make_virtual_master(name, tlv);3445 kctl = snd_ctl_make_virtual_master(name, tlv);
@@ -3454,20 +3449,7 @@ static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name, · 3 unmodified lines
3454 if (err < 0)3449 if (err < 0)
3455 return err;3450 return err;
3456 3451
3457 for (s = followers; *s; s++) {3452 return snd_ctl_add_followers(ac97->bus->card, kctl, followers);
3458 struct snd_kcontrol *sctl;
3459
3460 sctl = snd_ac97_find_mixer_ctl(ac97, *s);
3461 if (!sctl) {
3462 dev_dbg(ac97->bus->card->dev,
3463 "Cannot find follower %s, skipped\n", *s);
3464 continue;
3465 }
3466 err = snd_ctl_add_follower(kctl, sctl);
3467 if (err < 0)
3468 return err;
3469 }
3470 return 0;
3471}3453}
3472 3454
3473static int patch_vt1616_specific(struct snd_ac97 * ac97)3455static int patch_vt1616_specific(struct snd_ac97 * ac97)
sound/pci/asihpi/hpi.h+0−16
@@ -1191,19 +1191,6 @@ u16 hpi_adapter_set_mode_ex(u16 adapter_index, u32 adapter_mode, · 1190 unmodified lines
1191 1191
1192u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode);1192u16 hpi_adapter_get_mode(u16 adapter_index, u32 *padapter_mode);
1193 1193
1194u16 hpi_adapter_get_assert2(u16 adapter_index, u16 *p_assert_count,
1195 char *psz_assert, u32 *p_param1, u32 *p_param2,
1196 u32 *p_dsp_string_addr, u16 *p_processor_id);
1197
1198u16 hpi_adapter_test_assert(u16 adapter_index, u16 assert_id);
1199
1200u16 hpi_adapter_enable_capability(u16 adapter_index, u16 capability, u32 key);
1201
1202u16 hpi_adapter_self_test(u16 adapter_index);
1203
1204u16 hpi_adapter_debug_read(u16 adapter_index, u32 dsp_address, char *p_bytes,
1205 int *count_bytes);
1206
1207u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 paramter1,1194u16 hpi_adapter_set_property(u16 adapter_index, u16 property, u16 paramter1,
1208 u16 paramter2);1195 u16 paramter2);
1209 1196
@@ -1488,9 +1475,6 @@ u16 hpi_pad_get_program_type(u32 h_control, u32 *ppTY); · 278 unmodified lines
1488 1475
1489u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI);1476u16 hpi_pad_get_rdsPI(u32 h_control, u32 *ppI);
1490 1477
1491u16 hpi_pad_get_program_type_string(u32 h_control, const u32 data_type,
1492 const u32 pTY, char *psz_string, const u32 string_length);
1493
1494/****************************/1478/****************************/
1495/* AES/EBU Receiver control */1479/* AES/EBU Receiver control */
1496/****************************/1480/****************************/
sound/pci/asihpi/hpi_internal.h+0−5
@@ -1394,17 +1394,12 @@ u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index, · 1393 unmodified lines
1394void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);1394void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
1395 1395
1396/* used in PnP OS/driver */1396/* used in PnP OS/driver */
1397u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource,
1398 u16 *pw_adapter_index);
1399
1400u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,1397u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer,
1401 struct hpi_hostbuffer_status **pp_status);1398 struct hpi_hostbuffer_status **pp_status);
1402 1399
1403u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,1400u16 hpi_instream_host_buffer_get_info(u32 h_instream, u8 **pp_buffer,
1404 struct hpi_hostbuffer_status **pp_status);1401 struct hpi_hostbuffer_status **pp_status);
1405 1402
1406u16 hpi_adapter_restart(u16 adapter_index);
1407
1408/*1403/*
1409The following 3 functions were last declared in header files for1404The following 3 functions were last declared in header files for
1410driver 3.10. HPI_ControlQuery() used to be the recommended way1405driver 3.10. HPI_ControlQuery() used to be the recommended way
sound/pci/ca0106/ca0106_mixer.c+7−23
@@ -706,19 +706,9 @@ static int remove_ctl(struct snd_card *card, const char *name) · 705 unmodified lines
706 return snd_ctl_remove_id(card, &id);706 return snd_ctl_remove_id(card, &id);
707}707}
708 708
709static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
710{
711 struct snd_ctl_elem_id sid;
712 memset(&sid, 0, sizeof(sid));
713 /* FIXME: strcpy is bad. */
714 strcpy(sid.name, name);
715 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
716 return snd_ctl_find_id(card, &sid);
717}
718
719static int rename_ctl(struct snd_card *card, const char *src, const char *dst)709static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
720{710{
721 struct snd_kcontrol *kctl = ctl_find(card, src);711 struct snd_kcontrol *kctl = snd_ctl_find_id_mixer(card, src);
722 if (kctl) {712 if (kctl) {
723 snd_ctl_rename(card, kctl, dst);713 snd_ctl_rename(card, kctl, dst);
724 return 0;714 return 0;
@@ -761,16 +751,6 @@ static const char * const follower_sws[] = { · 36 unmodified lines
761 NULL751 NULL
762};752};
763 753
764static void add_followers(struct snd_card *card,
765 struct snd_kcontrol *master, const char * const *list)
766{
767 for (; *list; list++) {
768 struct snd_kcontrol *follower = ctl_find(card, *list);
769 if (follower)
770 snd_ctl_add_follower(master, follower);
771 }
772}
773
774int snd_ca0106_mixer(struct snd_ca0106 *emu)754int snd_ca0106_mixer(struct snd_ca0106 *emu)
775{755{
776 int err;756 int err;
@@ -852,7 +832,9 @@ int snd_ca0106_mixer(struct snd_ca0106 *emu) · 75 unmodified lines
852 err = snd_ctl_add(card, vmaster);832 err = snd_ctl_add(card, vmaster);
853 if (err < 0)833 if (err < 0)
854 return err;834 return err;
855 add_followers(card, vmaster, follower_vols);835 err = snd_ctl_add_followers(card, vmaster, follower_vols);
836 if (err < 0)
837 return err;
856 838
857 if (emu->details->spi_dac) {839 if (emu->details->spi_dac) {
858 vmaster = snd_ctl_make_virtual_master("Master Playback Switch",840 vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
@@ -862,7 +844,9 @@ int snd_ca0106_mixer(struct snd_ca0106 *emu) · 3 unmodified lines
862 err = snd_ctl_add(card, vmaster);844 err = snd_ctl_add(card, vmaster);
863 if (err < 0)845 if (err < 0)
864 return err;846 return err;
865 add_followers(card, vmaster, follower_sws);847 err = snd_ctl_add_followers(card, vmaster, follower_sws);
848 if (err < 0)
849 return err;
866 }850 }
867 851
868 strcpy(card->mixername, "CA0106");852 strcpy(card->mixername, "CA0106");
sound/pci/cmipci.c+1−5
@@ -2734,12 +2734,8 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device) · 2733 unmodified lines
2734 }2734 }
2735 2735
2736 for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {2736 for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
2737 struct snd_ctl_elem_id elem_id;
2738 struct snd_kcontrol *ctl;2737 struct snd_kcontrol *ctl;
2739 memset(&elem_id, 0, sizeof(elem_id));2738 ctl = snd_ctl_find_id_mixer(cm->card, cm_saved_mixer[idx].name);
2740 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2741 strcpy(elem_id.name, cm_saved_mixer[idx].name);
2742 ctl = snd_ctl_find_id(cm->card, &elem_id);
2743 if (ctl)2739 if (ctl)
2744 cm->mixer_res_ctl[idx] = ctl;2740 cm->mixer_res_ctl[idx] = ctl;
2745 }2741 }
sound/pci/cs46xx/cs46xx_lib.c+2−5
@@ -2449,7 +2449,6 @@ static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec) · 2448 unmodified lines
2449int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)2449int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
2450{2450{
2451 struct snd_card *card = chip->card;2451 struct snd_card *card = chip->card;
2452 struct snd_ctl_elem_id id;
2453 int err;2452 int err;
2454 unsigned int idx;2453 unsigned int idx;
2455 static const struct snd_ac97_bus_ops ops = {2454 static const struct snd_ac97_bus_ops ops = {
@@ -2490,10 +2489,8 @@ int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device) · 34 unmodified lines
2490 }2489 }
2491 2490
2492 /* get EAPD mixer switch (for voyetra hack) */2491 /* get EAPD mixer switch (for voyetra hack) */
2493 memset(&id, 0, sizeof(id));2492 chip->eapd_switch = snd_ctl_find_id_mixer(chip->card,
2494 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;2493 "External Amplifier");
2495 strcpy(id.name, "External Amplifier");
2496 chip->eapd_switch = snd_ctl_find_id(chip->card, &id);
2497 2494
2498#ifdef CONFIG_SND_CS46XX_NEW_DSP2495#ifdef CONFIG_SND_CS46XX_NEW_DSP
2499 if (chip->nr_ac97_codecs == 1) {2496 if (chip->nr_ac97_codecs == 1) {
sound/pci/emu10k1/emu10k1.c+3−10
@@ -2,9 +2,7 @@ · 1 unmodified line
2/*2/*
3 * The driver for the EMU10K1 (SB Live!) based soundcards3 * The driver for the EMU10K1 (SB Live!) based soundcards
4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
5 *5 * James Courtier-Dutton <James@superbug.co.uk>
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 * Added support for Audigy 2 Value.
8 */6 */
9 7
10#include <linux/init.h>8#include <linux/init.h>
@@ -176,9 +174,6 @@ static int snd_card_emu10k1_probe(struct pci_dev *pci, · 165 unmodified lines
176 if (err < 0)174 if (err < 0)
177 return err;175 return err;
178 176
179 if (emu->card_capabilities->emu_model)
180 schedule_delayed_work(&emu->emu1010.firmware_work, 0);
181
182 pci_set_drvdata(pci, card);177 pci_set_drvdata(pci, card);
183 dev++;178 dev++;
184 return 0;179 return 0;
@@ -194,7 +189,8 @@ static int snd_emu10k1_suspend(struct device *dev) · 9 unmodified lines
194 189
195 emu->suspend = 1;190 emu->suspend = 1;
196 191
197 cancel_delayed_work_sync(&emu->emu1010.firmware_work);192 cancel_work_sync(&emu->emu1010.firmware_work);
193 cancel_work_sync(&emu->emu1010.clock_work);
198 194
199 snd_ac97_suspend(emu->ac97);195 snd_ac97_suspend(emu->ac97);
200 196
@@ -224,9 +220,6 @@ static int snd_emu10k1_resume(struct device *dev) · 23 unmodified lines
224 220
225 snd_power_change_state(card, SNDRV_CTL_POWER_D0);221 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
226 222
227 if (emu->card_capabilities->emu_model)
228 schedule_delayed_work(&emu->emu1010.firmware_work, 0);
229
230 return 0;223 return 0;
231}224}
232 225
sound/pci/emu10k1/emu10k1_main.c+61−37
@@ -1,19 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * James Courtier-Dutton <James@superbug.co.uk>
5 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
4 * Creative Labs, Inc.6 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips
6 *
7 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
8 * Added support for Audigy 2 Value.
9 * Added EMU 1010 support.
10 * General bug fixes and enhancements.
11 *7 *
12 * BUGS:8 * Routines for control of EMU10K1 chips
13 * --
14 *
15 * TODO:
16 * --
17 */9 */
18 10
19#include <linux/sched.h>11#include <linux/sched.h>
@@ -391,7 +383,10 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu) · 371 unmodified lines
391 }383 }
392#endif384#endif
393 385
394 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);386 if (emu->card_capabilities->emu_model)
387 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE | INTE_A_GPIOENABLE);
388 else
389 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
395}390}
396 391
397int snd_emu10k1_done(struct snd_emu10k1 *emu)392int snd_emu10k1_done(struct snd_emu10k1 *emu)
@@ -664,7 +659,6 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 266 unmodified lines
664 u16 reg;659 u16 reg;
665 u8 value;660 u8 value;
666 __always_unused u16 write_post;661 __always_unused u16 write_post;
667 unsigned long flags;
668 662
669 if (!fw_entry)663 if (!fw_entry)
670 return -EIO;664 return -EIO;
@@ -676,7 +670,7 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 5 unmodified lines
676 * GPIO5 -> FPGA DIN670 * GPIO5 -> FPGA DIN
677 * FPGA CONFIG OFF -> FPGA PGMN671 * FPGA CONFIG OFF -> FPGA PGMN
678 */672 */
679 spin_lock_irqsave(&emu->emu_lock, flags);673 spin_lock_irq(&emu->emu_lock);
680 outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */674 outw(0x00, emu->port + A_GPIO); /* Set PGMN low for 100uS. */
681 write_post = inw(emu->port + A_GPIO);675 write_post = inw(emu->port + A_GPIO);
682 udelay(100);676 udelay(100);
@@ -699,7 +693,7 @@ static int snd_emu1010_load_firmware_entry(struct snd_emu10k1 *emu, · 16 unmodified lines
699 /* After programming, set GPIO bit 4 high again. */693 /* After programming, set GPIO bit 4 high again. */
700 outw(0x10, emu->port + A_GPIO);694 outw(0x10, emu->port + A_GPIO);
701 write_post = inw(emu->port + A_GPIO);695 write_post = inw(emu->port + A_GPIO);
702 spin_unlock_irqrestore(&emu->emu_lock, flags);696 spin_unlock_irq(&emu->emu_lock);
703 697
704 return 0;698 return 0;
705}699}
@@ -745,14 +739,13 @@ static void emu1010_firmware_work(struct work_struct *work) · 39 unmodified lines
745 int err;739 int err;
746 740
747 emu = container_of(work, struct snd_emu10k1,741 emu = container_of(work, struct snd_emu10k1,
748 emu1010.firmware_work.work);742 emu1010.firmware_work);
749 if (emu->card->shutdown)743 if (emu->card->shutdown)
750 return;744 return;
751#ifdef CONFIG_PM_SLEEP745#ifdef CONFIG_PM_SLEEP
752 if (emu->suspend)746 if (emu->suspend)
753 return;747 return;
754#endif748#endif
755 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
756 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */749 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
757 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {750 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
758 /* Audio Dock attached */751 /* Audio Dock attached */
@@ -763,13 +756,8 @@ static void emu1010_firmware_work(struct work_struct *work) · 4 unmodified lines
763 EMU_HANA_FPGA_CONFIG_AUDIODOCK);756 EMU_HANA_FPGA_CONFIG_AUDIODOCK);
764 err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);757 err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);
765 if (err < 0)758 if (err < 0)
766 goto next;759 return;
767
768 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);760 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
769 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp);
770 dev_info(emu->card->dev,
771 "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", tmp);
772 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
773 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp);761 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp);
774 dev_info(emu->card->dev,762 dev_info(emu->card->dev,
775 "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp);763 "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp);
@@ -778,7 +766,7 @@ static void emu1010_firmware_work(struct work_struct *work) · 2 unmodified lines
778 dev_info(emu->card->dev,766 dev_info(emu->card->dev,
779 "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n",767 "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n",
780 tmp);768 tmp);
781 goto next;769 return;
782 }770 }
783 dev_info(emu->card->dev,771 dev_info(emu->card->dev,
784 "emu1010: Audio Dock Firmware loaded\n");772 "emu1010: Audio Dock Firmware loaded\n");
@@ -790,18 +778,48 @@ static void emu1010_firmware_work(struct work_struct *work) · 5 unmodified lines
790 msleep(10);778 msleep(10);
791 /* Unmute all. Default is muted after a firmware load */779 /* Unmute all. Default is muted after a firmware load */
792 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);780 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
793 } else if (!reg && emu->emu1010.last_reg) {781 }
782}
783
784static void emu1010_clock_work(struct work_struct *work)
785{
786 struct snd_emu10k1 *emu;
787 struct snd_ctl_elem_id id;
788
789 emu = container_of(work, struct snd_emu10k1,
790 emu1010.clock_work);
791 if (emu->card->shutdown)
792 return;
793#ifdef CONFIG_PM_SLEEP
794 if (emu->suspend)
795 return;
796#endif
797
798 spin_lock_irq(&emu->reg_lock);
799 // This is the only thing that can actually happen.
800 emu->emu1010.clock_source = emu->emu1010.clock_fallback;
801 emu->emu1010.wclock = 1 - emu->emu1010.clock_source;
802 snd_emu1010_update_clock(emu);
803 spin_unlock_irq(&emu->reg_lock);
804 snd_ctl_build_ioff(&id, emu->ctl_clock_source, 0);
805 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
806}
807
808static void emu1010_interrupt(struct snd_emu10k1 *emu)
809{
810 u32 sts;
811
812 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts);
813 if (sts & EMU_HANA_IRQ_DOCK_LOST) {
794 /* Audio Dock removed */814 /* Audio Dock removed */
795 dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");815 dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");
796 /* The hardware auto-mutes all, so we unmute again */816 /* The hardware auto-mutes all, so we unmute again */
797 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);817 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
818 } else if (sts & EMU_HANA_IRQ_DOCK) {
819 schedule_work(&emu->emu1010.firmware_work);
798 }820 }
799 821 if (sts & EMU_HANA_IRQ_WCLK_CHANGED)
800 next:822 schedule_work(&emu->emu1010.clock_work);
801 emu->emu1010.last_reg = reg;
802 if (!emu->card->shutdown)
803 schedule_delayed_work(&emu->emu1010.firmware_work,
804 msecs_to_jiffies(1000));
805}823}
806 824
807/*825/*
@@ -870,6 +888,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 62 unmodified lines
870 888
871 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);889 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
872 dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);890 dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);
891 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE)
892 schedule_work(&emu->emu1010.firmware_work);
873 if (emu->card_capabilities->no_adat) {893 if (emu->card_capabilities->no_adat) {
874 emu->emu1010.optical_in = 0; /* IN_SPDIF */894 emu->emu1010.optical_in = 0; /* IN_SPDIF */
875 emu->emu1010.optical_out = 0; /* OUT_SPDIF */895 emu->emu1010.optical_out = 0; /* OUT_SPDIF */
@@ -895,10 +915,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu) · 19 unmodified lines
895 /* MIDI routing */915 /* MIDI routing */
896 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, EMU_HANA_MIDI_INA_FROM_HAMOA | EMU_HANA_MIDI_INB_FROM_DOCK2);916 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, EMU_HANA_MIDI_INA_FROM_HAMOA | EMU_HANA_MIDI_INB_FROM_DOCK2);
897 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, EMU_HANA_MIDI_OUT_DOCK2 | EMU_HANA_MIDI_OUT_SYNC2);917 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, EMU_HANA_MIDI_OUT_DOCK2 | EMU_HANA_MIDI_OUT_SYNC2);
898 /* IRQ Enable: All on */918
899 /* snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x0f); */919 emu->gpio_interrupt = emu1010_interrupt;
900 /* IRQ Enable: All off */920 // Note: The Audigy INTE is set later
901 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);921 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE,
922 EMU_HANA_IRQ_DOCK | EMU_HANA_IRQ_DOCK_LOST | EMU_HANA_IRQ_WCLK_CHANGED);
923 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg); // Clear pending IRQs
902 924
903 emu->emu1010.clock_source = 1; /* 48000 */925 emu->emu1010.clock_source = 1; /* 48000 */
904 emu->emu1010.clock_fallback = 1; /* 48000 */926 emu->emu1010.clock_fallback = 1; /* 48000 */
@@ -938,7 +960,8 @@ static void snd_emu10k1_free(struct snd_card *card) · 33 unmodified lines
938 /* Disable 48Volt power to Audio Dock */960 /* Disable 48Volt power to Audio Dock */
939 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);961 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
940 }962 }
941 cancel_delayed_work_sync(&emu->emu1010.firmware_work);963 cancel_work_sync(&emu->emu1010.firmware_work);
964 cancel_work_sync(&emu->emu1010.clock_work);
942 release_firmware(emu->firmware);965 release_firmware(emu->firmware);
943 release_firmware(emu->dock_fw);966 release_firmware(emu->dock_fw);
944 snd_util_memhdr_free(emu->memhdr);967 snd_util_memhdr_free(emu->memhdr);
@@ -1517,7 +1540,8 @@ int snd_emu10k1_create(struct snd_card *card, · 572 unmodified lines
1517 emu->irq = -1;1540 emu->irq = -1;
1518 emu->synth = NULL;1541 emu->synth = NULL;
1519 emu->get_synth_voice = NULL;1542 emu->get_synth_voice = NULL;
1520 INIT_DELAYED_WORK(&emu->emu1010.firmware_work, emu1010_firmware_work);1543 INIT_WORK(&emu->emu1010.firmware_work, emu1010_firmware_work);
1544 INIT_WORK(&emu->emu1010.clock_work, emu1010_clock_work);
1521 /* read revision & serial */1545 /* read revision & serial */
1522 emu->revision = pci->revision;1546 emu->revision = pci->revision;
1523 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);1547 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
sound/pci/emu10k1/emu10k1_synth.c+4−6
@@ -22,7 +22,6 @@ static int snd_emu10k1_synth_probe(struct device *_dev) · 21 unmodified lines
22 struct snd_emux *emux;22 struct snd_emux *emux;
23 struct snd_emu10k1 *hw;23 struct snd_emu10k1 *hw;
24 struct snd_emu10k1_synth_arg *arg;24 struct snd_emu10k1_synth_arg *arg;
25 unsigned long flags;
26 25
27 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);26 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
28 if (arg == NULL)27 if (arg == NULL)
@@ -56,10 +55,10 @@ static int snd_emu10k1_synth_probe(struct device *_dev) · 27 unmodified lines
56 return -ENOMEM;55 return -ENOMEM;
57 }56 }
58 57
59 spin_lock_irqsave(&hw->voice_lock, flags);58 spin_lock_irq(&hw->voice_lock);
60 hw->synth = emux;59 hw->synth = emux;
61 hw->get_synth_voice = snd_emu10k1_synth_get_voice;60 hw->get_synth_voice = snd_emu10k1_synth_get_voice;
62 spin_unlock_irqrestore(&hw->voice_lock, flags);61 spin_unlock_irq(&hw->voice_lock);
63 62
64 dev->driver_data = emux;63 dev->driver_data = emux;
65 64
@@ -71,7 +70,6 @@ static int snd_emu10k1_synth_remove(struct device *_dev) · 5 unmodified lines
71 struct snd_seq_device *dev = to_seq_dev(_dev);70 struct snd_seq_device *dev = to_seq_dev(_dev);
72 struct snd_emux *emux;71 struct snd_emux *emux;
73 struct snd_emu10k1 *hw;72 struct snd_emu10k1 *hw;
74 unsigned long flags;
75 73
76 if (dev->driver_data == NULL)74 if (dev->driver_data == NULL)
77 return 0; /* not registered actually */75 return 0; /* not registered actually */
@@ -79,10 +77,10 @@ static int snd_emu10k1_synth_remove(struct device *_dev) · 1 unmodified line
79 emux = dev->driver_data;77 emux = dev->driver_data;
80 78
81 hw = emux->hw;79 hw = emux->hw;
82 spin_lock_irqsave(&hw->voice_lock, flags);80 spin_lock_irq(&hw->voice_lock);
83 hw->synth = NULL;81 hw->synth = NULL;
84 hw->get_synth_voice = NULL;82 hw->get_synth_voice = NULL;
85 spin_unlock_irqrestore(&hw->voice_lock, flags);83 spin_unlock_irq(&hw->voice_lock);
86 84
87 snd_emux_free(emux);85 snd_emux_free(emux);
88 return 0;86 return 0;
sound/pci/emu10k1/emufx.c+3−14
@@ -1,17 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * James Courtier-Dutton <James@superbug.co.uk>
5 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
4 * Creative Labs, Inc.6 * Creative Labs, Inc.
5 * Routines for effect processor FX8010
6 *
7 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
8 * Added EMU 1010 support.
9 *7 *
10 * BUGS:8 * Routines for effect processor FX8010
11 * --
12 *
13 * TODO:
14 * --
15 */9 */
16 10
17#include <linux/pci.h>11#include <linux/pci.h>
@@ -799,13 +793,10 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, · 781 unmodified lines
799 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))793 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
800 continue;794 continue;
801 gctl_id = (struct snd_ctl_elem_id *)&gctl->id;795 gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
802 down_read(&emu->card->controls_rwsem);
803 if (snd_ctl_find_id(emu->card, gctl_id)) {796 if (snd_ctl_find_id(emu->card, gctl_id)) {
804 up_read(&emu->card->controls_rwsem);
805 err = -EEXIST;797 err = -EEXIST;
806 goto __error;798 goto __error;
807 }799 }
808 up_read(&emu->card->controls_rwsem);
809 if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&800 if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
810 gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {801 gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
811 err = -EINVAL;802 err = -EINVAL;
@@ -977,11 +968,9 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, · 165 unmodified lines
977 in_kernel);968 in_kernel);
978 if (err < 0)969 if (err < 0)
979 return err;970 return err;
980 down_write(&card->controls_rwsem);
981 ctl = snd_emu10k1_look_for_ctl(emu, &id);971 ctl = snd_emu10k1_look_for_ctl(emu, &id);
982 if (ctl)972 if (ctl)
983 snd_ctl_remove(card, ctl->kcontrol);973 snd_ctl_remove(card, ctl->kcontrol);
984 up_write(&card->controls_rwsem);
985 }974 }
986 return 0;975 return 0;
987}976}
sound/pci/emu10k1/emumixer.c+36−53
@@ -2,18 +2,12 @@ · 1 unmodified line
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
4 * Takashi Iwai <tiwai@suse.de>4 * Takashi Iwai <tiwai@suse.de>
5 * Lee Revell <rlrevell@joe-job.com>
6 * James Courtier-Dutton <James@superbug.co.uk>
7 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
5 * Creative Labs, Inc.8 * Creative Labs, Inc.
6 * Routines for control of EMU10K1 chips / mixer routines
7 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
8 *
9 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
10 * Added EMU 1010 support.
11 *
12 * BUGS:
13 * --
14 *9 *
15 * TODO:10 * Routines for control of EMU10K1 chips / mixer routines
16 * --
17 */11 */
18 12
19#include <linux/time.h>13#include <linux/time.h>
@@ -770,18 +764,21 @@ static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ct · 750 unmodified lines
770 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);764 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
771 unsigned int mask = snd_emu1010_adc_pad_regs[kcontrol->private_value];765 unsigned int mask = snd_emu1010_adc_pad_regs[kcontrol->private_value];
772 unsigned int val, cache;766 unsigned int val, cache;
767 int change;
768
773 val = ucontrol->value.integer.value[0];769 val = ucontrol->value.integer.value[0];
774 cache = emu->emu1010.adc_pads;770 cache = emu->emu1010.adc_pads;
775 if (val == 1) 771 if (val == 1)
776 cache = cache | mask;772 cache = cache | mask;
777 else773 else
778 cache = cache & ~mask;774 cache = cache & ~mask;
779 if (cache != emu->emu1010.adc_pads) {775 change = (cache != emu->emu1010.adc_pads);
776 if (change) {
780 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );777 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
781 emu->emu1010.adc_pads = cache;778 emu->emu1010.adc_pads = cache;
782 }779 }
783 780
784 return 0;781 return change;
785}782}
786 783
787static const struct snd_kcontrol_new emu1010_adc_pads_ctl = {784static const struct snd_kcontrol_new emu1010_adc_pads_ctl = {
@@ -983,17 +980,21 @@ static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol, · 195 unmodified lines
983 val = ucontrol->value.enumerated.item[0] ;980 val = ucontrol->value.enumerated.item[0] ;
984 if (val >= emu_ci->num)981 if (val >= emu_ci->num)
985 return -EINVAL;982 return -EINVAL;
983 spin_lock_irq(&emu->reg_lock);
986 change = (emu->emu1010.clock_source != val);984 change = (emu->emu1010.clock_source != val);
987 if (change) {985 if (change) {
988 emu->emu1010.clock_source = val;986 emu->emu1010.clock_source = val;
989 emu->emu1010.wclock = emu_ci->vals[val];987 emu->emu1010.wclock = emu_ci->vals[val];
988 snd_emu1010_update_clock(emu);
990 989
991 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE);990 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE);
992 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, emu->emu1010.wclock);991 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, emu->emu1010.wclock);
992 spin_unlock_irq(&emu->reg_lock);
993
993 msleep(10); // Allow DLL to settle994 msleep(10); // Allow DLL to settle
994 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);995 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
995 996 } else {
996 snd_emu1010_update_clock(emu);997 spin_unlock_irq(&emu->reg_lock);
997 }998 }
998 return change;999 return change;
999}1000}
@@ -1190,7 +1191,6 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, · 190 unmodified lines
1190 unsigned int ngain, ogain;1191 unsigned int ngain, ogain;
1191 u16 gpio;1192 u16 gpio;
1192 int change = 0;1193 int change = 0;
1193 unsigned long flags;
1194 u32 source;1194 u32 source;
1195 /* If the capture source has changed,1195 /* If the capture source has changed,
1196 * update the capture volume from the cached value1196 * update the capture volume from the cached value
@@ -1204,13 +1204,13 @@ static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol, · 7 unmodified lines
1204 change = (emu->i2c_capture_source != source_id);1204 change = (emu->i2c_capture_source != source_id);
1205 if (change) {1205 if (change) {
1206 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */1206 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
1207 spin_lock_irqsave(&emu->emu_lock, flags);1207 spin_lock_irq(&emu->emu_lock);
1208 gpio = inw(emu->port + A_IOCFG);1208 gpio = inw(emu->port + A_IOCFG);
1209 if (source_id==0)1209 if (source_id==0)
1210 outw(gpio | 0x4, emu->port + A_IOCFG);1210 outw(gpio | 0x4, emu->port + A_IOCFG);
1211 else1211 else
1212 outw(gpio & ~0x4, emu->port + A_IOCFG);1212 outw(gpio & ~0x4, emu->port + A_IOCFG);
1213 spin_unlock_irqrestore(&emu->emu_lock, flags);1213 spin_unlock_irq(&emu->emu_lock);
1214 1214
1215 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */1215 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
1216 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */1216 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
@@ -1354,7 +1354,6 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol, · 137 unmodified lines
1354 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1354 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1355 int change;1355 int change;
1356 unsigned int reg, val, tmp;1356 unsigned int reg, val, tmp;
1357 unsigned long flags;
1358 1357
1359 switch(ucontrol->value.enumerated.item[0]) {1358 switch(ucontrol->value.enumerated.item[0]) {
1360 case 0:1359 case 0:
@@ -1372,14 +1371,14 @@ static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol, · 11 unmodified lines
1372 }1371 }
1373 1372
1374 1373
1375 spin_lock_irqsave(&emu->reg_lock, flags);1374 spin_lock_irq(&emu->reg_lock);
1376 reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);1375 reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
1377 tmp = reg & ~A_SPDIF_RATE_MASK;1376 tmp = reg & ~A_SPDIF_RATE_MASK;
1378 tmp |= val;1377 tmp |= val;
1379 change = (tmp != reg);1378 change = (tmp != reg);
1380 if (change)1379 if (change)
1381 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);1380 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
1382 spin_unlock_irqrestore(&emu->reg_lock, flags);1381 spin_unlock_irq(&emu->reg_lock);
1383 return change;1382 return change;
1384}1383}
1385 1384
@@ -1496,7 +1495,6 @@ static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol, · 110 unmodified lines
1496static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,1495static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
1497 struct snd_ctl_elem_value *ucontrol)1496 struct snd_ctl_elem_value *ucontrol)
1498{1497{
1499 unsigned long flags;
1500 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1498 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1501 struct snd_emu10k1_pcm_mixer *mix =1499 struct snd_emu10k1_pcm_mixer *mix =
1502 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];1500 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
@@ -1504,7 +1502,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, · 1 unmodified line
1504 int num_efx = emu->audigy ? 8 : 4;1502 int num_efx = emu->audigy ? 8 : 4;
1505 int mask = emu->audigy ? 0x3f : 0x0f;1503 int mask = emu->audigy ? 0x3f : 0x0f;
1506 1504
1507 spin_lock_irqsave(&emu->reg_lock, flags);1505 spin_lock_irq(&emu->reg_lock);
1508 for (voice = 0; voice < 3; voice++)1506 for (voice = 0; voice < 3; voice++)
1509 for (idx = 0; idx < num_efx; idx++) {1507 for (idx = 0; idx < num_efx; idx++) {
1510 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;1508 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
@@ -1524,7 +1522,7 @@ static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol, · 13 unmodified lines
1524 &mix->send_routing[0][0]);1522 &mix->send_routing[0][0]);
1525 }1523 }
1526 }1524 }
1527 spin_unlock_irqrestore(&emu->reg_lock, flags);1525 spin_unlock_irq(&emu->reg_lock);
1528 return change;1526 return change;
1529}1527}
1530 1528
@@ -1566,14 +1564,13 @@ static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol, · 35 unmodified lines
1566static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,1564static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
1567 struct snd_ctl_elem_value *ucontrol)1565 struct snd_ctl_elem_value *ucontrol)
1568{1566{
1569 unsigned long flags;
1570 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1567 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1571 struct snd_emu10k1_pcm_mixer *mix =1568 struct snd_emu10k1_pcm_mixer *mix =
1572 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];1569 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1573 int change = 0, idx, val;1570 int change = 0, idx, val;
1574 int num_efx = emu->audigy ? 8 : 4;1571 int num_efx = emu->audigy ? 8 : 4;
1575 1572
1576 spin_lock_irqsave(&emu->reg_lock, flags);1573 spin_lock_irq(&emu->reg_lock);
1577 for (idx = 0; idx < 3*num_efx; idx++) {1574 for (idx = 0; idx < 3*num_efx; idx++) {
1578 val = ucontrol->value.integer.value[idx] & 255;1575 val = ucontrol->value.integer.value[idx] & 255;
1579 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {1576 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
@@ -1592,7 +1589,7 @@ static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol, · 12 unmodified lines
1592 &mix->send_volume[0][0]);1589 &mix->send_volume[0][0]);
1593 }1590 }
1594 }1591 }
1595 spin_unlock_irqrestore(&emu->reg_lock, flags);1592 spin_unlock_irq(&emu->reg_lock);
1596 return change;1593 return change;
1597}1594}
1598 1595
@@ -1632,13 +1629,12 @@ static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol, · 33 unmodified lines
1632static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,1629static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
1633 struct snd_ctl_elem_value *ucontrol)1630 struct snd_ctl_elem_value *ucontrol)
1634{1631{
1635 unsigned long flags;
1636 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1632 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1637 struct snd_emu10k1_pcm_mixer *mix =1633 struct snd_emu10k1_pcm_mixer *mix =
1638 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];1634 &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
1639 int change = 0, idx, val;1635 int change = 0, idx, val;
1640 1636
1641 spin_lock_irqsave(&emu->reg_lock, flags);1637 spin_lock_irq(&emu->reg_lock);
1642 for (idx = 0; idx < 3; idx++) {1638 for (idx = 0; idx < 3; idx++) {
1643 unsigned uval = ucontrol->value.integer.value[idx] & 0x1ffff;1639 unsigned uval = ucontrol->value.integer.value[idx] & 0x1ffff;
1644 val = uval * 0x8000U / 0xffffU;1640 val = uval * 0x8000U / 0xffffU;
@@ -1655,7 +1651,7 @@ static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol, · 10 unmodified lines
1655 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);1651 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
1656 }1652 }
1657 }1653 }
1658 spin_unlock_irqrestore(&emu->reg_lock, flags);1654 spin_unlock_irq(&emu->reg_lock);
1659 return change;1655 return change;
1660}1656}
1661 1657
@@ -1701,7 +1697,6 @@ static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol, · 39 unmodified lines
1701static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,1697static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
1702 struct snd_ctl_elem_value *ucontrol)1698 struct snd_ctl_elem_value *ucontrol)
1703{1699{
1704 unsigned long flags;
1705 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1700 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1706 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);1701 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1707 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];1702 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
@@ -1709,7 +1704,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, · 1 unmodified line
1709 int num_efx = emu->audigy ? 8 : 4;1704 int num_efx = emu->audigy ? 8 : 4;
1710 int mask = emu->audigy ? 0x3f : 0x0f;1705 int mask = emu->audigy ? 0x3f : 0x0f;
1711 1706
1712 spin_lock_irqsave(&emu->reg_lock, flags);1707 spin_lock_irq(&emu->reg_lock);
1713 for (idx = 0; idx < num_efx; idx++) {1708 for (idx = 0; idx < num_efx; idx++) {
1714 val = ucontrol->value.integer.value[idx] & mask;1709 val = ucontrol->value.integer.value[idx] & mask;
1715 if (mix->send_routing[0][idx] != val) {1710 if (mix->send_routing[0][idx] != val) {
@@ -1724,7 +1719,7 @@ static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol, · 8 unmodified lines
1724 &mix->send_routing[0][0]);1719 &mix->send_routing[0][0]);
1725 }1720 }
1726 }1721 }
1727 spin_unlock_irqrestore(&emu->reg_lock, flags);1722 spin_unlock_irq(&emu->reg_lock);
1728 return change;1723 return change;
1729}1724}
1730 1725
@@ -1766,14 +1761,13 @@ static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol, · 35 unmodified lines
1766static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,1761static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
1767 struct snd_ctl_elem_value *ucontrol)1762 struct snd_ctl_elem_value *ucontrol)
1768{1763{
1769 unsigned long flags;
1770 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1764 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1771 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);1765 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1772 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];1766 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
1773 int change = 0, idx, val;1767 int change = 0, idx, val;
1774 int num_efx = emu->audigy ? 8 : 4;1768 int num_efx = emu->audigy ? 8 : 4;
1775 1769
1776 spin_lock_irqsave(&emu->reg_lock, flags);1770 spin_lock_irq(&emu->reg_lock);
1777 for (idx = 0; idx < num_efx; idx++) {1771 for (idx = 0; idx < num_efx; idx++) {
1778 val = ucontrol->value.integer.value[idx] & 255;1772 val = ucontrol->value.integer.value[idx] & 255;
1779 if (mix->send_volume[0][idx] != val) {1773 if (mix->send_volume[0][idx] != val) {
@@ -1787,7 +1781,7 @@ static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol, · 7 unmodified lines
1787 &mix->send_volume[0][0]);1781 &mix->send_volume[0][0]);
1788 }1782 }
1789 }1783 }
1790 spin_unlock_irqrestore(&emu->reg_lock, flags);1784 spin_unlock_irq(&emu->reg_lock);
1791 return change;1785 return change;
1792}1786}
1793 1787
@@ -1826,14 +1820,13 @@ static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol, · 32 unmodified lines
1826static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,1820static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
1827 struct snd_ctl_elem_value *ucontrol)1821 struct snd_ctl_elem_value *ucontrol)
1828{1822{
1829 unsigned long flags;
1830 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1823 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1831 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);1824 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1832 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];1825 struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
1833 int change = 0, val;1826 int change = 0, val;
1834 unsigned uval;1827 unsigned uval;
1835 1828
1836 spin_lock_irqsave(&emu->reg_lock, flags);1829 spin_lock_irq(&emu->reg_lock);
1837 uval = ucontrol->value.integer.value[0] & 0x1ffff;1830 uval = ucontrol->value.integer.value[0] & 0x1ffff;
1838 val = uval * 0x8000U / 0xffffU;1831 val = uval * 0x8000U / 0xffffU;
1839 if (mix->attn[0] != val) {1832 if (mix->attn[0] != val) {
@@ -1845,7 +1838,7 @@ static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol, · 5 unmodified lines
1845 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);1838 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
1846 }1839 }
1847 }1840 }
1848 spin_unlock_irqrestore(&emu->reg_lock, flags);1841 spin_unlock_irq(&emu->reg_lock);
1849 return change;1842 return change;
1850}1843}
1851 1844
@@ -1881,7 +1874,6 @@ static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol, · 29 unmodified lines
1881static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,1874static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
1882 struct snd_ctl_elem_value *ucontrol)1875 struct snd_ctl_elem_value *ucontrol)
1883{1876{
1884 unsigned long flags;
1885 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);1877 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1886 unsigned int reg, val, sw;1878 unsigned int reg, val, sw;
1887 int change = 0;1879 int change = 0;
@@ -1889,7 +1881,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, · 1 unmodified line
1889 sw = ucontrol->value.integer.value[0];1881 sw = ucontrol->value.integer.value[0];
1890 if (emu->card_capabilities->invert_shared_spdif)1882 if (emu->card_capabilities->invert_shared_spdif)
1891 sw = !sw;1883 sw = !sw;
1892 spin_lock_irqsave(&emu->emu_lock, flags);1884 spin_lock_irq(&emu->emu_lock);
1893 if ( emu->card_capabilities->i2c_adc) {1885 if ( emu->card_capabilities->i2c_adc) {
1894 /* Do nothing for Audigy 2 ZS Notebook */1886 /* Do nothing for Audigy 2 ZS Notebook */
1895 } else if (emu->audigy) {1887 } else if (emu->audigy) {
@@ -1910,7 +1902,7 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol, · 14 unmodified lines
1910 reg |= val;1902 reg |= val;
1911 outl(reg | val, emu->port + HCFG);1903 outl(reg | val, emu->port + HCFG);
1912 }1904 }
1913 spin_unlock_irqrestore(&emu->emu_lock, flags);1905 spin_unlock_irq(&emu->emu_lock);
1914 return change;1906 return change;
1915}1907}
1916 1908
@@ -1990,18 +1982,9 @@ static int remove_ctl(struct snd_card *card, const char *name) · 73 unmodified lines
1990 return snd_ctl_remove_id(card, &id);1982 return snd_ctl_remove_id(card, &id);
1991}1983}
1992 1984
1993static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
1994{
1995 struct snd_ctl_elem_id sid;
1996 memset(&sid, 0, sizeof(sid));
1997 strcpy(sid.name, name);
1998 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1999 return snd_ctl_find_id(card, &sid);
2000}
2001
2002static int rename_ctl(struct snd_card *card, const char *src, const char *dst)1985static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
2003{1986{
2004 struct snd_kcontrol *kctl = ctl_find(card, src);1987 struct snd_kcontrol *kctl = snd_ctl_find_id_mixer(card, src);
2005 if (kctl) {1988 if (kctl) {
2006 snd_ctl_rename(card, kctl, dst);1989 snd_ctl_rename(card, kctl, dst);
2007 return 0;1990 return 0;
@@ -2342,8 +2325,8 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu, · 334 unmodified lines
2342 emu1010_map_source(emu_ri, emu_ri->out_dflts[i]);2325 emu1010_map_source(emu_ri, emu_ri->out_dflts[i]);
2343 snd_emu1010_apply_sources(emu);2326 snd_emu1010_apply_sources(emu);
2344 2327
2345 err = snd_ctl_add(card,2328 kctl = emu->ctl_clock_source = snd_ctl_new1(&snd_emu1010_clock_source, emu);
2346 snd_ctl_new1(&snd_emu1010_clock_source, emu));2329 err = snd_ctl_add(card, kctl);
2347 if (err < 0)2330 if (err < 0)
2348 return err;2331 return err;
2349 err = snd_ctl_add(card,2332 err = snd_ctl_add(card,
sound/pci/emu10k1/emumpu401.c+17−23
@@ -104,10 +104,9 @@ static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int st · 103 unmodified lines
104 104
105static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)105static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
106{106{
107 unsigned long flags;
108 int timeout, ok;107 int timeout, ok;
109 108
110 spin_lock_irqsave(&midi->input_lock, flags);109 spin_lock_irq(&midi->input_lock);
111 mpu401_write_data(emu, midi, 0x00);110 mpu401_write_data(emu, midi, 0x00);
112 /* mpu401_clear_rx(emu, midi); */111 /* mpu401_clear_rx(emu, midi); */
113 112
@@ -126,7 +125,7 @@ static int snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_mid · 12 unmodified lines
126 } else {125 } else {
127 ok = 1;126 ok = 1;
128 }127 }
129 spin_unlock_irqrestore(&midi->input_lock, flags);128 spin_unlock_irq(&midi->input_lock);
130 if (!ok) {129 if (!ok) {
131 dev_err(emu->card->dev,130 dev_err(emu->card->dev,
132 "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",131 "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
@@ -142,22 +141,21 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) · 9 unmodified lines
142{141{
143 struct snd_emu10k1 *emu;142 struct snd_emu10k1 *emu;
144 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;143 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
145 unsigned long flags;
146 144
147 emu = midi->emu;145 emu = midi->emu;
148 if (snd_BUG_ON(!emu))146 if (snd_BUG_ON(!emu))
149 return -ENXIO;147 return -ENXIO;
150 spin_lock_irqsave(&midi->open_lock, flags);148 spin_lock_irq(&midi->open_lock);
151 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;149 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
152 midi->substream_input = substream;150 midi->substream_input = substream;
153 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {151 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
154 spin_unlock_irqrestore(&midi->open_lock, flags);152 spin_unlock_irq(&midi->open_lock);
155 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))153 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
156 goto error_out;154 goto error_out;
157 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))155 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
158 goto error_out;156 goto error_out;
159 } else {157 } else {
160 spin_unlock_irqrestore(&midi->open_lock, flags);158 spin_unlock_irq(&midi->open_lock);
161 }159 }
162 return 0;160 return 0;
163 161
@@ -169,22 +167,21 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) · 5 unmodified lines
169{167{
170 struct snd_emu10k1 *emu;168 struct snd_emu10k1 *emu;
171 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;169 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
172 unsigned long flags;
173 170
174 emu = midi->emu;171 emu = midi->emu;
175 if (snd_BUG_ON(!emu))172 if (snd_BUG_ON(!emu))
176 return -ENXIO;173 return -ENXIO;
177 spin_lock_irqsave(&midi->open_lock, flags);174 spin_lock_irq(&midi->open_lock);
178 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;175 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
179 midi->substream_output = substream;176 midi->substream_output = substream;
180 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {177 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
181 spin_unlock_irqrestore(&midi->open_lock, flags);178 spin_unlock_irq(&midi->open_lock);
182 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))179 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1))
183 goto error_out;180 goto error_out;
184 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))181 if (snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1))
185 goto error_out;182 goto error_out;
186 } else {183 } else {
187 spin_unlock_irqrestore(&midi->open_lock, flags);184 spin_unlock_irq(&midi->open_lock);
188 }185 }
189 return 0;186 return 0;
190 187
@@ -196,21 +193,20 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) · 5 unmodified lines
196{193{
197 struct snd_emu10k1 *emu;194 struct snd_emu10k1 *emu;
198 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;195 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
199 unsigned long flags;
200 int err = 0;196 int err = 0;
201 197
202 emu = midi->emu;198 emu = midi->emu;
203 if (snd_BUG_ON(!emu))199 if (snd_BUG_ON(!emu))
204 return -ENXIO;200 return -ENXIO;
205 spin_lock_irqsave(&midi->open_lock, flags);201 spin_lock_irq(&midi->open_lock);
206 snd_emu10k1_intr_disable(emu, midi->rx_enable);202 snd_emu10k1_intr_disable(emu, midi->rx_enable);
207 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;203 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
208 midi->substream_input = NULL;204 midi->substream_input = NULL;
209 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {205 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
210 spin_unlock_irqrestore(&midi->open_lock, flags);206 spin_unlock_irq(&midi->open_lock);
211 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);207 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
212 } else {208 } else {
213 spin_unlock_irqrestore(&midi->open_lock, flags);209 spin_unlock_irq(&midi->open_lock);
214 }210 }
215 return err;211 return err;
216}212}
@@ -219,21 +215,20 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream · 2 unmodified lines
219{215{
220 struct snd_emu10k1 *emu;216 struct snd_emu10k1 *emu;
221 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;217 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
222 unsigned long flags;
223 int err = 0;218 int err = 0;
224 219
225 emu = midi->emu;220 emu = midi->emu;
226 if (snd_BUG_ON(!emu))221 if (snd_BUG_ON(!emu))
227 return -ENXIO;222 return -ENXIO;
228 spin_lock_irqsave(&midi->open_lock, flags);223 spin_lock_irq(&midi->open_lock);
229 snd_emu10k1_intr_disable(emu, midi->tx_enable);224 snd_emu10k1_intr_disable(emu, midi->tx_enable);
230 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;225 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
231 midi->substream_output = NULL;226 midi->substream_output = NULL;
232 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {227 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
233 spin_unlock_irqrestore(&midi->open_lock, flags);228 spin_unlock_irq(&midi->open_lock);
234 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);229 err = snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
235 } else {230 } else {
236 spin_unlock_irqrestore(&midi->open_lock, flags);231 spin_unlock_irq(&midi->open_lock);
237 }232 }
238 return err;233 return err;
239}234}
@@ -256,7 +251,6 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr · 16 unmodified lines
256{251{
257 struct snd_emu10k1 *emu;252 struct snd_emu10k1 *emu;
258 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;253 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
259 unsigned long flags;
260 254
261 emu = midi->emu;255 emu = midi->emu;
262 if (snd_BUG_ON(!emu))256 if (snd_BUG_ON(!emu))
@@ -267,13 +261,13 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr · 4 unmodified lines
267 unsigned char byte;261 unsigned char byte;
268 262
269 /* try to send some amount of bytes here before interrupts */263 /* try to send some amount of bytes here before interrupts */
270 spin_lock_irqsave(&midi->output_lock, flags);264 spin_lock_irq(&midi->output_lock);
271 while (max > 0) {265 while (max > 0) {
272 if (mpu401_output_ready(emu, midi)) {266 if (mpu401_output_ready(emu, midi)) {
273 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||267 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
274 snd_rawmidi_transmit(substream, &byte, 1) != 1) {268 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
275 /* no more data */269 /* no more data */
276 spin_unlock_irqrestore(&midi->output_lock, flags);270 spin_unlock_irq(&midi->output_lock);
277 return;271 return;
278 }272 }
279 mpu401_write_data(emu, midi, byte);273 mpu401_write_data(emu, midi, byte);
@@ -282,7 +276,7 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr · 2 unmodified lines
282 break;276 break;
283 }277 }
284 }278 }
285 spin_unlock_irqrestore(&midi->output_lock, flags);279 spin_unlock_irq(&midi->output_lock);
286 snd_emu10k1_intr_enable(emu, midi->tx_enable);280 snd_emu10k1_intr_enable(emu, midi->tx_enable);
287 } else {281 } else {
288 snd_emu10k1_intr_disable(emu, midi->tx_enable);282 snd_emu10k1_intr_disable(emu, midi->tx_enable);
sound/pci/emu10k1/emupcm.c+6−11
@@ -1,15 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Lee Revell <rlrevell@joe-job.com>
5 * James Courtier-Dutton <James@superbug.co.uk>
6 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
4 * Creative Labs, Inc.7 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips / PCM routines
6 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
7 *
8 * BUGS:
9 * --
10 *8 *
11 * TODO:9 * Routines for control of EMU10K1 chips / PCM routines
12 * --
13 */10 */
14 11
15#include <linux/pci.h>12#include <linux/pci.h>
@@ -343,9 +340,7 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu, · 327 unmodified lines
343 unsigned int end_addr,340 unsigned int end_addr,
344 struct snd_emu10k1_pcm_mixer *mix)341 struct snd_emu10k1_pcm_mixer *mix)
345{342{
346 unsigned long flags;343 spin_lock_irq(&emu->reg_lock);
347
348 spin_lock_irqsave(&emu->reg_lock, flags);
349 snd_emu10k1_pcm_init_voice(emu, evoice, w_16, stereo,344 snd_emu10k1_pcm_init_voice(emu, evoice, w_16, stereo,
350 start_addr, end_addr,345 start_addr, end_addr,
351 &mix->send_routing[stereo][0],346 &mix->send_routing[stereo][0],
@@ -355,7 +350,7 @@ static void snd_emu10k1_pcm_init_voices(struct snd_emu10k1 *emu, · 3 unmodified lines
355 start_addr, end_addr,350 start_addr, end_addr,
356 &mix->send_routing[2][0],351 &mix->send_routing[2][0],
357 &mix->send_volume[2][0]);352 &mix->send_volume[2][0]);
358 spin_unlock_irqrestore(&emu->reg_lock, flags);353 spin_unlock_irq(&emu->reg_lock);
359}354}
360 355
361static void snd_emu10k1_pcm_init_extra_voice(struct snd_emu10k1 *emu,356static void snd_emu10k1_pcm_init_extra_voice(struct snd_emu10k1 *emu,
sound/pci/emu10k1/emuproc.c+8−15
@@ -1,17 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Lee Revell <rlrevell@joe-job.com>
5 * James Courtier-Dutton <James@superbug.co.uk>
6 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
4 * Creative Labs, Inc.7 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips / proc interface routines
6 *
7 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
8 * Added EMU 1010 support.
9 *8 *
10 * BUGS:9 * Routines for control of EMU10K1 chips / proc interface routines
11 * --
12 *
13 * TODO:
14 * --
15 */10 */
16 11
17#include <linux/slab.h>12#include <linux/slab.h>
@@ -536,15 +531,14 @@ static unsigned int snd_ptr_read(struct snd_emu10k1 * emu, · 518 unmodified lines
536 unsigned int reg,531 unsigned int reg,
537 unsigned int chn)532 unsigned int chn)
538{533{
539 unsigned long flags;
540 unsigned int regptr, val;534 unsigned int regptr, val;
541 535
542 regptr = (reg << 16) | chn;536 regptr = (reg << 16) | chn;
543 537
544 spin_lock_irqsave(&emu->emu_lock, flags);538 spin_lock_irq(&emu->emu_lock);
545 outl(regptr, emu->port + iobase + PTR);539 outl(regptr, emu->port + iobase + PTR);
546 val = inl(emu->port + iobase + DATA);540 val = inl(emu->port + iobase + DATA);
547 spin_unlock_irqrestore(&emu->emu_lock, flags);541 spin_unlock_irq(&emu->emu_lock);
548 return val;542 return val;
549}543}
550 544
@@ -555,14 +549,13 @@ static void snd_ptr_write(struct snd_emu10k1 *emu, · 4 unmodified lines
555 unsigned int data)549 unsigned int data)
556{550{
557 unsigned int regptr;551 unsigned int regptr;
558 unsigned long flags;
559 552
560 regptr = (reg << 16) | chn;553 regptr = (reg << 16) | chn;
561 554
562 spin_lock_irqsave(&emu->emu_lock, flags);555 spin_lock_irq(&emu->emu_lock);
563 outl(regptr, emu->port + iobase + PTR);556 outl(regptr, emu->port + iobase + PTR);
564 outl(data, emu->port + iobase + DATA);557 outl(data, emu->port + iobase + DATA);
565 spin_unlock_irqrestore(&emu->emu_lock, flags);558 spin_unlock_irq(&emu->emu_lock);
566}559}
567 560
568 561
sound/pci/emu10k1/io.c+6−6
@@ -1,14 +1,12 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Lee Revell <rlrevell@joe-job.com>
5 * James Courtier-Dutton <James@superbug.co.uk>
6 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
4 * Creative Labs, Inc.7 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips
6 *
7 * BUGS:
8 * --
9 *8 *
10 * TODO:9 * Routines for control of EMU10K1 chips
11 * --
12 */10 */
13 11
14#include <linux/time.h>12#include <linux/time.h>
@@ -302,6 +300,8 @@ static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 * · 287 unmodified lines
302{300{
303 // The higest input pin is used as the designated interrupt trigger,301 // The higest input pin is used as the designated interrupt trigger,
304 // so it needs to be masked out.302 // so it needs to be masked out.
303 // But note that any other input pin change will also cause an IRQ,
304 // so using this function often causes an IRQ as a side effect.
305 u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;305 u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
306 if (snd_BUG_ON(reg > 0x3f))306 if (snd_BUG_ON(reg > 0x3f))
307 return;307 return;
sound/pci/emu10k1/irq.c+7−6
@@ -3,12 +3,6 @@ · 2 unmodified lines
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Creative Labs, Inc.4 * Creative Labs, Inc.
5 * Routines for IRQ control of EMU10K1 chips5 * Routines for IRQ control of EMU10K1 chips
6 *
7 * BUGS:
8 * --
9 *
10 * TODO:
11 * --
12 */6 */
13 7
14#include <linux/time.h>8#include <linux/time.h>
@@ -149,6 +143,13 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id) · 134 unmodified lines
149 outl(0, emu->port + INTE2);143 outl(0, emu->port + INTE2);
150 status &= ~IPR_P16V;144 status &= ~IPR_P16V;
151 }145 }
146 if (status & IPR_A_GPIO) {
147 if (emu->gpio_interrupt)
148 emu->gpio_interrupt(emu);
149 else
150 snd_emu10k1_intr_disable(emu, INTE_A_GPIOENABLE);
151 status &= ~IPR_A_GPIO;
152 }
152 153
153 if (status) {154 if (status) {
154 dev_err(emu->card->dev,155 dev_err(emu->card->dev,
sound/pci/emu10k1/p16v.h+0−56
@@ -2,62 +2,6 @@ · 1 unmodified line
2/*2/*
3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
4 * Driver p16v chips4 * Driver p16v chips
5 * Version: 0.21
6 *
7 * FEATURES currently supported:
8 * Output fixed at S32_LE, 2 channel to hw:0,0
9 * Rates: 44.1, 48, 96, 192.
10 *
11 * Changelog:
12 * 0.8
13 * Use separate card based buffer for periods table.
14 * 0.9
15 * Use 2 channel output streams instead of 8 channel.
16 * (8 channel output streams might be good for ASIO type output)
17 * Corrected speaker output, so Front -> Front etc.
18 * 0.10
19 * Fixed missed interrupts.
20 * 0.11
21 * Add Sound card model number and names.
22 * Add Analog volume controls.
23 * 0.12
24 * Corrected playback interrupts. Now interrupt per period, instead of half period.
25 * 0.13
26 * Use single trigger for multichannel.
27 * 0.14
28 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
29 * 0.15
30 * Force buffer_size / period_size == INTEGER.
31 * 0.16
32 * Update p16v.c to work with changed alsa api.
33 * 0.17
34 * Update p16v.c to work with changed alsa api. Removed boot_devs.
35 * 0.18
36 * Merging with snd-emu10k1 driver.
37 * 0.19
38 * One stereo channel at 24bit now works.
39 * 0.20
40 * Added better register defines.
41 * 0.21
42 * Split from p16v.c
43 *
44 * BUGS:
45 * Some stability problems when unloading the snd-p16v kernel module.
46 * --
47 *
48 * TODO:
49 * SPDIF out.
50 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
51 * Currently capture fixed at 48000Hz.
52 *
53 * --
54 * GENERAL INFO:
55 * Model: SB0240
56 * P16V Chip: CA0151-DBS
57 * Audigy 2 Chip: CA0102-IAT
58 * AC97 Codec: STAC 9721
59 * ADC: Philips 1361T (Stereo 24bit)
60 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
61 *5 *
62 * This code was initially based on code from ALSA's emu10k1x.c which is:6 * This code was initially based on code from ALSA's emu10k1x.c which is:
63 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>7 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
sound/pci/emu10k1/p17v.h+0−1
@@ -2,7 +2,6 @@ · 1 unmodified line
2/*2/*
3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
4 * Driver p17v chips4 * Driver p17v chips
5 * Version: 0.01
6 */5 */
7 6
8/******************************************************************************/7/******************************************************************************/
sound/pci/emu10k1/timer.c+2−6
@@ -2,13 +2,9 @@ · 1 unmodified line
2/*2/*
3 * Copyright (c) by Lee Revell <rlrevell@joe-job.com>3 * Copyright (c) by Lee Revell <rlrevell@joe-job.com>
4 * Clemens Ladisch <clemens@ladisch.de>4 * Clemens Ladisch <clemens@ladisch.de>
5 * Routines for control of EMU10K1 chips5 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
6 *
7 * BUGS:
8 * --
9 *6 *
10 * TODO:7 * Routines for control of EMU10K1 chips
11 * --
12 */8 */
13 9
14#include <linux/time.h>10#include <linux/time.h>
sound/pci/emu10k1/tina2.h+0−1
@@ -2,7 +2,6 @@ · 1 unmodified line
2/*2/*
3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>3 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
4 * Driver tina2 chips4 * Driver tina2 chips
5 * Version: 0.1
6 */5 */
7 6
8/********************************************************************************************************/7/********************************************************************************************************/
sound/pci/emu10k1/voice.c+3−9
@@ -1,17 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2/*2/*
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 * Creative Labs, Inc.
5 * Lee Revell <rlrevell@joe-job.com>4 * Lee Revell <rlrevell@joe-job.com>
6 * Routines for control of EMU10K1 chips - voice manager5 * Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
7 *6 * Creative Labs, Inc.
8 * Rewrote voice allocator for multichannel support - rlrevell 12/2004
9 *
10 * BUGS:
11 * --
12 *7 *
13 * TODO:8 * Routines for control of EMU10K1 chips - voice manager
14 * --
15 */9 */
16 10
17#include <linux/time.h>11#include <linux/time.h>
sound/pci/es1938.c+5−25
@@ -824,7 +824,7 @@ static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *s · 823 unmodified lines
824 824
825static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,825static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
826 int channel, unsigned long pos,826 int channel, unsigned long pos,
827 void __user *dst, unsigned long count)827 struct iov_iter *dst, unsigned long count)
828{828{
829 struct snd_pcm_runtime *runtime = substream->runtime;829 struct snd_pcm_runtime *runtime = substream->runtime;
830 struct es1938 *chip = snd_pcm_substream_chip(substream);830 struct es1938 *chip = snd_pcm_substream_chip(substream);
@@ -832,36 +832,17 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream, · 1 unmodified line
832 if (snd_BUG_ON(pos + count > chip->dma1_size))832 if (snd_BUG_ON(pos + count > chip->dma1_size))
833 return -EINVAL;833 return -EINVAL;
834 if (pos + count < chip->dma1_size) {834 if (pos + count < chip->dma1_size) {
835 if (copy_to_user(dst, runtime->dma_area + pos + 1, count))835 if (copy_to_iter(runtime->dma_area + pos + 1, count, dst) != count)
836 return -EFAULT;836 return -EFAULT;
837 } else {837 } else {
838 if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))838 if (copy_to_iter(runtime->dma_area + pos + 1, count - 1, dst) != count - 1)
839 return -EFAULT;839 return -EFAULT;
840 if (put_user(runtime->dma_area[0],840 if (copy_to_iter(runtime->dma_area, 1, dst) != 1)
841 ((unsigned char __user *)dst) + count - 1))
842 return -EFAULT;841 return -EFAULT;
843 }842 }
844 return 0;843 return 0;
845}844}
846 845
847static int snd_es1938_capture_copy_kernel(struct snd_pcm_substream *substream,
848 int channel, unsigned long pos,
849 void *dst, unsigned long count)
850{
851 struct snd_pcm_runtime *runtime = substream->runtime;
852 struct es1938 *chip = snd_pcm_substream_chip(substream);
853
854 if (snd_BUG_ON(pos + count > chip->dma1_size))
855 return -EINVAL;
856 if (pos + count < chip->dma1_size) {
857 memcpy(dst, runtime->dma_area + pos + 1, count);
858 } else {
859 memcpy(dst, runtime->dma_area + pos + 1, count - 1);
860 runtime->dma_area[0] = *((unsigned char *)dst + count - 1);
861 }
862 return 0;
863}
864
865/* ----------------------------------------------------------------------846/* ----------------------------------------------------------------------
866 * Audio1 Capture (ADC)847 * Audio1 Capture (ADC)
867 * ----------------------------------------------------------------------*/848 * ----------------------------------------------------------------------*/
@@ -987,8 +968,7 @@ static const struct snd_pcm_ops snd_es1938_capture_ops = { · 119 unmodified lines
987 .prepare = snd_es1938_capture_prepare,968 .prepare = snd_es1938_capture_prepare,
988 .trigger = snd_es1938_capture_trigger,969 .trigger = snd_es1938_capture_trigger,
989 .pointer = snd_es1938_capture_pointer,970 .pointer = snd_es1938_capture_pointer,
990 .copy_user = snd_es1938_capture_copy,971 .copy = snd_es1938_capture_copy,
991 .copy_kernel = snd_es1938_capture_copy_kernel,
992};972};
993 973
994static int snd_es1938_new_pcm(struct es1938 *chip, int device)974static int snd_es1938_new_pcm(struct es1938 *chip, int device)
sound/pci/es1968.c+4−11
@@ -2005,9 +2005,6 @@ snd_es1968_mixer(struct es1968 *chip) · 2004 unmodified lines
2005{2005{
2006 struct snd_ac97_bus *pbus;2006 struct snd_ac97_bus *pbus;
2007 struct snd_ac97_template ac97;2007 struct snd_ac97_template ac97;
2008#ifndef CONFIG_SND_ES1968_INPUT
2009 struct snd_ctl_elem_id elem_id;
2010#endif
2011 int err;2008 int err;
2012 static const struct snd_ac97_bus_ops ops = {2009 static const struct snd_ac97_bus_ops ops = {
2013 .write = snd_es1968_ac97_write,2010 .write = snd_es1968_ac97_write,
@@ -2027,14 +2024,10 @@ snd_es1968_mixer(struct es1968 *chip) · 13 unmodified lines
2027 2024
2028#ifndef CONFIG_SND_ES1968_INPUT2025#ifndef CONFIG_SND_ES1968_INPUT
2029 /* attach master switch / volumes for h/w volume control */2026 /* attach master switch / volumes for h/w volume control */
2030 memset(&elem_id, 0, sizeof(elem_id));2027 chip->master_switch = snd_ctl_find_id_mixer(chip->card,
2031 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;2028 "Master Playback Switch");
2032 strcpy(elem_id.name, "Master Playback Switch");2029 chip->master_volume = snd_ctl_find_id_mixer(chip->card,
2033 chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);2030 "Master Playback Volume");
2034 memset(&elem_id, 0, sizeof(elem_id));
2035 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2036 strcpy(elem_id.name, "Master Playback Volume");
2037 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2038#endif2031#endif
2039 2032
2040 return 0;2033 return 0;
sound/pci/hda/Kconfig+49−0
@@ -104,6 +104,7 @@ config SND_HDA_SCODEC_CS35L41_I2C · 103 unmodified lines
104 tristate "Build CS35L41 HD-audio side codec support for I2C Bus"104 tristate "Build CS35L41 HD-audio side codec support for I2C Bus"
105 depends on I2C105 depends on I2C
106 depends on ACPI106 depends on ACPI
107 depends on EFI
107 depends on SND_SOC108 depends on SND_SOC
108 select SND_SOC_CS35L41_LIB109 select SND_SOC_CS35L41_LIB
109 select SND_HDA_SCODEC_CS35L41110 select SND_HDA_SCODEC_CS35L41
@@ -119,6 +120,7 @@ config SND_HDA_SCODEC_CS35L41_SPI · 9 unmodified lines
119 tristate "Build CS35L41 HD-audio codec support for SPI Bus"120 tristate "Build CS35L41 HD-audio codec support for SPI Bus"
120 depends on SPI_MASTER121 depends on SPI_MASTER
121 depends on ACPI122 depends on ACPI
123 depends on EFI
122 depends on SND_SOC124 depends on SND_SOC
123 select SND_SOC_CS35L41_LIB125 select SND_SOC_CS35L41_LIB
124 select SND_HDA_SCODEC_CS35L41126 select SND_HDA_SCODEC_CS35L41
@@ -130,6 +132,53 @@ config SND_HDA_SCODEC_CS35L41_SPI · 5 unmodified lines
130comment "Set to Y if you want auto-loading the side codec driver"132comment "Set to Y if you want auto-loading the side codec driver"
131 depends on SND_HDA=y && SND_HDA_SCODEC_CS35L41_SPI=m133 depends on SND_HDA=y && SND_HDA_SCODEC_CS35L41_SPI=m
132 134
135config SND_HDA_SCODEC_CS35L56
136 tristate
137
138config SND_HDA_SCODEC_CS35L56_I2C
139 tristate "Build CS35L56 HD-audio side codec support for I2C Bus"
140 depends on I2C
141 depends on ACPI || COMPILE_TEST
142 depends on SND_SOC
143 select CS_DSP
144 select SND_HDA_GENERIC
145 select SND_SOC_CS35L56_SHARED
146 select SND_HDA_SCODEC_CS35L56
147 select SND_HDA_CS_DSP_CONTROLS
148 help
149 Say Y or M here to include CS35L56 amplifier support with
150 I2C control.
151
152config SND_HDA_SCODEC_CS35L56_SPI
153 tristate "Build CS35L56 HD-audio side codec support for SPI Bus"
154 depends on SPI_MASTER
155 depends on ACPI || COMPILE_TEST
156 depends on SND_SOC
157 select CS_DSP
158 select SND_HDA_GENERIC
159 select SND_SOC_CS35L56_SHARED
160 select SND_HDA_SCODEC_CS35L56
161 select SND_HDA_CS_DSP_CONTROLS
162 help
163 Say Y or M here to include CS35L56 amplifier support with
164 SPI control.
165
166config SND_HDA_SCODEC_TAS2781_I2C
167 tristate "Build TAS2781 HD-audio side codec support for I2C Bus"
168 depends on I2C
169 depends on ACPI
170 depends on EFI
171 depends on SND_SOC
172 select SND_SOC_TAS2781_COMLIB
173 select SND_SOC_TAS2781_FMWLIB
174 select CRC32_SARWATE
175 help
176 Say Y or M here to include TAS2781 I2C HD-audio side codec support
177 in snd-hda-intel driver, such as ALC287.
178
179comment "Set to Y if you want auto-loading the side codec driver"
180 depends on SND_HDA=y && SND_HDA_SCODEC_TAS2781_I2C=m
181
133config SND_HDA_CODEC_REALTEK182config SND_HDA_CODEC_REALTEK
134 tristate "Build Realtek HD-audio codec support"183 tristate "Build Realtek HD-audio codec support"
135 select SND_HDA_GENERIC184 select SND_HDA_GENERIC
sound/pci/hda/Makefile+9−1
@@ -28,10 +28,14 @@ snd-hda-codec-via-objs := patch_via.o · 27 unmodified lines
28snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o28snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
29 29
30# side codecs30# side codecs
31snd-hda-scodec-cs35l41-objs := cs35l41_hda.o31snd-hda-scodec-cs35l41-objs := cs35l41_hda.o cs35l41_hda_property.o
32snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o32snd-hda-scodec-cs35l41-i2c-objs := cs35l41_hda_i2c.o
33snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o33snd-hda-scodec-cs35l41-spi-objs := cs35l41_hda_spi.o
34snd-hda-scodec-cs35l56-objs := cs35l56_hda.o
35snd-hda-scodec-cs35l56-i2c-objs := cs35l56_hda_i2c.o
36snd-hda-scodec-cs35l56-spi-objs := cs35l56_hda_spi.o
34snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o37snd-hda-cs-dsp-ctls-objs := hda_cs_dsp_ctl.o
38snd-hda-scodec-tas2781-i2c-objs := tas2781_hda_i2c.o
35 39
36# common driver40# common driver
37obj-$(CONFIG_SND_HDA) := snd-hda-codec.o41obj-$(CONFIG_SND_HDA) := snd-hda-codec.o
@@ -55,7 +59,11 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o · 17 unmodified lines
55obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o59obj-$(CONFIG_SND_HDA_SCODEC_CS35L41) += snd-hda-scodec-cs35l41.o
56obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o60obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_I2C) += snd-hda-scodec-cs35l41-i2c.o
57obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o61obj-$(CONFIG_SND_HDA_SCODEC_CS35L41_SPI) += snd-hda-scodec-cs35l41-spi.o
62obj-$(CONFIG_SND_HDA_SCODEC_CS35L56) += snd-hda-scodec-cs35l56.o
63obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_I2C) += snd-hda-scodec-cs35l56-i2c.o
64obj-$(CONFIG_SND_HDA_SCODEC_CS35L56_SPI) += snd-hda-scodec-cs35l56-spi.o
58obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o65obj-$(CONFIG_SND_HDA_CS_DSP_CONTROLS) += snd-hda-cs-dsp-ctls.o
66obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o
59 67
60# this must be the last entry after codec drivers;68# this must be the last entry after codec drivers;
61# otherwise the codec patches won't be hooked before the PCI probe69# otherwise the codec patches won't be hooked before the PCI probe
sound/pci/hda/cs35l41_hda.c+245−115
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include "hda_component.h"19#include "hda_component.h"
20#include "cs35l41_hda.h"20#include "cs35l41_hda.h"
21#include "hda_cs_dsp_ctl.h"21#include "hda_cs_dsp_ctl.h"
22#include "cs35l41_hda_property.h"
22 23
23#define CS35L41_FIRMWARE_ROOT "cirrus/"24#define CS35L41_FIRMWARE_ROOT "cirrus/"
24#define CS35L41_PART "cs35l41"25#define CS35L41_PART "cs35l41"
@@ -58,8 +59,6 @@ static const struct reg_sequence cs35l41_hda_config[] = { · 33 unmodified lines
58 { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON59 { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON
59 { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON60 { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON
60 { CS35L41_DSP1_RX5_SRC, 0x00000020 }, // DSP1RX5 SRC = ERRVOL61 { CS35L41_DSP1_RX5_SRC, 0x00000020 }, // DSP1RX5 SRC = ERRVOL
61 { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB
62 { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB
63};62};
64 63
65static const struct reg_sequence cs35l41_hda_config_dsp[] = {64static const struct reg_sequence cs35l41_hda_config_dsp[] = {
@@ -82,6 +81,14 @@ static const struct reg_sequence cs35l41_hda_config_dsp[] = { · 16 unmodified lines
82 { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON81 { CS35L41_DSP1_RX3_SRC, 0x00000018 }, // DSP1RX3 SRC = VMON
83 { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON82 { CS35L41_DSP1_RX4_SRC, 0x00000019 }, // DSP1RX4 SRC = IMON
84 { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON83 { CS35L41_DSP1_RX5_SRC, 0x00000029 }, // DSP1RX5 SRC = VBSTMON
84};
85
86static const struct reg_sequence cs35l41_hda_unmute[] = {
87 { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB
88 { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB
89};
90
91static const struct reg_sequence cs35l41_hda_unmute_dsp[] = {
85 { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB92 { CS35L41_AMP_DIG_VOL_CTRL, 0x00008000 }, // AMP_HPF_PCM_EN = 1, AMP_VOL_PCM 0.0 dB
86 { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB93 { CS35L41_AMP_GAIN_CTRL, 0x00000233 }, // AMP_GAIN_PCM = 17.5dB AMP_GAIN_PDM = 19.5dB
87};94};
@@ -483,73 +490,159 @@ static void cs35l41_irq_release(struct cs35l41_hda *cs35l41) · 395 unmodified lines
483 cs35l41->irq_errors = 0;490 cs35l41->irq_errors = 0;
484}491}
485 492
486static void cs35l41_hda_playback_hook(struct device *dev, int action)493static void cs35l41_hda_play_start(struct device *dev)
487{494{
488 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);495 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
489 struct regmap *reg = cs35l41->regmap;496 struct regmap *reg = cs35l41->regmap;
490 int ret = 0;497
498 dev_dbg(dev, "Play (Start)\n");
499
500 if (cs35l41->playback_started) {
501 dev_dbg(dev, "Playback already started.");
502 return;
503 }
504
505 cs35l41->playback_started = true;
506
507 if (cs35l41->firmware_running) {
508 regmap_multi_reg_write(reg, cs35l41_hda_config_dsp,
509 ARRAY_SIZE(cs35l41_hda_config_dsp));
510 regmap_update_bits(reg, CS35L41_PWR_CTRL2,
511 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
512 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT);
513 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, reg, CSPL_MBOX_CMD_RESUME);
514 } else {
515 regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config));
516 }
517 regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
518 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
519 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
520
521}
522
523static void cs35l41_hda_play_done(struct device *dev)
524{
525 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
526 struct regmap *reg = cs35l41->regmap;
527
528 dev_dbg(dev, "Play (Complete)\n");
529
530 cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, NULL,
531 cs35l41->firmware_running);
532 if (cs35l41->firmware_running) {
533 regmap_multi_reg_write(reg, cs35l41_hda_unmute_dsp,
534 ARRAY_SIZE(cs35l41_hda_unmute_dsp));
535 } else {
536 regmap_multi_reg_write(reg, cs35l41_hda_unmute,
537 ARRAY_SIZE(cs35l41_hda_unmute));
538 }
539}
540
541static void cs35l41_hda_pause_start(struct device *dev)
542{
543 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
544 struct regmap *reg = cs35l41->regmap;
545
546 dev_dbg(dev, "Pause (Start)\n");
547
548 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
549 cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0, NULL,
550 cs35l41->firmware_running);
551}
552
553static void cs35l41_hda_pause_done(struct device *dev)
554{
555 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
556 struct regmap *reg = cs35l41->regmap;
557
558 dev_dbg(dev, "Pause (Complete)\n");
559
560 regmap_update_bits(reg, CS35L41_PWR_CTRL2, CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
561 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
562 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);
563 if (cs35l41->firmware_running) {
564 cs35l41_set_cspl_mbox_cmd(dev, reg, CSPL_MBOX_CMD_PAUSE);
565 regmap_update_bits(reg, CS35L41_PWR_CTRL2,
566 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
567 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
568 }
569 cs35l41_irq_release(cs35l41);
570 cs35l41->playback_started = false;
571}
572
573static void cs35l41_hda_pre_playback_hook(struct device *dev, int action)
574{
575 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
491 576
492 switch (action) {577 switch (action) {
493 case HDA_GEN_PCM_ACT_OPEN:578 case HDA_GEN_PCM_ACT_CLEANUP:
494 pm_runtime_get_sync(dev);
495 mutex_lock(&cs35l41->fw_mutex);579 mutex_lock(&cs35l41->fw_mutex);
496 cs35l41->playback_started = true;580 cs35l41_hda_pause_start(dev);
497 if (cs35l41->firmware_running) {
498 regmap_multi_reg_write(reg, cs35l41_hda_config_dsp,
499 ARRAY_SIZE(cs35l41_hda_config_dsp));
500 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
501 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
502 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT);
503 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
504 CSPL_MBOX_CMD_RESUME);
505 } else {
506 regmap_multi_reg_write(reg, cs35l41_hda_config,
507 ARRAY_SIZE(cs35l41_hda_config));
508 }
509 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,
510 CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
511 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
512 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
513 mutex_unlock(&cs35l41->fw_mutex);581 mutex_unlock(&cs35l41->fw_mutex);
514 break;582 break;
583 default:
584 break;
585 }
586}
587static void cs35l41_hda_playback_hook(struct device *dev, int action)
588{
589 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
590
591 switch (action) {
592 case HDA_GEN_PCM_ACT_OPEN:
593 /*
594 * All amps must be resumed before we can start playing back.
595 * This ensures, for external boost, that all amps are in AMP_SAFE mode.
596 * Do this in HDA_GEN_PCM_ACT_OPEN, since this is run prior to any of the
597 * other actions.
598 */
599 pm_runtime_get_sync(dev);
600 break;
515 case HDA_GEN_PCM_ACT_PREPARE:601 case HDA_GEN_PCM_ACT_PREPARE:
516 mutex_lock(&cs35l41->fw_mutex);602 mutex_lock(&cs35l41->fw_mutex);
517 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1, NULL);603 cs35l41_hda_play_start(dev);
518 mutex_unlock(&cs35l41->fw_mutex);604 mutex_unlock(&cs35l41->fw_mutex);
519 break;605 break;
520 case HDA_GEN_PCM_ACT_CLEANUP:606 case HDA_GEN_PCM_ACT_CLEANUP:
521 mutex_lock(&cs35l41->fw_mutex);607 mutex_lock(&cs35l41->fw_mutex);
522 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));608 cs35l41_hda_pause_done(dev);
523 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0, NULL);
524 mutex_unlock(&cs35l41->fw_mutex);609 mutex_unlock(&cs35l41->fw_mutex);
525 break;610 break;
526 case HDA_GEN_PCM_ACT_CLOSE:611 case HDA_GEN_PCM_ACT_CLOSE:
527 mutex_lock(&cs35l41->fw_mutex);612 mutex_lock(&cs35l41->fw_mutex);
528 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2,613 if (!cs35l41->firmware_running && cs35l41->request_fw_load &&
529 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);614 !cs35l41->fw_request_ongoing) {
530 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)615 dev_info(dev, "Requesting Firmware Load after HDA_GEN_PCM_ACT_CLOSE\n");
531 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);616 cs35l41->fw_request_ongoing = true;
532 if (cs35l41->firmware_running) {617 schedule_work(&cs35l41->fw_load_work);
533 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
534 CSPL_MBOX_CMD_PAUSE);
535 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
536 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
537 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
538 }618 }
539 cs35l41_irq_release(cs35l41);
540 cs35l41->playback_started = false;
541 mutex_unlock(&cs35l41->fw_mutex);619 mutex_unlock(&cs35l41->fw_mutex);
542 620
621 /*
622 * Playback must be finished for all amps before we start runtime suspend.
623 * This ensures no amps are playing back when we start putting them to sleep.
624 */
543 pm_runtime_mark_last_busy(dev);625 pm_runtime_mark_last_busy(dev);
544 pm_runtime_put_autosuspend(dev);626 pm_runtime_put_autosuspend(dev);
545 break;627 break;
546 default:628 default:
547 dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action);
548 break;629 break;
549 }630 }
631}
550 632
551 if (ret)633static void cs35l41_hda_post_playback_hook(struct device *dev, int action)
552 dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret);634{
635 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
636
637 switch (action) {
638 case HDA_GEN_PCM_ACT_PREPARE:
639 mutex_lock(&cs35l41->fw_mutex);
640 cs35l41_hda_play_done(dev);
641 mutex_unlock(&cs35l41->fw_mutex);
642 break;
643 default:
644 break;
645 }
553}646}
554 647
555static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot,648static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot,
@@ -572,21 +665,62 @@ static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsi · 16 unmodified lines
572 rx_slot);665 rx_slot);
573}666}
574 667
575static void cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41)668static int cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41)
576{669{
670 int ret = 0;
671
577 mutex_lock(&cs35l41->fw_mutex);672 mutex_lock(&cs35l41->fw_mutex);
578 if (cs35l41->firmware_running) {673 if (cs35l41->firmware_running) {
579 674
580 regcache_cache_only(cs35l41->regmap, false);675 regcache_cache_only(cs35l41->regmap, false);
581 676
582 cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap);677 ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap);
678 if (ret) {
679 dev_warn(cs35l41->dev, "Unable to exit Hibernate.");
680 goto err;
681 }
682
683 /* Test key needs to be unlocked to allow the OTP settings to re-apply */
684 cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
685 ret = regcache_sync(cs35l41->regmap);
686 cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
687 if (ret) {
688 dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
689 goto err;
690 }
691
692 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
693 cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg);
694
583 cs35l41_shutdown_dsp(cs35l41);695 cs35l41_shutdown_dsp(cs35l41);
584 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);696 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
697 }
698err:
699 regcache_cache_only(cs35l41->regmap, true);
700 regcache_mark_dirty(cs35l41->regmap);
701
702 mutex_unlock(&cs35l41->fw_mutex);
585 703
586 regcache_cache_only(cs35l41->regmap, true);704 return ret;
587 regcache_mark_dirty(cs35l41->regmap);705}
706
707static int cs35l41_system_suspend_prep(struct device *dev)
708{
709 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
710
711 dev_dbg(cs35l41->dev, "System Suspend Prepare\n");
712
713 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) {
714 dev_err_once(cs35l41->dev, "System Suspend not supported\n");
715 return 0; /* don't block the whole system suspend */
588 }716 }
717
718 mutex_lock(&cs35l41->fw_mutex);
719 if (cs35l41->playback_started)
720 cs35l41_hda_pause_start(dev);
589 mutex_unlock(&cs35l41->fw_mutex);721 mutex_unlock(&cs35l41->fw_mutex);
722
723 return 0;
590}724}
591 725
592static int cs35l41_system_suspend(struct device *dev)726static int cs35l41_system_suspend(struct device *dev)
@@ -601,18 +735,28 @@ static int cs35l41_system_suspend(struct device *dev) · 8 unmodified lines
601 return 0; /* don't block the whole system suspend */735 return 0; /* don't block the whole system suspend */
602 }736 }
603 737
738 mutex_lock(&cs35l41->fw_mutex);
739 if (cs35l41->playback_started)
740 cs35l41_hda_pause_done(dev);
741 mutex_unlock(&cs35l41->fw_mutex);
742
604 ret = pm_runtime_force_suspend(dev);743 ret = pm_runtime_force_suspend(dev);
605 if (ret)744 if (ret) {
745 dev_err(dev, "System Suspend Failed, unable to runtime suspend: %d\n", ret);
606 return ret;746 return ret;
747 }
607 748
608 /* Shutdown DSP before system suspend */749 /* Shutdown DSP before system suspend */
609 cs35l41_ready_for_reset(cs35l41);750 ret = cs35l41_ready_for_reset(cs35l41);
751
752 if (ret)
753 dev_err(dev, "System Suspend Failed, not ready for Reset: %d\n", ret);
610 754
611 /*755 /*
612 * Reset GPIO may be shared, so cannot reset here.756 * Reset GPIO may be shared, so cannot reset here.
613 * However beyond this point, amps may be powered down.757 * However beyond this point, amps may be powered down.
614 */758 */
615 return 0;759 return ret;
616}760}
617 761
618static int cs35l41_system_resume(struct device *dev)762static int cs35l41_system_resume(struct device *dev)
@@ -635,9 +779,14 @@ static int cs35l41_system_resume(struct device *dev) · 16 unmodified lines
635 usleep_range(2000, 2100);779 usleep_range(2000, 2100);
636 780
637 ret = pm_runtime_force_resume(dev);781 ret = pm_runtime_force_resume(dev);
782 if (ret) {
783 dev_err(dev, "System Resume Failed: Unable to runtime resume: %d\n", ret);
784 return ret;
785 }
638 786
639 mutex_lock(&cs35l41->fw_mutex);787 mutex_lock(&cs35l41->fw_mutex);
640 if (!ret && cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) {788
789 if (cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) {
641 cs35l41->fw_request_ongoing = true;790 cs35l41->fw_request_ongoing = true;
642 schedule_work(&cs35l41->fw_load_work);791 schedule_work(&cs35l41->fw_load_work);
643 }792 }
@@ -669,20 +818,6 @@ static int cs35l41_runtime_suspend(struct device *dev) · 25 unmodified lines
669 818
670 mutex_lock(&cs35l41->fw_mutex);819 mutex_lock(&cs35l41->fw_mutex);
671 820
672 if (cs35l41->playback_started) {
673 regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
674 ARRAY_SIZE(cs35l41_hda_mute));
675 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0, NULL);
676 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
677 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
678 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
679 regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001);
680 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
681 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK,
682 0 << CS35L41_VMON_EN_SHIFT | 0 << CS35L41_IMON_EN_SHIFT);
683 cs35l41->playback_started = false;
684 }
685
686 if (cs35l41->firmware_running) {821 if (cs35l41->firmware_running) {
687 ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap,822 ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap,
688 cs35l41->hw_cfg.bst_type);823 cs35l41->hw_cfg.bst_type);
@@ -778,7 +913,12 @@ static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) · 89 unmodified lines
778 goto clean_dsp;913 goto clean_dsp;
779 }914 }
780 915
781 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE);916 ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE);
917 if (ret) {
918 dev_err(cs35l41->dev, "Error waiting for DSP to pause: %u\n", ret);
919 goto clean_dsp;
920 }
921
782 cs35l41->firmware_running = true;922 cs35l41->firmware_running = true;
783 923
784 return 0;924 return 0;
@@ -937,6 +1077,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas · 152 unmodified lines
937{1077{
938 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);1078 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
939 struct hda_component *comps = master_data;1079 struct hda_component *comps = master_data;
1080 unsigned int sleep_flags;
940 int ret = 0;1081 int ret = 0;
941 1082
942 if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS)1083 if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS)
@@ -971,12 +1112,26 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas · 28 unmodified lines
971 ret = cs35l41_create_controls(cs35l41);1112 ret = cs35l41_create_controls(cs35l41);
972 1113
973 comps->playback_hook = cs35l41_hda_playback_hook;1114 comps->playback_hook = cs35l41_hda_playback_hook;
1115 comps->pre_playback_hook = cs35l41_hda_pre_playback_hook;
1116 comps->post_playback_hook = cs35l41_hda_post_playback_hook;
974 1117
975 mutex_unlock(&cs35l41->fw_mutex);1118 mutex_unlock(&cs35l41->fw_mutex);
976 1119
1120 sleep_flags = lock_system_sleep();
1121 if (!device_link_add(&comps->codec->core.dev, cs35l41->dev, DL_FLAG_STATELESS))
1122 dev_warn(dev, "Unable to create device link\n");
1123 unlock_system_sleep(sleep_flags);
1124
977 pm_runtime_mark_last_busy(dev);1125 pm_runtime_mark_last_busy(dev);
978 pm_runtime_put_autosuspend(dev);1126 pm_runtime_put_autosuspend(dev);
979 1127
1128 dev_info(cs35l41->dev,
1129 "CS35L41 Bound - SSID: %s, BST: %d, VSPK: %d, CH: %c, FW EN: %d, SPKID: %d\n",
1130 cs35l41->acpi_subsystem_id, cs35l41->hw_cfg.bst_type,
1131 cs35l41->hw_cfg.gpio1.func == CS35l41_VSPK_SWITCH,
1132 cs35l41->hw_cfg.spk_pos ? 'R' : 'L',
1133 cs35l41->firmware_running, cs35l41->speaker_id);
1134
980 return ret;1135 return ret;
981}1136}
982 1137
@@ -984,9 +1139,14 @@ static void cs35l41_hda_unbind(struct device *dev, struct device *master, void * · 1 unmodified line
984{1139{
985 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);1140 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
986 struct hda_component *comps = master_data;1141 struct hda_component *comps = master_data;
1142 unsigned int sleep_flags;
987 1143
988 if (comps[cs35l41->index].dev == dev)1144 if (comps[cs35l41->index].dev == dev) {
989 memset(&comps[cs35l41->index], 0, sizeof(*comps));1145 memset(&comps[cs35l41->index], 0, sizeof(*comps));
1146 sleep_flags = lock_system_sleep();
1147 device_link_remove(&comps->codec->core.dev, cs35l41->dev);
1148 unlock_system_sleep(sleep_flags);
1149 }
990}1150}
991 1151
992static const struct component_ops cs35l41_hda_comp_ops = {1152static const struct component_ops cs35l41_hda_comp_ops = {
@@ -1156,8 +1316,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) · 163 unmodified lines
1156 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);1316 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
1157}1317}
1158 1318
1159static int cs35l41_get_speaker_id(struct device *dev, int amp_index,1319int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id)
1160 int num_amps, int fixed_gpio_id)
1161{1320{
1162 struct gpio_desc *speaker_id_desc;1321 struct gpio_desc *speaker_id_desc;
1163 int speaker_id = -ENODEV;1322 int speaker_id = -ENODEV;
@@ -1211,49 +1370,6 @@ static int cs35l41_get_speaker_id(struct device *dev, int amp_index, · 47 unmodified lines
1211 return speaker_id;1370 return speaker_id;
1212}1371}
1213 1372
1214/*
1215 * Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work.
1216 * And devices created by serial-multi-instantiate don't have their device struct
1217 * pointing to the correct fwnode, so acpi_dev must be used here.
1218 * And devm functions expect that the device requesting the resource has the correct
1219 * fwnode.
1220 */
1221static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
1222 const char *hid)
1223{
1224 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
1225
1226 /* check I2C address to assign the index */
1227 cs35l41->index = id == 0x40 ? 0 : 1;
1228 cs35l41->channel_index = 0;
1229 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
1230 cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
1231 hw_cfg->spk_pos = cs35l41->index;
1232 hw_cfg->gpio2.func = CS35L41_INTERRUPT;
1233 hw_cfg->gpio2.valid = true;
1234 hw_cfg->valid = true;
1235
1236 if (strncmp(hid, "CLSA0100", 8) == 0) {
1237 hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
1238 } else if (strncmp(hid, "CLSA0101", 8) == 0) {
1239 hw_cfg->bst_type = CS35L41_EXT_BOOST;
1240 hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
1241 hw_cfg->gpio1.valid = true;
1242 } else {
1243 /*
1244 * Note: CLSA010(0/1) are special cases which use a slightly different design.
1245 * All other HIDs e.g. CSC3551 require valid ACPI _DSD properties to be supported.
1246 */
1247 dev_err(cs35l41->dev, "Error: ACPI _DSD Properties are missing for HID %s.\n", hid);
1248 hw_cfg->valid = false;
1249 hw_cfg->gpio1.valid = false;
1250 hw_cfg->gpio2.valid = false;
1251 return -EINVAL;
1252 }
1253
1254 return 0;
1255}
1256
1257static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)1373static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
1258{1374{
1259 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;1375 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
@@ -1279,12 +1395,17 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i · 19 unmodified lines
1279 sub = NULL;1395 sub = NULL;
1280 cs35l41->acpi_subsystem_id = sub;1396 cs35l41->acpi_subsystem_id = sub;
1281 1397
1398 ret = cs35l41_add_dsd_properties(cs35l41, physdev, id, hid);
1399 if (!ret) {
1400 dev_info(cs35l41->dev, "Using extra _DSD properties, bypassing _DSD in ACPI\n");
1401 goto put_physdev;
1402 }
1403
1282 property = "cirrus,dev-index";1404 property = "cirrus,dev-index";
1283 ret = device_property_count_u32(physdev, property);1405 ret = device_property_count_u32(physdev, property);
1284 if (ret <= 0) {1406 if (ret <= 0)
1285 ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid);1407 goto err;
1286 goto err_put_physdev;1408
1287 }
1288 if (ret > ARRAY_SIZE(values)) {1409 if (ret > ARRAY_SIZE(values)) {
1289 ret = -EINVAL;1410 ret = -EINVAL;
1290 goto err;1411 goto err;
@@ -1374,7 +1495,10 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i · 83 unmodified lines
1374 1495
1375err:1496err:
1376 dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);1497 dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
1377err_put_physdev:1498 hw_cfg->valid = false;
1499 hw_cfg->gpio1.valid = false;
1500 hw_cfg->gpio2.valid = false;
1501put_physdev:
1378 put_device(physdev);1502 put_device(physdev);
1379 1503
1380 return ret;1504 return ret;
@@ -1477,6 +1601,11 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i · 96 unmodified lines
1477 if (ret)1601 if (ret)
1478 goto err;1602 goto err;
1479 1603
1604 ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute,
1605 ARRAY_SIZE(cs35l41_hda_mute));
1606 if (ret)
1607 goto err;
1608
1480 INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work);1609 INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work);
1481 mutex_init(&cs35l41->fw_mutex);1610 mutex_init(&cs35l41->fw_mutex);
1482 1611
@@ -1542,6 +1671,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); · 59 unmodified lines
1542const struct dev_pm_ops cs35l41_hda_pm_ops = {1671const struct dev_pm_ops cs35l41_hda_pm_ops = {
1543 RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume,1672 RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume,
1544 cs35l41_runtime_idle)1673 cs35l41_runtime_idle)
1674 .prepare = cs35l41_system_suspend_prep,
1545 SYSTEM_SLEEP_PM_OPS(cs35l41_system_suspend, cs35l41_system_resume)1675 SYSTEM_SLEEP_PM_OPS(cs35l41_system_suspend, cs35l41_system_resume)
1546};1676};
1547EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41);1677EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41);
sound/pci/hda/cs35l41_hda.h+1−0
@@ -83,5 +83,6 @@ extern const struct dev_pm_ops cs35l41_hda_pm_ops; · 82 unmodified lines
83int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,83int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
84 struct regmap *regmap);84 struct regmap *regmap);
85void cs35l41_hda_remove(struct device *dev);85void cs35l41_hda_remove(struct device *dev);
86int cs35l41_get_speaker_id(struct device *dev, int amp_index, int num_amps, int fixed_gpio_id);
86 87
87#endif /*__CS35L41_HDA_H__*/88#endif /*__CS35L41_HDA_H__*/
sound/pci/hda/cs35l41_hda_property.c+105−0
@@ -0,0 +1,105 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// CS35L41 ALSA HDA Property driver
4//
5// Copyright 2023 Cirrus Logic, Inc.
6//
7// Author: Stefan Binding <sbinding@opensource.cirrus.com>
8
9#include <linux/gpio/consumer.h>
10#include <linux/string.h>
11#include "cs35l41_hda_property.h"
12
13/*
14 * Device CLSA010(0/1) doesn't have _DSD so a gpiod_get by the label reset won't work.
15 * And devices created by serial-multi-instantiate don't have their device struct
16 * pointing to the correct fwnode, so acpi_dev must be used here.
17 * And devm functions expect that the device requesting the resource has the correct
18 * fwnode.
19 */
20static int lenovo_legion_no_acpi(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
21 const char *hid)
22{
23 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
24
25 /* check I2C address to assign the index */
26 cs35l41->index = id == 0x40 ? 0 : 1;
27 cs35l41->channel_index = 0;
28 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
29 cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2);
30 hw_cfg->spk_pos = cs35l41->index;
31 hw_cfg->gpio2.func = CS35L41_INTERRUPT;
32 hw_cfg->gpio2.valid = true;
33 hw_cfg->valid = true;
34
35 if (strcmp(hid, "CLSA0100") == 0) {
36 hw_cfg->bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH;
37 } else if (strcmp(hid, "CLSA0101") == 0) {
38 hw_cfg->bst_type = CS35L41_EXT_BOOST;
39 hw_cfg->gpio1.func = CS35l41_VSPK_SWITCH;
40 hw_cfg->gpio1.valid = true;
41 }
42
43 return 0;
44}
45
46/*
47 * Device 103C89C6 does have _DSD, however it is setup to use the wrong boost type.
48 * We can override the _DSD to correct the boost type here.
49 * Since this laptop has valid ACPI, we do not need to handle cs-gpios, since that already exists
50 * in the ACPI.
51 */
52static int hp_vision_acpi_fix(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
53 const char *hid)
54{
55 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
56
57 dev_info(cs35l41->dev, "Adding DSD properties for %s\n", cs35l41->acpi_subsystem_id);
58
59 cs35l41->index = id;
60 cs35l41->channel_index = 0;
61 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 1, GPIOD_OUT_HIGH);
62 cs35l41->speaker_id = -ENOENT;
63 hw_cfg->spk_pos = cs35l41->index ? 1 : 0; // right:left
64 hw_cfg->gpio1.func = CS35L41_NOT_USED;
65 hw_cfg->gpio1.valid = true;
66 hw_cfg->gpio2.func = CS35L41_INTERRUPT;
67 hw_cfg->gpio2.valid = true;
68 hw_cfg->bst_type = CS35L41_INT_BOOST;
69 hw_cfg->bst_ind = 1000;
70 hw_cfg->bst_ipk = 4500;
71 hw_cfg->bst_cap = 24;
72 hw_cfg->valid = true;
73
74 return 0;
75}
76
77struct cs35l41_prop_model {
78 const char *hid;
79 const char *ssid;
80 int (*add_prop)(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
81 const char *hid);
82};
83
84static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
85 { "CLSA0100", NULL, lenovo_legion_no_acpi },
86 { "CLSA0101", NULL, lenovo_legion_no_acpi },
87 { "CSC3551", "103C89C6", hp_vision_acpi_fix },
88 {}
89};
90
91int cs35l41_add_dsd_properties(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
92 const char *hid)
93{
94 const struct cs35l41_prop_model *model;
95
96 for (model = cs35l41_prop_model_table; model->hid; model++) {
97 if (!strcmp(model->hid, hid) &&
98 (!model->ssid ||
99 (cs35l41->acpi_subsystem_id &&
100 !strcmp(model->ssid, cs35l41->acpi_subsystem_id))))
101 return model->add_prop(cs35l41, physdev, id, hid);
102 }
103
104 return -ENOENT;
105}
sound/pci/hda/cs35l41_hda_property.h+18−0
@@ -0,0 +1,18 @@
1/* SPDX-License-Identifier: GPL-2.0
2 *
3 * CS35L41 ALSA HDA Property driver
4 *
5 * Copyright 2023 Cirrus Logic, Inc.
6 *
7 * Author: Stefan Binding <sbinding@opensource.cirrus.com>
8 */
9
10#ifndef CS35L41_HDA_PROP_H
11#define CS35L41_HDA_PROP_H
12
13#include <linux/device.h>
14#include "cs35l41_hda.h"
15
16int cs35l41_add_dsd_properties(struct cs35l41_hda *cs35l41, struct device *physdev, int id,
17 const char *hid);
18#endif /* CS35L41_HDA_PROP_H */
sound/pci/hda/cs35l56_hda.c+1034−0
@@ -0,0 +1,1034 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// HDA audio driver for Cirrus Logic CS35L56 smart amp
4//
5// Copyright (C) 2023 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7//
8
9#include <linux/acpi.h>
10#include <linux/debugfs.h>
11#include <linux/gpio/consumer.h>
12#include <linux/module.h>
13#include <linux/pm_runtime.h>
14#include <linux/regmap.h>
15#include <linux/slab.h>
16#include <sound/core.h>
17#include <sound/hda_codec.h>
18#include <sound/tlv.h>
19#include "cs35l56_hda.h"
20#include "hda_component.h"
21#include "hda_cs_dsp_ctl.h"
22#include "hda_generic.h"
23
24 /*
25 * The cs35l56_hda_dai_config[] reg sequence configures the device as
26 * ASP1_BCLK_FREQ = 3.072 MHz
27 * ASP1_RX_WIDTH = 32 cycles per slot, ASP1_TX_WIDTH = 32 cycles per slot, ASP1_FMT = I2S
28 * ASP1_DOUT_HIZ_CONTROL = Hi-Z during unused timeslots
29 * ASP1_RX_WL = 24 bits per sample
30 * ASP1_TX_WL = 24 bits per sample
31 * ASP1_RXn_EN 1..3 and ASP1_TXn_EN 1..4 disabled
32 */
33static const struct reg_sequence cs35l56_hda_dai_config[] = {
34 { CS35L56_ASP1_CONTROL1, 0x00000021 },
35 { CS35L56_ASP1_CONTROL2, 0x20200200 },
36 { CS35L56_ASP1_CONTROL3, 0x00000003 },
37 { CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
38 { CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
39 { CS35L56_ASP1_ENABLES1, 0x00000000 },
40};
41
42static void cs35l56_hda_play(struct cs35l56_hda *cs35l56)
43{
44 unsigned int val;
45 int ret;
46
47 pm_runtime_get_sync(cs35l56->base.dev);
48 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PLAY);
49 if (ret == 0) {
50 /* Wait for firmware to enter PS0 power state */
51 ret = regmap_read_poll_timeout(cs35l56->base.regmap,
52 CS35L56_TRANSDUCER_ACTUAL_PS,
53 val, (val == CS35L56_PS0),
54 CS35L56_PS0_POLL_US,
55 CS35L56_PS0_TIMEOUT_US);
56 if (ret)
57 dev_warn(cs35l56->base.dev, "PS0 wait failed: %d\n", ret);
58 }
59 regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,
60 BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |
61 cs35l56->asp_tx_mask);
62 cs35l56->playing = true;
63}
64
65static void cs35l56_hda_pause(struct cs35l56_hda *cs35l56)
66{
67 cs35l56->playing = false;
68 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE);
69 regmap_clear_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,
70 BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |
71 BIT(CS35L56_ASP_TX1_EN_SHIFT) | BIT(CS35L56_ASP_TX2_EN_SHIFT) |
72 BIT(CS35L56_ASP_TX3_EN_SHIFT) | BIT(CS35L56_ASP_TX4_EN_SHIFT));
73
74 pm_runtime_mark_last_busy(cs35l56->base.dev);
75 pm_runtime_put_autosuspend(cs35l56->base.dev);
76}
77
78static void cs35l56_hda_playback_hook(struct device *dev, int action)
79{
80 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
81
82 dev_dbg(cs35l56->base.dev, "%s()%d: action: %d\n", __func__, __LINE__, action);
83
84 switch (action) {
85 case HDA_GEN_PCM_ACT_PREPARE:
86 if (cs35l56->playing)
87 break;
88
89 /* If we're suspended: flag that resume should start playback */
90 if (cs35l56->suspended) {
91 cs35l56->playing = true;
92 break;
93 }
94
95 cs35l56_hda_play(cs35l56);
96 break;
97 case HDA_GEN_PCM_ACT_CLEANUP:
98 if (!cs35l56->playing)
99 break;
100
101 cs35l56_hda_pause(cs35l56);
102 break;
103 default:
104 break;
105 }
106}
107
108static int __maybe_unused cs35l56_hda_runtime_suspend(struct device *dev)
109{
110 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
111
112 if (cs35l56->cs_dsp.booted)
113 cs_dsp_stop(&cs35l56->cs_dsp);
114
115 return cs35l56_runtime_suspend_common(&cs35l56->base);
116}
117
118static int __maybe_unused cs35l56_hda_runtime_resume(struct device *dev)
119{
120 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
121 int ret;
122
123 ret = cs35l56_runtime_resume_common(&cs35l56->base, false);
124 if (ret < 0)
125 return ret;
126
127 if (cs35l56->cs_dsp.booted) {
128 ret = cs_dsp_run(&cs35l56->cs_dsp);
129 if (ret) {
130 dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
131 goto err;
132 }
133 }
134
135 return 0;
136
137err:
138 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);
139 regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
140 CS35L56_MBOX_CMD_HIBERNATE_NOW);
141
142 regcache_cache_only(cs35l56->base.regmap, true);
143
144 return ret;
145}
146
147static int cs35l56_hda_mixer_info(struct snd_kcontrol *kcontrol,
148 struct snd_ctl_elem_info *uinfo)
149{
150 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
151 uinfo->count = 1;
152 uinfo->value.enumerated.items = CS35L56_NUM_INPUT_SRC;
153 if (uinfo->value.enumerated.item >= CS35L56_NUM_INPUT_SRC)
154 uinfo->value.enumerated.item = CS35L56_NUM_INPUT_SRC - 1;
155 strscpy(uinfo->value.enumerated.name, cs35l56_tx_input_texts[uinfo->value.enumerated.item],
156 sizeof(uinfo->value.enumerated.name));
157
158 return 0;
159}
160
161static int cs35l56_hda_mixer_get(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
165 unsigned int reg_val;
166 int i;
167
168 regmap_read(cs35l56->base.regmap, kcontrol->private_value, &reg_val);
169 reg_val &= CS35L56_ASP_TXn_SRC_MASK;
170
171 for (i = 0; i < CS35L56_NUM_INPUT_SRC; ++i) {
172 if (cs35l56_tx_input_values[i] == reg_val) {
173 ucontrol->value.enumerated.item[0] = i;
174 break;
175 }
176 }
177
178 return 0;
179}
180
181static int cs35l56_hda_mixer_put(struct snd_kcontrol *kcontrol,
182 struct snd_ctl_elem_value *ucontrol)
183{
184 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
185 unsigned int item = ucontrol->value.enumerated.item[0];
186 bool changed;
187
188 if (item >= CS35L56_NUM_INPUT_SRC)
189 return -EINVAL;
190
191 regmap_update_bits_check(cs35l56->base.regmap, kcontrol->private_value,
192 CS35L56_INPUT_MASK, cs35l56_tx_input_values[item],
193 &changed);
194
195 return changed;
196}
197
198static int cs35l56_hda_posture_info(struct snd_kcontrol *kcontrol,
199 struct snd_ctl_elem_info *uinfo)
200{
201 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
202 uinfo->count = 1;
203 uinfo->value.integer.min = CS35L56_MAIN_POSTURE_MIN;
204 uinfo->value.integer.max = CS35L56_MAIN_POSTURE_MAX;
205 return 0;
206}
207
208static int cs35l56_hda_posture_get(struct snd_kcontrol *kcontrol,
209 struct snd_ctl_elem_value *ucontrol)
210{
211 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
212 unsigned int pos;
213 int ret;
214
215 ret = regmap_read(cs35l56->base.regmap, CS35L56_MAIN_POSTURE_NUMBER, &pos);
216 if (ret)
217 return ret;
218
219 ucontrol->value.integer.value[0] = pos;
220
221 return ret;
222}
223
224static int cs35l56_hda_posture_put(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
228 unsigned long pos = ucontrol->value.integer.value[0];
229 bool changed;
230 int ret;
231
232 if ((pos < CS35L56_MAIN_POSTURE_MIN) ||
233 (pos > CS35L56_MAIN_POSTURE_MAX))
234 return -EINVAL;
235
236 ret = regmap_update_bits_check(cs35l56->base.regmap,
237 CS35L56_MAIN_POSTURE_NUMBER,
238 CS35L56_MAIN_POSTURE_MASK,
239 pos, &changed);
240 if (ret)
241 return ret;
242
243 return changed;
244}
245
246static const struct {
247 const char *name;
248 unsigned int reg;
249} cs35l56_hda_mixer_controls[] = {
250 { "ASP1 TX1 Source", CS35L56_ASP1TX1_INPUT },
251 { "ASP1 TX2 Source", CS35L56_ASP1TX2_INPUT },
252 { "ASP1 TX3 Source", CS35L56_ASP1TX3_INPUT },
253 { "ASP1 TX4 Source", CS35L56_ASP1TX4_INPUT },
254};
255
256static const DECLARE_TLV_DB_SCALE(cs35l56_hda_vol_tlv, -10000, 25, 0);
257
258static int cs35l56_hda_vol_info(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_info *uinfo)
260{
261 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
262 uinfo->count = 1;
263 uinfo->value.integer.step = 1;
264 uinfo->value.integer.min = 0;
265 uinfo->value.integer.max = CS35L56_MAIN_RENDER_USER_VOLUME_MAX -
266 CS35L56_MAIN_RENDER_USER_VOLUME_MIN;
267
268 return 0;
269}
270
271static int cs35l56_hda_vol_get(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
273{
274 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
275 unsigned int raw_vol;
276 int vol;
277 int ret;
278
279 ret = regmap_read(cs35l56->base.regmap, CS35L56_MAIN_RENDER_USER_VOLUME, &raw_vol);
280
281 if (ret)
282 return ret;
283
284 vol = (s16)(raw_vol & 0xFFFF);
285 vol >>= CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;
286
287 if (vol & BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT))
288 vol |= ~((int)(BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT) - 1));
289
290 ucontrol->value.integer.value[0] = vol - CS35L56_MAIN_RENDER_USER_VOLUME_MIN;
291
292 return 0;
293}
294
295static int cs35l56_hda_vol_put(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct cs35l56_hda *cs35l56 = (struct cs35l56_hda *)kcontrol->private_data;
299 long vol = ucontrol->value.integer.value[0];
300 unsigned int raw_vol;
301 bool changed;
302 int ret;
303
304 if ((vol < 0) || (vol > (CS35L56_MAIN_RENDER_USER_VOLUME_MAX -
305 CS35L56_MAIN_RENDER_USER_VOLUME_MIN)))
306 return -EINVAL;
307
308 raw_vol = (vol + CS35L56_MAIN_RENDER_USER_VOLUME_MIN) <<
309 CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;
310
311 ret = regmap_update_bits_check(cs35l56->base.regmap,
312 CS35L56_MAIN_RENDER_USER_VOLUME,
313 CS35L56_MAIN_RENDER_USER_VOLUME_MASK,
314 raw_vol, &changed);
315 if (ret)
316 return ret;
317
318 return changed;
319}
320
321static void cs35l56_hda_create_controls(struct cs35l56_hda *cs35l56)
322{
323 struct snd_kcontrol_new ctl_template = {
324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
325 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
326 .info = cs35l56_hda_posture_info,
327 .get = cs35l56_hda_posture_get,
328 .put = cs35l56_hda_posture_put,
329 };
330 char name[64];
331 int i;
332
333 snprintf(name, sizeof(name), "%s Posture Number", cs35l56->amp_name);
334 ctl_template.name = name;
335 cs35l56->posture_ctl = snd_ctl_new1(&ctl_template, cs35l56);
336 if (snd_ctl_add(cs35l56->codec->card, cs35l56->posture_ctl))
337 dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);
338
339 /* Mixer controls */
340 ctl_template.info = cs35l56_hda_mixer_info;
341 ctl_template.get = cs35l56_hda_mixer_get;
342 ctl_template.put = cs35l56_hda_mixer_put;
343
344 BUILD_BUG_ON(ARRAY_SIZE(cs35l56->mixer_ctl) != ARRAY_SIZE(cs35l56_hda_mixer_controls));
345
346 for (i = 0; i < ARRAY_SIZE(cs35l56_hda_mixer_controls); ++i) {
347 snprintf(name, sizeof(name), "%s %s", cs35l56->amp_name,
348 cs35l56_hda_mixer_controls[i].name);
349 ctl_template.private_value = cs35l56_hda_mixer_controls[i].reg;
350 cs35l56->mixer_ctl[i] = snd_ctl_new1(&ctl_template, cs35l56);
351 if (snd_ctl_add(cs35l56->codec->card, cs35l56->mixer_ctl[i])) {
352 dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n",
353 ctl_template.name);
354 }
355 }
356
357 ctl_template.info = cs35l56_hda_vol_info;
358 ctl_template.get = cs35l56_hda_vol_get;
359 ctl_template.put = cs35l56_hda_vol_put;
360 ctl_template.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ);
361 ctl_template.tlv.p = cs35l56_hda_vol_tlv;
362 snprintf(name, sizeof(name), "%s Speaker Playback Volume", cs35l56->amp_name);
363 ctl_template.name = name;
364 cs35l56->volume_ctl = snd_ctl_new1(&ctl_template, cs35l56);
365 if (snd_ctl_add(cs35l56->codec->card, cs35l56->volume_ctl))
366 dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);
367}
368
369static void cs35l56_hda_remove_controls(struct cs35l56_hda *cs35l56)
370{
371 int i;
372
373 for (i = ARRAY_SIZE(cs35l56->mixer_ctl) - 1; i >= 0; i--)
374 snd_ctl_remove(cs35l56->codec->card, cs35l56->mixer_ctl[i]);
375
376 snd_ctl_remove(cs35l56->codec->card, cs35l56->posture_ctl);
377 snd_ctl_remove(cs35l56->codec->card, cs35l56->volume_ctl);
378}
379
380static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {
381 .control_remove = hda_cs_dsp_control_remove,
382};
383
384static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,
385 const struct firmware **firmware, char **filename,
386 const char *dir, const char *system_name,
387 const char *amp_name,
388 const char *filetype)
389{
390 char *s, c;
391 int ret = 0;
392
393 if (system_name && amp_name)
394 *filename = kasprintf(GFP_KERNEL, "%scs35l56%s-%02x-dsp1-misc-%s-%s.%s", dir,
395 cs35l56->base.secured ? "s" : "", cs35l56->base.rev,
396 system_name, amp_name, filetype);
397 else if (system_name)
398 *filename = kasprintf(GFP_KERNEL, "%scs35l56%s-%02x-dsp1-misc-%s.%s", dir,
399 cs35l56->base.secured ? "s" : "", cs35l56->base.rev,
400 system_name, filetype);
401 else
402 *filename = kasprintf(GFP_KERNEL, "%scs35l56%s-%02x-dsp1-misc.%s", dir,
403 cs35l56->base.secured ? "s" : "", cs35l56->base.rev,
404 filetype);
405
406 if (!*filename)
407 return -ENOMEM;
408
409 /*
410 * Make sure that filename is lower-case and any non alpha-numeric
411 * characters except full stop and forward slash are replaced with
412 * hyphens.
413 */
414 s = *filename;
415 while (*s) {
416 c = *s;
417 if (isalnum(c))
418 *s = tolower(c);
419 else if (c != '.' && c != '/')
420 *s = '-';
421 s++;
422 }
423
424 ret = firmware_request_nowarn(firmware, *filename, cs35l56->base.dev);
425 if (ret) {
426 dev_dbg(cs35l56->base.dev, "Failed to request '%s'\n", *filename);
427 kfree(*filename);
428 *filename = NULL;
429 return ret;
430 }
431
432 dev_dbg(cs35l56->base.dev, "Found '%s'\n", *filename);
433
434 return 0;
435}
436
437static const char cirrus_dir[] = "cirrus/";
438static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56,
439 const struct firmware **wmfw_firmware,
440 char **wmfw_filename,
441 const struct firmware **coeff_firmware,
442 char **coeff_filename)
443{
444 const char *system_name = cs35l56->system_name;
445 const char *amp_name = cs35l56->amp_name;
446 int ret;
447
448 if (system_name && amp_name) {
449 if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
450 cirrus_dir, system_name, amp_name, "wmfw")) {
451 cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
452 cirrus_dir, system_name, amp_name, "bin");
453 return;
454 }
455 }
456
457 if (system_name) {
458 if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
459 cirrus_dir, system_name, NULL, "wmfw")) {
460 if (amp_name)
461 cs35l56_hda_request_firmware_file(cs35l56,
462 coeff_firmware, coeff_filename,
463 cirrus_dir, system_name,
464 amp_name, "bin");
465 if (!*coeff_firmware)
466 cs35l56_hda_request_firmware_file(cs35l56,
467 coeff_firmware, coeff_filename,
468 cirrus_dir, system_name,
469 NULL, "bin");
470 return;
471 }
472 }
473
474 ret = cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
475 cirrus_dir, NULL, NULL, "wmfw");
476 if (!ret) {
477 cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
478 cirrus_dir, NULL, NULL, "bin");
479 return;
480 }
481
482 /* When a firmware file is not found must still search for the coeff files */
483 if (system_name) {
484 if (amp_name)
485 cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
486 cirrus_dir, system_name, amp_name, "bin");
487 if (!*coeff_firmware)
488 cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
489 cirrus_dir, system_name, NULL, "bin");
490 }
491
492 if (!*coeff_firmware)
493 cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
494 cirrus_dir, NULL, NULL, "bin");
495}
496
497static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmware,
498 char *wmfw_filename,
499 const struct firmware *coeff_firmware,
500 char *coeff_filename)
501{
502 if (wmfw_firmware)
503 release_firmware(wmfw_firmware);
504 kfree(wmfw_filename);
505
506 if (coeff_firmware)
507 release_firmware(coeff_firmware);
508 kfree(coeff_filename);
509}
510
511static void cs35l56_hda_add_dsp_controls(struct cs35l56_hda *cs35l56)
512{
513 struct hda_cs_dsp_ctl_info info;
514
515 info.device_name = cs35l56->amp_name;
516 info.fw_type = HDA_CS_DSP_FW_MISC;
517 info.card = cs35l56->codec->card;
518
519 hda_cs_dsp_add_controls(&cs35l56->cs_dsp, &info);
520}
521
522static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
523{
524 const struct firmware *coeff_firmware = NULL;
525 const struct firmware *wmfw_firmware = NULL;
526 char *coeff_filename = NULL;
527 char *wmfw_filename = NULL;
528 unsigned int firmware_missing;
529 int ret = 0;
530
531 /* Prepare for a new DSP power-up */
532 if (cs35l56->base.fw_patched)
533 cs_dsp_power_down(&cs35l56->cs_dsp);
534
535 cs35l56->base.fw_patched = false;
536
537 pm_runtime_get_sync(cs35l56->base.dev);
538
539 ret = regmap_read(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS, &firmware_missing);
540 if (ret) {
541 dev_err(cs35l56->base.dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
542 goto err_pm_put;
543 }
544
545 firmware_missing &= CS35L56_FIRMWARE_MISSING;
546
547 /*
548 * Firmware can only be downloaded if the CS35L56 is secured or is
549 * running from the built-in ROM. If it is secured the BIOS will have
550 * downloaded firmware, and the wmfw/bin files will only contain
551 * tunings that are safe to download with the firmware running.
552 */
553 if (cs35l56->base.secured || firmware_missing) {
554 cs35l56_hda_request_firmware_files(cs35l56, &wmfw_firmware, &wmfw_filename,
555 &coeff_firmware, &coeff_filename);
556 }
557
558 /*
559 * If the BIOS didn't patch the firmware a bin file is mandatory to
560 * enable the ASP·
561 */
562 if (!coeff_firmware && firmware_missing) {
563 dev_err(cs35l56->base.dev, ".bin file required but not found\n");
564 ret = -ENOENT;
565 goto err_fw_release;
566 }
567
568 mutex_lock(&cs35l56->base.irq_lock);
569
570 /*
571 * When the device is running in secure mode the firmware files can
572 * only contain insecure tunings and therefore we do not need to
573 * shutdown the firmware to apply them and can use the lower cost
574 * reinit sequence instead.
575 */
576 if (!cs35l56->base.secured && (wmfw_firmware || coeff_firmware)) {
577 ret = cs35l56_firmware_shutdown(&cs35l56->base);
578 if (ret)
579 goto err;
580 }
581
582 ret = cs_dsp_power_up(&cs35l56->cs_dsp, wmfw_firmware, wmfw_filename,
583 coeff_firmware, coeff_filename, "misc");
584 if (ret) {
585 dev_dbg(cs35l56->base.dev, "%s: cs_dsp_power_up ret %d\n", __func__, ret);
586 goto err;
587 }
588
589 if (wmfw_filename)
590 dev_dbg(cs35l56->base.dev, "Loaded WMFW Firmware: %s\n", wmfw_filename);
591
592 if (coeff_filename)
593 dev_dbg(cs35l56->base.dev, "Loaded Coefficients: %s\n", coeff_filename);
594
595 if (cs35l56->base.secured) {
596 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
597 if (ret)
598 goto err_powered_up;
599 } else if (wmfw_firmware || coeff_firmware) {
600 /* If we downloaded firmware, reset the device and wait for it to boot */
601 cs35l56_system_reset(&cs35l56->base, false);
602 regcache_mark_dirty(cs35l56->base.regmap);
603 ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
604 if (ret)
605 goto err_powered_up;
606 }
607
608 /* Disable auto-hibernate so that runtime_pm has control */
609 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
610 if (ret)
611 goto err_powered_up;
612
613 regcache_sync(cs35l56->base.regmap);
614
615 regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS,
616 CS35L56_FIRMWARE_MISSING);
617 cs35l56->base.fw_patched = true;
618
619 ret = cs_dsp_run(&cs35l56->cs_dsp);
620 if (ret)
621 dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
622
623err_powered_up:
624 if (!cs35l56->base.fw_patched)
625 cs_dsp_power_down(&cs35l56->cs_dsp);
626err:
627 mutex_unlock(&cs35l56->base.irq_lock);
628err_fw_release:
629 cs35l56_hda_release_firmware_files(wmfw_firmware, wmfw_filename,
630 coeff_firmware, coeff_filename);
631err_pm_put:
632 pm_runtime_put(cs35l56->base.dev);
633
634 return ret;
635}
636
637static int cs35l56_hda_bind(struct device *dev, struct device *master, void *master_data)
638{
639 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
640 struct hda_component *comps = master_data;
641 int ret;
642
643 if (!comps || cs35l56->index < 0 || cs35l56->index >= HDA_MAX_COMPONENTS)
644 return -EINVAL;
645
646 comps = &comps[cs35l56->index];
647 if (comps->dev)
648 return -EBUSY;
649
650 comps->dev = dev;
651 cs35l56->codec = comps->codec;
652 strscpy(comps->name, dev_name(dev), sizeof(comps->name));
653 comps->playback_hook = cs35l56_hda_playback_hook;
654
655 ret = cs35l56_hda_fw_load(cs35l56);
656 if (ret)
657 return ret;
658
659 cs35l56_hda_create_controls(cs35l56);
660 cs35l56_hda_add_dsp_controls(cs35l56);
661
662#if IS_ENABLED(CONFIG_SND_DEBUG)
663 cs35l56->debugfs_root = debugfs_create_dir(dev_name(cs35l56->base.dev), sound_debugfs_root);
664 cs_dsp_init_debugfs(&cs35l56->cs_dsp, cs35l56->debugfs_root);
665#endif
666
667 dev_dbg(cs35l56->base.dev, "Bound\n");
668
669 return 0;
670}
671
672static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *master_data)
673{
674 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
675 struct hda_component *comps = master_data;
676
677 cs35l56_hda_remove_controls(cs35l56);
678
679#if IS_ENABLED(CONFIG_SND_DEBUG)
680 cs_dsp_cleanup_debugfs(&cs35l56->cs_dsp);
681 debugfs_remove_recursive(cs35l56->debugfs_root);
682#endif
683
684 if (cs35l56->base.fw_patched)
685 cs_dsp_power_down(&cs35l56->cs_dsp);
686
687 cs_dsp_remove(&cs35l56->cs_dsp);
688
689 if (comps[cs35l56->index].dev == dev)
690 memset(&comps[cs35l56->index], 0, sizeof(*comps));
691
692 dev_dbg(cs35l56->base.dev, "Unbound\n");
693}
694
695static const struct component_ops cs35l56_hda_comp_ops = {
696 .bind = cs35l56_hda_bind,
697 .unbind = cs35l56_hda_unbind,
698};
699
700static int cs35l56_hda_system_suspend(struct device *dev)
701{
702 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
703
704 if (cs35l56->playing)
705 cs35l56_hda_pause(cs35l56);
706
707 cs35l56->suspended = true;
708
709 /*
710 * The interrupt line is normally shared, but after we start suspending
711 * we can't check if our device is the source of an interrupt, and can't
712 * clear it. Prevent this race by temporarily disabling the parent irq
713 * until we reach _no_irq.
714 */
715 if (cs35l56->base.irq)
716 disable_irq(cs35l56->base.irq);
717
718 return pm_runtime_force_suspend(dev);
719}
720
721static int cs35l56_hda_system_suspend_late(struct device *dev)
722{
723 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
724
725 /*
726 * RESET is usually shared by all amps so it must not be asserted until
727 * all driver instances have done their suspend() stage.
728 */
729 if (cs35l56->base.reset_gpio) {
730 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
731 cs35l56_wait_min_reset_pulse();
732 }
733
734 return 0;
735}
736
737static int cs35l56_hda_system_suspend_no_irq(struct device *dev)
738{
739 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
740
741 /* Handlers are now disabled so the parent IRQ can safely be re-enabled. */
742 if (cs35l56->base.irq)
743 enable_irq(cs35l56->base.irq);
744
745 return 0;
746}
747
748static int cs35l56_hda_system_resume_no_irq(struct device *dev)
749{
750 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
751
752 /*
753 * WAKE interrupts unmask if the CS35L56 hibernates, which can cause
754 * spurious interrupts, and the interrupt line is normally shared.
755 * We can't check if our device is the source of an interrupt, and can't
756 * clear it, until it has fully resumed. Prevent this race by temporarily
757 * disabling the parent irq until we complete resume().
758 */
759 if (cs35l56->base.irq)
760 disable_irq(cs35l56->base.irq);
761
762 return 0;
763}
764
765static int cs35l56_hda_system_resume_early(struct device *dev)
766{
767 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
768
769 /* Ensure a spec-compliant RESET pulse. */
770 if (cs35l56->base.reset_gpio) {
771 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
772 cs35l56_wait_min_reset_pulse();
773
774 /* Release shared RESET before drivers start resume(). */
775 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);
776 cs35l56_wait_control_port_ready();
777 }
778
779 return 0;
780}
781
782static int cs35l56_hda_system_resume(struct device *dev)
783{
784 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
785 int ret;
786
787 /* Undo pm_runtime_force_suspend() before re-enabling the irq */
788 ret = pm_runtime_force_resume(dev);
789 if (cs35l56->base.irq)
790 enable_irq(cs35l56->base.irq);
791
792 if (ret)
793 return ret;
794
795 cs35l56->suspended = false;
796
797 ret = cs35l56_is_fw_reload_needed(&cs35l56->base);
798 dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret);
799 if (ret > 0) {
800 ret = cs35l56_hda_fw_load(cs35l56);
801 if (ret)
802 return ret;
803 }
804
805 if (cs35l56->playing)
806 cs35l56_hda_play(cs35l56);
807
808 return 0;
809}
810
811static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int id)
812{
813 u32 values[HDA_MAX_COMPONENTS];
814 struct acpi_device *adev;
815 const char *property, *sub;
816 size_t nval;
817 int i, ret;
818
819 /*
820 * ACPI_COMPANION isn't available when this driver was instantiated by
821 * the serial-multi-instantiate driver, so lookup the node by HID
822 */
823 if (!ACPI_COMPANION(cs35l56->base.dev)) {
824 adev = acpi_dev_get_first_match_dev("CSC3556", NULL, -1);
825 if (!adev) {
826 dev_err(cs35l56->base.dev, "Failed to find an ACPI device for %s\n",
827 dev_name(cs35l56->base.dev));
828 return -ENODEV;
829 }
830 ACPI_COMPANION_SET(cs35l56->base.dev, adev);
831 }
832
833 property = "cirrus,dev-index";
834 ret = device_property_count_u32(cs35l56->base.dev, property);
835 if (ret <= 0)
836 goto err;
837
838 if (ret > ARRAY_SIZE(values)) {
839 ret = -EINVAL;
840 goto err;
841 }
842 nval = ret;
843
844 ret = device_property_read_u32_array(cs35l56->base.dev, property, values, nval);
845 if (ret)
846 goto err;
847
848 cs35l56->index = -1;
849 for (i = 0; i < nval; i++) {
850 if (values[i] == id) {
851 cs35l56->index = i;
852 break;
853 }
854 }
855 /*
856 * It's not an error for the ID to be missing: for I2C there can be
857 * an alias address that is not a real device. So reject silently.
858 */
859 if (cs35l56->index == -1) {
860 dev_dbg(cs35l56->base.dev, "No index found in %s\n", property);
861 ret = -ENODEV;
862 goto err;
863 }
864
865 sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
866
867 if (IS_ERR(sub)) {
868 /* If no ACPI SUB, return 0 and fallback to legacy firmware path, otherwise fail */
869 if (PTR_ERR(sub) == -ENODATA)
870 return 0;
871 else
872 return PTR_ERR(sub);
873 }
874
875 cs35l56->system_name = sub;
876
877 cs35l56->base.reset_gpio = devm_gpiod_get_index_optional(cs35l56->base.dev,
878 "reset",
879 cs35l56->index,
880 GPIOD_OUT_LOW);
881 if (IS_ERR(cs35l56->base.reset_gpio)) {
882 ret = PTR_ERR(cs35l56->base.reset_gpio);
883
884 /*
885 * If RESET is shared the first amp to probe will grab the reset
886 * line and reset all the amps
887 */
888 if (ret != -EBUSY)
889 return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n");
890
891 dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n");
892 cs35l56->base.reset_gpio = NULL;
893 }
894
895 return 0;
896
897err:
898 if (ret != -ENODEV)
899 dev_err(cs35l56->base.dev, "Failed property %s: %d\n", property, ret);
900
901 return ret;
902}
903
904int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id)
905{
906 int ret;
907
908 mutex_init(&cs35l56->base.irq_lock);
909 dev_set_drvdata(cs35l56->base.dev, cs35l56);
910
911 ret = cs35l56_hda_read_acpi(cs35l56, id);
912 if (ret)
913 goto err;
914
915 cs35l56->amp_name = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, "AMP%d",
916 cs35l56->index + 1);
917 if (!cs35l56->amp_name) {
918 ret = -ENOMEM;
919 goto err;
920 }
921
922 cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp);
923 cs35l56->cs_dsp.client_ops = &cs35l56_hda_client_ops;
924
925 if (cs35l56->base.reset_gpio) {
926 dev_dbg(cs35l56->base.dev, "Hard reset\n");
927
928 /*
929 * The GPIOD_OUT_LOW to *_gpiod_get_*() will be ignored if the
930 * ACPI defines a different default state. So explicitly set low.
931 */
932 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
933 cs35l56_wait_min_reset_pulse();
934 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);
935 }
936
937 ret = cs35l56_hw_init(&cs35l56->base);
938 if (ret < 0)
939 goto err;
940
941 /* Reset the device and wait for it to boot */
942 cs35l56_system_reset(&cs35l56->base, false);
943 ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
944 if (ret)
945 goto err;
946
947 ret = cs35l56_set_patch(&cs35l56->base);
948 if (ret)
949 goto err;
950
951 regcache_mark_dirty(cs35l56->base.regmap);
952 regcache_sync(cs35l56->base.regmap);
953
954 /* Disable auto-hibernate so that runtime_pm has control */
955 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
956 if (ret)
957 goto err;
958
959 ret = cs_dsp_halo_init(&cs35l56->cs_dsp);
960 if (ret) {
961 dev_err_probe(cs35l56->base.dev, ret, "cs_dsp_halo_init failed\n");
962 goto err;
963 }
964
965 dev_dbg(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
966 cs35l56->system_name, cs35l56->amp_name);
967
968 regmap_multi_reg_write(cs35l56->base.regmap, cs35l56_hda_dai_config,
969 ARRAY_SIZE(cs35l56_hda_dai_config));
970
971 /*
972 * By default only enable one ASP1TXn, where n=amplifier index,
973 * This prevents multiple amps trying to drive the same slot.
974 */
975 cs35l56->asp_tx_mask = BIT(cs35l56->index);
976
977 pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 3000);
978 pm_runtime_use_autosuspend(cs35l56->base.dev);
979 pm_runtime_set_active(cs35l56->base.dev);
980 pm_runtime_mark_last_busy(cs35l56->base.dev);
981 pm_runtime_enable(cs35l56->base.dev);
982
983 ret = component_add(cs35l56->base.dev, &cs35l56_hda_comp_ops);
984 if (ret) {
985 dev_err(cs35l56->base.dev, "Register component failed: %d\n", ret);
986 goto pm_err;
987 }
988
989 cs35l56->base.init_done = true;
990
991 return 0;
992
993pm_err:
994 pm_runtime_disable(cs35l56->base.dev);
995err:
996 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
997
998 return ret;
999}
1000EXPORT_SYMBOL_NS_GPL(cs35l56_hda_common_probe, SND_HDA_SCODEC_CS35L56);
1001
1002void cs35l56_hda_remove(struct device *dev)
1003{
1004 struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
1005
1006 pm_runtime_get_sync(cs35l56->base.dev);
1007 pm_runtime_disable(cs35l56->base.dev);
1008
1009 component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops);
1010
1011 kfree(cs35l56->system_name);
1012 pm_runtime_put_noidle(cs35l56->base.dev);
1013
1014 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
1015}
1016EXPORT_SYMBOL_NS_GPL(cs35l56_hda_remove, SND_HDA_SCODEC_CS35L56);
1017
1018const struct dev_pm_ops cs35l56_hda_pm_ops = {
1019 SET_RUNTIME_PM_OPS(cs35l56_hda_runtime_suspend, cs35l56_hda_runtime_resume, NULL)
1020 SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend, cs35l56_hda_system_resume)
1021 LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_late,
1022 cs35l56_hda_system_resume_early)
1023 NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_no_irq,
1024 cs35l56_hda_system_resume_no_irq)
1025};
1026EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, SND_HDA_SCODEC_CS35L56);
1027
1028MODULE_DESCRIPTION("CS35L56 HDA Driver");
1029MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS);
1030MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
1031MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1032MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
1033MODULE_LICENSE("GPL");
1034MODULE_IMPORT_NS(FW_CS_DSP);
sound/pci/hda/cs35l56_hda.h+48−0
@@ -0,0 +1,48 @@
1/* SPDX-License-Identifier: GPL-2.0-only
2 *
3 * HDA audio driver 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_HDA_H__
10#define __CS35L56_HDA_H__
11
12#include <linux/device.h>
13#include <linux/gpio/consumer.h>
14#include <linux/firmware/cirrus/cs_dsp.h>
15#include <linux/firmware/cirrus/wmfw.h>
16#include <linux/regulator/consumer.h>
17#include <sound/cs35l56.h>
18
19struct dentry;
20
21struct cs35l56_hda {
22 struct cs35l56_base base;
23 struct hda_codec *codec;
24
25 int index;
26 const char *system_name;
27 const char *amp_name;
28
29 struct cs_dsp cs_dsp;
30 bool playing;
31 bool suspended;
32 u8 asp_tx_mask;
33
34 struct snd_kcontrol *posture_ctl;
35 struct snd_kcontrol *volume_ctl;
36 struct snd_kcontrol *mixer_ctl[4];
37
38#if IS_ENABLED(CONFIG_SND_DEBUG)
39 struct dentry *debugfs_root;
40#endif
41};
42
43extern const struct dev_pm_ops cs35l56_hda_pm_ops;
44
45int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id);
46void cs35l56_hda_remove(struct device *dev);
47
48#endif /*__CS35L56_HDA_H__*/
sound/pci/hda/cs35l56_hda_i2c.c+69−0
@@ -0,0 +1,69 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// CS35L56 HDA audio driver I2C binding
4//
5// Copyright (C) 2023 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7
8#include <linux/i2c.h>
9#include <linux/module.h>
10#include <linux/regmap.h>
11
12#include "cs35l56_hda.h"
13
14static int cs35l56_hda_i2c_probe(struct i2c_client *clt)
15{
16 struct cs35l56_hda *cs35l56;
17 int ret;
18
19 cs35l56 = devm_kzalloc(&clt->dev, sizeof(*cs35l56), GFP_KERNEL);
20 if (!cs35l56)
21 return -ENOMEM;
22
23 cs35l56->base.dev = &clt->dev;
24 cs35l56->base.can_hibernate = true;
25 cs35l56->base.regmap = devm_regmap_init_i2c(clt, &cs35l56_regmap_i2c);
26 if (IS_ERR(cs35l56->base.regmap)) {
27 ret = PTR_ERR(cs35l56->base.regmap);
28 dev_err(cs35l56->base.dev, "Failed to allocate register map: %d\n",
29 ret);
30 return ret;
31 }
32
33 ret = cs35l56_hda_common_probe(cs35l56, clt->addr);
34 if (ret)
35 return ret;
36 ret = cs35l56_irq_request(&cs35l56->base, clt->irq);
37 if (ret < 0)
38 cs35l56_hda_remove(cs35l56->base.dev);
39
40 return ret;
41}
42
43static void cs35l56_hda_i2c_remove(struct i2c_client *clt)
44{
45 cs35l56_hda_remove(&clt->dev);
46}
47
48static const struct i2c_device_id cs35l56_hda_i2c_id[] = {
49 { "cs35l56-hda", 0 },
50 {}
51};
52
53static struct i2c_driver cs35l56_hda_i2c_driver = {
54 .driver = {
55 .name = "cs35l56-hda",
56 .pm = &cs35l56_hda_pm_ops,
57 },
58 .id_table = cs35l56_hda_i2c_id,
59 .probe = cs35l56_hda_i2c_probe,
60 .remove = cs35l56_hda_i2c_remove,
61};
62module_i2c_driver(cs35l56_hda_i2c_driver);
63
64MODULE_DESCRIPTION("HDA CS35L56 I2C driver");
65MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L56);
66MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
67MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
68MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
69MODULE_LICENSE("GPL");
sound/pci/hda/cs35l56_hda_spi.c+68−0
@@ -0,0 +1,68 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// CS35L56 HDA audio driver SPI binding
4//
5// Copyright (C) 2023 Cirrus Logic, Inc. and
6// Cirrus Logic International Semiconductor Ltd.
7
8#include <linux/module.h>
9#include <linux/regmap.h>
10#include <linux/spi/spi.h>
11
12#include "cs35l56_hda.h"
13
14static int cs35l56_hda_spi_probe(struct spi_device *spi)
15{
16 struct cs35l56_hda *cs35l56;
17 int ret;
18
19 cs35l56 = devm_kzalloc(&spi->dev, sizeof(*cs35l56), GFP_KERNEL);
20 if (!cs35l56)
21 return -ENOMEM;
22
23 cs35l56->base.dev = &spi->dev;
24 cs35l56->base.regmap = devm_regmap_init_spi(spi, &cs35l56_regmap_spi);
25 if (IS_ERR(cs35l56->base.regmap)) {
26 ret = PTR_ERR(cs35l56->base.regmap);
27 dev_err(cs35l56->base.dev, "Failed to allocate register map: %d\n",
28 ret);
29 return ret;
30 }
31
32 ret = cs35l56_hda_common_probe(cs35l56, spi->chip_select);
33 if (ret)
34 return ret;
35 ret = cs35l56_irq_request(&cs35l56->base, spi->irq);
36 if (ret < 0)
37 cs35l56_hda_remove(cs35l56->base.dev);
38
39 return ret;
40}
41
42static void cs35l56_hda_spi_remove(struct spi_device *spi)
43{
44 cs35l56_hda_remove(&spi->dev);
45}
46
47static const struct spi_device_id cs35l56_hda_spi_id[] = {
48 { "cs35l56-hda", 0 },
49 {}
50};
51
52static struct spi_driver cs35l56_hda_spi_driver = {
53 .driver = {
54 .name = "cs35l56-hda",
55 .pm = &cs35l56_hda_pm_ops,
56 },
57 .id_table = cs35l56_hda_spi_id,
58 .probe = cs35l56_hda_spi_probe,
59 .remove = cs35l56_hda_spi_remove,
60};
61module_spi_driver(cs35l56_hda_spi_driver);
62
63MODULE_DESCRIPTION("HDA CS35L56 SPI driver");
64MODULE_IMPORT_NS(SND_HDA_SCODEC_CS35L56);
65MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
66MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
67MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
68MODULE_LICENSE("GPL");
sound/pci/hda/hda_auto_parser.h+2−0
@@ -8,6 +8,8 @@ · 7 unmodified lines
8#ifndef __SOUND_HDA_AUTO_PARSER_H8#ifndef __SOUND_HDA_AUTO_PARSER_H
9#define __SOUND_HDA_AUTO_PARSER_H9#define __SOUND_HDA_AUTO_PARSER_H
10 10
11#include "hda_local.h"
12
11/*13/*
12 * Helper for automatic pin configuration14 * Helper for automatic pin configuration
13 */15 */
sound/pci/hda/hda_codec.c+0−2
@@ -1769,10 +1769,8 @@ void snd_hda_ctls_clear(struct hda_codec *codec) · 1768 unmodified lines
1769 int i;1769 int i;
1770 struct hda_nid_item *items = codec->mixers.list;1770 struct hda_nid_item *items = codec->mixers.list;
1771 1771
1772 down_write(&codec->card->controls_rwsem);
1773 for (i = 0; i < codec->mixers.used; i++)1772 for (i = 0; i < codec->mixers.used; i++)
1774 snd_ctl_remove(codec->card, items[i].kctl);1773 snd_ctl_remove(codec->card, items[i].kctl);
1775 up_write(&codec->card->controls_rwsem);
1776 snd_array_free(&codec->mixers);1774 snd_array_free(&codec->mixers);
1777 snd_array_free(&codec->nids);1775 snd_array_free(&codec->nids);
1778}1776}
sound/pci/hda/hda_component.h+2−0
@@ -15,5 +15,7 @@ struct hda_component { · 14 unmodified lines
15 struct device *dev;15 struct device *dev;
16 char name[HDA_MAX_NAME_SIZE];16 char name[HDA_MAX_NAME_SIZE];
17 struct hda_codec *codec;17 struct hda_codec *codec;
18 void (*pre_playback_hook)(struct device *dev, int action);
18 void (*playback_hook)(struct device *dev, int action);19 void (*playback_hook)(struct device *dev, int action);
20 void (*post_playback_hook)(struct device *dev, int action);
19};21};
sound/pci/hda/hda_generic.h+3−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
9#define __SOUND_HDA_GENERIC_H9#define __SOUND_HDA_GENERIC_H
10 10
11#include <linux/leds.h>11#include <linux/leds.h>
12#include "hda_auto_parser.h"
13
14struct hda_jack_callback;
12 15
13/* table entry for multi-io paths */16/* table entry for multi-io paths */
14struct hda_multi_io {17struct hda_multi_io {
sound/pci/hda/hda_hwdep.c+2−2
@@ -114,8 +114,8 @@ int snd_hda_create_hwdep(struct hda_codec *codec) · 113 unmodified lines
114#endif114#endif
115 115
116 /* for sysfs */116 /* for sysfs */
117 hwdep->dev.groups = snd_hda_dev_attr_groups;117 hwdep->dev->groups = snd_hda_dev_attr_groups;
118 dev_set_drvdata(&hwdep->dev, codec);118 dev_set_drvdata(hwdep->dev, codec);
119 119
120 return 0;120 return 0;
121}121}
sound/pci/hda/hda_intel.c+146−229
@@ -330,18 +330,6 @@ enum { · 329 unmodified lines
330#define needs_eld_notify_link(chip) false330#define needs_eld_notify_link(chip) false
331#endif331#endif
332 332
333#define CONTROLLER_IN_GPU(pci) (((pci)->vendor == 0x8086) && \
334 (((pci)->device == 0x0a0c) || \
335 ((pci)->device == 0x0c0c) || \
336 ((pci)->device == 0x0d0c) || \
337 ((pci)->device == 0x160c) || \
338 ((pci)->device == 0x490d) || \
339 ((pci)->device == 0x4f90) || \
340 ((pci)->device == 0x4f91) || \
341 ((pci)->device == 0x4f92)))
342
343#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
344
345static const char * const driver_short_names[] = {333static const char * const driver_short_names[] = {
346 [AZX_DRIVER_ICH] = "HDA Intel",334 [AZX_DRIVER_ICH] = "HDA Intel",
347 [AZX_DRIVER_PCH] = "HDA Intel PCH",335 [AZX_DRIVER_PCH] = "HDA Intel PCH",
@@ -573,7 +561,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset) · 225 unmodified lines
573 snd_hdac_set_codec_wakeup(bus, false);561 snd_hdac_set_codec_wakeup(bus, false);
574 562
575 /* reduce dma latency to avoid noise */563 /* reduce dma latency to avoid noise */
576 if (IS_BXT(pci))564 if (HDA_CONTROLLER_IS_APL(pci))
577 bxt_reduce_dma_latency(chip);565 bxt_reduce_dma_latency(chip);
578 566
579 if (bus->mlcap != NULL)567 if (bus->mlcap != NULL)
@@ -2175,7 +2163,7 @@ static int azx_probe(struct pci_dev *pci, · 1595 unmodified lines
2175#endif /* CONFIG_SND_HDA_PATCH_LOADER */2163#endif /* CONFIG_SND_HDA_PATCH_LOADER */
2176 2164
2177#ifndef CONFIG_SND_HDA_I9152165#ifndef CONFIG_SND_HDA_I915
2178 if (CONTROLLER_IN_GPU(pci))2166 if (HDA_CONTROLLER_IN_GPU(pci))
2179 dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");2167 dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
2180#endif2168#endif
2181 2169
@@ -2283,7 +2271,7 @@ static int azx_probe_continue(struct azx *chip) · 101 unmodified lines
2283 * for other chips, still continue probing as other2271 * for other chips, still continue probing as other
2284 * codecs can be on the same link.2272 * codecs can be on the same link.
2285 */2273 */
2286 if (CONTROLLER_IN_GPU(pci)) {2274 if (HDA_CONTROLLER_IN_GPU(pci)) {
2287 dev_err(chip->card->dev,2275 dev_err(chip->card->dev,
2288 "HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");2276 "HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
2289 goto out_free;2277 goto out_free;
@@ -2294,7 +2282,7 @@ static int azx_probe_continue(struct azx *chip) · 4 unmodified lines
2294 }2282 }
2295 2283
2296 /* HSW/BDW controllers need this power */2284 /* HSW/BDW controllers need this power */
2297 if (CONTROLLER_IN_GPU(pci))2285 if (HDA_CONTROLLER_IN_GPU(pci))
2298 hda->need_i915_power = true;2286 hda->need_i915_power = true;
2299 }2287 }
2300 2288
@@ -2428,333 +2416,262 @@ static void azx_shutdown(struct pci_dev *pci) · 127 unmodified lines
2428/* PCI IDs */2416/* PCI IDs */
2429static const struct pci_device_id azx_ids[] = {2417static const struct pci_device_id azx_ids[] = {
2430 /* CPT */2418 /* CPT */
2431 { PCI_DEVICE(0x8086, 0x1c20),2419 { PCI_DEVICE_DATA(INTEL, HDA_CPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2432 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
2433 /* PBG */2420 /* PBG */
2434 { PCI_DEVICE(0x8086, 0x1d20),2421 { PCI_DEVICE_DATA(INTEL, HDA_PBG, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2435 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
2436 /* Panther Point */2422 /* Panther Point */
2437 { PCI_DEVICE(0x8086, 0x1e20),2423 { PCI_DEVICE_DATA(INTEL, HDA_PPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2438 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
2439 /* Lynx Point */2424 /* Lynx Point */
2440 { PCI_DEVICE(0x8086, 0x8c20),2425 { PCI_DEVICE_DATA(INTEL, HDA_LPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2441 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2442 /* 9 Series */2426 /* 9 Series */
2443 { PCI_DEVICE(0x8086, 0x8ca0),2427 { PCI_DEVICE_DATA(INTEL, HDA_9_SERIES, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2444 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2445 /* Wellsburg */2428 /* Wellsburg */
2446 { PCI_DEVICE(0x8086, 0x8d20),2429 { PCI_DEVICE_DATA(INTEL, HDA_WBG_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2447 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },2430 { PCI_DEVICE_DATA(INTEL, HDA_WBG_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2448 { PCI_DEVICE(0x8086, 0x8d21),
2449 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2450 /* Lewisburg */2431 /* Lewisburg */
2451 { PCI_DEVICE(0x8086, 0xa1f0),2432 { PCI_DEVICE_DATA(INTEL, HDA_LBG_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE) },
2452 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },2433 { PCI_DEVICE_DATA(INTEL, HDA_LBG_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE) },
2453 { PCI_DEVICE(0x8086, 0xa270),
2454 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
2455 /* Lynx Point-LP */2434 /* Lynx Point-LP */
2456 { PCI_DEVICE(0x8086, 0x9c20),2435 { PCI_DEVICE_DATA(INTEL, HDA_LPT_LP_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2457 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2458 /* Lynx Point-LP */2436 /* Lynx Point-LP */
2459 { PCI_DEVICE(0x8086, 0x9c21),2437 { PCI_DEVICE_DATA(INTEL, HDA_LPT_LP_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2460 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
2461 /* Wildcat Point-LP */2438 /* Wildcat Point-LP */
2462 { PCI_DEVICE(0x8086, 0x9ca0),2439 { PCI_DEVICE_DATA(INTEL, HDA_WPT_LP, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2463 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },2440 /* Skylake (Sunrise Point) */
2464 /* Sunrise Point */2441 { PCI_DEVICE_DATA(INTEL, HDA_SKL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2465 { PCI_DEVICE(0x8086, 0xa170),2442 /* Skylake-LP (Sunrise Point-LP) */
2466 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },2443 { PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2467 /* Sunrise Point-LP */
2468 { PCI_DEVICE(0x8086, 0x9d70),
2469 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
2470 /* Kabylake */2444 /* Kabylake */
2471 { PCI_DEVICE(0x8086, 0xa171),2445 { PCI_DEVICE_DATA(INTEL, HDA_KBL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2472 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
2473 /* Kabylake-LP */2446 /* Kabylake-LP */
2474 { PCI_DEVICE(0x8086, 0x9d71),2447 { PCI_DEVICE_DATA(INTEL, HDA_KBL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2475 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
2476 /* Kabylake-H */2448 /* Kabylake-H */
2477 { PCI_DEVICE(0x8086, 0xa2f0),2449 { PCI_DEVICE_DATA(INTEL, HDA_KBL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2478 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE },
2479 /* Coffelake */2450 /* Coffelake */
2480 { PCI_DEVICE(0x8086, 0xa348),2451 { PCI_DEVICE_DATA(INTEL, HDA_CNL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2481 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2482 /* Cannonlake */2452 /* Cannonlake */
2483 { PCI_DEVICE(0x8086, 0x9dc8),2453 { PCI_DEVICE_DATA(INTEL, HDA_CNL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2484 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2485 /* CometLake-LP */2454 /* CometLake-LP */
2486 { PCI_DEVICE(0x8086, 0x02C8),2455 { PCI_DEVICE_DATA(INTEL, HDA_CML_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2487 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2488 /* CometLake-H */2456 /* CometLake-H */
2489 { PCI_DEVICE(0x8086, 0x06C8),2457 { PCI_DEVICE_DATA(INTEL, HDA_CML_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2490 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2458 { PCI_DEVICE_DATA(INTEL, HDA_RKL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2491 { PCI_DEVICE(0x8086, 0xf1c8),
2492 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2493 /* CometLake-S */2459 /* CometLake-S */
2494 { PCI_DEVICE(0x8086, 0xa3f0),2460 { PCI_DEVICE_DATA(INTEL, HDA_CML_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2495 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2496 /* CometLake-R */2461 /* CometLake-R */
2497 { PCI_DEVICE(0x8086, 0xf0c8),2462 { PCI_DEVICE_DATA(INTEL, HDA_CML_R, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2498 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2499 /* Icelake */2463 /* Icelake */
2500 { PCI_DEVICE(0x8086, 0x34c8),2464 { PCI_DEVICE_DATA(INTEL, HDA_ICL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2501 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2502 /* Icelake-H */2465 /* Icelake-H */
2503 { PCI_DEVICE(0x8086, 0x3dc8),2466 { PCI_DEVICE_DATA(INTEL, HDA_ICL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2504 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2505 /* Jasperlake */2467 /* Jasperlake */
2506 { PCI_DEVICE(0x8086, 0x38c8),2468 { PCI_DEVICE_DATA(INTEL, HDA_ICL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2507 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2469 { PCI_DEVICE_DATA(INTEL, HDA_JSL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2508 { PCI_DEVICE(0x8086, 0x4dc8),
2509 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2510 /* Tigerlake */2470 /* Tigerlake */
2511 { PCI_DEVICE(0x8086, 0xa0c8),2471 { PCI_DEVICE_DATA(INTEL, HDA_TGL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2512 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2513 /* Tigerlake-H */2472 /* Tigerlake-H */
2514 { PCI_DEVICE(0x8086, 0x43c8),2473 { PCI_DEVICE_DATA(INTEL, HDA_TGL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2515 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2516 /* DG1 */2474 /* DG1 */
2517 { PCI_DEVICE(0x8086, 0x490d),2475 { PCI_DEVICE_DATA(INTEL, HDA_DG1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2518 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2519 /* DG2 */2476 /* DG2 */
2520 { PCI_DEVICE(0x8086, 0x4f90),2477 { PCI_DEVICE_DATA(INTEL, HDA_DG2_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2521 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2478 { PCI_DEVICE_DATA(INTEL, HDA_DG2_1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2522 { PCI_DEVICE(0x8086, 0x4f91),2479 { PCI_DEVICE_DATA(INTEL, HDA_DG2_2, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2523 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2524 { PCI_DEVICE(0x8086, 0x4f92),
2525 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2526 /* Alderlake-S */2480 /* Alderlake-S */
2527 { PCI_DEVICE(0x8086, 0x7ad0),2481 { PCI_DEVICE_DATA(INTEL, HDA_ADL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2528 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2529 /* Alderlake-P */2482 /* Alderlake-P */
2530 { PCI_DEVICE(0x8086, 0x51c8),2483 { PCI_DEVICE_DATA(INTEL, HDA_ADL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2531 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2484 { PCI_DEVICE_DATA(INTEL, HDA_ADL_PS, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2532 { PCI_DEVICE(0x8086, 0x51c9),2485 { PCI_DEVICE_DATA(INTEL, HDA_ADL_PX, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2533 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2534 { PCI_DEVICE(0x8086, 0x51cd),
2535 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2536 /* Alderlake-M */2486 /* Alderlake-M */
2537 { PCI_DEVICE(0x8086, 0x51cc),2487 { PCI_DEVICE_DATA(INTEL, HDA_ADL_M, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2538 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2539 /* Alderlake-N */2488 /* Alderlake-N */
2540 { PCI_DEVICE(0x8086, 0x54c8),2489 { PCI_DEVICE_DATA(INTEL, HDA_ADL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2541 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2542 /* Elkhart Lake */2490 /* Elkhart Lake */
2543 { PCI_DEVICE(0x8086, 0x4b55),2491 { PCI_DEVICE_DATA(INTEL, HDA_EHL_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2544 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2492 { PCI_DEVICE_DATA(INTEL, HDA_EHL_3, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2545 { PCI_DEVICE(0x8086, 0x4b58),
2546 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2547 /* Raptor Lake */2493 /* Raptor Lake */
2548 { PCI_DEVICE(0x8086, 0x7a50),2494 { PCI_DEVICE_DATA(INTEL, HDA_RPL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2549 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2495 { PCI_DEVICE_DATA(INTEL, HDA_RPL_P_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2550 { PCI_DEVICE(0x8086, 0x51ca),2496 { PCI_DEVICE_DATA(INTEL, HDA_RPL_P_1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2551 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2497 { PCI_DEVICE_DATA(INTEL, HDA_RPL_M, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2552 { PCI_DEVICE(0x8086, 0x51cb),2498 { PCI_DEVICE_DATA(INTEL, HDA_RPL_PX, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2553 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2499 { PCI_DEVICE_DATA(INTEL, HDA_MTL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2554 { PCI_DEVICE(0x8086, 0x51ce),
2555 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2556 { PCI_DEVICE(0x8086, 0x51cf),
2557 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2558 /* Meteorlake-P */
2559 { PCI_DEVICE(0x8086, 0x7e28),
2560 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
2561 /* Lunarlake-P */2500 /* Lunarlake-P */
2562 { PCI_DEVICE(0x8086, 0xa828),2501 { PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2563 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},2502 /* Arrow Lake-S */
2564 /* Broxton-P(Apollolake) */2503 { PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2565 { PCI_DEVICE(0x8086, 0x5a98),2504 /* Apollolake (Broxton-P) */
2566 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },2505 { PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
2567 /* Broxton-T */
2568 { PCI_DEVICE(0x8086, 0x1a98),
2569 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
2570 /* Gemini-Lake */2506 /* Gemini-Lake */
2571 { PCI_DEVICE(0x8086, 0x3198),2507 { PCI_DEVICE_DATA(INTEL, HDA_GML, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
2572 .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
2573 /* Haswell */2508 /* Haswell */
2574 { PCI_DEVICE(0x8086, 0x0a0c),2509 { PCI_DEVICE_DATA(INTEL, HDA_HSW_0, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2575 .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },2510 { PCI_DEVICE_DATA(INTEL, HDA_HSW_2, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2576 { PCI_DEVICE(0x8086, 0x0c0c),2511 { PCI_DEVICE_DATA(INTEL, HDA_HSW_3, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2577 .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
2578 { PCI_DEVICE(0x8086, 0x0d0c),
2579 .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
2580 /* Broadwell */2512 /* Broadwell */
2581 { PCI_DEVICE(0x8086, 0x160c),2513 { PCI_DEVICE_DATA(INTEL, HDA_BDW, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_BROADWELL) },
2582 .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_BROADWELL },
2583 /* 5 Series/3400 */2514 /* 5 Series/3400 */
2584 { PCI_DEVICE(0x8086, 0x3b56),2515 { PCI_DEVICE_DATA(INTEL, HDA_5_3400_SERIES_0, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2585 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },2516 { PCI_DEVICE_DATA(INTEL, HDA_5_3400_SERIES_1, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2586 { PCI_DEVICE(0x8086, 0x3b57),
2587 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
2588 /* Poulsbo */2517 /* Poulsbo */
2589 { PCI_DEVICE(0x8086, 0x811b),2518 { PCI_DEVICE_DATA(INTEL, HDA_POULSBO, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE |
2590 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE |2519 AZX_DCAPS_POSFIX_LPIB) },
2591 AZX_DCAPS_POSFIX_LPIB },
2592 /* Oaktrail */2520 /* Oaktrail */
2593 { PCI_DEVICE(0x8086, 0x080a),2521 { PCI_DEVICE_DATA(INTEL, HDA_OAKTRAIL, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE) },
2594 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
2595 /* BayTrail */2522 /* BayTrail */
2596 { PCI_DEVICE(0x8086, 0x0f04),2523 { PCI_DEVICE_DATA(INTEL, HDA_BYT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL) },
2597 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL },
2598 /* Braswell */2524 /* Braswell */
2599 { PCI_DEVICE(0x8086, 0x2284),2525 { PCI_DEVICE_DATA(INTEL, HDA_BSW, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL) },
2600 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL },
2601 /* ICH6 */2526 /* ICH6 */
2602 { PCI_DEVICE(0x8086, 0x2668),2527 { PCI_DEVICE_DATA(INTEL, HDA_ICH6, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2603 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2604 /* ICH7 */2528 /* ICH7 */
2605 { PCI_DEVICE(0x8086, 0x27d8),2529 { PCI_DEVICE_DATA(INTEL, HDA_ICH7, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2606 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2607 /* ESB2 */2530 /* ESB2 */
2608 { PCI_DEVICE(0x8086, 0x269a),2531 { PCI_DEVICE_DATA(INTEL, HDA_ESB2, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2609 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2610 /* ICH8 */2532 /* ICH8 */
2611 { PCI_DEVICE(0x8086, 0x284b),2533 { PCI_DEVICE_DATA(INTEL, HDA_ICH8, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2612 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2613 /* ICH9 */2534 /* ICH9 */
2614 { PCI_DEVICE(0x8086, 0x293e),2535 { PCI_DEVICE_DATA(INTEL, HDA_ICH9_0, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2615 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2616 /* ICH9 */2536 /* ICH9 */
2617 { PCI_DEVICE(0x8086, 0x293f),2537 { PCI_DEVICE_DATA(INTEL, HDA_ICH9_1, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2618 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2619 /* ICH10 */2538 /* ICH10 */
2620 { PCI_DEVICE(0x8086, 0x3a3e),2539 { PCI_DEVICE_DATA(INTEL, HDA_ICH10_0, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2621 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2622 /* ICH10 */2540 /* ICH10 */
2623 { PCI_DEVICE(0x8086, 0x3a6e),2541 { PCI_DEVICE_DATA(INTEL, HDA_ICH10_1, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2624 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
2625 /* Generic Intel */2542 /* Generic Intel */
2626 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),2543 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2627 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,2544 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2628 .class_mask = 0xffffff,2545 .class_mask = 0xffffff,
2629 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE },2546 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE },
2630 /* ATI SB 450/600/700/800/900 */2547 /* ATI SB 450/600/700/800/900 */
2631 { PCI_DEVICE(0x1002, 0x437b),2548 { PCI_VDEVICE(ATI, 0x437b),
2632 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },2549 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
2633 { PCI_DEVICE(0x1002, 0x4383),2550 { PCI_VDEVICE(ATI, 0x4383),
2634 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },2551 .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
2635 /* AMD Hudson */2552 /* AMD Hudson */
2636 { PCI_DEVICE(0x1022, 0x780d),2553 { PCI_VDEVICE(AMD, 0x780d),
2637 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },2554 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
2638 /* AMD, X370 & co */2555 /* AMD, X370 & co */
2639 { PCI_DEVICE(0x1022, 0x1457),2556 { PCI_VDEVICE(AMD, 0x1457),
2640 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },2557 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
2641 /* AMD, X570 & co */2558 /* AMD, X570 & co */
2642 { PCI_DEVICE(0x1022, 0x1487),2559 { PCI_VDEVICE(AMD, 0x1487),
2643 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },2560 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
2644 /* AMD Stoney */2561 /* AMD Stoney */
2645 { PCI_DEVICE(0x1022, 0x157a),2562 { PCI_VDEVICE(AMD, 0x157a),
2646 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |2563 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
2647 AZX_DCAPS_PM_RUNTIME },2564 AZX_DCAPS_PM_RUNTIME },
2648 /* AMD Raven */2565 /* AMD Raven */
2649 { PCI_DEVICE(0x1022, 0x15e3),2566 { PCI_VDEVICE(AMD, 0x15e3),
2650 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },2567 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
2651 /* ATI HDMI */2568 /* ATI HDMI */
2652 { PCI_DEVICE(0x1002, 0x0002),2569 { PCI_VDEVICE(ATI, 0x0002),
2653 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2570 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2654 AZX_DCAPS_PM_RUNTIME },2571 AZX_DCAPS_PM_RUNTIME },
2655 { PCI_DEVICE(0x1002, 0x1308),2572 { PCI_VDEVICE(ATI, 0x1308),
2656 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2573 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2657 { PCI_DEVICE(0x1002, 0x157a),2574 { PCI_VDEVICE(ATI, 0x157a),
2658 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2575 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2659 { PCI_DEVICE(0x1002, 0x15b3),2576 { PCI_VDEVICE(ATI, 0x15b3),
2660 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2577 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2661 { PCI_DEVICE(0x1002, 0x793b),2578 { PCI_VDEVICE(ATI, 0x793b),
2662 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2579 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2663 { PCI_DEVICE(0x1002, 0x7919),2580 { PCI_VDEVICE(ATI, 0x7919),
2664 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2581 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2665 { PCI_DEVICE(0x1002, 0x960f),2582 { PCI_VDEVICE(ATI, 0x960f),
2666 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2583 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2667 { PCI_DEVICE(0x1002, 0x970f),2584 { PCI_VDEVICE(ATI, 0x970f),
2668 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2585 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2669 { PCI_DEVICE(0x1002, 0x9840),2586 { PCI_VDEVICE(ATI, 0x9840),
2670 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2587 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2671 { PCI_DEVICE(0x1002, 0xaa00),2588 { PCI_VDEVICE(ATI, 0xaa00),
2672 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2589 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2673 { PCI_DEVICE(0x1002, 0xaa08),2590 { PCI_VDEVICE(ATI, 0xaa08),
2674 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2591 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2675 { PCI_DEVICE(0x1002, 0xaa10),2592 { PCI_VDEVICE(ATI, 0xaa10),
2676 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2593 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2677 { PCI_DEVICE(0x1002, 0xaa18),2594 { PCI_VDEVICE(ATI, 0xaa18),
2678 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2595 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2679 { PCI_DEVICE(0x1002, 0xaa20),2596 { PCI_VDEVICE(ATI, 0xaa20),
2680 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2597 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2681 { PCI_DEVICE(0x1002, 0xaa28),2598 { PCI_VDEVICE(ATI, 0xaa28),
2682 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2599 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2683 { PCI_DEVICE(0x1002, 0xaa30),2600 { PCI_VDEVICE(ATI, 0xaa30),
2684 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2601 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2685 { PCI_DEVICE(0x1002, 0xaa38),2602 { PCI_VDEVICE(ATI, 0xaa38),
2686 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2603 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2687 { PCI_DEVICE(0x1002, 0xaa40),2604 { PCI_VDEVICE(ATI, 0xaa40),
2688 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2605 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2689 { PCI_DEVICE(0x1002, 0xaa48),2606 { PCI_VDEVICE(ATI, 0xaa48),
2690 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2607 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2691 { PCI_DEVICE(0x1002, 0xaa50),2608 { PCI_VDEVICE(ATI, 0xaa50),
2692 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2609 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2693 { PCI_DEVICE(0x1002, 0xaa58),2610 { PCI_VDEVICE(ATI, 0xaa58),
2694 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2611 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2695 { PCI_DEVICE(0x1002, 0xaa60),2612 { PCI_VDEVICE(ATI, 0xaa60),
2696 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2613 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2697 { PCI_DEVICE(0x1002, 0xaa68),2614 { PCI_VDEVICE(ATI, 0xaa68),
2698 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2615 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2699 { PCI_DEVICE(0x1002, 0xaa80),2616 { PCI_VDEVICE(ATI, 0xaa80),
2700 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2617 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2701 { PCI_DEVICE(0x1002, 0xaa88),2618 { PCI_VDEVICE(ATI, 0xaa88),
2702 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2619 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2703 { PCI_DEVICE(0x1002, 0xaa90),2620 { PCI_VDEVICE(ATI, 0xaa90),
2704 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2621 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2705 { PCI_DEVICE(0x1002, 0xaa98),2622 { PCI_VDEVICE(ATI, 0xaa98),
2706 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },2623 .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2707 { PCI_DEVICE(0x1002, 0x9902),2624 { PCI_VDEVICE(ATI, 0x9902),
2708 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2625 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2709 { PCI_DEVICE(0x1002, 0xaaa0),2626 { PCI_VDEVICE(ATI, 0xaaa0),
2710 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2627 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2711 { PCI_DEVICE(0x1002, 0xaaa8),2628 { PCI_VDEVICE(ATI, 0xaaa8),
2712 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2629 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2713 { PCI_DEVICE(0x1002, 0xaab0),2630 { PCI_VDEVICE(ATI, 0xaab0),
2714 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },2631 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2715 { PCI_DEVICE(0x1002, 0xaac0),2632 { PCI_VDEVICE(ATI, 0xaac0),
2716 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2633 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2717 AZX_DCAPS_PM_RUNTIME },2634 AZX_DCAPS_PM_RUNTIME },
2718 { PCI_DEVICE(0x1002, 0xaac8),2635 { PCI_VDEVICE(ATI, 0xaac8),
2719 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2636 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2720 AZX_DCAPS_PM_RUNTIME },2637 AZX_DCAPS_PM_RUNTIME },
2721 { PCI_DEVICE(0x1002, 0xaad8),2638 { PCI_VDEVICE(ATI, 0xaad8),
2722 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2639 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2723 AZX_DCAPS_PM_RUNTIME },2640 AZX_DCAPS_PM_RUNTIME },
2724 { PCI_DEVICE(0x1002, 0xaae0),2641 { PCI_VDEVICE(ATI, 0xaae0),
2725 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2642 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2726 AZX_DCAPS_PM_RUNTIME },2643 AZX_DCAPS_PM_RUNTIME },
2727 { PCI_DEVICE(0x1002, 0xaae8),2644 { PCI_VDEVICE(ATI, 0xaae8),
2728 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2645 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2729 AZX_DCAPS_PM_RUNTIME },2646 AZX_DCAPS_PM_RUNTIME },
2730 { PCI_DEVICE(0x1002, 0xaaf0),2647 { PCI_VDEVICE(ATI, 0xaaf0),
2731 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2648 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2732 AZX_DCAPS_PM_RUNTIME },2649 AZX_DCAPS_PM_RUNTIME },
2733 { PCI_DEVICE(0x1002, 0xaaf8),2650 { PCI_VDEVICE(ATI, 0xaaf8),
2734 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2651 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2735 AZX_DCAPS_PM_RUNTIME },2652 AZX_DCAPS_PM_RUNTIME },
2736 { PCI_DEVICE(0x1002, 0xab00),2653 { PCI_VDEVICE(ATI, 0xab00),
2737 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2654 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2738 AZX_DCAPS_PM_RUNTIME },2655 AZX_DCAPS_PM_RUNTIME },
2739 { PCI_DEVICE(0x1002, 0xab08),2656 { PCI_VDEVICE(ATI, 0xab08),
2740 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2657 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2741 AZX_DCAPS_PM_RUNTIME },2658 AZX_DCAPS_PM_RUNTIME },
2742 { PCI_DEVICE(0x1002, 0xab10),2659 { PCI_VDEVICE(ATI, 0xab10),
2743 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2660 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2744 AZX_DCAPS_PM_RUNTIME },2661 AZX_DCAPS_PM_RUNTIME },
2745 { PCI_DEVICE(0x1002, 0xab18),2662 { PCI_VDEVICE(ATI, 0xab18),
2746 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2663 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2747 AZX_DCAPS_PM_RUNTIME },2664 AZX_DCAPS_PM_RUNTIME },
2748 { PCI_DEVICE(0x1002, 0xab20),2665 { PCI_VDEVICE(ATI, 0xab20),
2749 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2666 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2750 AZX_DCAPS_PM_RUNTIME },2667 AZX_DCAPS_PM_RUNTIME },
2751 { PCI_DEVICE(0x1002, 0xab28),2668 { PCI_VDEVICE(ATI, 0xab28),
2752 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2669 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2753 AZX_DCAPS_PM_RUNTIME },2670 AZX_DCAPS_PM_RUNTIME },
2754 { PCI_DEVICE(0x1002, 0xab30),2671 { PCI_VDEVICE(ATI, 0xab30),
2755 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2672 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2756 AZX_DCAPS_PM_RUNTIME },2673 AZX_DCAPS_PM_RUNTIME },
2757 { PCI_DEVICE(0x1002, 0xab38),2674 { PCI_VDEVICE(ATI, 0xab38),
2758 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |2675 .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2759 AZX_DCAPS_PM_RUNTIME },2676 AZX_DCAPS_PM_RUNTIME },
2760 /* GLENFLY */2677 /* GLENFLY */
@@ -2764,15 +2681,15 @@ static const struct pci_device_id azx_ids[] = { · 3 unmodified lines
2764 .driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |2681 .driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |
2765 AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },2682 AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },
2766 /* VIA VT8251/VT8237A */2683 /* VIA VT8251/VT8237A */
2767 { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA },2684 { PCI_VDEVICE(VIA, 0x3288), .driver_data = AZX_DRIVER_VIA },
2768 /* VIA GFX VT7122/VX900 */2685 /* VIA GFX VT7122/VX900 */
2769 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },2686 { PCI_VDEVICE(VIA, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
2770 /* VIA GFX VT6122/VX11 */2687 /* VIA GFX VT6122/VX11 */
2771 { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },2688 { PCI_VDEVICE(VIA, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
2772 /* SIS966 */2689 /* SIS966 */
2773 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },2690 { PCI_VDEVICE(SI, 0x7502), .driver_data = AZX_DRIVER_SIS },
2774 /* ULI M5461 */2691 /* ULI M5461 */
2775 { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },2692 { PCI_VDEVICE(AL, 0x5461), .driver_data = AZX_DRIVER_ULI },
2776 /* NVIDIA MCP */2693 /* NVIDIA MCP */
2777 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),2694 { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
2778 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,2695 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
@@ -2785,9 +2702,9 @@ static const struct pci_device_id azx_ids[] = { · 6 unmodified lines
2785 .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },2702 .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
2786 /* Creative X-Fi (CA0110-IBG) */2703 /* Creative X-Fi (CA0110-IBG) */
2787 /* CTHDA chips */2704 /* CTHDA chips */
2788 { PCI_DEVICE(0x1102, 0x0010),2705 { PCI_VDEVICE(CREATIVE, 0x0010),
2789 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },2706 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
2790 { PCI_DEVICE(0x1102, 0x0012),2707 { PCI_VDEVICE(CREATIVE, 0x0012),
2791 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },2708 .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
2792#if !IS_ENABLED(CONFIG_SND_CTXFI)2709#if !IS_ENABLED(CONFIG_SND_CTXFI)
2793 /* the following entry conflicts with snd-ctxfi driver,2710 /* the following entry conflicts with snd-ctxfi driver,
@@ -2801,18 +2718,18 @@ static const struct pci_device_id azx_ids[] = { · 7 unmodified lines
2801 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },2718 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2802#else2719#else
2803 /* this entry seems still valid -- i.e. without emu20kx chip */2720 /* this entry seems still valid -- i.e. without emu20kx chip */
2804 { PCI_DEVICE(0x1102, 0x0009),2721 { PCI_VDEVICE(CREATIVE, 0x0009),
2805 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |2722 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2806 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },2723 AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2807#endif2724#endif
2808 /* CM8888 */2725 /* CM8888 */
2809 { PCI_DEVICE(0x13f6, 0x5011),2726 { PCI_VDEVICE(CMEDIA, 0x5011),
2810 .driver_data = AZX_DRIVER_CMEDIA |2727 .driver_data = AZX_DRIVER_CMEDIA |
2811 AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF },2728 AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF },
2812 /* Vortex86MX */2729 /* Vortex86MX */
2813 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },2730 { PCI_VDEVICE(RDC, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
2814 /* VMware HDAudio */2731 /* VMware HDAudio */
2815 { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },2732 { PCI_VDEVICE(VMWARE, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
2816 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */2733 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2817 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),2734 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2818 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,2735 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
@@ -2823,11 +2740,11 @@ static const struct pci_device_id azx_ids[] = { · 4 unmodified lines
2823 .class_mask = 0xffffff,2740 .class_mask = 0xffffff,
2824 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },2741 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
2825 /* Zhaoxin */2742 /* Zhaoxin */
2826 { PCI_DEVICE(0x1d17, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },2743 { PCI_VDEVICE(ZHAOXIN, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },
2827 /* Loongson HDAudio*/2744 /* Loongson HDAudio*/
2828 {PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_HDA),2745 { PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDA),
2829 .driver_data = AZX_DRIVER_LOONGSON },2746 .driver_data = AZX_DRIVER_LOONGSON },
2830 {PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_HDMI),2747 { PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDMI),
2831 .driver_data = AZX_DRIVER_LOONGSON },2748 .driver_data = AZX_DRIVER_LOONGSON },
2832 { 0, }2749 { 0, }
2833};2750};
sound/pci/hda/hda_tegra.c+4−3
@@ -16,7 +16,8 @@ · 15 unmodified lines
16#include <linux/module.h>16#include <linux/module.h>
17#include <linux/moduleparam.h>17#include <linux/moduleparam.h>
18#include <linux/mutex.h>18#include <linux/mutex.h>
19#include <linux/of_device.h>19#include <linux/of.h>
20#include <linux/platform_device.h>
20#include <linux/reset.h>21#include <linux/reset.h>
21#include <linux/slab.h>22#include <linux/slab.h>
22#include <linux/time.h>23#include <linux/time.h>
@@ -378,14 +379,14 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) · 355 unmodified lines
378 }379 }
379 380
380 /* driver name */381 /* driver name */
381 strncpy(card->driver, drv_name, sizeof(card->driver));382 strscpy(card->driver, drv_name, sizeof(card->driver));
382 /* shortname for card */383 /* shortname for card */
383 sname = of_get_property(np, "nvidia,model", NULL);384 sname = of_get_property(np, "nvidia,model", NULL);
384 if (!sname)385 if (!sname)
385 sname = drv_name;386 sname = drv_name;
386 if (strlen(sname) > sizeof(card->shortname))387 if (strlen(sname) > sizeof(card->shortname))
387 dev_info(card->dev, "truncating shortname for card\n");388 dev_info(card->dev, "truncating shortname for card\n");
388 strncpy(card->shortname, sname, sizeof(card->shortname));389 strscpy(card->shortname, sname, sizeof(card->shortname));
389 390
390 /* longname for card */391 /* longname for card */
391 snprintf(card->longname, sizeof(card->longname),392 snprintf(card->longname, sizeof(card->longname),
sound/pci/hda/patch_hdmi.c+3−2
@@ -4632,8 +4632,9 @@ HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI", patch_i915_tgl_hdmi), · 4631 unmodified lines
4632HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),4632HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
4633HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),4633HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
4634HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),4634HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
4635HDA_CODEC_ENTRY(0x8086281f, "Raptorlake-P HDMI", patch_i915_adlp_hdmi),4635HDA_CODEC_ENTRY(0x8086281d, "Meteor Lake HDMI", patch_i915_adlp_hdmi),
4636HDA_CODEC_ENTRY(0x8086281d, "Meteorlake HDMI", patch_i915_adlp_hdmi),4636HDA_CODEC_ENTRY(0x8086281f, "Raptor Lake P HDMI", patch_i915_adlp_hdmi),
4637HDA_CODEC_ENTRY(0x80862820, "Lunar Lake HDMI", patch_i915_adlp_hdmi),
4637HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),4638HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
4638HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),4639HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
4639HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),4640HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
sound/pci/hda/patch_realtek.c+124−4
@@ -4639,6 +4639,22 @@ static void alc236_fixup_hp_mute_led_coefbit2(struct hda_codec *codec, · 4638 unmodified lines
4639 }4639 }
4640}4640}
4641 4641
4642static void alc245_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
4643 const struct hda_fixup *fix,
4644 int action)
4645{
4646 struct alc_spec *spec = codec->spec;
4647
4648 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4649 spec->mute_led_polarity = 0;
4650 spec->mute_led_coef.idx = 0x0b;
4651 spec->mute_led_coef.mask = 3 << 2;
4652 spec->mute_led_coef.on = 2 << 2;
4653 spec->mute_led_coef.off = 1 << 2;
4654 snd_hda_gen_add_mute_led_cdev(codec, coef_mute_led_set);
4655 }
4656}
4657
4642/* turn on/off mic-mute LED per capture hook by coef bit */4658/* turn on/off mic-mute LED per capture hook by coef bit */
4643static int coef_micmute_led_set(struct led_classdev *led_cdev,4659static int coef_micmute_led_set(struct led_classdev *led_cdev,
4644 enum led_brightness brightness)4660 enum led_brightness brightness)
@@ -6716,12 +6732,20 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_ · 2071 unmodified lines
6716 int i;6732 int i;
6717 6733
6718 for (i = 0; i < HDA_MAX_COMPONENTS; i++) {6734 for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
6719 if (spec->comps[i].dev)6735 if (spec->comps[i].dev && spec->comps[i].pre_playback_hook)
6736 spec->comps[i].pre_playback_hook(spec->comps[i].dev, action);
6737 }
6738 for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
6739 if (spec->comps[i].dev && spec->comps[i].playback_hook)
6720 spec->comps[i].playback_hook(spec->comps[i].dev, action);6740 spec->comps[i].playback_hook(spec->comps[i].dev, action);
6721 }6741 }
6742 for (i = 0; i < HDA_MAX_COMPONENTS; i++) {
6743 if (spec->comps[i].dev && spec->comps[i].post_playback_hook)
6744 spec->comps[i].post_playback_hook(spec->comps[i].dev, action);
6745 }
6722}6746}
6723 6747
6724struct cs35l41_dev_name {6748struct scodec_dev_name {
6725 const char *bus;6749 const char *bus;
6726 const char *hid;6750 const char *hid;
6727 int index;6751 int index;
@@ -6730,7 +6754,7 @@ struct cs35l41_dev_name { · 2 unmodified lines
6730/* match the device name in a slightly relaxed manner */6754/* match the device name in a slightly relaxed manner */
6731static int comp_match_cs35l41_dev_name(struct device *dev, void *data)6755static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
6732{6756{
6733 struct cs35l41_dev_name *p = data;6757 struct scodec_dev_name *p = data;
6734 const char *d = dev_name(dev);6758 const char *d = dev_name(dev);
6735 int n = strlen(p->bus);6759 int n = strlen(p->bus);
6736 char tmp[32];6760 char tmp[32];
@@ -6746,12 +6770,32 @@ static int comp_match_cs35l41_dev_name(struct device *dev, void *data) · 9 unmodified lines
6746 return !strcmp(d + n, tmp);6770 return !strcmp(d + n, tmp);
6747}6771}
6748 6772
6773static int comp_match_tas2781_dev_name(struct device *dev,
6774 void *data)
6775{
6776 struct scodec_dev_name *p = data;
6777 const char *d = dev_name(dev);
6778 int n = strlen(p->bus);
6779 char tmp[32];
6780
6781 /* check the bus name */
6782 if (strncmp(d, p->bus, n))
6783 return 0;
6784 /* skip the bus number */
6785 if (isdigit(d[n]))
6786 n++;
6787 /* the rest must be exact matching */
6788 snprintf(tmp, sizeof(tmp), "-%s:00", p->hid);
6789
6790 return !strcmp(d + n, tmp);
6791}
6792
6749static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,6793static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
6750 const char *hid, int count)6794 const char *hid, int count)
6751{6795{
6752 struct device *dev = hda_codec_dev(cdc);6796 struct device *dev = hda_codec_dev(cdc);
6753 struct alc_spec *spec = cdc->spec;6797 struct alc_spec *spec = cdc->spec;
6754 struct cs35l41_dev_name *rec;6798 struct scodec_dev_name *rec;
6755 int ret, i;6799 int ret, i;
6756 6800
6757 switch (action) {6801 switch (action) {
@@ -6779,6 +6823,41 @@ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char · 21 unmodified lines
6779 }6823 }
6780}6824}
6781 6825
6826static void tas2781_generic_fixup(struct hda_codec *cdc, int action,
6827 const char *bus, const char *hid)
6828{
6829 struct device *dev = hda_codec_dev(cdc);
6830 struct alc_spec *spec = cdc->spec;
6831 struct scodec_dev_name *rec;
6832 int ret;
6833
6834 switch (action) {
6835 case HDA_FIXUP_ACT_PRE_PROBE:
6836 rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL);
6837 if (!rec)
6838 return;
6839 rec->bus = bus;
6840 rec->hid = hid;
6841 rec->index = 0;
6842 spec->comps[0].codec = cdc;
6843 component_match_add(dev, &spec->match,
6844 comp_match_tas2781_dev_name, rec);
6845 ret = component_master_add_with_match(dev, &comp_master_ops,
6846 spec->match);
6847 if (ret)
6848 codec_err(cdc,
6849 "Fail to register component aggregator %d\n",
6850 ret);
6851 else
6852 spec->gen.pcm_playback_hook =
6853 comp_generic_playback_hook;
6854 break;
6855 case HDA_FIXUP_ACT_FREE:
6856 component_master_del(dev, &comp_master_ops);
6857 break;
6858 }
6859}
6860
6782static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)6861static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup *fix, int action)
6783{6862{
6784 cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);6863 cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
@@ -6806,6 +6885,12 @@ static void alc287_fixup_legion_16ithg6_speakers(struct hda_codec *cdc, const st · 21 unmodified lines
6806 cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);6885 cs35l41_generic_fixup(cdc, action, "i2c", "CLSA0101", 2);
6807}6886}
6808 6887
6888static void tas2781_fixup_i2c(struct hda_codec *cdc,
6889 const struct hda_fixup *fix, int action)
6890{
6891 tas2781_generic_fixup(cdc, action, "i2c", "TIAS2781");
6892}
6893
6809/* for alc295_fixup_hp_top_speakers */6894/* for alc295_fixup_hp_top_speakers */
6810#include "hp_x360_helper.c"6895#include "hp_x360_helper.c"
6811 6896
@@ -7231,6 +7316,9 @@ enum { · 419 unmodified lines
7231 ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,7316 ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
7232 ALC236_FIXUP_DELL_DUAL_CODECS,7317 ALC236_FIXUP_DELL_DUAL_CODECS,
7233 ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,7318 ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
7319 ALC287_FIXUP_TAS2781_I2C,
7320 ALC245_FIXUP_HP_MUTE_LED_COEFBIT,
7321 ALC245_FIXUP_HP_X360_MUTE_LEDS,
7234};7322};
7235 7323
7236/* A special fixup for Lenovo C940 and Yoga Duet 7;7324/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -9309,6 +9397,22 @@ static const struct hda_fixup alc269_fixups[] = { · 2072 unmodified lines
9309 .chained = true,9397 .chained = true,
9310 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,9398 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
9311 },9399 },
9400 [ALC287_FIXUP_TAS2781_I2C] = {
9401 .type = HDA_FIXUP_FUNC,
9402 .v.func = tas2781_fixup_i2c,
9403 .chained = true,
9404 .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
9405 },
9406 [ALC245_FIXUP_HP_MUTE_LED_COEFBIT] = {
9407 .type = HDA_FIXUP_FUNC,
9408 .v.func = alc245_fixup_hp_mute_led_coefbit,
9409 },
9410 [ALC245_FIXUP_HP_X360_MUTE_LEDS] = {
9411 .type = HDA_FIXUP_FUNC,
9412 .v.func = alc245_fixup_hp_mute_led_coefbit,
9413 .chained = true,
9414 .chain_id = ALC245_FIXUP_HP_GPIO_LED
9415 },
9312};9416};
9313 9417
9314static const struct snd_pci_quirk alc269_fixup_tbl[] = {9418static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9551,6 +9655,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 236 unmodified lines
9551 SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),9655 SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
9552 SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),9656 SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT),
9553 SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),9657 SND_PCI_QUIRK(0x103c, 0x887a, "HP Laptop 15s-eq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
9658 SND_PCI_QUIRK(0x103c, 0x888a, "HP ENVY x360 Convertible 15-eu0xxx", ALC245_FIXUP_HP_X360_MUTE_LEDS),
9554 SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),9659 SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
9555 SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED),9660 SND_PCI_QUIRK(0x103c, 0x8895, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED),
9556 SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),9661 SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
@@ -9582,6 +9687,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 25 unmodified lines
9582 SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),9687 SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
9583 SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),9688 SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
9584 SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),9689 SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
9690 SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
9585 SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),9691 SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
9586 SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED),9692 SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED),
9587 SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),9693 SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
@@ -9889,6 +9995,20 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 301 unmodified lines
9889 SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),9995 SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
9890 SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),9996 SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
9891 SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),9997 SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
9998 SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
9999 SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
10000 SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
10001 SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
10002 SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
10003 SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
10004 SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C),
10005 SND_PCI_QUIRK(0x17aa, 0x38ba, "Yoga S780-14.5 Air AMD quad YC", ALC287_FIXUP_TAS2781_I2C),
10006 SND_PCI_QUIRK(0x17aa, 0x38bb, "Yoga S780-14.5 Air AMD quad AAC", ALC287_FIXUP_TAS2781_I2C),
10007 SND_PCI_QUIRK(0x17aa, 0x38be, "Yoga S980-14.5 proX YC Dual", ALC287_FIXUP_TAS2781_I2C),
10008 SND_PCI_QUIRK(0x17aa, 0x38bf, "Yoga S980-14.5 proX LX Dual", ALC287_FIXUP_TAS2781_I2C),
10009 SND_PCI_QUIRK(0x17aa, 0x38c3, "Y980 DUAL", ALC287_FIXUP_TAS2781_I2C),
10010 SND_PCI_QUIRK(0x17aa, 0x38cb, "Y790 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
10011 SND_PCI_QUIRK(0x17aa, 0x38cd, "Y790 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
9892 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),10012 SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
9893 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),10013 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
9894 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),10014 SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
sound/pci/hda/tas2781_hda_i2c.c+856−0
@@ -0,0 +1,856 @@
1// SPDX-License-Identifier: GPL-2.0
2//
3// TAS2781 HDA I2C driver
4//
5// Copyright 2023 Texas Instruments, Inc.
6//
7// Author: Shenghao Ding <shenghao-ding@ti.com>
8
9#include <linux/acpi.h>
10#include <linux/crc8.h>
11#include <linux/crc32.h>
12#include <linux/efi.h>
13#include <linux/firmware.h>
14#include <linux/i2c.h>
15#include <linux/mod_devicetable.h>
16#include <linux/module.h>
17#include <linux/pm_runtime.h>
18#include <linux/regmap.h>
19#include <sound/hda_codec.h>
20#include <sound/soc.h>
21#include <sound/tas2781.h>
22#include <sound/tlv.h>
23#include <sound/tas2781-tlv.h>
24
25#include "hda_local.h"
26#include "hda_auto_parser.h"
27#include "hda_component.h"
28#include "hda_jack.h"
29#include "hda_generic.h"
30
31#define TASDEVICE_SPEAKER_CALIBRATION_SIZE 20
32
33/* No standard control callbacks for SNDRV_CTL_ELEM_IFACE_CARD
34 * Define two controls, one is Volume control callbacks, the other is
35 * flag setting control callbacks.
36 */
37
38/* Volume control callbacks for tas2781 */
39#define ACARD_SINGLE_RANGE_EXT_TLV(xname, xreg, xshift, xmin, xmax, xinvert, \
40 xhandler_get, xhandler_put, tlv_array) \
41{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = (xname),\
42 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
43 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
44 .tlv.p = (tlv_array), \
45 .info = snd_soc_info_volsw_range, \
46 .get = xhandler_get, .put = xhandler_put, \
47 .private_value = (unsigned long)&(struct soc_mixer_control) \
48 {.reg = xreg, .rreg = xreg, .shift = xshift, \
49 .rshift = xshift, .min = xmin, .max = xmax, \
50 .invert = xinvert} }
51
52/* Flag control callbacks for tas2781 */
53#define ACARD_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
54{ .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, \
55 .info = snd_ctl_boolean_mono_info, \
56 .get = xhandler_get, .put = xhandler_put, \
57 .private_value = xdata }
58
59enum calib_data {
60 R0_VAL = 0,
61 INV_R0,
62 R0LOW,
63 POWER,
64 TLIM,
65 CALIB_MAX
66};
67
68static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
69{
70 struct tasdevice_priv *tas_priv = data;
71 struct acpi_resource_i2c_serialbus *sb;
72
73 if (i2c_acpi_get_i2c_resource(ares, &sb)) {
74 if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&
75 sb->slave_address != TAS2781_GLOBAL_ADDR) {
76 tas_priv->tasdevice[tas_priv->ndev].dev_addr =
77 (unsigned int)sb->slave_address;
78 tas_priv->ndev++;
79 }
80 }
81 return 1;
82}
83
84static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)
85{
86 struct acpi_device *adev;
87 struct device *physdev;
88 LIST_HEAD(resources);
89 const char *sub;
90 int ret;
91
92 adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
93 if (!adev) {
94 dev_err(p->dev,
95 "Failed to find an ACPI device for %s\n", hid);
96 return -ENODEV;
97 }
98
99 ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p);
100 if (ret < 0)
101 goto err;
102
103 acpi_dev_free_resource_list(&resources);
104 strscpy(p->dev_name, hid, sizeof(p->dev_name));
105 physdev = get_device(acpi_get_first_physical_node(adev));
106 acpi_dev_put(adev);
107
108 /* No side-effect to the playback even if subsystem_id is NULL*/
109 sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
110 if (IS_ERR(sub))
111 sub = NULL;
112
113 p->acpi_subsystem_id = sub;
114
115 put_device(physdev);
116
117 return 0;
118
119err:
120 dev_err(p->dev, "read acpi error, ret: %d\n", ret);
121 acpi_dev_put(adev);
122
123 return ret;
124}
125
126static void tas2781_hda_playback_hook(struct device *dev, int action)
127{
128 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
129
130 dev_dbg(tas_priv->dev, "%s: action = %d\n", __func__, action);
131 switch (action) {
132 case HDA_GEN_PCM_ACT_OPEN:
133 pm_runtime_get_sync(dev);
134 mutex_lock(&tas_priv->codec_lock);
135 tasdevice_tuning_switch(tas_priv, 0);
136 mutex_unlock(&tas_priv->codec_lock);
137 break;
138 case HDA_GEN_PCM_ACT_CLOSE:
139 mutex_lock(&tas_priv->codec_lock);
140 tasdevice_tuning_switch(tas_priv, 1);
141 mutex_unlock(&tas_priv->codec_lock);
142
143 pm_runtime_mark_last_busy(dev);
144 pm_runtime_put_autosuspend(dev);
145 break;
146 default:
147 dev_dbg(tas_priv->dev, "Playback action not supported: %d\n",
148 action);
149 break;
150 }
151}
152
153static int tasdevice_info_profile(struct snd_kcontrol *kcontrol,
154 struct snd_ctl_elem_info *uinfo)
155{
156 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
157
158 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
159 uinfo->count = 1;
160 uinfo->value.integer.min = 0;
161 uinfo->value.integer.max = tas_priv->rcabin.ncfgs - 1;
162
163 return 0;
164}
165
166static int tasdevice_get_profile_id(struct snd_kcontrol *kcontrol,
167 struct snd_ctl_elem_value *ucontrol)
168{
169 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
170
171 ucontrol->value.integer.value[0] = tas_priv->rcabin.profile_cfg_id;
172
173 return 0;
174}
175
176static int tasdevice_hda_clamp(int val, int max)
177{
178 if (val > max)
179 val = max;
180
181 if (val < 0)
182 val = 0;
183 return val;
184}
185
186static int tasdevice_set_profile_id(struct snd_kcontrol *kcontrol,
187 struct snd_ctl_elem_value *ucontrol)
188{
189 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
190 int nr_profile = ucontrol->value.integer.value[0];
191 int max = tas_priv->rcabin.ncfgs - 1;
192 int val, ret = 0;
193
194 val = tasdevice_hda_clamp(nr_profile, max);
195
196 if (tas_priv->rcabin.profile_cfg_id != val) {
197 tas_priv->rcabin.profile_cfg_id = val;
198 ret = 1;
199 }
200
201 return ret;
202}
203
204static int tasdevice_info_programs(struct snd_kcontrol *kcontrol,
205 struct snd_ctl_elem_info *uinfo)
206{
207 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
208 struct tasdevice_fw *tas_fw = tas_priv->fmw;
209
210 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
211 uinfo->count = 1;
212 uinfo->value.integer.min = 0;
213 uinfo->value.integer.max = tas_fw->nr_programs - 1;
214
215 return 0;
216}
217
218static int tasdevice_info_config(struct snd_kcontrol *kcontrol,
219 struct snd_ctl_elem_info *uinfo)
220{
221 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
222 struct tasdevice_fw *tas_fw = tas_priv->fmw;
223
224 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
225 uinfo->count = 1;
226 uinfo->value.integer.min = 0;
227 uinfo->value.integer.max = tas_fw->nr_configurations - 1;
228
229 return 0;
230}
231
232static int tasdevice_program_get(struct snd_kcontrol *kcontrol,
233 struct snd_ctl_elem_value *ucontrol)
234{
235 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
236
237 ucontrol->value.integer.value[0] = tas_priv->cur_prog;
238
239 return 0;
240}
241
242static int tasdevice_program_put(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
244{
245 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
246 struct tasdevice_fw *tas_fw = tas_priv->fmw;
247 int nr_program = ucontrol->value.integer.value[0];
248 int max = tas_fw->nr_programs - 1;
249 int val, ret = 0;
250
251 val = tasdevice_hda_clamp(nr_program, max);
252
253 if (tas_priv->cur_prog != val) {
254 tas_priv->cur_prog = val;
255 ret = 1;
256 }
257
258 return ret;
259}
260
261static int tasdevice_config_get(struct snd_kcontrol *kcontrol,
262 struct snd_ctl_elem_value *ucontrol)
263{
264 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
265
266 ucontrol->value.integer.value[0] = tas_priv->cur_conf;
267
268 return 0;
269}
270
271static int tasdevice_config_put(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
273{
274 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
275 struct tasdevice_fw *tas_fw = tas_priv->fmw;
276 int nr_config = ucontrol->value.integer.value[0];
277 int max = tas_fw->nr_configurations - 1;
278 int val, ret = 0;
279
280 val = tasdevice_hda_clamp(nr_config, max);
281
282 if (tas_priv->cur_conf != val) {
283 tas_priv->cur_conf = val;
284 ret = 1;
285 }
286
287 return ret;
288}
289
290/*
291 * tas2781_digital_getvol - get the volum control
292 * @kcontrol: control pointer
293 * @ucontrol: User data
294 * Customer Kcontrol for tas2781 is primarily for regmap booking, paging
295 * depends on internal regmap mechanism.
296 * tas2781 contains book and page two-level register map, especially
297 * book switching will set the register BXXP00R7F, after switching to the
298 * correct book, then leverage the mechanism for paging to access the
299 * register.
300 */
301static int tas2781_digital_getvol(struct snd_kcontrol *kcontrol,
302 struct snd_ctl_elem_value *ucontrol)
303{
304 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
305 struct soc_mixer_control *mc =
306 (struct soc_mixer_control *)kcontrol->private_value;
307
308 return tasdevice_digital_getvol(tas_priv, ucontrol, mc);
309}
310
311static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
313{
314 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
315 struct soc_mixer_control *mc =
316 (struct soc_mixer_control *)kcontrol->private_value;
317
318 return tasdevice_amp_getvol(tas_priv, ucontrol, mc);
319}
320
321static int tas2781_digital_putvol(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol)
323{
324 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
325 struct soc_mixer_control *mc =
326 (struct soc_mixer_control *)kcontrol->private_value;
327
328 /* The check of the given value is in tasdevice_digital_putvol. */
329 return tasdevice_digital_putvol(tas_priv, ucontrol, mc);
330}
331
332static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,
333 struct snd_ctl_elem_value *ucontrol)
334{
335 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
336 struct soc_mixer_control *mc =
337 (struct soc_mixer_control *)kcontrol->private_value;
338
339 /* The check of the given value is in tasdevice_amp_putvol. */
340 return tasdevice_amp_putvol(tas_priv, ucontrol, mc);
341}
342
343static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,
344 struct snd_ctl_elem_value *ucontrol)
345{
346 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
347
348 ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;
349 dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
350 tas_priv->force_fwload_status ? "ON" : "OFF");
351
352 return 0;
353}
354
355static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
356 struct snd_ctl_elem_value *ucontrol)
357{
358 struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);
359 bool change, val = (bool)ucontrol->value.integer.value[0];
360
361 if (tas_priv->force_fwload_status == val)
362 change = false;
363 else {
364 change = true;
365 tas_priv->force_fwload_status = val;
366 }
367 dev_dbg(tas_priv->dev, "%s : Force FWload %s\n", __func__,
368 tas_priv->force_fwload_status ? "ON" : "OFF");
369
370 return change;
371}
372
373static const struct snd_kcontrol_new tas2781_snd_controls[] = {
374 ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Gain", TAS2781_AMP_LEVEL,
375 1, 0, 20, 0, tas2781_amp_getvol,
376 tas2781_amp_putvol, amp_vol_tlv),
377 ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Gain", TAS2781_DVC_LVL,
378 0, 0, 200, 1, tas2781_digital_getvol,
379 tas2781_digital_putvol, dvc_tlv),
380 ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,
381 tas2781_force_fwload_get, tas2781_force_fwload_put),
382};
383
384static const struct snd_kcontrol_new tas2781_prof_ctrl = {
385 .name = "Speaker Profile Id",
386 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
387 .info = tasdevice_info_profile,
388 .get = tasdevice_get_profile_id,
389 .put = tasdevice_set_profile_id,
390};
391
392static const struct snd_kcontrol_new tas2781_dsp_prog_ctrl = {
393 .name = "Speaker Program Id",
394 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
395 .info = tasdevice_info_programs,
396 .get = tasdevice_program_get,
397 .put = tasdevice_program_put,
398};
399
400static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = {
401 .name = "Speaker Config Id",
402 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
403 .info = tasdevice_info_config,
404 .get = tasdevice_config_get,
405 .put = tasdevice_config_put,
406};
407
408static void tas2781_apply_calib(struct tasdevice_priv *tas_priv)
409{
410 static const unsigned char page_array[CALIB_MAX] = {
411 0x17, 0x18, 0x18, 0x0d, 0x18
412 };
413 static const unsigned char rgno_array[CALIB_MAX] = {
414 0x74, 0x0c, 0x14, 0x3c, 0x7c
415 };
416 unsigned char *data;
417 int i, j, rc;
418
419 for (i = 0; i < tas_priv->ndev; i++) {
420 data = tas_priv->cali_data.data +
421 i * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
422 for (j = 0; j < CALIB_MAX; j++) {
423 rc = tasdevice_dev_bulk_write(tas_priv, i,
424 TASDEVICE_REG(0, page_array[j], rgno_array[j]),
425 &(data[4 * j]), 4);
426 if (rc < 0)
427 dev_err(tas_priv->dev,
428 "chn %d calib %d bulk_wr err = %d\n",
429 i, j, rc);
430 }
431 }
432}
433
434/* Update the calibrate data, including speaker impedance, f0, etc, into algo.
435 * Calibrate data is done by manufacturer in the factory. These data are used
436 * by Algo for calucating the speaker temperature, speaker membrance excursion
437 * and f0 in real time during playback.
438 */
439static int tas2781_save_calibration(struct tasdevice_priv *tas_priv)
440{
441 efi_guid_t efi_guid = EFI_GUID(0x02f9af02, 0x7734, 0x4233, 0xb4, 0x3d,
442 0x93, 0xfe, 0x5a, 0xa3, 0x5d, 0xb3);
443 static efi_char16_t efi_name[] = L"CALI_DATA";
444 struct tm *tm = &tas_priv->tm;
445 unsigned int attr, crc;
446 unsigned int *tmp_val;
447 efi_status_t status;
448
449 /* Lenovo devices */
450 if (tas_priv->catlog_id == LENOVO)
451 efi_guid = EFI_GUID(0x1f52d2a1, 0xbb3a, 0x457d, 0xbc, 0x09,
452 0x43, 0xa3, 0xf4, 0x31, 0x0a, 0x92);
453
454 tas_priv->cali_data.total_sz = 0;
455 /* Get real size of UEFI variable */
456 status = efi.get_variable(efi_name, &efi_guid, &attr,
457 &tas_priv->cali_data.total_sz, tas_priv->cali_data.data);
458 if (status == EFI_BUFFER_TOO_SMALL) {
459 /* Allocate data buffer of data_size bytes */
460 tas_priv->cali_data.data = devm_kzalloc(tas_priv->dev,
461 tas_priv->cali_data.total_sz, GFP_KERNEL);
462 if (!tas_priv->cali_data.data)
463 return -ENOMEM;
464 /* Get variable contents into buffer */
465 status = efi.get_variable(efi_name, &efi_guid, &attr,
466 &tas_priv->cali_data.total_sz,
467 tas_priv->cali_data.data);
468 if (status != EFI_SUCCESS)
469 return -EINVAL;
470 }
471
472 tmp_val = (unsigned int *)tas_priv->cali_data.data;
473
474 crc = crc32(~0, tas_priv->cali_data.data, 84) ^ ~0;
475 dev_dbg(tas_priv->dev, "cali crc 0x%08x PK tmp_val 0x%08x\n",
476 crc, tmp_val[21]);
477
478 if (crc == tmp_val[21]) {
479 time64_to_tm(tmp_val[20], 0, tm);
480 dev_dbg(tas_priv->dev, "%4ld-%2d-%2d, %2d:%2d:%2d\n",
481 tm->tm_year, tm->tm_mon, tm->tm_mday,
482 tm->tm_hour, tm->tm_min, tm->tm_sec);
483 tas2781_apply_calib(tas_priv);
484 } else
485 tas_priv->cali_data.total_sz = 0;
486
487 return 0;
488}
489
490static void tasdev_fw_ready(const struct firmware *fmw, void *context)
491{
492 struct tasdevice_priv *tas_priv = context;
493 struct hda_codec *codec = tas_priv->codec;
494 int i, ret;
495
496 pm_runtime_get_sync(tas_priv->dev);
497 mutex_lock(&tas_priv->codec_lock);
498
499 ret = tasdevice_rca_parser(tas_priv, fmw);
500 if (ret)
501 goto out;
502
503 ret = snd_ctl_add(codec->card,
504 snd_ctl_new1(&tas2781_prof_ctrl, tas_priv));
505 if (ret) {
506 dev_err(tas_priv->dev,
507 "Failed to add KControl %s = %d\n",
508 tas2781_prof_ctrl.name, ret);
509 goto out;
510 }
511
512 for (i = 0; i < ARRAY_SIZE(tas2781_snd_controls); i++) {
513 ret = snd_ctl_add(codec->card,
514 snd_ctl_new1(&tas2781_snd_controls[i], tas_priv));
515 if (ret) {
516 dev_err(tas_priv->dev,
517 "Failed to add KControl %s = %d\n",
518 tas2781_snd_controls[i].name, ret);
519 goto out;
520 }
521 }
522
523 tasdevice_dsp_remove(tas_priv);
524
525 tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
526 scnprintf(tas_priv->coef_binaryname, 64, "TAS2XXX%04X.bin",
527 codec->core.subsystem_id & 0xffff);
528 ret = tasdevice_dsp_parser(tas_priv);
529 if (ret) {
530 dev_err(tas_priv->dev, "dspfw load %s error\n",
531 tas_priv->coef_binaryname);
532 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
533 goto out;
534 }
535
536 ret = snd_ctl_add(codec->card,
537 snd_ctl_new1(&tas2781_dsp_prog_ctrl, tas_priv));
538 if (ret) {
539 dev_err(tas_priv->dev,
540 "Failed to add KControl %s = %d\n",
541 tas2781_dsp_prog_ctrl.name, ret);
542 goto out;
543 }
544
545 ret = snd_ctl_add(codec->card,
546 snd_ctl_new1(&tas2781_dsp_conf_ctrl, tas_priv));
547 if (ret) {
548 dev_err(tas_priv->dev,
549 "Failed to add KControl %s = %d\n",
550 tas2781_dsp_conf_ctrl.name, ret);
551 goto out;
552 }
553
554 tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
555 tasdevice_prmg_load(tas_priv, 0);
556
557 /* If calibrated data occurs error, dsp will still works with default
558 * calibrated data inside algo.
559 */
560 tas2781_save_calibration(tas_priv);
561
562out:
563 if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
564 /*If DSP FW fail, kcontrol won't be created */
565 tasdevice_config_info_remove(tas_priv);
566 tasdevice_dsp_remove(tas_priv);
567 }
568 mutex_unlock(&tas_priv->codec_lock);
569 if (fmw)
570 release_firmware(fmw);
571 pm_runtime_mark_last_busy(tas_priv->dev);
572 pm_runtime_put_autosuspend(tas_priv->dev);
573}
574
575static int tas2781_hda_bind(struct device *dev, struct device *master,
576 void *master_data)
577{
578 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
579 struct hda_component *comps = master_data;
580 struct hda_codec *codec;
581 unsigned int subid;
582 int ret;
583
584 if (!comps || tas_priv->index < 0 ||
585 tas_priv->index >= HDA_MAX_COMPONENTS)
586 return -EINVAL;
587
588 comps = &comps[tas_priv->index];
589 if (comps->dev)
590 return -EBUSY;
591
592 codec = comps->codec;
593 subid = codec->core.subsystem_id >> 16;
594
595 switch (subid) {
596 case 0x17aa:
597 tas_priv->catlog_id = LENOVO;
598 break;
599 default:
600 tas_priv->catlog_id = OTHERS;
601 break;
602 }
603
604 pm_runtime_get_sync(dev);
605
606 comps->dev = dev;
607
608 strscpy(comps->name, dev_name(dev), sizeof(comps->name));
609
610 ret = tascodec_init(tas_priv, codec, tasdev_fw_ready);
611 if (!ret)
612 comps->playback_hook = tas2781_hda_playback_hook;
613
614 pm_runtime_mark_last_busy(dev);
615 pm_runtime_put_autosuspend(dev);
616
617 return ret;
618}
619
620static void tas2781_hda_unbind(struct device *dev,
621 struct device *master, void *master_data)
622{
623 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
624 struct hda_component *comps = master_data;
625
626 if (comps[tas_priv->index].dev == dev)
627 memset(&comps[tas_priv->index], 0, sizeof(*comps));
628
629 tasdevice_config_info_remove(tas_priv);
630 tasdevice_dsp_remove(tas_priv);
631
632 tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
633}
634
635static const struct component_ops tas2781_hda_comp_ops = {
636 .bind = tas2781_hda_bind,
637 .unbind = tas2781_hda_unbind,
638};
639
640static void tas2781_hda_remove(struct device *dev)
641{
642 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
643
644 pm_runtime_get_sync(tas_priv->dev);
645 pm_runtime_disable(tas_priv->dev);
646
647 component_del(tas_priv->dev, &tas2781_hda_comp_ops);
648
649 pm_runtime_put_noidle(tas_priv->dev);
650
651 tasdevice_remove(tas_priv);
652}
653
654static int tas2781_hda_i2c_probe(struct i2c_client *clt)
655{
656 struct tasdevice_priv *tas_priv;
657 const char *device_name;
658 int ret;
659
660 if (strstr(dev_name(&clt->dev), "TIAS2781"))
661 device_name = "TIAS2781";
662 else
663 return -ENODEV;
664
665 tas_priv = tasdevice_kzalloc(clt);
666 if (!tas_priv)
667 return -ENOMEM;
668
669 tas_priv->irq_info.irq = clt->irq;
670 ret = tas2781_read_acpi(tas_priv, device_name);
671 if (ret)
672 return dev_err_probe(tas_priv->dev, ret,
673 "Platform not supported\n");
674
675 ret = tasdevice_init(tas_priv);
676 if (ret)
677 goto err;
678
679 pm_runtime_set_autosuspend_delay(tas_priv->dev, 3000);
680 pm_runtime_use_autosuspend(tas_priv->dev);
681 pm_runtime_mark_last_busy(tas_priv->dev);
682 pm_runtime_set_active(tas_priv->dev);
683 pm_runtime_get_noresume(tas_priv->dev);
684 pm_runtime_enable(tas_priv->dev);
685
686 pm_runtime_put_autosuspend(tas_priv->dev);
687
688 ret = component_add(tas_priv->dev, &tas2781_hda_comp_ops);
689 if (ret) {
690 dev_err(tas_priv->dev, "Register component failed: %d\n", ret);
691 pm_runtime_disable(tas_priv->dev);
692 goto err;
693 }
694
695 tas2781_reset(tas_priv);
696err:
697 if (ret)
698 tas2781_hda_remove(&clt->dev);
699 return ret;
700}
701
702static void tas2781_hda_i2c_remove(struct i2c_client *clt)
703{
704 tas2781_hda_remove(&clt->dev);
705}
706
707static int tas2781_runtime_suspend(struct device *dev)
708{
709 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
710 int i;
711
712 dev_dbg(tas_priv->dev, "Runtime Suspend\n");
713
714 mutex_lock(&tas_priv->codec_lock);
715
716 if (tas_priv->playback_started) {
717 tasdevice_tuning_switch(tas_priv, 1);
718 tas_priv->playback_started = false;
719 }
720
721 for (i = 0; i < tas_priv->ndev; i++) {
722 tas_priv->tasdevice[i].cur_book = -1;
723 tas_priv->tasdevice[i].cur_prog = -1;
724 tas_priv->tasdevice[i].cur_conf = -1;
725 }
726
727 regcache_cache_only(tas_priv->regmap, true);
728 regcache_mark_dirty(tas_priv->regmap);
729
730 mutex_unlock(&tas_priv->codec_lock);
731
732 return 0;
733}
734
735static int tas2781_runtime_resume(struct device *dev)
736{
737 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
738 unsigned long calib_data_sz =
739 tas_priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
740 int ret;
741
742 dev_dbg(tas_priv->dev, "Runtime Resume\n");
743
744 mutex_lock(&tas_priv->codec_lock);
745
746 regcache_cache_only(tas_priv->regmap, false);
747 ret = regcache_sync(tas_priv->regmap);
748 if (ret) {
749 dev_err(tas_priv->dev,
750 "Failed to restore register cache: %d\n", ret);
751 goto out;
752 }
753
754 tasdevice_prmg_load(tas_priv, tas_priv->cur_prog);
755
756 /* If calibrated data occurs error, dsp will still works with default
757 * calibrated data inside algo.
758 */
759 if (tas_priv->cali_data.total_sz > calib_data_sz)
760 tas2781_apply_calib(tas_priv);
761
762out:
763 mutex_unlock(&tas_priv->codec_lock);
764
765 return ret;
766}
767
768static int tas2781_system_suspend(struct device *dev)
769{
770 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
771 int ret;
772
773 dev_dbg(tas_priv->dev, "System Suspend\n");
774
775 ret = pm_runtime_force_suspend(dev);
776 if (ret)
777 return ret;
778
779 /* Shutdown chip before system suspend */
780 regcache_cache_only(tas_priv->regmap, false);
781 tasdevice_tuning_switch(tas_priv, 1);
782 regcache_cache_only(tas_priv->regmap, true);
783 regcache_mark_dirty(tas_priv->regmap);
784
785 /*
786 * Reset GPIO may be shared, so cannot reset here.
787 * However beyond this point, amps may be powered down.
788 */
789 return 0;
790}
791
792static int tas2781_system_resume(struct device *dev)
793{
794 struct tasdevice_priv *tas_priv = dev_get_drvdata(dev);
795 unsigned long calib_data_sz =
796 tas_priv->ndev * TASDEVICE_SPEAKER_CALIBRATION_SIZE;
797 int i, ret;
798
799 dev_dbg(tas_priv->dev, "System Resume\n");
800
801 ret = pm_runtime_force_resume(dev);
802 if (ret)
803 return ret;
804
805 mutex_lock(&tas_priv->codec_lock);
806
807 for (i = 0; i < tas_priv->ndev; i++) {
808 tas_priv->tasdevice[i].cur_book = -1;
809 tas_priv->tasdevice[i].cur_prog = -1;
810 tas_priv->tasdevice[i].cur_conf = -1;
811 }
812 tas2781_reset(tas_priv);
813 tasdevice_prmg_load(tas_priv, tas_priv->cur_prog);
814
815 /* If calibrated data occurs error, dsp will still work with default
816 * calibrated data inside algo.
817 */
818 if (tas_priv->cali_data.total_sz > calib_data_sz)
819 tas2781_apply_calib(tas_priv);
820 mutex_unlock(&tas_priv->codec_lock);
821
822 return 0;
823}
824
825static const struct dev_pm_ops tas2781_hda_pm_ops = {
826 RUNTIME_PM_OPS(tas2781_runtime_suspend, tas2781_runtime_resume, NULL)
827 SYSTEM_SLEEP_PM_OPS(tas2781_system_suspend, tas2781_system_resume)
828};
829
830static const struct i2c_device_id tas2781_hda_i2c_id[] = {
831 { "tas2781-hda", 0 },
832 {}
833};
834
835static const struct acpi_device_id tas2781_acpi_hda_match[] = {
836 {"TIAS2781", 0 },
837 {}
838};
839MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);
840
841static struct i2c_driver tas2781_hda_i2c_driver = {
842 .driver = {
843 .name = "tas2781-hda",
844 .acpi_match_table = tas2781_acpi_hda_match,
845 .pm = &tas2781_hda_pm_ops,
846 },
847 .id_table = tas2781_hda_i2c_id,
848 .probe = tas2781_hda_i2c_probe,
849 .remove = tas2781_hda_i2c_remove,
850};
851module_i2c_driver(tas2781_hda_i2c_driver);
852
853MODULE_DESCRIPTION("TAS2781 HDA Driver");
854MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");
855MODULE_LICENSE("GPL");
856MODULE_IMPORT_NS(SND_SOC_TAS2781_FMWLIB);
sound/pci/ice1712/juli.c+3−25
@@ -408,30 +408,6 @@ static const char * const follower_vols[] = { · 407 unmodified lines
408static408static
409DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1);409DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1);
410 410
411static struct snd_kcontrol *ctl_find(struct snd_card *card,
412 const char *name)
413{
414 struct snd_ctl_elem_id sid = {0};
415
416 strscpy(sid.name, name, sizeof(sid.name));
417 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
418 return snd_ctl_find_id(card, &sid);
419}
420
421static void add_followers(struct snd_card *card,
422 struct snd_kcontrol *master,
423 const char * const *list)
424{
425 for (; *list; list++) {
426 struct snd_kcontrol *follower = ctl_find(card, *list);
427 /* dev_dbg(card->dev, "add_followers - %s\n", *list); */
428 if (follower) {
429 /* dev_dbg(card->dev, "follower %s found\n", *list); */
430 snd_ctl_add_follower(master, follower);
431 }
432 }
433}
434
435static int juli_add_controls(struct snd_ice1712 *ice)411static int juli_add_controls(struct snd_ice1712 *ice)
436{412{
437 struct juli_spec *spec = ice->spec;413 struct juli_spec *spec = ice->spec;
@@ -454,8 +430,10 @@ static int juli_add_controls(struct snd_ice1712 *ice) · 16 unmodified lines
454 juli_master_db_scale);430 juli_master_db_scale);
455 if (!vmaster)431 if (!vmaster)
456 return -ENOMEM;432 return -ENOMEM;
457 add_followers(ice->card, vmaster, follower_vols);
458 err = snd_ctl_add(ice->card, vmaster);433 err = snd_ctl_add(ice->card, vmaster);
434 if (err < 0)
435 return err;
436 err = snd_ctl_add_followers(ice->card, vmaster, follower_vols);
459 if (err < 0)437 if (err < 0)
460 return err;438 return err;
461 439
sound/pci/ice1712/psc724.c+8−11
@@ -177,7 +177,6 @@ static bool psc724_get_master_switch(struct snd_ice1712 *ice) · 176 unmodified lines
177static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected)177static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected)
178{178{
179 struct psc724_spec *spec = ice->spec;179 struct psc724_spec *spec = ice->spec;
180 struct snd_ctl_elem_id elem_id;
181 struct snd_kcontrol *kctl;180 struct snd_kcontrol *kctl;
182 u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD;181 u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD;
183 182
@@ -187,17 +186,15 @@ static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected) · 3 unmodified lines
187 snd_wm8776_set_power(&spec->wm8776, power);186 snd_wm8776_set_power(&spec->wm8776, power);
188 spec->hp_connected = hp_connected;187 spec->hp_connected = hp_connected;
189 /* notify about master speaker mute change */188 /* notify about master speaker mute change */
190 memset(&elem_id, 0, sizeof(elem_id));189 kctl = snd_ctl_find_id_mixer(ice->card,
191 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;190 "Master Speakers Playback Switch");
192 strscpy(elem_id.name, "Master Speakers Playback Switch",191 if (kctl)
193 sizeof(elem_id.name));192 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
194 kctl = snd_ctl_find_id(ice->card, &elem_id);
195 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
196 /* and headphone mute change */193 /* and headphone mute change */
197 strscpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name,194 kctl = snd_ctl_find_id_mixer(ice->card,
198 sizeof(elem_id.name));195 spec->wm8776.ctl[WM8776_CTL_HP_SW].name);
199 kctl = snd_ctl_find_id(ice->card, &elem_id);196 if (kctl)
200 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);197 snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
201}198}
202 199
203static void psc724_update_hp_jack_state(struct work_struct *work)200static void psc724_update_hp_jack_state(struct work_struct *work)
sound/pci/ice1712/quartet.c+3−21
@@ -766,26 +766,6 @@ static const char * const follower_vols[] = { · 765 unmodified lines
766static766static
767DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);767DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);
768 768
769static struct snd_kcontrol *ctl_find(struct snd_card *card,
770 const char *name)
771{
772 struct snd_ctl_elem_id sid = {0};
773
774 strscpy(sid.name, name, sizeof(sid.name));
775 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
776 return snd_ctl_find_id(card, &sid);
777}
778
779static void add_followers(struct snd_card *card,
780 struct snd_kcontrol *master, const char * const *list)
781{
782 for (; *list; list++) {
783 struct snd_kcontrol *follower = ctl_find(card, *list);
784 if (follower)
785 snd_ctl_add_follower(master, follower);
786 }
787}
788
789static int qtet_add_controls(struct snd_ice1712 *ice)769static int qtet_add_controls(struct snd_ice1712 *ice)
790{770{
791 struct qtet_spec *spec = ice->spec;771 struct qtet_spec *spec = ice->spec;
@@ -806,8 +786,10 @@ static int qtet_add_controls(struct snd_ice1712 *ice) · 14 unmodified lines
806 qtet_master_db_scale);786 qtet_master_db_scale);
807 if (!vmaster)787 if (!vmaster)
808 return -ENOMEM;788 return -ENOMEM;
809 add_followers(ice->card, vmaster, follower_vols);
810 err = snd_ctl_add(ice->card, vmaster);789 err = snd_ctl_add(ice->card, vmaster);
790 if (err < 0)
791 return err;
792 err = snd_ctl_add_followers(ice->card, vmaster, follower_vols);
811 if (err < 0)793 if (err < 0)
812 return err;794 return err;
813 /* only capture SPDIF over AK4113 */795 /* only capture SPDIF over AK4113 */
sound/pci/ice1712/wm8776.c+1−5
@@ -34,13 +34,9 @@ static void snd_wm8776_activate_ctl(struct snd_wm8776 *wm, · 33 unmodified lines
34 struct snd_card *card = wm->card;34 struct snd_card *card = wm->card;
35 struct snd_kcontrol *kctl;35 struct snd_kcontrol *kctl;
36 struct snd_kcontrol_volatile *vd;36 struct snd_kcontrol_volatile *vd;
37 struct snd_ctl_elem_id elem_id;
38 unsigned int index_offset;37 unsigned int index_offset;
39 38
40 memset(&elem_id, 0, sizeof(elem_id));39 kctl = snd_ctl_find_id_mixer(card, ctl_name);
41 strscpy(elem_id.name, ctl_name, sizeof(elem_id.name));
42 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
43 kctl = snd_ctl_find_id(card, &elem_id);
44 if (!kctl)40 if (!kctl)
45 return;41 return;
46 index_offset = snd_ctl_get_ioff(kctl, &kctl->id);42 index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
sound/pci/korg1212/korg1212.c+12−38
@@ -1285,8 +1285,7 @@ static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int coun · 1284 unmodified lines
1285}1285}
1286 1286
1287static int snd_korg1212_copy_to(struct snd_pcm_substream *substream,1287static int snd_korg1212_copy_to(struct snd_pcm_substream *substream,
1288 void __user *dst, int pos, int count,1288 struct iov_iter *dst, int pos, int count)
1289 bool in_kernel)
1290{1289{
1291 struct snd_pcm_runtime *runtime = substream->runtime;1290 struct snd_pcm_runtime *runtime = substream->runtime;
1292 struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);1291 struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
@@ -1306,24 +1305,20 @@ static int snd_korg1212_copy_to(struct snd_pcm_substream *substream, · 13 unmodified lines
1306#if K1212_DEBUG_LEVEL > 01305#if K1212_DEBUG_LEVEL > 0
1307 if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||1306 if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
1308 (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {1307 (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
1309 printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);1308 printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst->kvec.iov_base, i);
1310 return -EFAULT;1309 return -EFAULT;
1311 }1310 }
1312#endif1311#endif
1313 if (in_kernel)1312 if (copy_to_iter(src, size, dst) != size)
1314 memcpy((__force void *)dst, src, size);
1315 else if (copy_to_user(dst, src, size))
1316 return -EFAULT;1313 return -EFAULT;
1317 src++;1314 src++;
1318 dst += size;
1319 }1315 }
1320 1316
1321 return 0;1317 return 0;
1322}1318}
1323 1319
1324static int snd_korg1212_copy_from(struct snd_pcm_substream *substream,1320static int snd_korg1212_copy_from(struct snd_pcm_substream *substream,
1325 void __user *src, int pos, int count,1321 struct iov_iter *src, int pos, int count)
1326 bool in_kernel)
1327{1322{
1328 struct snd_pcm_runtime *runtime = substream->runtime;1323 struct snd_pcm_runtime *runtime = substream->runtime;
1329 struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);1324 struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
@@ -1345,16 +1340,13 @@ static int snd_korg1212_copy_from(struct snd_pcm_substream *substream, · 15 unmodified lines
1345#if K1212_DEBUG_LEVEL > 01340#if K1212_DEBUG_LEVEL > 0
1346 if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||1341 if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
1347 (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {1342 (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
1348 printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);1343 printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src->kvec.iov_base, dst, i);
1349 return -EFAULT;1344 return -EFAULT;
1350 }1345 }
1351#endif1346#endif
1352 if (in_kernel)1347 if (copy_from_iter(dst, size, src) != size)
1353 memcpy(dst, (__force void *)src, size);
1354 else if (copy_from_user(dst, src, size))
1355 return -EFAULT;1348 return -EFAULT;
1356 dst++;1349 dst++;
1357 src += size;
1358 }1350 }
1359 1351
1360 return 0;1352 return 0;
@@ -1642,17 +1634,9 @@ static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream * · 281 unmodified lines
1642 1634
1643static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,1635static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
1644 int channel, unsigned long pos,1636 int channel, unsigned long pos,
1645 void __user *src, unsigned long count)1637 struct iov_iter *src, unsigned long count)
1646{1638{
1647 return snd_korg1212_copy_from(substream, src, pos, count, false);1639 return snd_korg1212_copy_from(substream, src, pos, count);
1648}
1649
1650static int snd_korg1212_playback_copy_kernel(struct snd_pcm_substream *substream,
1651 int channel, unsigned long pos,
1652 void *src, unsigned long count)
1653{
1654 return snd_korg1212_copy_from(substream, (void __user *)src,
1655 pos, count, true);
1656}1640}
1657 1641
1658static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,1642static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,
@@ -1670,17 +1654,9 @@ static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream, · 11 unmodified lines
1670 1654
1671static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,1655static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
1672 int channel, unsigned long pos,1656 int channel, unsigned long pos,
1673 void __user *dst, unsigned long count)1657 struct iov_iter *dst, unsigned long count)
1674{
1675 return snd_korg1212_copy_to(substream, dst, pos, count, false);
1676}
1677
1678static int snd_korg1212_capture_copy_kernel(struct snd_pcm_substream *substream,
1679 int channel, unsigned long pos,
1680 void *dst, unsigned long count)
1681{1658{
1682 return snd_korg1212_copy_to(substream, (void __user *)dst,1659 return snd_korg1212_copy_to(substream, dst, pos, count);
1683 pos, count, true);
1684}1660}
1685 1661
1686static const struct snd_pcm_ops snd_korg1212_playback_ops = {1662static const struct snd_pcm_ops snd_korg1212_playback_ops = {
@@ -1691,8 +1667,7 @@ static const struct snd_pcm_ops snd_korg1212_playback_ops = { · 4 unmodified lines
1691 .prepare = snd_korg1212_prepare,1667 .prepare = snd_korg1212_prepare,
1692 .trigger = snd_korg1212_trigger,1668 .trigger = snd_korg1212_trigger,
1693 .pointer = snd_korg1212_playback_pointer,1669 .pointer = snd_korg1212_playback_pointer,
1694 .copy_user = snd_korg1212_playback_copy,1670 .copy = snd_korg1212_playback_copy,
1695 .copy_kernel = snd_korg1212_playback_copy_kernel,
1696 .fill_silence = snd_korg1212_playback_silence,1671 .fill_silence = snd_korg1212_playback_silence,
1697};1672};
1698 1673
@@ -1704,8 +1679,7 @@ static const struct snd_pcm_ops snd_korg1212_capture_ops = { · 5 unmodified lines
1704 .prepare = snd_korg1212_prepare,1679 .prepare = snd_korg1212_prepare,
1705 .trigger = snd_korg1212_trigger,1680 .trigger = snd_korg1212_trigger,
1706 .pointer = snd_korg1212_capture_pointer,1681 .pointer = snd_korg1212_capture_pointer,
1707 .copy_user = snd_korg1212_capture_copy,1682 .copy = snd_korg1212_capture_copy,
1708 .copy_kernel = snd_korg1212_capture_copy_kernel,
1709};1683};
1710 1684
1711/*1685/*
sound/pci/maestro3.c+4−11
@@ -2029,9 +2029,6 @@ static int snd_m3_mixer(struct snd_m3 *chip) · 2028 unmodified lines
2029{2029{
2030 struct snd_ac97_bus *pbus;2030 struct snd_ac97_bus *pbus;
2031 struct snd_ac97_template ac97;2031 struct snd_ac97_template ac97;
2032#ifndef CONFIG_SND_MAESTRO3_INPUT
2033 struct snd_ctl_elem_id elem_id;
2034#endif
2035 int err;2032 int err;
2036 static const struct snd_ac97_bus_ops ops = {2033 static const struct snd_ac97_bus_ops ops = {
2037 .write = snd_m3_ac97_write,2034 .write = snd_m3_ac97_write,
@@ -2054,14 +2051,10 @@ static int snd_m3_mixer(struct snd_m3 *chip) · 16 unmodified lines
2054 snd_ac97_write(chip->ac97, AC97_PCM, 0);2051 snd_ac97_write(chip->ac97, AC97_PCM, 0);
2055 2052
2056#ifndef CONFIG_SND_MAESTRO3_INPUT2053#ifndef CONFIG_SND_MAESTRO3_INPUT
2057 memset(&elem_id, 0, sizeof(elem_id));2054 chip->master_switch = snd_ctl_find_id_mixer(chip->card,
2058 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;2055 "Master Playback Switch");
2059 strcpy(elem_id.name, "Master Playback Switch");2056 chip->master_volume = snd_ctl_find_id_mixer(chip->card,
2060 chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);2057 "Master Playback Volume");
2061 memset(&elem_id, 0, sizeof(elem_id));
2062 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2063 strcpy(elem_id.name, "Master Playback Volume");
2064 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2065#endif2058#endif
2066 2059
2067 return 0;2060 return 0;
sound/pci/nm256/nm256.c+6−36
@@ -691,26 +691,12 @@ snd_nm256_playback_silence(struct snd_pcm_substream *substream, · 690 unmodified lines
691static int691static int
692snd_nm256_playback_copy(struct snd_pcm_substream *substream,692snd_nm256_playback_copy(struct snd_pcm_substream *substream,
693 int channel, unsigned long pos,693 int channel, unsigned long pos,
694 void __user *src, unsigned long count)694 struct iov_iter *src, unsigned long count)
695{695{
696 struct snd_pcm_runtime *runtime = substream->runtime;696 struct snd_pcm_runtime *runtime = substream->runtime;
697 struct nm256_stream *s = runtime->private_data;697 struct nm256_stream *s = runtime->private_data;
698 698
699 if (copy_from_user_toio(s->bufptr + pos, src, count))699 return copy_from_iter_toio(s->bufptr + pos, src, count);
700 return -EFAULT;
701 return 0;
702}
703
704static int
705snd_nm256_playback_copy_kernel(struct snd_pcm_substream *substream,
706 int channel, unsigned long pos,
707 void *src, unsigned long count)
708{
709 struct snd_pcm_runtime *runtime = substream->runtime;
710 struct nm256_stream *s = runtime->private_data;
711
712 memcpy_toio(s->bufptr + pos, src, count);
713 return 0;
714}700}
715 701
716/*702/*
@@ -719,26 +705,12 @@ snd_nm256_playback_copy_kernel(struct snd_pcm_substream *substream, · 2 unmodified lines
719static int705static int
720snd_nm256_capture_copy(struct snd_pcm_substream *substream,706snd_nm256_capture_copy(struct snd_pcm_substream *substream,
721 int channel, unsigned long pos,707 int channel, unsigned long pos,
722 void __user *dst, unsigned long count)708 struct iov_iter *dst, unsigned long count)
723{709{
724 struct snd_pcm_runtime *runtime = substream->runtime;710 struct snd_pcm_runtime *runtime = substream->runtime;
725 struct nm256_stream *s = runtime->private_data;711 struct nm256_stream *s = runtime->private_data;
726 712
727 if (copy_to_user_fromio(dst, s->bufptr + pos, count))713 return copy_to_iter_fromio(dst, s->bufptr + pos, count);
728 return -EFAULT;
729 return 0;
730}
731
732static int
733snd_nm256_capture_copy_kernel(struct snd_pcm_substream *substream,
734 int channel, unsigned long pos,
735 void *dst, unsigned long count)
736{
737 struct snd_pcm_runtime *runtime = substream->runtime;
738 struct nm256_stream *s = runtime->private_data;
739
740 memcpy_fromio(dst, s->bufptr + pos, count);
741 return 0;
742}714}
743 715
744#endif /* !__i386__ */716#endif /* !__i386__ */
@@ -909,8 +881,7 @@ static const struct snd_pcm_ops snd_nm256_playback_ops = { · 164 unmodified lines
909 .trigger = snd_nm256_playback_trigger,881 .trigger = snd_nm256_playback_trigger,
910 .pointer = snd_nm256_playback_pointer,882 .pointer = snd_nm256_playback_pointer,
911#ifndef __i386__883#ifndef __i386__
912 .copy_user = snd_nm256_playback_copy,884 .copy = snd_nm256_playback_copy,
913 .copy_kernel = snd_nm256_playback_copy_kernel,
914 .fill_silence = snd_nm256_playback_silence,885 .fill_silence = snd_nm256_playback_silence,
915#endif886#endif
916 .mmap = snd_pcm_lib_mmap_iomem,887 .mmap = snd_pcm_lib_mmap_iomem,
@@ -924,8 +895,7 @@ static const struct snd_pcm_ops snd_nm256_capture_ops = { · 7 unmodified lines
924 .trigger = snd_nm256_capture_trigger,895 .trigger = snd_nm256_capture_trigger,
925 .pointer = snd_nm256_capture_pointer,896 .pointer = snd_nm256_capture_pointer,
926#ifndef __i386__897#ifndef __i386__
927 .copy_user = snd_nm256_capture_copy,898 .copy = snd_nm256_capture_copy,
928 .copy_kernel = snd_nm256_capture_copy_kernel,
929#endif899#endif
930 .mmap = snd_pcm_lib_mmap_iomem,900 .mmap = snd_pcm_lib_mmap_iomem,
931};901};
sound/pci/rme32.c+11−39
@@ -252,48 +252,24 @@ static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, · 251 unmodified lines
252/* copy callback for halfduplex mode */252/* copy callback for halfduplex mode */
253static int snd_rme32_playback_copy(struct snd_pcm_substream *substream,253static int snd_rme32_playback_copy(struct snd_pcm_substream *substream,
254 int channel, unsigned long pos,254 int channel, unsigned long pos,
255 void __user *src, unsigned long count)255 struct iov_iter *src, unsigned long count)
256{256{
257 struct rme32 *rme32 = snd_pcm_substream_chip(substream);257 struct rme32 *rme32 = snd_pcm_substream_chip(substream);
258 258
259 if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,259 return copy_from_iter_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
260 src, count))260 src, count);
261 return -EFAULT;
262 return 0;
263}
264
265static int snd_rme32_playback_copy_kernel(struct snd_pcm_substream *substream,
266 int channel, unsigned long pos,
267 void *src, unsigned long count)
268{
269 struct rme32 *rme32 = snd_pcm_substream_chip(substream);
270
271 memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos, src, count);
272 return 0;
273}261}
274 262
275/* copy callback for halfduplex mode */263/* copy callback for halfduplex mode */
276static int snd_rme32_capture_copy(struct snd_pcm_substream *substream,264static int snd_rme32_capture_copy(struct snd_pcm_substream *substream,
277 int channel, unsigned long pos,265 int channel, unsigned long pos,
278 void __user *dst, unsigned long count)266 struct iov_iter *dst, unsigned long count)
279{267{
280 struct rme32 *rme32 = snd_pcm_substream_chip(substream);268 struct rme32 *rme32 = snd_pcm_substream_chip(substream);
281 269
282 if (copy_to_user_fromio(dst,270 return copy_to_iter_fromio(dst,
283 rme32->iobase + RME32_IO_DATA_BUFFER + pos,271 rme32->iobase + RME32_IO_DATA_BUFFER + pos,
284 count))272 count);
285 return -EFAULT;
286 return 0;
287}
288
289static int snd_rme32_capture_copy_kernel(struct snd_pcm_substream *substream,
290 int channel, unsigned long pos,
291 void *dst, unsigned long count)
292{
293 struct rme32 *rme32 = snd_pcm_substream_chip(substream);
294
295 memcpy_fromio(dst, rme32->iobase + RME32_IO_DATA_BUFFER + pos, count);
296 return 0;
297}273}
298 274
299/*275/*
@@ -1194,8 +1170,7 @@ static const struct snd_pcm_ops snd_rme32_playback_spdif_ops = { · 894 unmodified lines
1194 .prepare = snd_rme32_playback_prepare,1170 .prepare = snd_rme32_playback_prepare,
1195 .trigger = snd_rme32_pcm_trigger,1171 .trigger = snd_rme32_pcm_trigger,
1196 .pointer = snd_rme32_playback_pointer,1172 .pointer = snd_rme32_playback_pointer,
1197 .copy_user = snd_rme32_playback_copy,1173 .copy = snd_rme32_playback_copy,
1198 .copy_kernel = snd_rme32_playback_copy_kernel,
1199 .fill_silence = snd_rme32_playback_silence,1174 .fill_silence = snd_rme32_playback_silence,
1200 .mmap = snd_pcm_lib_mmap_iomem,1175 .mmap = snd_pcm_lib_mmap_iomem,
1201};1176};
@@ -1207,8 +1182,7 @@ static const struct snd_pcm_ops snd_rme32_capture_spdif_ops = { · 5 unmodified lines
1207 .prepare = snd_rme32_capture_prepare,1182 .prepare = snd_rme32_capture_prepare,
1208 .trigger = snd_rme32_pcm_trigger,1183 .trigger = snd_rme32_pcm_trigger,
1209 .pointer = snd_rme32_capture_pointer,1184 .pointer = snd_rme32_capture_pointer,
1210 .copy_user = snd_rme32_capture_copy,1185 .copy = snd_rme32_capture_copy,
1211 .copy_kernel = snd_rme32_capture_copy_kernel,
1212 .mmap = snd_pcm_lib_mmap_iomem,1186 .mmap = snd_pcm_lib_mmap_iomem,
1213};1187};
1214 1188
@@ -1219,8 +1193,7 @@ static const struct snd_pcm_ops snd_rme32_playback_adat_ops = { · 4 unmodified lines
1219 .prepare = snd_rme32_playback_prepare,1193 .prepare = snd_rme32_playback_prepare,
1220 .trigger = snd_rme32_pcm_trigger,1194 .trigger = snd_rme32_pcm_trigger,
1221 .pointer = snd_rme32_playback_pointer,1195 .pointer = snd_rme32_playback_pointer,
1222 .copy_user = snd_rme32_playback_copy,1196 .copy = snd_rme32_playback_copy,
1223 .copy_kernel = snd_rme32_playback_copy_kernel,
1224 .fill_silence = snd_rme32_playback_silence,1197 .fill_silence = snd_rme32_playback_silence,
1225 .mmap = snd_pcm_lib_mmap_iomem,1198 .mmap = snd_pcm_lib_mmap_iomem,
1226};1199};
@@ -1232,8 +1205,7 @@ static const struct snd_pcm_ops snd_rme32_capture_adat_ops = { · 5 unmodified lines
1232 .prepare = snd_rme32_capture_prepare,1205 .prepare = snd_rme32_capture_prepare,
1233 .trigger = snd_rme32_pcm_trigger,1206 .trigger = snd_rme32_pcm_trigger,
1234 .pointer = snd_rme32_capture_pointer,1207 .pointer = snd_rme32_capture_pointer,
1235 .copy_user = snd_rme32_capture_copy,1208 .copy = snd_rme32_capture_copy,
1236 .copy_kernel = snd_rme32_capture_copy_kernel,
1237 .mmap = snd_pcm_lib_mmap_iomem,1209 .mmap = snd_pcm_lib_mmap_iomem,
1238};1210};
1239 1211
sound/pci/rme96.c+8−34
@@ -320,48 +320,26 @@ snd_rme96_playback_silence(struct snd_pcm_substream *substream, · 319 unmodified lines
320static int320static int
321snd_rme96_playback_copy(struct snd_pcm_substream *substream,321snd_rme96_playback_copy(struct snd_pcm_substream *substream,
322 int channel, unsigned long pos,322 int channel, unsigned long pos,
323 void __user *src, unsigned long count)323 struct iov_iter *src, unsigned long count)
324{324{
325 struct rme96 *rme96 = snd_pcm_substream_chip(substream);325 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
326 326
327 return copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,327 return copy_from_iter_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
328 src, count);328 src, count);
329}329}
330 330
331static int
332snd_rme96_playback_copy_kernel(struct snd_pcm_substream *substream,
333 int channel, unsigned long pos,
334 void *src, unsigned long count)
335{
336 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
337
338 memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src, count);
339 return 0;
340}
341
342static int331static int
343snd_rme96_capture_copy(struct snd_pcm_substream *substream,332snd_rme96_capture_copy(struct snd_pcm_substream *substream,
344 int channel, unsigned long pos,333 int channel, unsigned long pos,
345 void __user *dst, unsigned long count)334 struct iov_iter *dst, unsigned long count)
346{335{
347 struct rme96 *rme96 = snd_pcm_substream_chip(substream);336 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
348 337
349 return copy_to_user_fromio(dst,338 return copy_to_iter_fromio(dst,
350 rme96->iobase + RME96_IO_REC_BUFFER + pos,339 rme96->iobase + RME96_IO_REC_BUFFER + pos,
351 count);340 count);
352}341}
353 342
354static int
355snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream,
356 int channel, unsigned long pos,
357 void *dst, unsigned long count)
358{
359 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
360
361 memcpy_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos, count);
362 return 0;
363}
364
365/*343/*
366 * Digital output capabilities (S/PDIF)344 * Digital output capabilities (S/PDIF)
367 */345 */
@@ -1518,8 +1496,7 @@ static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = { · 1150 unmodified lines
1518 .prepare = snd_rme96_playback_prepare,1496 .prepare = snd_rme96_playback_prepare,
1519 .trigger = snd_rme96_playback_trigger,1497 .trigger = snd_rme96_playback_trigger,
1520 .pointer = snd_rme96_playback_pointer,1498 .pointer = snd_rme96_playback_pointer,
1521 .copy_user = snd_rme96_playback_copy,1499 .copy = snd_rme96_playback_copy,
1522 .copy_kernel = snd_rme96_playback_copy_kernel,
1523 .fill_silence = snd_rme96_playback_silence,1500 .fill_silence = snd_rme96_playback_silence,
1524 .mmap = snd_pcm_lib_mmap_iomem,1501 .mmap = snd_pcm_lib_mmap_iomem,
1525};1502};
@@ -1531,8 +1508,7 @@ static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = { · 5 unmodified lines
1531 .prepare = snd_rme96_capture_prepare,1508 .prepare = snd_rme96_capture_prepare,
1532 .trigger = snd_rme96_capture_trigger,1509 .trigger = snd_rme96_capture_trigger,
1533 .pointer = snd_rme96_capture_pointer,1510 .pointer = snd_rme96_capture_pointer,
1534 .copy_user = snd_rme96_capture_copy,1511 .copy = snd_rme96_capture_copy,
1535 .copy_kernel = snd_rme96_capture_copy_kernel,
1536 .mmap = snd_pcm_lib_mmap_iomem,1512 .mmap = snd_pcm_lib_mmap_iomem,
1537};1513};
1538 1514
@@ -1543,8 +1519,7 @@ static const struct snd_pcm_ops snd_rme96_playback_adat_ops = { · 4 unmodified lines
1543 .prepare = snd_rme96_playback_prepare,1519 .prepare = snd_rme96_playback_prepare,
1544 .trigger = snd_rme96_playback_trigger,1520 .trigger = snd_rme96_playback_trigger,
1545 .pointer = snd_rme96_playback_pointer,1521 .pointer = snd_rme96_playback_pointer,
1546 .copy_user = snd_rme96_playback_copy,1522 .copy = snd_rme96_playback_copy,
1547 .copy_kernel = snd_rme96_playback_copy_kernel,
1548 .fill_silence = snd_rme96_playback_silence,1523 .fill_silence = snd_rme96_playback_silence,
1549 .mmap = snd_pcm_lib_mmap_iomem,1524 .mmap = snd_pcm_lib_mmap_iomem,
1550};1525};
@@ -1556,8 +1531,7 @@ static const struct snd_pcm_ops snd_rme96_capture_adat_ops = { · 5 unmodified lines
1556 .prepare = snd_rme96_capture_prepare,1531 .prepare = snd_rme96_capture_prepare,
1557 .trigger = snd_rme96_capture_trigger,1532 .trigger = snd_rme96_capture_trigger,
1558 .pointer = snd_rme96_capture_pointer,1533 .pointer = snd_rme96_capture_pointer,
1559 .copy_user = snd_rme96_capture_copy,1534 .copy = snd_rme96_capture_copy,
1560 .copy_kernel = snd_rme96_capture_copy_kernel,
1561 .mmap = snd_pcm_lib_mmap_iomem,1535 .mmap = snd_pcm_lib_mmap_iomem,
1562};1536};
1563 1537
sound/pci/rme9652/hdsp.c+6−36
@@ -3961,7 +3961,7 @@ static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp, · 3960 unmodified lines
3961 3961
3962static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,3962static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
3963 int channel, unsigned long pos,3963 int channel, unsigned long pos,
3964 void __user *src, unsigned long count)3964 struct iov_iter *src, unsigned long count)
3965{3965{
3966 struct hdsp *hdsp = snd_pcm_substream_chip(substream);3966 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3967 signed char *channel_buf;3967 signed char *channel_buf;
@@ -3972,28 +3972,14 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, · 4 unmodified lines
3972 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);3972 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
3973 if (snd_BUG_ON(!channel_buf))3973 if (snd_BUG_ON(!channel_buf))
3974 return -EIO;3974 return -EIO;
3975 if (copy_from_user(channel_buf + pos, src, count))3975 if (copy_from_iter(channel_buf + pos, count, src) != count)
3976 return -EFAULT;3976 return -EFAULT;
3977 return 0;3977 return 0;
3978}3978}
3979 3979
3980static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream,
3981 int channel, unsigned long pos,
3982 void *src, unsigned long count)
3983{
3984 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3985 signed char *channel_buf;
3986
3987 channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
3988 if (snd_BUG_ON(!channel_buf))
3989 return -EIO;
3990 memcpy(channel_buf + pos, src, count);
3991 return 0;
3992}
3993
3994static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,3980static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
3995 int channel, unsigned long pos,3981 int channel, unsigned long pos,
3996 void __user *dst, unsigned long count)3982 struct iov_iter *dst, unsigned long count)
3997{3983{
3998 struct hdsp *hdsp = snd_pcm_substream_chip(substream);3984 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
3999 signed char *channel_buf;3985 signed char *channel_buf;
@@ -4004,25 +3990,11 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, · 4 unmodified lines
4004 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);3990 channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
4005 if (snd_BUG_ON(!channel_buf))3991 if (snd_BUG_ON(!channel_buf))
4006 return -EIO;3992 return -EIO;
4007 if (copy_to_user(dst, channel_buf + pos, count))3993 if (copy_to_iter(channel_buf + pos, count, dst) != count)
4008 return -EFAULT;3994 return -EFAULT;
4009 return 0;3995 return 0;
4010}3996}
4011 3997
4012static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream,
4013 int channel, unsigned long pos,
4014 void *dst, unsigned long count)
4015{
4016 struct hdsp *hdsp = snd_pcm_substream_chip(substream);
4017 signed char *channel_buf;
4018
4019 channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
4020 if (snd_BUG_ON(!channel_buf))
4021 return -EIO;
4022 memcpy(dst, channel_buf + pos, count);
4023 return 0;
4024}
4025
4026static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,3998static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,
4027 int channel, unsigned long pos,3999 int channel, unsigned long pos,
4028 unsigned long count)4000 unsigned long count)
@@ -4950,8 +4922,7 @@ static const struct snd_pcm_ops snd_hdsp_playback_ops = { · 921 unmodified lines
4950 .prepare = snd_hdsp_prepare,4922 .prepare = snd_hdsp_prepare,
4951 .trigger = snd_hdsp_trigger,4923 .trigger = snd_hdsp_trigger,
4952 .pointer = snd_hdsp_hw_pointer,4924 .pointer = snd_hdsp_hw_pointer,
4953 .copy_user = snd_hdsp_playback_copy,4925 .copy = snd_hdsp_playback_copy,
4954 .copy_kernel = snd_hdsp_playback_copy_kernel,
4955 .fill_silence = snd_hdsp_hw_silence,4926 .fill_silence = snd_hdsp_hw_silence,
4956};4927};
4957 4928
@@ -4963,8 +4934,7 @@ static const struct snd_pcm_ops snd_hdsp_capture_ops = { · 5 unmodified lines
4963 .prepare = snd_hdsp_prepare,4934 .prepare = snd_hdsp_prepare,
4964 .trigger = snd_hdsp_trigger,4935 .trigger = snd_hdsp_trigger,
4965 .pointer = snd_hdsp_hw_pointer,4936 .pointer = snd_hdsp_hw_pointer,
4966 .copy_user = snd_hdsp_capture_copy,4937 .copy = snd_hdsp_capture_copy,
4967 .copy_kernel = snd_hdsp_capture_copy_kernel,
4968};4938};
4969 4939
4970static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)4940static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
sound/pci/rme9652/rme9652.c+6−40
@@ -1844,7 +1844,7 @@ static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, · 1843 unmodified lines
1844 1844
1845static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,1845static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
1846 int channel, unsigned long pos,1846 int channel, unsigned long pos,
1847 void __user *src, unsigned long count)1847 struct iov_iter *src, unsigned long count)
1848{1848{
1849 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);1849 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1850 signed char *channel_buf;1850 signed char *channel_buf;
@@ -1857,30 +1857,14 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, · 6 unmodified lines
1857 channel);1857 channel);
1858 if (snd_BUG_ON(!channel_buf))1858 if (snd_BUG_ON(!channel_buf))
1859 return -EIO;1859 return -EIO;
1860 if (copy_from_user(channel_buf + pos, src, count))1860 if (copy_from_iter(channel_buf + pos, count, src) != count)
1861 return -EFAULT;1861 return -EFAULT;
1862 return 0;1862 return 0;
1863}1863}
1864 1864
1865static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
1866 int channel, unsigned long pos,
1867 void *src, unsigned long count)
1868{
1869 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1870 signed char *channel_buf;
1871
1872 channel_buf = rme9652_channel_buffer_location(rme9652,
1873 substream->pstr->stream,
1874 channel);
1875 if (snd_BUG_ON(!channel_buf))
1876 return -EIO;
1877 memcpy(channel_buf + pos, src, count);
1878 return 0;
1879}
1880
1881static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,1865static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
1882 int channel, unsigned long pos,1866 int channel, unsigned long pos,
1883 void __user *dst, unsigned long count)1867 struct iov_iter *dst, unsigned long count)
1884{1868{
1885 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);1869 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1886 signed char *channel_buf;1870 signed char *channel_buf;
@@ -1893,27 +1877,11 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, · 6 unmodified lines
1893 channel);1877 channel);
1894 if (snd_BUG_ON(!channel_buf))1878 if (snd_BUG_ON(!channel_buf))
1895 return -EIO;1879 return -EIO;
1896 if (copy_to_user(dst, channel_buf + pos, count))1880 if (copy_to_iter(channel_buf + pos, count, dst) != count)
1897 return -EFAULT;1881 return -EFAULT;
1898 return 0;1882 return 0;
1899}1883}
1900 1884
1901static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
1902 int channel, unsigned long pos,
1903 void *dst, unsigned long count)
1904{
1905 struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
1906 signed char *channel_buf;
1907
1908 channel_buf = rme9652_channel_buffer_location(rme9652,
1909 substream->pstr->stream,
1910 channel);
1911 if (snd_BUG_ON(!channel_buf))
1912 return -EIO;
1913 memcpy(dst, channel_buf + pos, count);
1914 return 0;
1915}
1916
1917static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,1885static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
1918 int channel, unsigned long pos,1886 int channel, unsigned long pos,
1919 unsigned long count)1887 unsigned long count)
@@ -2370,8 +2338,7 @@ static const struct snd_pcm_ops snd_rme9652_playback_ops = { · 450 unmodified lines
2370 .prepare = snd_rme9652_prepare,2338 .prepare = snd_rme9652_prepare,
2371 .trigger = snd_rme9652_trigger,2339 .trigger = snd_rme9652_trigger,
2372 .pointer = snd_rme9652_hw_pointer,2340 .pointer = snd_rme9652_hw_pointer,
2373 .copy_user = snd_rme9652_playback_copy,2341 .copy = snd_rme9652_playback_copy,
2374 .copy_kernel = snd_rme9652_playback_copy_kernel,
2375 .fill_silence = snd_rme9652_hw_silence,2342 .fill_silence = snd_rme9652_hw_silence,
2376};2343};
2377 2344
@@ -2383,8 +2350,7 @@ static const struct snd_pcm_ops snd_rme9652_capture_ops = { · 5 unmodified lines
2383 .prepare = snd_rme9652_prepare,2350 .prepare = snd_rme9652_prepare,
2384 .trigger = snd_rme9652_trigger,2351 .trigger = snd_rme9652_trigger,
2385 .pointer = snd_rme9652_hw_pointer,2352 .pointer = snd_rme9652_hw_pointer,
2386 .copy_user = snd_rme9652_capture_copy,2353 .copy = snd_rme9652_capture_copy,
2387 .copy_kernel = snd_rme9652_capture_copy_kernel,
2388};2354};
2389 2355
2390static int snd_rme9652_create_pcm(struct snd_card *card,2356static int snd_rme9652_create_pcm(struct snd_card *card,
sound/pci/via82xx.c+1−5
@@ -1984,11 +1984,7 @@ static int snd_via8233_init_misc(struct via82xx *chip) · 1983 unmodified lines
1984 /* when no h/w PCM volume control is found, use DXS volume control1984 /* when no h/w PCM volume control is found, use DXS volume control
1985 * as the PCM vol control1985 * as the PCM vol control
1986 */1986 */
1987 struct snd_ctl_elem_id sid;1987 if (!snd_ctl_find_id_mixer(chip->card, "PCM Playback Volume")) {
1988 memset(&sid, 0, sizeof(sid));
1989 strcpy(sid.name, "PCM Playback Volume");
1990 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1991 if (! snd_ctl_find_id(chip->card, &sid)) {
1992 dev_info(chip->card->dev,1988 dev_info(chip->card->dev,
1993 "Using DXS as PCM Playback\n");1989 "Using DXS as PCM Playback\n");
1994 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));1990 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
sound/ppc/awacs.c+1−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <asm/nvram.h>11#include <asm/nvram.h>
12#include <linux/init.h>12#include <linux/init.h>
13#include <linux/delay.h>13#include <linux/delay.h>
14#include <linux/of.h>
14#include <linux/slab.h>15#include <linux/slab.h>
15#include <sound/core.h>16#include <sound/core.h>
16#include "pmac.h"17#include "pmac.h"
sound/ppc/burgundy.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/io.h>9#include <linux/io.h>
10#include <linux/init.h>10#include <linux/init.h>
11#include <linux/delay.h>11#include <linux/delay.h>
12#include <linux/of.h>
12#include <sound/core.h>13#include <sound/core.h>
13#include "pmac.h"14#include "pmac.h"
14#include "burgundy.h"15#include "burgundy.h"
sound/sh/sh_dac_audio.c+3−22
@@ -158,12 +158,12 @@ static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) · 157 unmodified lines
158 158
159static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream,159static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream,
160 int channel, unsigned long pos,160 int channel, unsigned long pos,
161 void __user *src, unsigned long count)161 struct iov_iter *src, unsigned long count)
162{162{
163 /* channel is not used (interleaved data) */163 /* channel is not used (interleaved data) */
164 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);164 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
165 165
166 if (copy_from_user_toio(chip->data_buffer + pos, src, count))166 if (copy_from_iter_toio(chip->data_buffer + pos, src, count))
167 return -EFAULT;167 return -EFAULT;
168 chip->buffer_end = chip->data_buffer + pos + count;168 chip->buffer_end = chip->data_buffer + pos + count;
169 169
@@ -175,24 +175,6 @@ static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, · 5 unmodified lines
175 return 0;175 return 0;
176}176}
177 177
178static int snd_sh_dac_pcm_copy_kernel(struct snd_pcm_substream *substream,
179 int channel, unsigned long pos,
180 void *src, unsigned long count)
181{
182 /* channel is not used (interleaved data) */
183 struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
184
185 memcpy_toio(chip->data_buffer + pos, src, count);
186 chip->buffer_end = chip->data_buffer + pos + count;
187
188 if (chip->empty) {
189 chip->empty = 0;
190 dac_audio_start_timer(chip);
191 }
192
193 return 0;
194}
195
196static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,178static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
197 int channel, unsigned long pos,179 int channel, unsigned long pos,
198 unsigned long count)180 unsigned long count)
@@ -227,8 +209,7 @@ static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { · 28 unmodified lines
227 .prepare = snd_sh_dac_pcm_prepare,209 .prepare = snd_sh_dac_pcm_prepare,
228 .trigger = snd_sh_dac_pcm_trigger,210 .trigger = snd_sh_dac_pcm_trigger,
229 .pointer = snd_sh_dac_pcm_pointer,211 .pointer = snd_sh_dac_pcm_pointer,
230 .copy_user = snd_sh_dac_pcm_copy,212 .copy = snd_sh_dac_pcm_copy,
231 .copy_kernel = snd_sh_dac_pcm_copy_kernel,
232 .fill_silence = snd_sh_dac_pcm_silence,213 .fill_silence = snd_sh_dac_pcm_silence,
233 .mmap = snd_pcm_lib_mmap_iomem,214 .mmap = snd_pcm_lib_mmap_iomem,
234};215};
sound/soc/Kconfig+11−0
@@ -38,6 +38,17 @@ config SND_SOC_TOPOLOGY · 37 unmodified lines
38 bool38 bool
39 select SND_DYNAMIC_MINORS39 select SND_DYNAMIC_MINORS
40 40
41config SND_SOC_TOPOLOGY_BUILD
42 bool "Build topology core"
43 select SND_SOC_TOPOLOGY
44 depends on KUNIT
45 help
46 This option exists to facilitate running the KUnit tests for
47 the topology core, KUnit is frequently tested in virtual
48 environments with minimal drivers enabled but the topology
49 core is usually selected by drivers. There is little reason
50 to enable it if not doing a KUnit build.
51
41config SND_SOC_TOPOLOGY_KUNIT_TEST52config SND_SOC_TOPOLOGY_KUNIT_TEST
42 tristate "KUnit tests for SoC topology"53 tristate "KUnit tests for SoC topology"
43 depends on KUNIT54 depends on KUNIT
sound/soc/adi/axi-i2s.c+1−1
@@ -147,6 +147,7 @@ static int axi_i2s_dai_probe(struct snd_soc_dai *dai) · 146 unmodified lines
147}147}
148 148
149static const struct snd_soc_dai_ops axi_i2s_dai_ops = {149static const struct snd_soc_dai_ops axi_i2s_dai_ops = {
150 .probe = axi_i2s_dai_probe,
150 .startup = axi_i2s_startup,151 .startup = axi_i2s_startup,
151 .shutdown = axi_i2s_shutdown,152 .shutdown = axi_i2s_shutdown,
152 .trigger = axi_i2s_trigger,153 .trigger = axi_i2s_trigger,
@@ -154,7 +155,6 @@ static const struct snd_soc_dai_ops axi_i2s_dai_ops = { · 1 unmodified line
154};155};
155 156
156static struct snd_soc_dai_driver axi_i2s_dai = {157static struct snd_soc_dai_driver axi_i2s_dai = {
157 .probe = axi_i2s_dai_probe,
158 .ops = &axi_i2s_dai_ops,158 .ops = &axi_i2s_dai_ops,
159 .symmetric_rate = 1,159 .symmetric_rate = 1,
160};160};
sound/soc/adi/axi-spdif.c+1−1
@@ -148,6 +148,7 @@ static void axi_spdif_shutdown(struct snd_pcm_substream *substream, · 147 unmodified lines
148}148}
149 149
150static const struct snd_soc_dai_ops axi_spdif_dai_ops = {150static const struct snd_soc_dai_ops axi_spdif_dai_ops = {
151 .probe = axi_spdif_dai_probe,
151 .startup = axi_spdif_startup,152 .startup = axi_spdif_startup,
152 .shutdown = axi_spdif_shutdown,153 .shutdown = axi_spdif_shutdown,
153 .trigger = axi_spdif_trigger,154 .trigger = axi_spdif_trigger,
@@ -155,7 +156,6 @@ static const struct snd_soc_dai_ops axi_spdif_dai_ops = { · 1 unmodified line
155};156};
156 157
157static struct snd_soc_dai_driver axi_spdif_dai = {158static struct snd_soc_dai_driver axi_spdif_dai = {
158 .probe = axi_spdif_dai_probe,
159 .playback = {159 .playback = {
160 .channels_min = 2,160 .channels_min = 2,
161 .channels_max = 2,161 .channels_max = 2,
sound/soc/amd/Kconfig+3−2
@@ -79,14 +79,15 @@ config SND_SOC_AMD_ACP5x · 78 unmodified lines
79 ACP DMA driver, CPU DAI driver.79 ACP DMA driver, CPU DAI driver.
80 80
81config SND_SOC_AMD_VANGOGH_MACH81config SND_SOC_AMD_VANGOGH_MACH
82 tristate "AMD Vangogh support for NAU8821 CS35L41"82 tristate "AMD Vangogh support for NAU8821/CS35L41/MAX98388"
83 select SND_SOC_NAU882183 select SND_SOC_NAU8821
84 select SND_SOC_CS35L41_SPI84 select SND_SOC_CS35L41_SPI
85 select SND_SOC_MAX98388
85 select SND_AMD_ACP_CONFIG86 select SND_AMD_ACP_CONFIG
86 depends on SND_SOC_AMD_ACP5x && I2C && SPI_MASTER87 depends on SND_SOC_AMD_ACP5x && I2C && SPI_MASTER
87 help88 help
88 This option enables machine driver for Vangogh platform89 This option enables machine driver for Vangogh platform
89 using NAU8821 and CS35L41 codecs.90 using NAU8821 and either CS35L41 or MAX98388 codecs.
90 Say m if you have such a device.91 Say m if you have such a device.
91 If unsure select "N".92 If unsure select "N".
92 93
sound/soc/amd/acp-config.c+33−0
@@ -47,6 +47,20 @@ static const struct config_entry config_table[] = { · 46 unmodified lines
47 {}47 {}
48 },48 },
49 },49 },
50 {
51 .flags = FLAG_AMD_SOF,
52 .device = ACP_PCI_DEV_ID,
53 .dmi_table = (const struct dmi_system_id []) {
54 {
55 .matches = {
56 DMI_MATCH(DMI_SYS_VENDOR, "Valve"),
57 DMI_MATCH(DMI_PRODUCT_NAME, "Galileo"),
58 DMI_MATCH(DMI_PRODUCT_FAMILY, "Sephiroth"),
59 },
60 },
61 {}
62 },
63 },
50};64};
51 65
52int snd_amd_acp_find_config(struct pci_dev *pci)66int snd_amd_acp_find_config(struct pci_dev *pci)
@@ -82,6 +96,11 @@ static struct snd_soc_acpi_codecs amp_max = { · 29 unmodified lines
82 .codecs = {"MX98360A"}96 .codecs = {"MX98360A"}
83};97};
84 98
99static struct snd_soc_acpi_codecs amp_max98388 = {
100 .num_codecs = 1,
101 .codecs = {"ADS8388"}
102};
103
85struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = {104struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = {
86 {105 {
87 .id = "10EC5682",106 .id = "10EC5682",
@@ -130,6 +149,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = { · 42 unmodified lines
130};149};
131EXPORT_SYMBOL(snd_soc_acpi_amd_sof_machines);150EXPORT_SYMBOL(snd_soc_acpi_amd_sof_machines);
132 151
152struct snd_soc_acpi_mach snd_soc_acpi_amd_vangogh_sof_machines[] = {
153 {
154 .id = "NVTN2020",
155 .drv_name = "nau8821-max",
156 .pdata = &acp_quirk_data,
157 .machine_quirk = snd_soc_acpi_codec_list,
158 .quirk_data = &amp_max98388,
159 .fw_filename = "sof-vangogh.ri",
160 .sof_tplg_filename = "sof-vangogh-nau8821-max.tplg",
161 },
162 {},
163};
164EXPORT_SYMBOL(snd_soc_acpi_amd_vangogh_sof_machines);
165
133struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[] = {166struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[] = {
134 {167 {
135 .id = "AMDI1019",168 .id = "AMDI1019",
sound/soc/amd/acp-da7219-max98357a.c+31−10
@@ -28,6 +28,21 @@ · 27 unmodified lines
28#define RT5682_PLL_FREQ (48000 * 512)28#define RT5682_PLL_FREQ (48000 * 512)
29 29
30static struct snd_soc_jack cz_jack;30static struct snd_soc_jack cz_jack;
31static struct snd_soc_jack_pin cz_jack_pins[] = {
32 {
33 .pin = "Headphone Jack",
34 .mask = SND_JACK_HEADPHONE,
35 },
36 {
37 .pin = "Headset Mic",
38 .mask = SND_JACK_MICROPHONE,
39 },
40 {
41 .pin = "Line Out",
42 .mask = SND_JACK_LINEOUT,
43 },
44};
45
31static struct clk *da7219_dai_wclk;46static struct clk *da7219_dai_wclk;
32static struct clk *da7219_dai_bclk;47static struct clk *da7219_dai_bclk;
33static struct clk *rt5682_dai_wclk;48static struct clk *rt5682_dai_wclk;
@@ -66,11 +81,13 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) · 32 unmodified lines
66 if (IS_ERR(da7219_dai_bclk))81 if (IS_ERR(da7219_dai_bclk))
67 return PTR_ERR(da7219_dai_bclk);82 return PTR_ERR(da7219_dai_bclk);
68 83
69 ret = snd_soc_card_jack_new(card, "Headset Jack",84 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
70 SND_JACK_HEADSET | SND_JACK_LINEOUT |85 SND_JACK_HEADSET | SND_JACK_LINEOUT |
71 SND_JACK_BTN_0 | SND_JACK_BTN_1 |86 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
72 SND_JACK_BTN_2 | SND_JACK_BTN_3,87 SND_JACK_BTN_2 | SND_JACK_BTN_3,
73 &cz_jack);88 &cz_jack,
89 cz_jack_pins,
90 ARRAY_SIZE(cz_jack_pins));
74 if (ret) {91 if (ret) {
75 dev_err(card->dev, "HP jack creation failed %d\n", ret);92 dev_err(card->dev, "HP jack creation failed %d\n", ret);
76 return ret;93 return ret;
@@ -146,11 +163,13 @@ static int cz_rt5682_init(struct snd_soc_pcm_runtime *rtd) · 69 unmodified lines
146 if (IS_ERR(rt5682_dai_bclk))163 if (IS_ERR(rt5682_dai_bclk))
147 return PTR_ERR(rt5682_dai_bclk);164 return PTR_ERR(rt5682_dai_bclk);
148 165
149 ret = snd_soc_card_jack_new(card, "Headset Jack",166 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
150 SND_JACK_HEADSET | SND_JACK_LINEOUT |167 SND_JACK_HEADSET | SND_JACK_LINEOUT |
151 SND_JACK_BTN_0 | SND_JACK_BTN_1 |168 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
152 SND_JACK_BTN_2 | SND_JACK_BTN_3,169 SND_JACK_BTN_2 | SND_JACK_BTN_3,
153 &cz_jack);170 &cz_jack,
171 cz_jack_pins,
172 ARRAY_SIZE(cz_jack_pins));
154 if (ret) {173 if (ret) {
155 dev_err(card->dev, "HP jack creation failed %d\n", ret);174 dev_err(card->dev, "HP jack creation failed %d\n", ret);
156 return ret;175 return ret;
@@ -631,6 +650,7 @@ static struct snd_soc_dai_link cz_dai_5682_98357[] = { · 474 unmodified lines
631static const struct snd_soc_dapm_widget cz_widgets[] = {650static const struct snd_soc_dapm_widget cz_widgets[] = {
632 SND_SOC_DAPM_HP("Headphones", NULL),651 SND_SOC_DAPM_HP("Headphones", NULL),
633 SND_SOC_DAPM_SPK("Speakers", NULL),652 SND_SOC_DAPM_SPK("Speakers", NULL),
653 SND_SOC_DAPM_LINE("Line Out", NULL),
634 SND_SOC_DAPM_MIC("Headset Mic", NULL),654 SND_SOC_DAPM_MIC("Headset Mic", NULL),
635 SND_SOC_DAPM_MIC("Int Mic", NULL),655 SND_SOC_DAPM_MIC("Int Mic", NULL),
636};656};
@@ -654,6 +674,7 @@ static const struct snd_soc_dapm_route cz_rt5682_audio_route[] = { · 17 unmodified lines
654static const struct snd_kcontrol_new cz_mc_controls[] = {674static const struct snd_kcontrol_new cz_mc_controls[] = {
655 SOC_DAPM_PIN_SWITCH("Headphones"),675 SOC_DAPM_PIN_SWITCH("Headphones"),
656 SOC_DAPM_PIN_SWITCH("Speakers"),676 SOC_DAPM_PIN_SWITCH("Speakers"),
677 SOC_DAPM_PIN_SWITCH("Line Out"),
657 SOC_DAPM_PIN_SWITCH("Headset Mic"),678 SOC_DAPM_PIN_SWITCH("Headset Mic"),
658 SOC_DAPM_PIN_SWITCH("Int Mic"),679 SOC_DAPM_PIN_SWITCH("Int Mic"),
659};680};
sound/soc/amd/acp-rt5645.c+17−5
@@ -42,6 +42,16 @@ · 41 unmodified lines
42#define CZ_PLAT_CLK 2400000042#define CZ_PLAT_CLK 24000000
43 43
44static struct snd_soc_jack cz_jack;44static struct snd_soc_jack cz_jack;
45static struct snd_soc_jack_pin cz_jack_pins[] = {
46 {
47 .pin = "Headphones",
48 .mask = SND_JACK_HEADPHONE,
49 },
50 {
51 .pin = "Headset Mic",
52 .mask = SND_JACK_MICROPHONE,
53 },
54};
45 55
46static int cz_aif1_hw_params(struct snd_pcm_substream *substream,56static int cz_aif1_hw_params(struct snd_pcm_substream *substream,
47 struct snd_pcm_hw_params *params)57 struct snd_pcm_hw_params *params)
@@ -76,11 +86,13 @@ static int cz_init(struct snd_soc_pcm_runtime *rtd) · 28 unmodified lines
76 codec = asoc_rtd_to_codec(rtd, 0)->component;86 codec = asoc_rtd_to_codec(rtd, 0)->component;
77 card = rtd->card;87 card = rtd->card;
78 88
79 ret = snd_soc_card_jack_new(card, "Headset Jack",89 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
80 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |90 SND_JACK_HEADPHONE | SND_JACK_MICROPHONE |
81 SND_JACK_BTN_0 | SND_JACK_BTN_1 |91 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
82 SND_JACK_BTN_2 | SND_JACK_BTN_3,92 SND_JACK_BTN_2 | SND_JACK_BTN_3,
83 &cz_jack);93 &cz_jack,
94 cz_jack_pins,
95 ARRAY_SIZE(cz_jack_pins));
84 if (ret) {96 if (ret) {
85 dev_err(card->dev, "HP jack creation failed %d\n", ret);97 dev_err(card->dev, "HP jack creation failed %d\n", ret);
86 return ret;98 return ret;
sound/soc/amd/acp/Kconfig+8−0
@@ -18,6 +18,9 @@ if SND_SOC_AMD_ACP_COMMON · 17 unmodified lines
18config SND_SOC_AMD_ACP_PDM18config SND_SOC_AMD_ACP_PDM
19 tristate19 tristate
20 20
21config SND_SOC_AMD_ACP_LEGACY_COMMON
22 tristate
23
21config SND_SOC_AMD_ACP_I2S24config SND_SOC_AMD_ACP_I2S
22 tristate25 tristate
23 26
@@ -27,6 +30,7 @@ config SND_SOC_AMD_ACP_PCM · 3 unmodified lines
27 30
28config SND_SOC_AMD_ACP_PCI31config SND_SOC_AMD_ACP_PCI
29 tristate "AMD ACP PCI Driver Support"32 tristate "AMD ACP PCI Driver Support"
33 select SND_SOC_AMD_ACP_LEGACY_COMMON
30 depends on X86 && PCI34 depends on X86 && PCI
31 help35 help
32 This options enables generic PCI driver for ACP device.36 This options enables generic PCI driver for ACP device.
@@ -36,6 +40,7 @@ config SND_AMD_ASOC_RENOIR · 3 unmodified lines
36 select SND_SOC_AMD_ACP_PCM40 select SND_SOC_AMD_ACP_PCM
37 select SND_SOC_AMD_ACP_I2S41 select SND_SOC_AMD_ACP_I2S
38 select SND_SOC_AMD_ACP_PDM42 select SND_SOC_AMD_ACP_PDM
43 select SND_SOC_AMD_ACP_LEGACY_COMMON
39 depends on X86 && PCI44 depends on X86 && PCI
40 help45 help
41 This option enables Renoir I2S support on AMD platform.46 This option enables Renoir I2S support on AMD platform.
@@ -45,6 +50,7 @@ config SND_AMD_ASOC_REMBRANDT · 3 unmodified lines
45 select SND_SOC_AMD_ACP_PCM50 select SND_SOC_AMD_ACP_PCM
46 select SND_SOC_AMD_ACP_I2S51 select SND_SOC_AMD_ACP_I2S
47 select SND_SOC_AMD_ACP_PDM52 select SND_SOC_AMD_ACP_PDM
53 select SND_SOC_AMD_ACP_LEGACY_COMMON
48 depends on X86 && PCI54 depends on X86 && PCI
49 help55 help
50 This option enables Rembrandt I2S support on AMD platform.56 This option enables Rembrandt I2S support on AMD platform.
@@ -61,6 +67,8 @@ config SND_SOC_AMD_MACH_COMMON · 10 unmodified lines
61 select SND_SOC_MAX98357A67 select SND_SOC_MAX98357A
62 select SND_SOC_RT5682S68 select SND_SOC_RT5682S
63 select SND_SOC_NAU882569 select SND_SOC_NAU8825
70 select SND_SOC_NAU8821
71 select SND_SOC_MAX98388
64 help72 help
65 This option enables common Machine driver module for ACP.73 This option enables common Machine driver module for ACP.
66 74
sound/soc/amd/acp/Makefile+2−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8snd-acp-pcm-objs := acp-platform.o8snd-acp-pcm-objs := acp-platform.o
9snd-acp-i2s-objs := acp-i2s.o9snd-acp-i2s-objs := acp-i2s.o
10snd-acp-pdm-objs := acp-pdm.o10snd-acp-pdm-objs := acp-pdm.o
11snd-acp-legacy-common-objs := acp-legacy-common.o
11snd-acp-pci-objs := acp-pci.o12snd-acp-pci-objs := acp-pci.o
12 13
13#platform specific driver14#platform specific driver
@@ -22,6 +23,7 @@ snd-acp-sof-mach-objs := acp-sof-mach.o · 8 unmodified lines
22obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o23obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
23obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o24obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
24obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o25obj-$(CONFIG_SND_SOC_AMD_ACP_PDM) += snd-acp-pdm.o
26obj-$(CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON) += snd-acp-legacy-common.o
25obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o27obj-$(CONFIG_SND_SOC_AMD_ACP_PCI) += snd-acp-pci.o
26 28
27obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o29obj-$(CONFIG_SND_AMD_ASOC_RENOIR) += snd-acp-renoir.o
sound/soc/amd/acp/acp-i2s.c+14−12
@@ -149,6 +149,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ · 148 unmodified lines
149 dev_err(dev, "Invalid dai id %x\n", dai->driver->id);149 dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
150 return -EINVAL;150 return -EINVAL;
151 }151 }
152 adata->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution;
152 } else {153 } else {
153 switch (dai->driver->id) {154 switch (dai->driver->id) {
154 case I2S_BT_INSTANCE:155 case I2S_BT_INSTANCE:
@@ -167,6 +168,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_ · 12 unmodified lines
167 dev_err(dev, "Invalid dai id %x\n", dai->driver->id);168 dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
168 return -EINVAL;169 return -EINVAL;
169 }170 }
171 adata->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution;
170 }172 }
171 173
172 val = readl(adata->acp_base + reg_val);174 val = readl(adata->acp_base + reg_val);
@@ -537,17 +539,7 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d · 364 unmodified lines
537 return 0;539 return 0;
538}540}
539 541
540const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = {542static int acp_i2s_probe(struct snd_soc_dai *dai)
541 .startup = acp_i2s_startup,
542 .hw_params = acp_i2s_hwparams,
543 .prepare = acp_i2s_prepare,
544 .trigger = acp_i2s_trigger,
545 .set_fmt = acp_i2s_set_fmt,
546 .set_tdm_slot = acp_i2s_set_tdm_slot,
547};
548EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, SND_SOC_ACP_COMMON);
549
550int asoc_acp_i2s_probe(struct snd_soc_dai *dai)
551{543{
552 struct device *dev = dai->component->dev;544 struct device *dev = dai->component->dev;
553 struct acp_dev_data *adata = dev_get_drvdata(dev);545 struct acp_dev_data *adata = dev_get_drvdata(dev);
@@ -567,7 +559,17 @@ int asoc_acp_i2s_probe(struct snd_soc_dai *dai) · 13 unmodified lines
567 559
568 return 0;560 return 0;
569}561}
570EXPORT_SYMBOL_NS_GPL(asoc_acp_i2s_probe, SND_SOC_ACP_COMMON);562
563const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = {
564 .probe = acp_i2s_probe,
565 .startup = acp_i2s_startup,
566 .hw_params = acp_i2s_hwparams,
567 .prepare = acp_i2s_prepare,
568 .trigger = acp_i2s_trigger,
569 .set_fmt = acp_i2s_set_fmt,
570 .set_tdm_slot = acp_i2s_set_tdm_slot,
571};
572EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, SND_SOC_ACP_COMMON);
571 573
572MODULE_LICENSE("Dual BSD/GPL");574MODULE_LICENSE("Dual BSD/GPL");
573MODULE_ALIAS(DRV_NAME);575MODULE_ALIAS(DRV_NAME);
sound/soc/amd/acp/acp-legacy-common.c+347−0
@@ -0,0 +1,347 @@
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) 2023 Advanced Micro Devices, Inc.
7//
8// Authors: Syed Saba Kareem <Syed.SabaKareem@amd.com>
9//
10
11/*
12 * Common file to be used by amd platforms
13 */
14
15#include "amd.h"
16#include <linux/pci.h>
17#include <linux/export.h>
18
19void acp_enable_interrupts(struct acp_dev_data *adata)
20{
21 struct acp_resource *rsrc = adata->rsrc;
22 u32 ext_intr_ctrl;
23
24 writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
25 ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
26 ext_intr_ctrl |= ACP_ERROR_MASK;
27 writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
28}
29EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, SND_SOC_ACP_COMMON);
30
31void acp_disable_interrupts(struct acp_dev_data *adata)
32{
33 struct acp_resource *rsrc = adata->rsrc;
34
35 writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
36 writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
37}
38EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, SND_SOC_ACP_COMMON);
39
40static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream,
41 struct snd_soc_dai *dai)
42{
43 struct snd_pcm_runtime *runtime = substream->runtime;
44 struct acp_stream *stream = runtime->private_data;
45 struct device *dev = dai->component->dev;
46 struct acp_dev_data *adata = dev_get_drvdata(dev);
47
48 u32 physical_addr, pdm_size, period_bytes;
49
50 period_bytes = frames_to_bytes(runtime, runtime->period_size);
51 pdm_size = frames_to_bytes(runtime, runtime->buffer_size);
52 physical_addr = stream->reg_offset + MEM_WINDOW_START;
53
54 /* Init ACP PDM Ring buffer */
55 writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
56 writel(pdm_size, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE);
57 writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
58 writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
59}
60
61static void set_acp_pdm_clk(struct snd_pcm_substream *substream,
62 struct snd_soc_dai *dai)
63{
64 struct device *dev = dai->component->dev;
65 struct acp_dev_data *adata = dev_get_drvdata(dev);
66 unsigned int pdm_ctrl;
67
68 /* Enable default ACP PDM clk */
69 writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
70 pdm_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
71 pdm_ctrl |= PDM_MISC_CTRL_MASK;
72 writel(pdm_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL);
73 set_acp_pdm_ring_buffer(substream, dai);
74}
75
76void restore_acp_pdm_params(struct snd_pcm_substream *substream,
77 struct acp_dev_data *adata)
78{
79 struct snd_soc_dai *dai;
80 struct snd_soc_pcm_runtime *soc_runtime;
81 u32 ext_int_ctrl;
82
83 soc_runtime = asoc_substream_to_rtd(substream);
84 dai = asoc_rtd_to_cpu(soc_runtime, 0);
85 /* Programming channel mask and sampling rate */
86 writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
87 writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
88
89 /* Enabling ACP Pdm interuppts */
90 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
91 ext_int_ctrl |= PDM_DMA_INTR_MASK;
92 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
93 set_acp_pdm_clk(substream, dai);
94}
95EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, SND_SOC_ACP_COMMON);
96
97static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
98 struct snd_soc_dai *dai)
99{
100 struct device *dev = dai->component->dev;
101 struct acp_dev_data *adata = dev_get_drvdata(dev);
102 struct acp_resource *rsrc = adata->rsrc;
103 struct acp_stream *stream = substream->runtime->private_data;
104 u32 reg_dma_size, reg_fifo_size, reg_fifo_addr;
105 u32 phy_addr, acp_fifo_addr, ext_int_ctrl;
106 unsigned int dir = substream->stream;
107
108 switch (dai->driver->id) {
109 case I2S_SP_INSTANCE:
110 if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
111 reg_dma_size = ACP_I2S_TX_DMA_SIZE;
112 acp_fifo_addr = rsrc->sram_pte_offset +
113 SP_PB_FIFO_ADDR_OFFSET;
114 reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
115 reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
116 phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
117 writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
118 } else {
119 reg_dma_size = ACP_I2S_RX_DMA_SIZE;
120 acp_fifo_addr = rsrc->sram_pte_offset +
121 SP_CAPT_FIFO_ADDR_OFFSET;
122 reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
123 reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
124 phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
125 writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
126 }
127 break;
128 case I2S_BT_INSTANCE:
129 if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
130 reg_dma_size = ACP_BT_TX_DMA_SIZE;
131 acp_fifo_addr = rsrc->sram_pte_offset +
132 BT_PB_FIFO_ADDR_OFFSET;
133 reg_fifo_addr = ACP_BT_TX_FIFOADDR;
134 reg_fifo_size = ACP_BT_TX_FIFOSIZE;
135 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
136 writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
137 } else {
138 reg_dma_size = ACP_BT_RX_DMA_SIZE;
139 acp_fifo_addr = rsrc->sram_pte_offset +
140 BT_CAPT_FIFO_ADDR_OFFSET;
141 reg_fifo_addr = ACP_BT_RX_FIFOADDR;
142 reg_fifo_size = ACP_BT_RX_FIFOSIZE;
143 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
144 writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
145 }
146 break;
147 case I2S_HS_INSTANCE:
148 if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
149 reg_dma_size = ACP_HS_TX_DMA_SIZE;
150 acp_fifo_addr = rsrc->sram_pte_offset +
151 HS_PB_FIFO_ADDR_OFFSET;
152 reg_fifo_addr = ACP_HS_TX_FIFOADDR;
153 reg_fifo_size = ACP_HS_TX_FIFOSIZE;
154 phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
155 writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
156 } else {
157 reg_dma_size = ACP_HS_RX_DMA_SIZE;
158 acp_fifo_addr = rsrc->sram_pte_offset +
159 HS_CAPT_FIFO_ADDR_OFFSET;
160 reg_fifo_addr = ACP_HS_RX_FIFOADDR;
161 reg_fifo_size = ACP_HS_RX_FIFOSIZE;
162 phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
163 writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
164 }
165 break;
166 default:
167 dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
168 return -EINVAL;
169 }
170
171 writel(DMA_SIZE, adata->acp_base + reg_dma_size);
172 writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
173 writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
174
175 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
176 ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
177 BIT(BT_RX_THRESHOLD(rsrc->offset)) |
178 BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
179 BIT(BT_TX_THRESHOLD(rsrc->offset)) |
180 BIT(HS_RX_THRESHOLD(rsrc->offset)) |
181 BIT(HS_TX_THRESHOLD(rsrc->offset));
182
183 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
184 return 0;
185}
186
187int restore_acp_i2s_params(struct snd_pcm_substream *substream,
188 struct acp_dev_data *adata,
189 struct acp_stream *stream)
190{
191 struct snd_soc_dai *dai;
192 struct snd_soc_pcm_runtime *soc_runtime;
193 u32 tdm_fmt, reg_val, fmt_reg, val;
194
195 soc_runtime = asoc_substream_to_rtd(substream);
196 dai = asoc_rtd_to_cpu(soc_runtime, 0);
197 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
198 tdm_fmt = adata->tdm_tx_fmt[stream->dai_id - 1];
199 switch (stream->dai_id) {
200 case I2S_BT_INSTANCE:
201 reg_val = ACP_BTTDM_ITER;
202 fmt_reg = ACP_BTTDM_TXFRMT;
203 break;
204 case I2S_SP_INSTANCE:
205 reg_val = ACP_I2STDM_ITER;
206 fmt_reg = ACP_I2STDM_TXFRMT;
207 break;
208 case I2S_HS_INSTANCE:
209 reg_val = ACP_HSTDM_ITER;
210 fmt_reg = ACP_HSTDM_TXFRMT;
211 break;
212 default:
213 pr_err("Invalid dai id %x\n", stream->dai_id);
214 return -EINVAL;
215 }
216 val = adata->xfer_tx_resolution[stream->dai_id - 1] << 3;
217 } else {
218 tdm_fmt = adata->tdm_rx_fmt[stream->dai_id - 1];
219 switch (stream->dai_id) {
220 case I2S_BT_INSTANCE:
221 reg_val = ACP_BTTDM_IRER;
222 fmt_reg = ACP_BTTDM_RXFRMT;
223 break;
224 case I2S_SP_INSTANCE:
225 reg_val = ACP_I2STDM_IRER;
226 fmt_reg = ACP_I2STDM_RXFRMT;
227 break;
228 case I2S_HS_INSTANCE:
229 reg_val = ACP_HSTDM_IRER;
230 fmt_reg = ACP_HSTDM_RXFRMT;
231 break;
232 default:
233 pr_err("Invalid dai id %x\n", stream->dai_id);
234 return -EINVAL;
235 }
236 val = adata->xfer_rx_resolution[stream->dai_id - 1] << 3;
237 }
238 writel(val, adata->acp_base + reg_val);
239 if (adata->tdm_mode == TDM_ENABLE) {
240 writel(tdm_fmt, adata->acp_base + fmt_reg);
241 val = readl(adata->acp_base + reg_val);
242 writel(val | 0x2, adata->acp_base + reg_val);
243 }
244 return set_acp_i2s_dma_fifo(substream, dai);
245}
246EXPORT_SYMBOL_NS_GPL(restore_acp_i2s_params, SND_SOC_ACP_COMMON);
247
248static int acp_power_on(struct acp_chip_info *chip)
249{
250 u32 val, acp_pgfsm_stat_reg, acp_pgfsm_ctrl_reg;
251 void __iomem *base;
252
253 base = chip->base;
254 switch (chip->acp_rev) {
255 case ACP3X_DEV:
256 acp_pgfsm_stat_reg = ACP_PGFSM_STATUS;
257 acp_pgfsm_ctrl_reg = ACP_PGFSM_CONTROL;
258 break;
259 case ACP6X_DEV:
260 acp_pgfsm_stat_reg = ACP6X_PGFSM_STATUS;
261 acp_pgfsm_ctrl_reg = ACP6X_PGFSM_CONTROL;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 val = readl(base + acp_pgfsm_stat_reg);
268 if (val == ACP_POWERED_ON)
269 return 0;
270
271 if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
272 writel(ACP_PGFSM_CNTL_POWER_ON_MASK, base + acp_pgfsm_ctrl_reg);
273
274 return readl_poll_timeout(base + acp_pgfsm_stat_reg, val,
275 !val, DELAY_US, ACP_TIMEOUT);
276}
277
278static int acp_reset(void __iomem *base)
279{
280 u32 val;
281 int ret;
282
283 writel(1, base + ACP_SOFT_RESET);
284 ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK,
285 DELAY_US, ACP_TIMEOUT);
286 if (ret)
287 return ret;
288
289 writel(0, base + ACP_SOFT_RESET);
290 return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
291}
292
293int acp_init(struct acp_chip_info *chip)
294{
295 int ret;
296
297 /* power on */
298 ret = acp_power_on(chip);
299 if (ret) {
300 pr_err("ACP power on failed\n");
301 return ret;
302 }
303 writel(0x01, chip->base + ACP_CONTROL);
304
305 /* Reset */
306 ret = acp_reset(chip->base);
307 if (ret) {
308 pr_err("ACP reset failed\n");
309 return ret;
310 }
311 return 0;
312}
313EXPORT_SYMBOL_NS_GPL(acp_init, SND_SOC_ACP_COMMON);
314
315int acp_deinit(void __iomem *base)
316{
317 int ret;
318
319 /* Reset */
320 ret = acp_reset(base);
321 if (ret)
322 return ret;
323
324 writel(0, base + ACP_CONTROL);
325 return 0;
326}
327EXPORT_SYMBOL_NS_GPL(acp_deinit, SND_SOC_ACP_COMMON);
328
329int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
330{
331 pci_write_config_dword(dev, 0x60, smn_addr);
332 pci_write_config_dword(dev, 0x64, data);
333 return 0;
334}
335EXPORT_SYMBOL_NS_GPL(smn_write, SND_SOC_ACP_COMMON);
336
337int smn_read(struct pci_dev *dev, u32 smn_addr)
338{
339 u32 data;
340
341 pci_write_config_dword(dev, 0x60, smn_addr);
342 pci_read_config_dword(dev, 0x64, &data);
343 return data;
344}
345EXPORT_SYMBOL_NS_GPL(smn_read, SND_SOC_ACP_COMMON);
346
347MODULE_LICENSE("Dual BSD/GPL");
sound/soc/amd/acp/acp-legacy-mach.c+1−21
@@ -75,23 +75,6 @@ static struct acp_card_drvdata rt5682s_rt1019_rmb_data = { · 74 unmodified lines
75 .tdm_mode = false,75 .tdm_mode = false,
76};76};
77 77
78static const struct snd_kcontrol_new acp_controls[] = {
79 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
80 SOC_DAPM_PIN_SWITCH("Headset Mic"),
81 SOC_DAPM_PIN_SWITCH("Spk"),
82 SOC_DAPM_PIN_SWITCH("Left Spk"),
83 SOC_DAPM_PIN_SWITCH("Right Spk"),
84
85};
86
87static const struct snd_soc_dapm_widget acp_widgets[] = {
88 SND_SOC_DAPM_HP("Headphone Jack", NULL),
89 SND_SOC_DAPM_MIC("Headset Mic", NULL),
90 SND_SOC_DAPM_SPK("Spk", NULL),
91 SND_SOC_DAPM_SPK("Left Spk", NULL),
92 SND_SOC_DAPM_SPK("Right Spk", NULL),
93};
94
95static int acp_asoc_probe(struct platform_device *pdev)78static int acp_asoc_probe(struct platform_device *pdev)
96{79{
97 struct snd_soc_card *card = NULL;80 struct snd_soc_card *card = NULL;
@@ -110,11 +93,8 @@ static int acp_asoc_probe(struct platform_device *pdev) · 12 unmodified lines
110 card->dev = dev;93 card->dev = dev;
111 card->owner = THIS_MODULE;94 card->owner = THIS_MODULE;
112 card->name = pdev->id_entry->name;95 card->name = pdev->id_entry->name;
113 card->dapm_widgets = acp_widgets;
114 card->num_dapm_widgets = ARRAY_SIZE(acp_widgets);
115 card->controls = acp_controls;
116 card->num_controls = ARRAY_SIZE(acp_controls);
117 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;96 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
97 /* Widgets and controls added per-codec in acp-mach-common.c */
118 98
119 acp_card_drvdata = card->drvdata;99 acp_card_drvdata = card->drvdata;
120 dmi_id = dmi_first_match(acp_quirk_table);100 dmi_id = dmi_first_match(acp_quirk_table);
sound/soc/amd/acp/acp-mach-common.c+496−29
@@ -25,12 +25,17 @@ · 24 unmodified lines
25#include "../../codecs/rt1019.h"25#include "../../codecs/rt1019.h"
26#include "../../codecs/rt5682s.h"26#include "../../codecs/rt5682s.h"
27#include "../../codecs/nau8825.h"27#include "../../codecs/nau8825.h"
28#include "../../codecs/nau8821.h"
28#include "acp-mach.h"29#include "acp-mach.h"
29 30
30#define PCO_PLAT_CLK 4800000031#define PCO_PLAT_CLK 48000000
31#define RT5682_PLL_FREQ (48000 * 512)32#define RT5682_PLL_FREQ (48000 * 512)
32#define DUAL_CHANNEL 233#define DUAL_CHANNEL 2
33#define FOUR_CHANNEL 434#define FOUR_CHANNEL 4
35#define NAU8821_CODEC_DAI "nau8821-hifi"
36#define NAU8821_BCLK 1536000
37#define NAU8821_FREQ_OUT 12288000
38#define MAX98388_CODEC_DAI "max98388-aif1"
34 39
35#define TDM_MODE_ENABLE 140#define TDM_MODE_ENABLE 1
36 41
@@ -46,8 +51,6 @@ const struct dmi_system_id acp_quirk_table[] = { · 9 unmodified lines
46};51};
47EXPORT_SYMBOL_GPL(acp_quirk_table);52EXPORT_SYMBOL_GPL(acp_quirk_table);
48 53
49static struct snd_soc_jack pco_jack;
50
51static const unsigned int channels[] = {54static const unsigned int channels[] = {
52 DUAL_CHANNEL,55 DUAL_CHANNEL,
53};56};
@@ -81,6 +84,28 @@ static int acp_clk_enable(struct acp_card_drvdata *drvdata, · 27 unmodified lines
81SND_SOC_DAILINK_DEF(rt5682,84SND_SOC_DAILINK_DEF(rt5682,
82 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));85 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
83 86
87static struct snd_soc_jack rt5682_jack;
88static struct snd_soc_jack_pin rt5682_jack_pins[] = {
89 {
90 .pin = "Headphone Jack",
91 .mask = SND_JACK_HEADPHONE,
92 },
93 {
94 .pin = "Headset Mic",
95 .mask = SND_JACK_MICROPHONE,
96 },
97};
98
99static const struct snd_kcontrol_new rt5682_controls[] = {
100 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
101 SOC_DAPM_PIN_SWITCH("Headset Mic"),
102};
103
104static const struct snd_soc_dapm_widget rt5682_widgets[] = {
105 SND_SOC_DAPM_HP("Headphone Jack", NULL),
106 SND_SOC_DAPM_MIC("Headset Mic", NULL),
107};
108
84static const struct snd_soc_dapm_route rt5682_map[] = {109static const struct snd_soc_dapm_route rt5682_map[] = {
85 { "Headphone Jack", NULL, "HPOL" },110 { "Headphone Jack", NULL, "HPOL" },
86 { "Headphone Jack", NULL, "HPOR" },111 { "Headphone Jack", NULL, "HPOR" },
@@ -104,22 +129,38 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) · 17 unmodified lines
104 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");129 drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
105 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");130 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
106 131
107 ret = snd_soc_card_jack_new(card, "Headset Jack",132 ret = snd_soc_dapm_new_controls(&card->dapm, rt5682_widgets,
108 SND_JACK_HEADSET | SND_JACK_LINEOUT |133 ARRAY_SIZE(rt5682_widgets));
109 SND_JACK_BTN_0 | SND_JACK_BTN_1 |134 if (ret) {
110 SND_JACK_BTN_2 | SND_JACK_BTN_3,135 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
111 &pco_jack);136 return ret;
137 }
138
139 ret = snd_soc_add_card_controls(card, rt5682_controls,
140 ARRAY_SIZE(rt5682_controls));
141 if (ret) {
142 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
143 return ret;
144 }
145
146 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
147 SND_JACK_HEADSET | SND_JACK_LINEOUT |
148 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
149 SND_JACK_BTN_2 | SND_JACK_BTN_3,
150 &rt5682_jack,
151 rt5682_jack_pins,
152 ARRAY_SIZE(rt5682_jack_pins));
112 if (ret) {153 if (ret) {
113 dev_err(card->dev, "HP jack creation failed %d\n", ret);154 dev_err(card->dev, "HP jack creation failed %d\n", ret);
114 return ret;155 return ret;
115 }156 }
116 157
117 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);158 snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
118 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);159 snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
119 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);160 snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
120 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);161 snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
121 162
122 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);163 ret = snd_soc_component_set_jack(component, &rt5682_jack, NULL);
123 if (ret) {164 if (ret) {
124 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);165 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
125 return ret;166 return ret;
@@ -269,6 +310,28 @@ static const struct snd_soc_ops acp_card_rt5682_ops = { · 143 unmodified lines
269SND_SOC_DAILINK_DEF(rt5682s,310SND_SOC_DAILINK_DEF(rt5682s,
270 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));311 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
271 312
313static struct snd_soc_jack rt5682s_jack;
314static struct snd_soc_jack_pin rt5682s_jack_pins[] = {
315 {
316 .pin = "Headphone Jack",
317 .mask = SND_JACK_HEADPHONE,
318 },
319 {
320 .pin = "Headset Mic",
321 .mask = SND_JACK_MICROPHONE,
322 },
323};
324
325static const struct snd_kcontrol_new rt5682s_controls[] = {
326 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
327 SOC_DAPM_PIN_SWITCH("Headset Mic"),
328};
329
330static const struct snd_soc_dapm_widget rt5682s_widgets[] = {
331 SND_SOC_DAPM_HP("Headphone Jack", NULL),
332 SND_SOC_DAPM_MIC("Headset Mic", NULL),
333};
334
272static const struct snd_soc_dapm_route rt5682s_map[] = {335static const struct snd_soc_dapm_route rt5682s_map[] = {
273 { "Headphone Jack", NULL, "HPOL" },336 { "Headphone Jack", NULL, "HPOL" },
274 { "Headphone Jack", NULL, "HPOR" },337 { "Headphone Jack", NULL, "HPOR" },
@@ -293,22 +356,38 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) · 18 unmodified lines
293 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");356 drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
294 }357 }
295 358
296 ret = snd_soc_card_jack_new(card, "Headset Jack",359 ret = snd_soc_dapm_new_controls(&card->dapm, rt5682s_widgets,
297 SND_JACK_HEADSET | SND_JACK_LINEOUT |360 ARRAY_SIZE(rt5682s_widgets));
298 SND_JACK_BTN_0 | SND_JACK_BTN_1 |361 if (ret) {
299 SND_JACK_BTN_2 | SND_JACK_BTN_3,362 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
300 &pco_jack);363 return ret;
364 }
365
366 ret = snd_soc_add_card_controls(card, rt5682s_controls,
367 ARRAY_SIZE(rt5682s_controls));
368 if (ret) {
369 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
370 return ret;
371 }
372
373 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
374 SND_JACK_HEADSET | SND_JACK_LINEOUT |
375 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
376 SND_JACK_BTN_2 | SND_JACK_BTN_3,
377 &rt5682s_jack,
378 rt5682s_jack_pins,
379 ARRAY_SIZE(rt5682s_jack_pins));
301 if (ret) {380 if (ret) {
302 dev_err(card->dev, "HP jack creation failed %d\n", ret);381 dev_err(card->dev, "HP jack creation failed %d\n", ret);
303 return ret;382 return ret;
304 }383 }
305 384
306 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);385 snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
307 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);386 snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
308 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);387 snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
309 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);388 snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
310 389
311 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);390 ret = snd_soc_component_set_jack(component, &rt5682s_jack, NULL);
312 if (ret) {391 if (ret) {
313 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);392 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
314 return ret;393 return ret;
@@ -434,6 +513,16 @@ SND_SOC_DAILINK_DEF(rt1019, · 119 unmodified lines
434 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),513 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
435 COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));514 COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
436 515
516static const struct snd_kcontrol_new rt1019_controls[] = {
517 SOC_DAPM_PIN_SWITCH("Left Spk"),
518 SOC_DAPM_PIN_SWITCH("Right Spk"),
519};
520
521static const struct snd_soc_dapm_widget rt1019_widgets[] = {
522 SND_SOC_DAPM_SPK("Left Spk", NULL),
523 SND_SOC_DAPM_SPK("Right Spk", NULL),
524};
525
437static const struct snd_soc_dapm_route rt1019_map_lr[] = {526static const struct snd_soc_dapm_route rt1019_map_lr[] = {
438 { "Left Spk", NULL, "Left SPO" },527 { "Left Spk", NULL, "Left SPO" },
439 { "Right Spk", NULL, "Right SPO" },528 { "Right Spk", NULL, "Right SPO" },
@@ -454,10 +543,25 @@ static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd) · 14 unmodified lines
454{543{
455 struct snd_soc_card *card = rtd->card;544 struct snd_soc_card *card = rtd->card;
456 struct acp_card_drvdata *drvdata = card->drvdata;545 struct acp_card_drvdata *drvdata = card->drvdata;
546 int ret;
457 547
458 if (drvdata->amp_codec_id != RT1019)548 if (drvdata->amp_codec_id != RT1019)
459 return -EINVAL;549 return -EINVAL;
460 550
551 ret = snd_soc_dapm_new_controls(&card->dapm, rt1019_widgets,
552 ARRAY_SIZE(rt1019_widgets));
553 if (ret) {
554 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
555 return ret;
556 }
557
558 ret = snd_soc_add_card_controls(card, rt1019_controls,
559 ARRAY_SIZE(rt1019_controls));
560 if (ret) {
561 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
562 return ret;
563 }
564
461 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,565 return snd_soc_dapm_add_routes(&rtd->card->dapm, rt1019_map_lr,
462 ARRAY_SIZE(rt1019_map_lr));566 ARRAY_SIZE(rt1019_map_lr));
463}567}
@@ -588,6 +692,14 @@ static const struct snd_soc_ops acp_card_rt1019_ops = { · 124 unmodified lines
588SND_SOC_DAILINK_DEF(max98360a,692SND_SOC_DAILINK_DEF(max98360a,
589 DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));693 DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
590 694
695static const struct snd_kcontrol_new max98360a_controls[] = {
696 SOC_DAPM_PIN_SWITCH("Spk"),
697};
698
699static const struct snd_soc_dapm_widget max98360a_widgets[] = {
700 SND_SOC_DAPM_SPK("Spk", NULL),
701};
702
591static const struct snd_soc_dapm_route max98360a_map[] = {703static const struct snd_soc_dapm_route max98360a_map[] = {
592 {"Spk", NULL, "Speaker"},704 {"Spk", NULL, "Speaker"},
593};705};
@@ -596,10 +708,25 @@ static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd) · 2 unmodified lines
596{708{
597 struct snd_soc_card *card = rtd->card;709 struct snd_soc_card *card = rtd->card;
598 struct acp_card_drvdata *drvdata = card->drvdata;710 struct acp_card_drvdata *drvdata = card->drvdata;
711 int ret;
599 712
600 if (drvdata->amp_codec_id != MAX98360A)713 if (drvdata->amp_codec_id != MAX98360A)
601 return -EINVAL;714 return -EINVAL;
602 715
716 ret = snd_soc_dapm_new_controls(&card->dapm, max98360a_widgets,
717 ARRAY_SIZE(max98360a_widgets));
718 if (ret) {
719 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
720 return ret;
721 }
722
723 ret = snd_soc_add_card_controls(card, max98360a_controls,
724 ARRAY_SIZE(max98360a_controls));
725 if (ret) {
726 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
727 return ret;
728 }
729
603 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,730 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98360a_map,
604 ARRAY_SIZE(max98360a_map));731 ARRAY_SIZE(max98360a_map));
605}732}
@@ -661,10 +788,137 @@ static const struct snd_soc_ops acp_card_maxim_ops = { · 55 unmodified lines
661 .hw_params = acp_card_maxim_hw_params,788 .hw_params = acp_card_maxim_hw_params,
662};789};
663 790
791SND_SOC_DAILINK_DEF(max98388,
792 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"),
793 COMP_CODEC("i2c-ADS8388:01", "max98388-aif1")));
794
795static const struct snd_kcontrol_new max98388_controls[] = {
796 SOC_DAPM_PIN_SWITCH("Left Spk"),
797 SOC_DAPM_PIN_SWITCH("Right Spk"),
798};
799
800static const struct snd_soc_dapm_widget max98388_widgets[] = {
801 SND_SOC_DAPM_SPK("Left Spk", NULL),
802 SND_SOC_DAPM_SPK("Right Spk", NULL),
803};
804
805static const struct snd_soc_dapm_route max98388_map[] = {
806 { "Left Spk", NULL, "Left BE_OUT" },
807 { "Right Spk", NULL, "Right BE_OUT" },
808};
809
810static struct snd_soc_codec_conf max98388_conf[] = {
811 {
812 .dlc = COMP_CODEC_CONF("i2c-ADS8388:00"),
813 .name_prefix = "Left",
814 },
815 {
816 .dlc = COMP_CODEC_CONF("i2c-ADS8388:01"),
817 .name_prefix = "Right",
818 },
819};
820
821static const unsigned int max98388_format[] = {16};
822
823static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = {
824 .list = max98388_format,
825 .count = ARRAY_SIZE(max98388_format),
826};
827
828static int acp_card_max98388_startup(struct snd_pcm_substream *substream)
829{
830 struct snd_pcm_runtime *runtime = substream->runtime;
831
832 runtime->hw.channels_max = DUAL_CHANNEL;
833 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
834 &constraints_channels);
835 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
836 &constraints_rates);
837 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
838 &constraints_sample_bits_max);
839
840 return 0;
841}
842
843static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)
844{
845 struct snd_soc_card *card = rtd->card;
846 struct acp_card_drvdata *drvdata = card->drvdata;
847 int ret;
848
849 if (drvdata->amp_codec_id != MAX98388)
850 return -EINVAL;
851
852 ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets,
853 ARRAY_SIZE(max98388_widgets));
854
855 if (ret) {
856 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
857 /* Don't need to add routes if widget addition failed */
858 return ret;
859 }
860
861 ret = snd_soc_add_card_controls(card, max98388_controls,
862 ARRAY_SIZE(max98388_controls));
863 if (ret) {
864 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
865 return ret;
866 }
867
868 return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map,
869 ARRAY_SIZE(max98388_map));
870}
871
872static int acp_max98388_hw_params(struct snd_pcm_substream *substream,
873 struct snd_pcm_hw_params *params)
874{
875 struct snd_soc_pcm_runtime *rtd = substream->private_data;
876 struct snd_soc_card *card = rtd->card;
877 struct snd_soc_dai *codec_dai =
878 snd_soc_card_get_codec_dai(card,
879 MAX98388_CODEC_DAI);
880 int ret;
881
882 ret = snd_soc_dai_set_fmt(codec_dai,
883 SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |
884 SND_SOC_DAIFMT_NB_NF);
885 if (ret < 0)
886 return ret;
887
888 return ret;
889}
890
891static const struct snd_soc_ops acp_max98388_ops = {
892 .startup = acp_card_max98388_startup,
893 .hw_params = acp_max98388_hw_params,
894};
895
664/* Declare nau8825 codec components */896/* Declare nau8825 codec components */
665SND_SOC_DAILINK_DEF(nau8825,897SND_SOC_DAILINK_DEF(nau8825,
666 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));898 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
667 899
900static struct snd_soc_jack nau8825_jack;
901static struct snd_soc_jack_pin nau8825_jack_pins[] = {
902 {
903 .pin = "Headphone Jack",
904 .mask = SND_JACK_HEADPHONE,
905 },
906 {
907 .pin = "Headset Mic",
908 .mask = SND_JACK_MICROPHONE,
909 },
910};
911
912static const struct snd_kcontrol_new nau8825_controls[] = {
913 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
914 SOC_DAPM_PIN_SWITCH("Headset Mic"),
915};
916
917static const struct snd_soc_dapm_widget nau8825_widgets[] = {
918 SND_SOC_DAPM_HP("Headphone Jack", NULL),
919 SND_SOC_DAPM_MIC("Headset Mic", NULL),
920};
921
668static const struct snd_soc_dapm_route nau8825_map[] = {922static const struct snd_soc_dapm_route nau8825_map[] = {
669 { "Headphone Jack", NULL, "HPOL" },923 { "Headphone Jack", NULL, "HPOL" },
670 { "Headphone Jack", NULL, "HPOR" },924 { "Headphone Jack", NULL, "HPOR" },
@@ -683,22 +937,38 @@ static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd) · 12 unmodified lines
683 if (drvdata->hs_codec_id != NAU8825)937 if (drvdata->hs_codec_id != NAU8825)
684 return -EINVAL;938 return -EINVAL;
685 939
686 ret = snd_soc_card_jack_new(card, "Headset Jack",940 ret = snd_soc_dapm_new_controls(&card->dapm, nau8825_widgets,
941 ARRAY_SIZE(nau8825_widgets));
942 if (ret) {
943 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
944 return ret;
945 }
946
947 ret = snd_soc_add_card_controls(card, nau8825_controls,
948 ARRAY_SIZE(nau8825_controls));
949 if (ret) {
950 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
951 return ret;
952 }
953
954 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
687 SND_JACK_HEADSET | SND_JACK_LINEOUT |955 SND_JACK_HEADSET | SND_JACK_LINEOUT |
688 SND_JACK_BTN_0 | SND_JACK_BTN_1 |956 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
689 SND_JACK_BTN_2 | SND_JACK_BTN_3,957 SND_JACK_BTN_2 | SND_JACK_BTN_3,
690 &pco_jack);958 &nau8825_jack,
959 nau8825_jack_pins,
960 ARRAY_SIZE(nau8825_jack_pins));
691 if (ret) {961 if (ret) {
692 dev_err(card->dev, "HP jack creation failed %d\n", ret);962 dev_err(card->dev, "HP jack creation failed %d\n", ret);
693 return ret;963 return ret;
694 }964 }
695 965
696 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);966 snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
697 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);967 snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
698 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);968 snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
699 snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);969 snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
700 970
701 ret = snd_soc_component_set_jack(component, &pco_jack, NULL);971 ret = snd_soc_component_set_jack(component, &nau8825_jack, NULL);
702 if (ret) {972 if (ret) {
703 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);973 dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
704 return ret;974 return ret;
@@ -790,6 +1060,189 @@ static const struct snd_soc_ops acp_card_nau8825_ops = { · 85 unmodified lines
790 .hw_params = acp_nau8825_hw_params,1060 .hw_params = acp_nau8825_hw_params,
791};1061};
792 1062
1063static int platform_clock_control(struct snd_soc_dapm_widget *w,
1064 struct snd_kcontrol *k, int event)
1065{
1066 struct snd_soc_dapm_context *dapm = w->dapm;
1067 struct snd_soc_card *card = dapm->card;
1068 struct snd_soc_dai *codec_dai;
1069 int ret = 0;
1070
1071 codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI);
1072 if (!codec_dai) {
1073 dev_err(card->dev, "Codec dai not found\n");
1074 return -EIO;
1075 }
1076
1077 if (SND_SOC_DAPM_EVENT_OFF(event)) {
1078 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,
1079 0, SND_SOC_CLOCK_IN);
1080 if (ret < 0) {
1081 dev_err(card->dev, "set sysclk err = %d\n", ret);
1082 return -EIO;
1083 }
1084 } else {
1085 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1086 SND_SOC_CLOCK_IN);
1087 if (ret < 0)
1088 dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
1089 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK,
1090 NAU8821_FREQ_OUT);
1091 if (ret < 0)
1092 dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
1093 }
1094 return ret;
1095}
1096
1097static struct snd_soc_jack nau8821_jack;
1098static struct snd_soc_jack_pin nau8821_jack_pins[] = {
1099 {
1100 .pin = "Headphone Jack",
1101 .mask = SND_JACK_HEADPHONE,
1102 },
1103 {
1104 .pin = "Headset Mic",
1105 .mask = SND_JACK_MICROPHONE,
1106 },
1107};
1108
1109static const struct snd_kcontrol_new nau8821_controls[] = {
1110 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
1111 SOC_DAPM_PIN_SWITCH("Headset Mic"),
1112};
1113
1114static const struct snd_soc_dapm_widget nau8821_widgets[] = {
1115 SND_SOC_DAPM_HP("Headphone Jack", NULL),
1116 SND_SOC_DAPM_MIC("Headset Mic", NULL),
1117 SND_SOC_DAPM_MIC("Int Mic", NULL),
1118 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
1119 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
1120 SND_SOC_DAPM_POST_PMD),
1121};
1122
1123static const struct snd_soc_dapm_route nau8821_audio_route[] = {
1124 /* HP jack connectors - unknown if we have jack detection */
1125 { "Headphone Jack", NULL, "HPOL" },
1126 { "Headphone Jack", NULL, "HPOR" },
1127 { "MICL", NULL, "Headset Mic" },
1128 { "MICR", NULL, "Headset Mic" },
1129 { "DMIC", NULL, "Int Mic" },
1130 { "Headphone Jack", NULL, "Platform Clock" },
1131 { "Headset Mic", NULL, "Platform Clock" },
1132 { "Int Mic", NULL, "Platform Clock" },
1133};
1134
1135static const unsigned int nau8821_format[] = {16};
1136
1137static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
1138 .list = nau8821_format,
1139 .count = ARRAY_SIZE(nau8821_format),
1140};
1141
1142static int acp_8821_init(struct snd_soc_pcm_runtime *rtd)
1143{
1144 struct snd_soc_card *card = rtd->card;
1145 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
1146 struct snd_soc_component *component = codec_dai->component;
1147 int ret;
1148
1149 dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
1150
1151 ret = snd_soc_dapm_new_controls(&card->dapm, nau8821_widgets,
1152 ARRAY_SIZE(nau8821_widgets));
1153 if (ret) {
1154 dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
1155 // Don't need to add routes if widget addition failed
1156 return ret;
1157 }
1158
1159 ret = snd_soc_add_card_controls(card, nau8821_controls,
1160 ARRAY_SIZE(nau8821_controls));
1161 if (ret) {
1162 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
1163 return ret;
1164 }
1165
1166 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
1167 SND_JACK_HEADSET | SND_JACK_LINEOUT |
1168 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1169 SND_JACK_BTN_2 | SND_JACK_BTN_3,
1170 &nau8821_jack,
1171 nau8821_jack_pins,
1172 ARRAY_SIZE(nau8821_jack_pins));
1173 if (ret) {
1174 dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
1175 return ret;
1176 }
1177
1178 snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
1179 snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
1180 snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
1181 snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
1182
1183 nau8821_enable_jack_detect(component, &nau8821_jack);
1184
1185 return snd_soc_dapm_add_routes(&rtd->card->dapm, nau8821_audio_route,
1186 ARRAY_SIZE(nau8821_audio_route));
1187}
1188
1189static int acp_8821_startup(struct snd_pcm_substream *substream)
1190{
1191 struct snd_pcm_runtime *runtime = substream->runtime;
1192
1193 runtime->hw.channels_max = DUAL_CHANNEL;
1194 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1195 &constraints_channels);
1196 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1197 &constraints_rates);
1198 snd_pcm_hw_constraint_list(substream->runtime, 0,
1199 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1200 &constraints_sample_bits);
1201 return 0;
1202}
1203
1204static int acp_nau8821_hw_params(struct snd_pcm_substream *substream,
1205 struct snd_pcm_hw_params *params)
1206{
1207 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1208 struct snd_soc_card *card = rtd->card;
1209 struct acp_card_drvdata *drvdata = card->drvdata;
1210 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
1211 int ret;
1212 unsigned int fmt;
1213
1214 if (drvdata->soc_mclk)
1215 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
1216 else
1217 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
1218
1219 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
1220 if (ret < 0) {
1221 dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
1222 return ret;
1223 }
1224
1225 ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1226 SND_SOC_CLOCK_IN);
1227 if (ret < 0)
1228 dev_err(card->dev, "can't set FS clock %d\n", ret);
1229 ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),
1230 params_rate(params) * 256);
1231 if (ret < 0)
1232 dev_err(card->dev, "can't set FLL: %d\n", ret);
1233
1234 return ret;
1235}
1236
1237static const struct snd_soc_ops acp_8821_ops = {
1238 .startup = acp_8821_startup,
1239 .hw_params = acp_nau8821_hw_params,
1240};
1241
1242SND_SOC_DAILINK_DEF(nau8821,
1243 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
1244 "nau8821-hifi")));
1245
793/* Declare DMIC codec components */1246/* Declare DMIC codec components */
794SND_SOC_DAILINK_DEF(dmic_codec,1247SND_SOC_DAILINK_DEF(dmic_codec,
795 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));1248 DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
@@ -920,6 +1373,12 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) · 124 unmodified lines
920 links[i].init = acp_card_rt5682s_init;1373 links[i].init = acp_card_rt5682s_init;
921 links[i].ops = &acp_card_rt5682s_ops;1374 links[i].ops = &acp_card_rt5682s_ops;
922 }1375 }
1376 if (drv_data->hs_codec_id == NAU8821) {
1377 links[i].codecs = nau8821;
1378 links[i].num_codecs = ARRAY_SIZE(nau8821);
1379 links[i].init = acp_8821_init;
1380 links[i].ops = &acp_8821_ops;
1381 }
923 i++;1382 i++;
924 }1383 }
925 1384
@@ -1007,6 +1466,14 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) · 81 unmodified lines
1007 links[i].ops = &acp_card_maxim_ops;1466 links[i].ops = &acp_card_maxim_ops;
1008 links[i].init = acp_card_maxim_init;1467 links[i].init = acp_card_maxim_init;
1009 }1468 }
1469 if (drv_data->amp_codec_id == MAX98388) {
1470 links[i].codecs = max98388;
1471 links[i].num_codecs = ARRAY_SIZE(max98388);
1472 links[i].ops = &acp_max98388_ops;
1473 links[i].init = acp_card_max98388_init;
1474 card->codec_conf = max98388_conf;
1475 card->num_configs = ARRAY_SIZE(max98388_conf);
1476 }
1010 if (drv_data->amp_codec_id == RT1019) {1477 if (drv_data->amp_codec_id == RT1019) {
1011 links[i].codecs = rt1019;1478 links[i].codecs = rt1019;
1012 links[i].num_codecs = ARRAY_SIZE(rt1019);1479 links[i].num_codecs = ARRAY_SIZE(rt1019);
sound/soc/amd/acp/acp-mach.h+2−0
@@ -41,6 +41,8 @@ enum codec_endpoints { · 40 unmodified lines
41 MAX98360A,41 MAX98360A,
42 RT5682S,42 RT5682S,
43 NAU8825,43 NAU8825,
44 NAU8821,
45 MAX98388,
44};46};
45 47
46enum platform_end_point {48enum platform_end_point {
sound/soc/amd/acp/acp-pci.c+56−1
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/pci.h>16#include <linux/pci.h>
17#include <linux/platform_device.h>17#include <linux/platform_device.h>
18#include <linux/module.h>18#include <linux/module.h>
19#include <linux/pm_runtime.h>
19 20
20#include "amd.h"21#include "amd.h"
21#include "../mach-config.h"22#include "../mach-config.h"
@@ -106,6 +107,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id · 84 unmodified lines
106 goto unregister_dmic_dev;107 goto unregister_dmic_dev;
107 }108 }
108 109
110 acp_init(chip);
109 res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL);111 res = devm_kcalloc(&pci->dev, num_res, sizeof(struct resource), GFP_KERNEL);
110 if (!res) {112 if (!res) {
111 ret = -ENOMEM;113 ret = -ENOMEM;
@@ -139,7 +141,12 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id · 27 unmodified lines
139 ret = PTR_ERR(pdev);141 ret = PTR_ERR(pdev);
140 goto unregister_dmic_dev;142 goto unregister_dmic_dev;
141 }143 }
142 144 chip->chip_pdev = pdev;
145 dev_set_drvdata(&pci->dev, chip);
146 pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
147 pm_runtime_use_autosuspend(&pci->dev);
148 pm_runtime_put_noidle(&pci->dev);
149 pm_runtime_allow(&pci->dev);
143 return ret;150 return ret;
144 151
145unregister_dmic_dev:152unregister_dmic_dev:
@@ -152,12 +159,56 @@ disable_pci: · 6 unmodified lines
152 return ret;159 return ret;
153};160};
154 161
162static int __maybe_unused snd_acp_suspend(struct device *dev)
163{
164 struct acp_chip_info *chip;
165 int ret;
166
167 chip = dev_get_drvdata(dev);
168 ret = acp_deinit(chip->base);
169 if (ret)
170 dev_err(dev, "ACP de-init failed\n");
171 return ret;
172}
173
174static int __maybe_unused snd_acp_resume(struct device *dev)
175{
176 struct acp_chip_info *chip;
177 struct acp_dev_data *adata;
178 struct device child;
179 int ret;
180
181 chip = dev_get_drvdata(dev);
182 ret = acp_init(chip);
183 if (ret)
184 dev_err(dev, "ACP init failed\n");
185 child = chip->chip_pdev->dev;
186 adata = dev_get_drvdata(&child);
187 if (adata)
188 acp_enable_interrupts(adata);
189 return ret;
190}
191
192static const struct dev_pm_ops acp_pm_ops = {
193 SET_RUNTIME_PM_OPS(snd_acp_suspend, snd_acp_resume, NULL)
194 SET_SYSTEM_SLEEP_PM_OPS(snd_acp_suspend, snd_acp_resume)
195};
196
155static void acp_pci_remove(struct pci_dev *pci)197static void acp_pci_remove(struct pci_dev *pci)
156{198{
199 struct acp_chip_info *chip;
200 int ret;
201
202 chip = pci_get_drvdata(pci);
203 pm_runtime_forbid(&pci->dev);
204 pm_runtime_get_noresume(&pci->dev);
157 if (dmic_dev)205 if (dmic_dev)
158 platform_device_unregister(dmic_dev);206 platform_device_unregister(dmic_dev);
159 if (pdev)207 if (pdev)
160 platform_device_unregister(pdev);208 platform_device_unregister(pdev);
209 ret = acp_deinit(chip->base);
210 if (ret)
211 dev_err(&pci->dev, "ACP de-init failed\n");
161}212}
162 213
163/* PCI IDs */214/* PCI IDs */
@@ -173,8 +224,12 @@ static struct pci_driver snd_amd_acp_pci_driver = { · 9 unmodified lines
173 .id_table = acp_pci_ids,224 .id_table = acp_pci_ids,
174 .probe = acp_pci_probe,225 .probe = acp_pci_probe,
175 .remove = acp_pci_remove,226 .remove = acp_pci_remove,
227 .driver = {
228 .pm = &acp_pm_ops,
229 },
176};230};
177module_pci_driver(snd_amd_acp_pci_driver);231module_pci_driver(snd_amd_acp_pci_driver);
178 232
179MODULE_LICENSE("Dual BSD/GPL");233MODULE_LICENSE("Dual BSD/GPL");
234MODULE_IMPORT_NS(SND_SOC_ACP_COMMON);
180MODULE_ALIAS(DRV_NAME);235MODULE_ALIAS(DRV_NAME);
sound/soc/amd/acp/acp-pdm.c+1−12
@@ -25,18 +25,6 @@ · 24 unmodified lines
25 25
26#define DRV_NAME "acp-pdm"26#define DRV_NAME "acp-pdm"
27 27
28#define PDM_DMA_STAT 0x10
29#define PDM_DMA_INTR_MASK 0x10000
30#define PDM_DEC_64 0x2
31#define PDM_CLK_FREQ_MASK 0x07
32#define PDM_MISC_CTRL_MASK 0x10
33#define PDM_ENABLE 0x01
34#define PDM_DISABLE 0x00
35#define DMA_EN_MASK 0x02
36#define DELAY_US 5
37#define PDM_TIMEOUT 1000
38#define ACP_REGION2_OFFSET 0x02000000
39
40static int acp_dmic_prepare(struct snd_pcm_substream *substream,28static int acp_dmic_prepare(struct snd_pcm_substream *substream,
41 struct snd_soc_dai *dai)29 struct snd_soc_dai *dai)
42{30{
@@ -135,6 +123,7 @@ static int acp_dmic_hwparams(struct snd_pcm_substream *substream, · 92 unmodified lines
135 return -EINVAL;123 return -EINVAL;
136 }124 }
137 125
126 adata->ch_mask = ch_mask;
138 if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) {127 if (params_format(hwparams) != SNDRV_PCM_FORMAT_S32_LE) {
139 dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams));128 dev_err(dai->dev, "Invalid format:%d\n", params_format(hwparams));
140 return -EINVAL;129 return -EINVAL;
sound/soc/amd/acp/acp-platform.c+4−2
@@ -127,7 +127,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *data) · 126 unmodified lines
127 return IRQ_NONE;127 return IRQ_NONE;
128}128}
129 129
130static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)130void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
131{131{
132 struct acp_resource *rsrc = adata->rsrc;132 struct acp_resource *rsrc = adata->rsrc;
133 u32 pte_reg, pte_size, reg_val;133 u32 pte_reg, pte_size, reg_val;
@@ -143,8 +143,9 @@ static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream · 9 unmodified lines
143 writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size);143 writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size);
144 writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);144 writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
145}145}
146EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON);
146 147
147static void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size)148void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size)
148{149{
149 struct snd_pcm_substream *substream = stream->substream;150 struct snd_pcm_substream *substream = stream->substream;
150 struct acp_resource *rsrc = adata->rsrc;151 struct acp_resource *rsrc = adata->rsrc;
@@ -168,6 +169,7 @@ static void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream · 17 unmodified lines
168 addr += PAGE_SIZE;169 addr += PAGE_SIZE;
169 }170 }
170}171}
172EXPORT_SYMBOL_NS_GPL(config_acp_dma, SND_SOC_ACP_COMMON);
171 173
172static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream)174static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream)
173{175{
sound/soc/amd/acp/acp-rembrandt.c+59−128
@@ -19,30 +19,17 @@ · 18 unmodified lines
19#include <sound/soc.h>19#include <sound/soc.h>
20#include <sound/soc-dai.h>20#include <sound/soc-dai.h>
21#include <linux/dma-mapping.h>21#include <linux/dma-mapping.h>
22#include <linux/pci.h>
23#include <linux/pm_runtime.h>
22 24
23#include "amd.h"25#include "amd.h"
24 26
25#define DRV_NAME "acp_asoc_rembrandt"27#define DRV_NAME "acp_asoc_rembrandt"
26 28
27#define ACP6X_PGFSM_CONTROL 0x102429#define MP1_C2PMSG_69 0x3B10A14
28#define ACP6X_PGFSM_STATUS 0x102830#define MP1_C2PMSG_85 0x3B10A54
29 31#define MP1_C2PMSG_93 0x3B10A74
30#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x0001000132#define HOST_BRIDGE_ID 0x14B5
31
32#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
33#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
34#define ACP_PGFSM_STATUS_MASK 0x03
35#define ACP_POWERED_ON 0x00
36#define ACP_POWER_ON_IN_PROGRESS 0x01
37#define ACP_POWERED_OFF 0x02
38#define ACP_POWER_OFF_IN_PROGRESS 0x03
39
40#define ACP_ERROR_MASK 0x20000000
41#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
42
43
44static int rmb_acp_init(void __iomem *base);
45static int rmb_acp_deinit(void __iomem *base);
46 33
47static struct acp_resource rsrc = {34static struct acp_resource rsrc = {
48 .offset = 0,35 .offset = 0,
@@ -111,7 +98,6 @@ static struct snd_soc_dai_driver acp_rmb_dai[] = { · 62 unmodified lines
111 .rate_max = 48000,98 .rate_max = 48000,
112 },99 },
113 .ops = &asoc_acp_cpu_dai_ops,100 .ops = &asoc_acp_cpu_dai_ops,
114 .probe = &asoc_acp_i2s_probe,
115},101},
116{102{
117 .name = "acp-i2s-bt",103 .name = "acp-i2s-bt",
@@ -137,7 +123,6 @@ static struct snd_soc_dai_driver acp_rmb_dai[] = { · 19 unmodified lines
137 .rate_max = 48000,123 .rate_max = 48000,
138 },124 },
139 .ops = &asoc_acp_cpu_dai_ops,125 .ops = &asoc_acp_cpu_dai_ops,
140 .probe = &asoc_acp_i2s_probe,
141},126},
142{127{
143 .name = "acp-i2s-hs",128 .name = "acp-i2s-hs",
@@ -163,7 +148,6 @@ static struct snd_soc_dai_driver acp_rmb_dai[] = { · 19 unmodified lines
163 .rate_max = 48000,148 .rate_max = 48000,
164 },149 },
165 .ops = &asoc_acp_cpu_dai_ops,150 .ops = &asoc_acp_cpu_dai_ops,
166 .probe = &asoc_acp_i2s_probe,
167},151},
168{152{
169 .name = "acp-pdm-dmic",153 .name = "acp-pdm-dmic",
@@ -180,108 +164,22 @@ static struct snd_soc_dai_driver acp_rmb_dai[] = { · 10 unmodified lines
180},164},
181};165};
182 166
183static int acp6x_power_on(void __iomem *base)167static int acp6x_master_clock_generate(struct device *dev)
184{
185 u32 val;
186 int timeout;
187
188 val = readl(base + ACP6X_PGFSM_STATUS);
189
190 if (val == ACP_POWERED_ON)
191 return 0;
192
193 if ((val & ACP_PGFSM_STATUS_MASK) !=
194 ACP_POWER_ON_IN_PROGRESS)
195 writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
196 base + ACP6X_PGFSM_CONTROL);
197 timeout = 0;
198 while (++timeout < 500) {
199 val = readl(base + ACP6X_PGFSM_STATUS);
200 if (!val)
201 return 0;
202 udelay(1);
203 }
204 return -ETIMEDOUT;
205}
206
207static int acp6x_reset(void __iomem *base)
208{168{
209 u32 val;169 int data = 0;
210 int timeout;170 struct pci_dev *smn_dev;
211
212 writel(1, base + ACP_SOFT_RESET);
213 timeout = 0;
214 while (++timeout < 500) {
215 val = readl(base + ACP_SOFT_RESET);
216 if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
217 break;
218 cpu_relax();
219 }
220 writel(0, base + ACP_SOFT_RESET);
221 timeout = 0;
222 while (++timeout < 500) {
223 val = readl(base + ACP_SOFT_RESET);
224 if (!val)
225 return 0;
226 cpu_relax();
227 }
228 return -ETIMEDOUT;
229}
230
231static void acp6x_enable_interrupts(struct acp_dev_data *adata)
232{
233 struct acp_resource *rsrc = adata->rsrc;
234 u32 ext_intr_ctrl;
235
236 writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
237 ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
238 ext_intr_ctrl |= ACP_ERROR_MASK;
239 writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
240}
241
242static void acp6x_disable_interrupts(struct acp_dev_data *adata)
243{
244 struct acp_resource *rsrc = adata->rsrc;
245
246 writel(ACP_EXT_INTR_STAT_CLEAR_MASK,
247 ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
248 writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
249}
250 171
251static int rmb_acp_init(void __iomem *base)172 smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, HOST_BRIDGE_ID, NULL);
252{173 if (!smn_dev) {
253 int ret;174 dev_err(dev, "Failed to get host bridge device\n");
254 175 return -ENODEV;
255 /* power on */
256 ret = acp6x_power_on(base);
257 if (ret) {
258 pr_err("ACP power on failed\n");
259 return ret;
260 }
261 writel(0x01, base + ACP_CONTROL);
262
263 /* Reset */
264 ret = acp6x_reset(base);
265 if (ret) {
266 pr_err("ACP reset failed\n");
267 return ret;
268 }
269
270 return 0;
271}
272
273static int rmb_acp_deinit(void __iomem *base)
274{
275 int ret = 0;
276
277 /* Reset */
278 ret = acp6x_reset(base);
279 if (ret) {
280 pr_err("ACP reset failed\n");
281 return ret;
282 }176 }
283 177
284 writel(0x00, base + ACP_CONTROL);178 smn_write(smn_dev, MP1_C2PMSG_93, 0);
179 smn_write(smn_dev, MP1_C2PMSG_85, 0xC4);
180 smn_write(smn_dev, MP1_C2PMSG_69, 0x4);
181 read_poll_timeout(smn_read, data, data, DELAY_US,
182 ACP_TIMEOUT, false, smn_dev, MP1_C2PMSG_93);
285 return 0;183 return 0;
286}184}
287 185
@@ -303,8 +201,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev) · 15 unmodified lines
303 return -ENODEV;201 return -ENODEV;
304 }202 }
305 203
306 rmb_acp_init(chip->base);
307
308 adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);204 adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
309 if (!adata)205 if (!adata)
310 return -ENOMEM;206 return -ENOMEM;
@@ -335,9 +231,14 @@ static int rembrandt_audio_probe(struct platform_device *pdev) · 24 unmodified lines
335 acp_machine_select(adata);231 acp_machine_select(adata);
336 232
337 dev_set_drvdata(dev, adata);233 dev_set_drvdata(dev, adata);
338 acp6x_enable_interrupts(adata);234 acp6x_master_clock_generate(dev);
235 acp_enable_interrupts(adata);
339 acp_platform_register(dev);236 acp_platform_register(dev);
340 237 pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
238 pm_runtime_use_autosuspend(&pdev->dev);
239 pm_runtime_mark_last_busy(&pdev->dev);
240 pm_runtime_set_active(&pdev->dev);
241 pm_runtime_enable(&pdev->dev);
341 return 0;242 return 0;
342}243}
343 244
@@ -345,19 +246,49 @@ static void rembrandt_audio_remove(struct platform_device *pdev) · 1 unmodified line
345{246{
346 struct device *dev = &pdev->dev;247 struct device *dev = &pdev->dev;
347 struct acp_dev_data *adata = dev_get_drvdata(dev);248 struct acp_dev_data *adata = dev_get_drvdata(dev);
348 struct acp_chip_info *chip = dev_get_platdata(dev);
349
350 rmb_acp_deinit(chip->base);
351 249
352 acp6x_disable_interrupts(adata);250 acp_disable_interrupts(adata);
353 acp_platform_unregister(dev);251 acp_platform_unregister(dev);
252 pm_runtime_disable(&pdev->dev);
354}253}
355 254
255static int __maybe_unused rmb_pcm_resume(struct device *dev)
256{
257 struct acp_dev_data *adata = dev_get_drvdata(dev);
258 struct acp_stream *stream;
259 struct snd_pcm_substream *substream;
260 snd_pcm_uframes_t buf_in_frames;
261 u64 buf_size;
262
263 acp6x_master_clock_generate(dev);
264 spin_lock(&adata->acp_lock);
265 list_for_each_entry(stream, &adata->stream_list, list) {
266 substream = stream->substream;
267 if (substream && substream->runtime) {
268 buf_in_frames = (substream->runtime->buffer_size);
269 buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
270 config_pte_for_stream(adata, stream);
271 config_acp_dma(adata, stream, buf_size);
272 if (stream->dai_id)
273 restore_acp_i2s_params(substream, adata, stream);
274 else
275 restore_acp_pdm_params(substream, adata);
276 }
277 }
278 spin_unlock(&adata->acp_lock);
279 return 0;
280}
281
282static const struct dev_pm_ops rmb_dma_pm_ops = {
283 SET_SYSTEM_SLEEP_PM_OPS(NULL, rmb_pcm_resume)
284};
285
356static struct platform_driver rembrandt_driver = {286static struct platform_driver rembrandt_driver = {
357 .probe = rembrandt_audio_probe,287 .probe = rembrandt_audio_probe,
358 .remove_new = rembrandt_audio_remove,288 .remove_new = rembrandt_audio_remove,
359 .driver = {289 .driver = {
360 .name = "acp_asoc_rembrandt",290 .name = "acp_asoc_rembrandt",
291 .pm = &rmb_dma_pm_ops,
361 },292 },
362};293};
363 294
sound/soc/amd/acp/acp-renoir.c+2−115
@@ -25,20 +25,6 @@ · 24 unmodified lines
25 25
26#define DRV_NAME "acp_asoc_renoir"26#define DRV_NAME "acp_asoc_renoir"
27 27
28#define ACP_SOFT_RST_DONE_MASK 0x00010001
29
30#define ACP_PWR_ON_MASK 0x01
31#define ACP_PWR_OFF_MASK 0x00
32#define ACP_PGFSM_STAT_MASK 0x03
33#define ACP_POWERED_ON 0x00
34#define ACP_PWR_ON_IN_PROGRESS 0x01
35#define ACP_POWERED_OFF 0x02
36#define DELAY_US 5
37#define ACP_TIMEOUT 500
38
39#define ACP_ERROR_MASK 0x20000000
40#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
41
42static struct acp_resource rsrc = {28static struct acp_resource rsrc = {
43 .offset = 20,29 .offset = 20,
44 .no_of_ctrls = 1,30 .no_of_ctrls = 1,
@@ -111,7 +97,6 @@ static struct snd_soc_dai_driver acp_renoir_dai[] = { · 66 unmodified lines
111 .rate_max = 48000,97 .rate_max = 48000,
112 },98 },
113 .ops = &asoc_acp_cpu_dai_ops,99 .ops = &asoc_acp_cpu_dai_ops,
114 .probe = &asoc_acp_i2s_probe,
115},100},
116{101{
117 .name = "acp-i2s-bt",102 .name = "acp-i2s-bt",
@@ -137,7 +122,6 @@ static struct snd_soc_dai_driver acp_renoir_dai[] = { · 19 unmodified lines
137 .rate_max = 48000,122 .rate_max = 48000,
138 },123 },
139 .ops = &asoc_acp_cpu_dai_ops,124 .ops = &asoc_acp_cpu_dai_ops,
140 .probe = &asoc_acp_i2s_probe,
141},125},
142{126{
143 .name = "acp-pdm-dmic",127 .name = "acp-pdm-dmic",
@@ -154,89 +138,7 @@ static struct snd_soc_dai_driver acp_renoir_dai[] = { · 10 unmodified lines
154},138},
155};139};
156 140
157static int acp3x_power_on(void __iomem *base)
158{
159 u32 val;
160
161 val = readl(base + ACP_PGFSM_STATUS);
162
163 if (val == ACP_POWERED_ON)
164 return 0;
165
166 if ((val & ACP_PGFSM_STAT_MASK) != ACP_PWR_ON_IN_PROGRESS)
167 writel(ACP_PWR_ON_MASK, base + ACP_PGFSM_CONTROL);
168
169 return readl_poll_timeout(base + ACP_PGFSM_STATUS, val, !val, DELAY_US, ACP_TIMEOUT);
170}
171
172static int acp3x_reset(void __iomem *base)
173{
174 u32 val;
175 int ret;
176
177 writel(1, base + ACP_SOFT_RESET);
178
179 ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK,
180 DELAY_US, ACP_TIMEOUT);
181 if (ret)
182 return ret;
183
184 writel(0, base + ACP_SOFT_RESET);
185
186 return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT);
187}
188
189static void acp3x_enable_interrupts(struct acp_dev_data *adata)
190{
191 struct acp_resource *rsrc = adata->rsrc;
192 u32 ext_intr_ctrl;
193
194 writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
195 ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
196 ext_intr_ctrl |= ACP_ERROR_MASK;
197 writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
198}
199
200static void acp3x_disable_interrupts(struct acp_dev_data *adata)
201{
202 struct acp_resource *rsrc = adata->rsrc;
203
204 writel(ACP_EXT_INTR_STAT_CLEAR_MASK,
205 ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
206 writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
207}
208 141
209static int rn_acp_init(void __iomem *base)
210{
211 int ret;
212
213 /* power on */
214 ret = acp3x_power_on(base);
215 if (ret)
216 return ret;
217
218 writel(0x01, base + ACP_CONTROL);
219
220 /* Reset */
221 ret = acp3x_reset(base);
222 if (ret)
223 return ret;
224
225 return 0;
226}
227
228static int rn_acp_deinit(void __iomem *base)
229{
230 int ret = 0;
231
232 /* Reset */
233 ret = acp3x_reset(base);
234 if (ret)
235 return ret;
236
237 writel(0x00, base + ACP_CONTROL);
238 return 0;
239}
240static int renoir_audio_probe(struct platform_device *pdev)142static int renoir_audio_probe(struct platform_device *pdev)
241{143{
242 struct device *dev = &pdev->dev;144 struct device *dev = &pdev->dev;
@@ -256,12 +158,6 @@ static int renoir_audio_probe(struct platform_device *pdev) · 13 unmodified lines
256 return -ENODEV;158 return -ENODEV;
257 }159 }
258 160
259 ret = rn_acp_init(chip->base);
260 if (ret) {
261 dev_err(&pdev->dev, "ACP Init failed\n");
262 return -EINVAL;
263 }
264
265 adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);161 adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
266 if (!adata)162 if (!adata)
267 return -ENOMEM;163 return -ENOMEM;
@@ -290,7 +186,7 @@ static int renoir_audio_probe(struct platform_device *pdev) · 22 unmodified lines
290 acp_machine_select(adata);186 acp_machine_select(adata);
291 187
292 dev_set_drvdata(dev, adata);188 dev_set_drvdata(dev, adata);
293 acp3x_enable_interrupts(adata);189 acp_enable_interrupts(adata);
294 acp_platform_register(dev);190 acp_platform_register(dev);
295 191
296 return 0;192 return 0;
@@ -300,17 +196,8 @@ static void renoir_audio_remove(struct platform_device *pdev) · 3 unmodified lines
300{196{
301 struct device *dev = &pdev->dev;197 struct device *dev = &pdev->dev;
302 struct acp_dev_data *adata = dev_get_drvdata(dev);198 struct acp_dev_data *adata = dev_get_drvdata(dev);
303 struct acp_chip_info *chip;
304 int ret;
305
306 chip = dev_get_platdata(&pdev->dev);
307
308 acp3x_disable_interrupts(adata);
309
310 ret = rn_acp_deinit(chip->base);
311 if (ret)
312 dev_err(&pdev->dev, "ACP de-init Failed (%pe)\n", ERR_PTR(ret));
313 199
200 acp_disable_interrupts(adata);
314 acp_platform_unregister(dev);201 acp_platform_unregister(dev);
315}202}
316 203
sound/soc/amd/acp/acp-sof-mach.c+15−18
@@ -83,20 +83,15 @@ static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { · 82 unmodified lines
83 .tdm_mode = false,83 .tdm_mode = false,
84};84};
85 85
86static const struct snd_kcontrol_new acp_controls[] = {86static struct acp_card_drvdata sof_nau8821_max98388_data = {
87 SOC_DAPM_PIN_SWITCH("Headphone Jack"),87 .hs_cpu_id = I2S_SP,
88 SOC_DAPM_PIN_SWITCH("Headset Mic"),88 .amp_cpu_id = I2S_HS,
89 SOC_DAPM_PIN_SWITCH("Spk"),89 .dmic_cpu_id = NONE,
90 SOC_DAPM_PIN_SWITCH("Left Spk"),90 .hs_codec_id = NAU8821,
91 SOC_DAPM_PIN_SWITCH("Right Spk"),91 .amp_codec_id = MAX98388,
92};92 .dmic_codec_id = NONE,
93 93 .soc_mclk = true,
94static const struct snd_soc_dapm_widget acp_widgets[] = {94 .tdm_mode = false,
95 SND_SOC_DAPM_HP("Headphone Jack", NULL),
96 SND_SOC_DAPM_MIC("Headset Mic", NULL),
97 SND_SOC_DAPM_SPK("Spk", NULL),
98 SND_SOC_DAPM_SPK("Left Spk", NULL),
99 SND_SOC_DAPM_SPK("Right Spk", NULL),
100};95};
101 96
102static int acp_sof_probe(struct platform_device *pdev)97static int acp_sof_probe(struct platform_device *pdev)
@@ -117,11 +112,8 @@ static int acp_sof_probe(struct platform_device *pdev) · 14 unmodified lines
117 card->dev = dev;112 card->dev = dev;
118 card->owner = THIS_MODULE;113 card->owner = THIS_MODULE;
119 card->name = pdev->id_entry->name;114 card->name = pdev->id_entry->name;
120 card->dapm_widgets = acp_widgets;
121 card->num_dapm_widgets = ARRAY_SIZE(acp_widgets);
122 card->controls = acp_controls;
123 card->num_controls = ARRAY_SIZE(acp_controls);
124 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;115 card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
116 /* Widgets and controls added per-codec in acp-mach-common.c */
125 117
126 acp_card_drvdata = card->drvdata;118 acp_card_drvdata = card->drvdata;
127 dmi_id = dmi_first_match(acp_quirk_table);119 dmi_id = dmi_first_match(acp_quirk_table);
@@ -166,6 +158,10 @@ static const struct platform_device_id board_ids[] = { · 38 unmodified lines
166 .name = "rt5682s-hs-rt1019",158 .name = "rt5682s-hs-rt1019",
167 .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data159 .driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data
168 },160 },
161 {
162 .name = "nau8821-max",
163 .driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data
164 },
169 { }165 { }
170};166};
171static struct platform_driver acp_asoc_audio = {167static struct platform_driver acp_asoc_audio = {
@@ -187,4 +183,5 @@ MODULE_ALIAS("platform:rt5682s-max"); · 15 unmodified lines
187MODULE_ALIAS("platform:rt5682s-rt1019");183MODULE_ALIAS("platform:rt5682s-rt1019");
188MODULE_ALIAS("platform:nau8825-max");184MODULE_ALIAS("platform:nau8825-max");
189MODULE_ALIAS("platform:rt5682s-hs-rt1019");185MODULE_ALIAS("platform:rt5682s-hs-rt1019");
186MODULE_ALIAS("platform:nau8821-max");
190MODULE_LICENSE("GPL v2");187MODULE_LICENSE("GPL v2");
sound/soc/amd/acp/amd.h+51−1
@@ -92,10 +92,43 @@ · 91 unmodified lines
92#define SLOT_WIDTH_24 0x1892#define SLOT_WIDTH_24 0x18
93#define SLOT_WIDTH_32 0x2093#define SLOT_WIDTH_32 0x20
94 94
95#define ACP6X_PGFSM_CONTROL 0x1024
96#define ACP6X_PGFSM_STATUS 0x1028
97
98#define ACP_SOFT_RST_DONE_MASK 0x00010001
99
100#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
101#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
102#define ACP_PGFSM_STATUS_MASK 0x03
103#define ACP_POWERED_ON 0x00
104#define ACP_POWER_ON_IN_PROGRESS 0x01
105#define ACP_POWERED_OFF 0x02
106#define ACP_POWER_OFF_IN_PROGRESS 0x03
107
108#define ACP_ERROR_MASK 0x20000000
109#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xffffffff
110
111#define ACP_TIMEOUT 500
112#define DELAY_US 5
113#define ACP_SUSPEND_DELAY_MS 2000
114
115#define PDM_DMA_STAT 0x10
116#define PDM_DMA_INTR_MASK 0x10000
117#define PDM_DEC_64 0x2
118#define PDM_CLK_FREQ_MASK 0x07
119#define PDM_MISC_CTRL_MASK 0x10
120#define PDM_ENABLE 0x01
121#define PDM_DISABLE 0x00
122#define DMA_EN_MASK 0x02
123#define DELAY_US 5
124#define PDM_TIMEOUT 1000
125#define ACP_REGION2_OFFSET 0x02000000
126
95struct acp_chip_info {127struct acp_chip_info {
96 char *name; /* Platform name */128 char *name; /* Platform name */
97 unsigned int acp_rev; /* ACP Revision id */129 unsigned int acp_rev; /* ACP Revision id */
98 void __iomem *base; /* ACP memory PCI base */130 void __iomem *base; /* ACP memory PCI base */
131 struct platform_device *chip_pdev;
99};132};
100 133
101struct acp_stream {134struct acp_stream {
@@ -144,8 +177,11 @@ struct acp_dev_data { · 42 unmodified lines
144 u32 lrclk_div;177 u32 lrclk_div;
145 178
146 struct acp_resource *rsrc;179 struct acp_resource *rsrc;
180 u32 ch_mask;
147 u32 tdm_tx_fmt[3];181 u32 tdm_tx_fmt[3];
148 u32 tdm_rx_fmt[3];182 u32 tdm_rx_fmt[3];
183 u32 xfer_tx_resolution[3];
184 u32 xfer_rx_resolution[3];
149};185};
150 186
151union acp_i2stdm_mstrclkgen {187union acp_i2stdm_mstrclkgen {
@@ -162,15 +198,29 @@ union acp_i2stdm_mstrclkgen { · 10 unmodified lines
162extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;198extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;
163extern const struct snd_soc_dai_ops acp_dmic_dai_ops;199extern const struct snd_soc_dai_ops acp_dmic_dai_ops;
164 200
165int asoc_acp_i2s_probe(struct snd_soc_dai *dai);
166int acp_platform_register(struct device *dev);201int acp_platform_register(struct device *dev);
167int acp_platform_unregister(struct device *dev);202int acp_platform_unregister(struct device *dev);
168 203
169int acp_machine_select(struct acp_dev_data *adata);204int acp_machine_select(struct acp_dev_data *adata);
170 205
206int smn_read(struct pci_dev *dev, u32 smn_addr);
207int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data);
208
209int acp_init(struct acp_chip_info *chip);
210int acp_deinit(void __iomem *base);
211void acp_enable_interrupts(struct acp_dev_data *adata);
212void acp_disable_interrupts(struct acp_dev_data *adata);
171/* Machine configuration */213/* Machine configuration */
172int snd_amd_acp_find_config(struct pci_dev *pci);214int snd_amd_acp_find_config(struct pci_dev *pci);
173 215
216void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream);
217void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size);
218void restore_acp_pdm_params(struct snd_pcm_substream *substream,
219 struct acp_dev_data *adata);
220
221int restore_acp_i2s_params(struct snd_pcm_substream *substream,
222 struct acp_dev_data *adata, struct acp_stream *stream);
223
174static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)224static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)
175{225{
176 u64 byte_count = 0, low = 0, high = 0;226 u64 byte_count = 0, low = 0, high = 0;
sound/soc/amd/acp3x-rt5682-max9836.c+18−5
@@ -28,6 +28,17 @@ · 27 unmodified lines
28#define DUAL_CHANNEL 228#define DUAL_CHANNEL 2
29 29
30static struct snd_soc_jack pco_jack;30static struct snd_soc_jack pco_jack;
31static struct snd_soc_jack_pin pco_jack_pins[] = {
32 {
33 .pin = "Headphone Jack",
34 .mask = SND_JACK_HEADPHONE,
35 },
36 {
37 .pin = "Headset Mic",
38 .mask = SND_JACK_MICROPHONE,
39 },
40};
41
31static struct clk *rt5682_dai_wclk;42static struct clk *rt5682_dai_wclk;
32static struct clk *rt5682_dai_bclk;43static struct clk *rt5682_dai_bclk;
33static struct gpio_desc *dmic_sel;44static struct gpio_desc *dmic_sel;
@@ -86,11 +97,13 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd) · 52 unmodified lines
86 rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");97 rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk");
87 rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");98 rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk");
88 99
89 ret = snd_soc_card_jack_new(card, "Headset Jack",100 ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
90 SND_JACK_HEADSET | SND_JACK_LINEOUT |101 SND_JACK_HEADSET |
91 SND_JACK_BTN_0 | SND_JACK_BTN_1 |102 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
92 SND_JACK_BTN_2 | SND_JACK_BTN_3,103 SND_JACK_BTN_2 | SND_JACK_BTN_3,
93 &pco_jack);104 &pco_jack,
105 pco_jack_pins,
106 ARRAY_SIZE(pco_jack_pins));
94 if (ret) {107 if (ret) {
95 dev_err(card->dev, "HP jack creation failed %d\n", ret);108 dev_err(card->dev, "HP jack creation failed %d\n", ret);
96 return ret;109 return ret;
sound/soc/amd/mach-config.h+1−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
20 20
21extern struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[];21extern struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[];
22extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[];22extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[];
23extern struct snd_soc_acpi_mach snd_soc_acpi_amd_vangogh_sof_machines[];
23 24
24struct config_entry {25struct config_entry {
25 u32 flags;26 u32 flags;
sound/soc/amd/ps/ps-sdw-dma.c+2−3
@@ -488,10 +488,9 @@ static int acp63_sdw_platform_probe(struct platform_device *pdev) · 487 unmodified lines
488 return 0;488 return 0;
489}489}
490 490
491static int acp63_sdw_platform_remove(struct platform_device *pdev)491static void acp63_sdw_platform_remove(struct platform_device *pdev)
492{492{
493 pm_runtime_disable(&pdev->dev);493 pm_runtime_disable(&pdev->dev);
494 return 0;
495}494}
496 495
497static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)496static int acp_restore_sdw_dma_config(struct sdw_dma_dev_data *sdw_data)
@@ -552,7 +551,7 @@ static const struct dev_pm_ops acp63_pm_ops = { · 54 unmodified lines
552 551
553static struct platform_driver acp63_sdw_dma_driver = {552static struct platform_driver acp63_sdw_dma_driver = {
554 .probe = acp63_sdw_platform_probe,553 .probe = acp63_sdw_platform_probe,
555 .remove = acp63_sdw_platform_remove,554 .remove_new = acp63_sdw_platform_remove,
556 .driver = {555 .driver = {
557 .name = "amd_ps_sdw_dma",556 .name = "amd_ps_sdw_dma",
558 .pm = &acp63_pm_ops,557 .pm = &acp63_pm_ops,
sound/soc/amd/vangogh/acp5x-mach.c+131−21
@@ -1,7 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0+1// SPDX-License-Identifier: GPL-2.0+
2/*2/*
3 * Machine driver for AMD Vangogh platform using NAU8821 & CS35L413 * Machine driver for AMD Vangogh platform using either
4 * codecs.4 * NAU8821 & CS35L41 or NAU8821 & MAX98388 codecs.
5 *5 *
6 * Copyright 2021 Advanced Micro Devices, Inc.6 * Copyright 2021 Advanced Micro Devices, Inc.
7 */7 */
@@ -22,7 +22,6 @@ · 14 unmodified lines
22 22
23#define DRV_NAME "acp5x_mach"23#define DRV_NAME "acp5x_mach"
24#define DUAL_CHANNEL 224#define DUAL_CHANNEL 2
25#define VG_JUPITER 1
26#define ACP5X_NAU8821_BCLK 307200025#define ACP5X_NAU8821_BCLK 3072000
27#define ACP5X_NAU8821_FREQ_OUT 1228800026#define ACP5X_NAU8821_FREQ_OUT 12288000
28#define ACP5X_NAU8821_COMP_NAME "i2c-NVTN2020:00"27#define ACP5X_NAU8821_COMP_NAME "i2c-NVTN2020:00"
@@ -30,8 +29,10 @@ · 1 unmodified line
30#define ACP5X_CS35L41_COMP_LNAME "spi-VLV1776:00"29#define ACP5X_CS35L41_COMP_LNAME "spi-VLV1776:00"
31#define ACP5X_CS35L41_COMP_RNAME "spi-VLV1776:01"30#define ACP5X_CS35L41_COMP_RNAME "spi-VLV1776:01"
32#define ACP5X_CS35L41_DAI_NAME "cs35l41-pcm"31#define ACP5X_CS35L41_DAI_NAME "cs35l41-pcm"
32#define ACP5X_MAX98388_COMP_LNAME "i2c-ADS8388:00"
33#define ACP5X_MAX98388_COMP_RNAME "i2c-ADS8388:01"
34#define ACP5X_MAX98388_DAI_NAME "max98388-aif1"
33 35
34static unsigned long acp5x_machine_id;
35static struct snd_soc_jack vg_headset;36static struct snd_soc_jack vg_headset;
36 37
37SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));38SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("acp5x_i2s_dma.0")));
@@ -169,6 +170,9 @@ static int acp5x_nau8821_hw_params(struct snd_pcm_substream *substream, · 131 unmodified lines
169 struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);170 struct snd_soc_dai *dai = snd_soc_card_get_codec_dai(card, ACP5X_NAU8821_DAI_NAME);
170 int ret, bclk;171 int ret, bclk;
171 172
173 if (!dai)
174 return -EINVAL;
175
172 ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);176 ret = snd_soc_dai_set_sysclk(dai, NAU8821_CLK_FLL_BLK, 0, SND_SOC_CLOCK_IN);
173 if (ret < 0)177 if (ret < 0)
174 dev_err(card->dev, "can't set FS clock %d\n", ret);178 dev_err(card->dev, "can't set FS clock %d\n", ret);
@@ -242,7 +246,6 @@ static int acp5x_cs35l41_hw_params(struct snd_pcm_substream *substream, · 67 unmodified lines
242 }246 }
243 247
244 return 0;248 return 0;
245
246}249}
247 250
248static const struct snd_soc_ops acp5x_cs35l41_play_ops = {251static const struct snd_soc_ops acp5x_cs35l41_play_ops = {
@@ -292,8 +295,6 @@ static struct snd_soc_dai_link acp5x_8821_35l41_dai[] = { · 43 unmodified lines
292 },295 },
293};296};
294 297
295
296
297static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = {298static const struct snd_soc_dapm_widget acp5x_8821_35l41_widgets[] = {
298 SND_SOC_DAPM_HP("Headphone", NULL),299 SND_SOC_DAPM_HP("Headphone", NULL),
299 SND_SOC_DAPM_MIC("Headset Mic", NULL),300 SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -331,16 +332,110 @@ static struct snd_soc_card acp5x_8821_35l41_card = { · 31 unmodified lines
331 .num_controls = ARRAY_SIZE(acp5x_8821_controls),332 .num_controls = ARRAY_SIZE(acp5x_8821_controls),
332};333};
333 334
334static int acp5x_vg_quirk_cb(const struct dmi_system_id *id)335static int acp5x_max98388_startup(struct snd_pcm_substream *substream)
335{336{
336 acp5x_machine_id = VG_JUPITER;337 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
338 struct acp5x_platform_info *machine = snd_soc_card_get_drvdata(rtd->card);
339 struct snd_pcm_runtime *runtime = substream->runtime;
340
341 machine->play_i2s_instance = I2S_HS_INSTANCE;
337 342
338 return 1;343 runtime->hw.channels_max = DUAL_CHANNEL;
344 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
345 &constraints_channels);
346 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
347 &constraints_rates);
348 return 0;
339}349}
340 350
351static const struct snd_soc_ops acp5x_max98388_play_ops = {
352 .startup = acp5x_max98388_startup,
353};
354
355static struct snd_soc_codec_conf acp5x_max98388_conf[] = {
356 {
357 .dlc = COMP_CODEC_CONF(ACP5X_MAX98388_COMP_LNAME),
358 .name_prefix = "Left",
359 },
360 {
361 .dlc = COMP_CODEC_CONF(ACP5X_MAX98388_COMP_RNAME),
362 .name_prefix = "Right",
363 },
364};
365
366SND_SOC_DAILINK_DEF(max98388, DAILINK_COMP_ARRAY(COMP_CODEC(ACP5X_MAX98388_COMP_LNAME,
367 ACP5X_MAX98388_DAI_NAME),
368 COMP_CODEC(ACP5X_MAX98388_COMP_RNAME,
369 ACP5X_MAX98388_DAI_NAME)));
370
371static struct snd_soc_dai_link acp5x_8821_98388_dai[] = {
372 {
373 .name = "acp5x-8821-play",
374 .stream_name = "Playback/Capture",
375 .dai_fmt = SND_SOC_DAIFMT_I2S |
376 SND_SOC_DAIFMT_NB_NF |
377 SND_SOC_DAIFMT_CBC_CFC,
378 .dpcm_playback = 1,
379 .dpcm_capture = 1,
380 .ops = &acp5x_8821_ops,
381 .init = acp5x_8821_init,
382 SND_SOC_DAILINK_REG(acp5x_i2s, nau8821, platform),
383 },
384 {
385 .name = "acp5x-max98388-play",
386 .stream_name = "MAX98388 Playback",
387 .dai_fmt = SND_SOC_DAIFMT_I2S |
388 SND_SOC_DAIFMT_NB_NF |
389 SND_SOC_DAIFMT_CBC_CFC,
390 .dpcm_playback = 1,
391 .playback_only = 1,
392 .ops = &acp5x_max98388_play_ops,
393 SND_SOC_DAILINK_REG(acp5x_bt, max98388, platform),
394 },
395};
396
397static const struct snd_soc_dapm_widget acp5x_8821_98388_widgets[] = {
398 SND_SOC_DAPM_HP("Headphone", NULL),
399 SND_SOC_DAPM_MIC("Headset Mic", NULL),
400 SND_SOC_DAPM_MIC("Int Mic", NULL),
401 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
402 platform_clock_control,
403 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
404 SND_SOC_DAPM_SPK("SPK", NULL),
405};
406
407static const struct snd_soc_dapm_route acp5x_8821_98388_route[] = {
408 { "Headphone", NULL, "HPOL" },
409 { "Headphone", NULL, "HPOR" },
410 { "MICL", NULL, "Headset Mic" },
411 { "MICR", NULL, "Headset Mic" },
412 { "DMIC", NULL, "Int Mic" },
413
414 { "Headphone", NULL, "Platform Clock" },
415 { "Headset Mic", NULL, "Platform Clock" },
416 { "Int Mic", NULL, "Platform Clock" },
417
418 { "SPK", NULL, "Left BE_OUT" },
419 { "SPK", NULL, "Right BE_OUT" },
420};
421
422static struct snd_soc_card acp5x_8821_98388_card = {
423 .name = "acp5x-max98388",
424 .owner = THIS_MODULE,
425 .dai_link = acp5x_8821_98388_dai,
426 .num_links = ARRAY_SIZE(acp5x_8821_98388_dai),
427 .dapm_widgets = acp5x_8821_98388_widgets,
428 .num_dapm_widgets = ARRAY_SIZE(acp5x_8821_98388_widgets),
429 .dapm_routes = acp5x_8821_98388_route,
430 .num_dapm_routes = ARRAY_SIZE(acp5x_8821_98388_route),
431 .codec_conf = acp5x_max98388_conf,
432 .num_configs = ARRAY_SIZE(acp5x_max98388_conf),
433 .controls = acp5x_8821_controls,
434 .num_controls = ARRAY_SIZE(acp5x_8821_controls),
435};
436
341static const struct dmi_system_id acp5x_vg_quirk_table[] = {437static const struct dmi_system_id acp5x_vg_quirk_table[] = {
342 {438 {
343 .callback = acp5x_vg_quirk_cb,
344 .matches = {439 .matches = {
345 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),440 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Valve"),
346 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),441 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"),
@@ -351,23 +446,31 @@ static const struct dmi_system_id acp5x_vg_quirk_table[] = { · 4 unmodified lines
351 446
352static int acp5x_probe(struct platform_device *pdev)447static int acp5x_probe(struct platform_device *pdev)
353{448{
449 const struct dmi_system_id *dmi_id;
354 struct acp5x_platform_info *machine;450 struct acp5x_platform_info *machine;
355 struct device *dev = &pdev->dev;451 struct device *dev = &pdev->dev;
356 struct snd_soc_card *card;452 struct snd_soc_card *card;
357 int ret;453 int ret;
358 454
455 card = (struct snd_soc_card *)device_get_match_data(dev);
456 if (!card) {
457 /*
458 * This is normally the result of directly probing the driver
459 * in pci-acp5x through platform_device_register_full(), which
460 * is necessary for the CS35L41 variant, as it doesn't support
461 * ACPI probing and relies on DMI quirks.
462 */
463 dmi_id = dmi_first_match(acp5x_vg_quirk_table);
464 if (!dmi_id)
465 return -ENODEV;
466
467 card = &acp5x_8821_35l41_card;
468 }
469
359 machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);470 machine = devm_kzalloc(dev, sizeof(*machine), GFP_KERNEL);
360 if (!machine)471 if (!machine)
361 return -ENOMEM;472 return -ENOMEM;
362 473
363 dmi_check_system(acp5x_vg_quirk_table);
364 switch (acp5x_machine_id) {
365 case VG_JUPITER:
366 card = &acp5x_8821_35l41_card;
367 break;
368 default:
369 return -ENODEV;
370 }
371 card->dev = dev;474 card->dev = dev;
372 platform_set_drvdata(pdev, card);475 platform_set_drvdata(pdev, card);
373 snd_soc_card_set_drvdata(card, machine);476 snd_soc_card_set_drvdata(card, machine);
@@ -379,10 +482,17 @@ static int acp5x_probe(struct platform_device *pdev) · 5 unmodified lines
379 return 0;482 return 0;
380}483}
381 484
485static const struct acpi_device_id acp5x_acpi_match[] = {
486 { "AMDI8821", (kernel_ulong_t)&acp5x_8821_98388_card },
487 {},
488};
489MODULE_DEVICE_TABLE(acpi, acp5x_acpi_match);
490
382static struct platform_driver acp5x_mach_driver = {491static struct platform_driver acp5x_mach_driver = {
383 .driver = {492 .driver = {
384 .name = "acp5x_mach",493 .name = DRV_NAME,
385 .pm = &snd_soc_pm_ops,494 .pm = &snd_soc_pm_ops,
495 .acpi_match_table = acp5x_acpi_match,
386 },496 },
387 .probe = acp5x_probe,497 .probe = acp5x_probe,
388};498};
@@ -390,6 +500,6 @@ static struct platform_driver acp5x_mach_driver = { · 1 unmodified line
390module_platform_driver(acp5x_mach_driver);500module_platform_driver(acp5x_mach_driver);
391 501
392MODULE_AUTHOR("Vijendar.Mukunda@amd.com");502MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
393MODULE_DESCRIPTION("NAU8821 & CS35L41 audio support");503MODULE_DESCRIPTION("NAU8821/CS35L41 & NAU8821/MAX98388 audio support");
394MODULE_LICENSE("GPL v2");504MODULE_LICENSE("GPL v2");
395MODULE_ALIAS("platform:" DRV_NAME);505MODULE_ALIAS("platform:" DRV_NAME);
sound/soc/atmel/atmel-i2s.c+9−9
@@ -532,13 +532,6 @@ static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd, · 531 unmodified lines
532 return err;532 return err;
533}533}
534 534
535static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
536 .prepare = atmel_i2s_prepare,
537 .trigger = atmel_i2s_trigger,
538 .hw_params = atmel_i2s_hw_params,
539 .set_fmt = atmel_i2s_set_dai_fmt,
540};
541
542static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)535static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)
543{536{
544 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);537 struct atmel_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
@@ -547,8 +540,15 @@ static int atmel_i2s_dai_probe(struct snd_soc_dai *dai) · 2 unmodified lines
547 return 0;540 return 0;
548}541}
549 542
543static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
544 .probe = atmel_i2s_dai_probe,
545 .prepare = atmel_i2s_prepare,
546 .trigger = atmel_i2s_trigger,
547 .hw_params = atmel_i2s_hw_params,
548 .set_fmt = atmel_i2s_set_dai_fmt,
549};
550
550static struct snd_soc_dai_driver atmel_i2s_dai = {551static struct snd_soc_dai_driver atmel_i2s_dai = {
551 .probe = atmel_i2s_dai_probe,
552 .playback = {552 .playback = {
553 .channels_min = 1,553 .channels_min = 1,
554 .channels_max = 2,554 .channels_max = 2,
@@ -730,7 +730,7 @@ static void atmel_i2s_remove(struct platform_device *pdev) · 175 unmodified lines
730static struct platform_driver atmel_i2s_driver = {730static struct platform_driver atmel_i2s_driver = {
731 .driver = {731 .driver = {
732 .name = "atmel_i2s",732 .name = "atmel_i2s",
733 .of_match_table = of_match_ptr(atmel_i2s_dt_ids),733 .of_match_table = atmel_i2s_dt_ids,
734 },734 },
735 .probe = atmel_i2s_probe,735 .probe = atmel_i2s_probe,
736 .remove_new = atmel_i2s_remove,736 .remove_new = atmel_i2s_remove,
sound/soc/atmel/atmel-pdmic.c+1−1
@@ -690,7 +690,7 @@ unregister_codec: · 689 unmodified lines
690static struct platform_driver atmel_pdmic_driver = {690static struct platform_driver atmel_pdmic_driver = {
691 .driver = {691 .driver = {
692 .name = "atmel-pdmic",692 .name = "atmel-pdmic",
693 .of_match_table = of_match_ptr(atmel_pdmic_of_match),693 .of_match_table = atmel_pdmic_of_match,
694 .pm = &snd_soc_pm_ops,694 .pm = &snd_soc_pm_ops,
695 },695 },
696 .probe = atmel_pdmic_probe,696 .probe = atmel_pdmic_probe,
sound/soc/atmel/mchp-i2s-mcc.c+13−13
@@ -870,17 +870,6 @@ static int mchp_i2s_mcc_startup(struct snd_pcm_substream *substream, · 869 unmodified lines
870 return 0;870 return 0;
871}871}
872 872
873static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = {
874 .set_sysclk = mchp_i2s_mcc_set_sysclk,
875 .set_bclk_ratio = mchp_i2s_mcc_set_bclk_ratio,
876 .startup = mchp_i2s_mcc_startup,
877 .trigger = mchp_i2s_mcc_trigger,
878 .hw_params = mchp_i2s_mcc_hw_params,
879 .hw_free = mchp_i2s_mcc_hw_free,
880 .set_fmt = mchp_i2s_mcc_set_dai_fmt,
881 .set_tdm_slot = mchp_i2s_mcc_set_dai_tdm_slot,
882};
883
884static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai)873static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai)
885{874{
886 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);875 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
@@ -895,6 +884,18 @@ static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai) · 8 unmodified lines
895 return 0;884 return 0;
896}885}
897 886
887static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = {
888 .probe = mchp_i2s_mcc_dai_probe,
889 .set_sysclk = mchp_i2s_mcc_set_sysclk,
890 .set_bclk_ratio = mchp_i2s_mcc_set_bclk_ratio,
891 .startup = mchp_i2s_mcc_startup,
892 .trigger = mchp_i2s_mcc_trigger,
893 .hw_params = mchp_i2s_mcc_hw_params,
894 .hw_free = mchp_i2s_mcc_hw_free,
895 .set_fmt = mchp_i2s_mcc_set_dai_fmt,
896 .set_tdm_slot = mchp_i2s_mcc_set_dai_tdm_slot,
897};
898
898#define MCHP_I2SMCC_RATES SNDRV_PCM_RATE_8000_192000899#define MCHP_I2SMCC_RATES SNDRV_PCM_RATE_8000_192000
899 900
900#define MCHP_I2SMCC_FORMATS (SNDRV_PCM_FMTBIT_S8 | \901#define MCHP_I2SMCC_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
@@ -906,7 +907,6 @@ static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai) · 5 unmodified lines
906 SNDRV_PCM_FMTBIT_S32_LE)907 SNDRV_PCM_FMTBIT_S32_LE)
907 908
908static struct snd_soc_dai_driver mchp_i2s_mcc_dai = {909static struct snd_soc_dai_driver mchp_i2s_mcc_dai = {
909 .probe = mchp_i2s_mcc_dai_probe,
910 .playback = {910 .playback = {
911 .stream_name = "I2SMCC-Playback",911 .stream_name = "I2SMCC-Playback",
912 .channels_min = 1,912 .channels_min = 1,
@@ -1098,7 +1098,7 @@ static void mchp_i2s_mcc_remove(struct platform_device *pdev) · 185 unmodified lines
1098static struct platform_driver mchp_i2s_mcc_driver = {1098static struct platform_driver mchp_i2s_mcc_driver = {
1099 .driver = {1099 .driver = {
1100 .name = "mchp_i2s_mcc",1100 .name = "mchp_i2s_mcc",
1101 .of_match_table = of_match_ptr(mchp_i2s_mcc_dt_ids),1101 .of_match_table = mchp_i2s_mcc_dt_ids,
1102 },1102 },
1103 .probe = mchp_i2s_mcc_probe,1103 .probe = mchp_i2s_mcc_probe,
1104 .remove_new = mchp_i2s_mcc_remove,1104 .remove_new = mchp_i2s_mcc_remove,
sound/soc/atmel/mchp-pdmc.c+12−20
@@ -386,7 +386,6 @@ static int mchp_pdmc_open(struct snd_soc_component *component, · 385 unmodified lines
386 for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {386 for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
387 const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];387 const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
388 struct snd_ctl_elem_id id;388 struct snd_ctl_elem_id id;
389 struct snd_kcontrol *kctl;
390 int err;389 int err;
391 390
392 if (component->name_prefix)391 if (component->name_prefix)
@@ -400,17 +399,10 @@ static int mchp_pdmc_open(struct snd_soc_component *component, · 7 unmodified lines
400 id.device = control->device;399 id.device = control->device;
401 id.subdevice = control->subdevice;400 id.subdevice = control->subdevice;
402 id.index = control->index;401 id.index = control->index;
403 kctl = snd_ctl_find_id(component->card->snd_card, &id);402 err = snd_ctl_remove_id(component->card->snd_card, &id);
404 if (!kctl) {403 if (err < 0)
405 dev_err(component->dev, "Failed to find %s\n", control->name);
406 continue;
407 }
408 err = snd_ctl_remove(component->card->snd_card, kctl);
409 if (err < 0) {
410 dev_err(component->dev, "%d: Failed to remove %s\n", err,404 dev_err(component->dev, "%d: Failed to remove %s\n", err,
411 control->name);405 control->name);
412 continue;
413 }
414 }406 }
415 407
416 return 0;408 return 0;
@@ -706,13 +698,6 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream, · 289 unmodified lines
706 return 0;698 return 0;
707}699}
708 700
709static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
710 .set_fmt = mchp_pdmc_set_fmt,
711 .startup = mchp_pdmc_startup,
712 .hw_params = mchp_pdmc_hw_params,
713 .trigger = mchp_pdmc_trigger,
714};
715
716static int mchp_pdmc_add_chmap_ctls(struct snd_pcm *pcm, struct mchp_pdmc *dd)701static int mchp_pdmc_add_chmap_ctls(struct snd_pcm *pcm, struct mchp_pdmc *dd)
717{702{
718 struct mchp_pdmc_chmap *info;703 struct mchp_pdmc_chmap *info;
@@ -765,8 +750,16 @@ static int mchp_pdmc_pcm_new(struct snd_soc_pcm_runtime *rtd, · 46 unmodified lines
765 return ret;750 return ret;
766}751}
767 752
753static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
754 .probe = mchp_pdmc_dai_probe,
755 .set_fmt = mchp_pdmc_set_fmt,
756 .startup = mchp_pdmc_startup,
757 .hw_params = mchp_pdmc_hw_params,
758 .trigger = mchp_pdmc_trigger,
759 .pcm_new = &mchp_pdmc_pcm_new,
760};
761
768static struct snd_soc_dai_driver mchp_pdmc_dai = {762static struct snd_soc_dai_driver mchp_pdmc_dai = {
769 .probe = mchp_pdmc_dai_probe,
770 .capture = {763 .capture = {
771 .stream_name = "Capture",764 .stream_name = "Capture",
772 .channels_min = 1,765 .channels_min = 1,
@@ -777,7 +770,6 @@ static struct snd_soc_dai_driver mchp_pdmc_dai = { · 4 unmodified lines
777 .formats = SNDRV_PCM_FMTBIT_S24_LE,770 .formats = SNDRV_PCM_FMTBIT_S24_LE,
778 },771 },
779 .ops = &mchp_pdmc_dai_ops,772 .ops = &mchp_pdmc_dai_ops,
780 .pcm_new = &mchp_pdmc_pcm_new,
781};773};
782 774
783/* PDMC interrupt handler */775/* PDMC interrupt handler */
@@ -962,7 +954,7 @@ static int mchp_pdmc_dt_init(struct mchp_pdmc *dd) · 178 unmodified lines
962/* used to clean the channel index found on RHR's MSB */954/* used to clean the channel index found on RHR's MSB */
963static int mchp_pdmc_process(struct snd_pcm_substream *substream,955static int mchp_pdmc_process(struct snd_pcm_substream *substream,
964 int channel, unsigned long hwoff,956 int channel, unsigned long hwoff,
965 void *buf, unsigned long bytes)957 struct iov_iter *buf, unsigned long bytes)
966{958{
967 struct snd_pcm_runtime *runtime = substream->runtime;959 struct snd_pcm_runtime *runtime = substream->runtime;
968 u8 *dma_ptr = runtime->dma_area + hwoff +960 u8 *dma_ptr = runtime->dma_area + hwoff +
sound/soc/atmel/mchp-spdifrx.c+8−8
@@ -503,11 +503,6 @@ unlock: · 502 unmodified lines
503 return ret;503 return ret;
504}504}
505 505
506static const struct snd_soc_dai_ops mchp_spdifrx_dai_ops = {
507 .trigger = mchp_spdifrx_trigger,
508 .hw_params = mchp_spdifrx_hw_params,
509};
510
511#define MCHP_SPDIF_RATES SNDRV_PCM_RATE_8000_192000506#define MCHP_SPDIF_RATES SNDRV_PCM_RATE_8000_192000
512 507
513#define MCHP_SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \508#define MCHP_SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -1009,10 +1004,15 @@ static int mchp_spdifrx_dai_remove(struct snd_soc_dai *dai) · 495 unmodified lines
1009 return 0;1004 return 0;
1010}1005}
1011 1006
1007static const struct snd_soc_dai_ops mchp_spdifrx_dai_ops = {
1008 .probe = mchp_spdifrx_dai_probe,
1009 .remove = mchp_spdifrx_dai_remove,
1010 .trigger = mchp_spdifrx_trigger,
1011 .hw_params = mchp_spdifrx_hw_params,
1012};
1013
1012static struct snd_soc_dai_driver mchp_spdifrx_dai = {1014static struct snd_soc_dai_driver mchp_spdifrx_dai = {
1013 .name = "mchp-spdifrx",1015 .name = "mchp-spdifrx",
1014 .probe = mchp_spdifrx_dai_probe,
1015 .remove = mchp_spdifrx_dai_remove,
1016 .capture = {1016 .capture = {
1017 .stream_name = "S/PDIF Capture",1017 .stream_name = "S/PDIF Capture",
1018 .channels_min = SPDIFRX_CHANNELS,1018 .channels_min = SPDIFRX_CHANNELS,
@@ -1197,7 +1197,7 @@ static struct platform_driver mchp_spdifrx_driver = { · 178 unmodified lines
1197 .remove_new = mchp_spdifrx_remove,1197 .remove_new = mchp_spdifrx_remove,
1198 .driver = {1198 .driver = {
1199 .name = "mchp_spdifrx",1199 .name = "mchp_spdifrx",
1200 .of_match_table = of_match_ptr(mchp_spdifrx_dt_ids),1200 .of_match_table = mchp_spdifrx_dt_ids,
1201 .pm = pm_ptr(&mchp_spdifrx_pm_ops),1201 .pm = pm_ptr(&mchp_spdifrx_pm_ops),
1202 },1202 },
1203};1203};
sound/soc/atmel/mchp-spdiftx.c+10−10
@@ -516,14 +516,6 @@ static int mchp_spdiftx_hw_free(struct snd_pcm_substream *substream, · 515 unmodified lines
516 SPDIFTX_CR_SWRST | SPDIFTX_CR_FCLR);516 SPDIFTX_CR_SWRST | SPDIFTX_CR_FCLR);
517}517}
518 518
519static const struct snd_soc_dai_ops mchp_spdiftx_dai_ops = {
520 .startup = mchp_spdiftx_dai_startup,
521 .shutdown = mchp_spdiftx_dai_shutdown,
522 .trigger = mchp_spdiftx_trigger,
523 .hw_params = mchp_spdiftx_hw_params,
524 .hw_free = mchp_spdiftx_hw_free,
525};
526
527#define MCHP_SPDIFTX_RATES SNDRV_PCM_RATE_8000_192000519#define MCHP_SPDIFTX_RATES SNDRV_PCM_RATE_8000_192000
528 520
529#define MCHP_SPDIFTX_FORMATS (SNDRV_PCM_FMTBIT_S8 | \521#define MCHP_SPDIFTX_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
@@ -703,9 +695,17 @@ static int mchp_spdiftx_dai_probe(struct snd_soc_dai *dai) · 173 unmodified lines
703 return 0;695 return 0;
704}696}
705 697
698static const struct snd_soc_dai_ops mchp_spdiftx_dai_ops = {
699 .probe = mchp_spdiftx_dai_probe,
700 .startup = mchp_spdiftx_dai_startup,
701 .shutdown = mchp_spdiftx_dai_shutdown,
702 .trigger = mchp_spdiftx_trigger,
703 .hw_params = mchp_spdiftx_hw_params,
704 .hw_free = mchp_spdiftx_hw_free,
705};
706
706static struct snd_soc_dai_driver mchp_spdiftx_dai = {707static struct snd_soc_dai_driver mchp_spdiftx_dai = {
707 .name = "mchp-spdiftx",708 .name = "mchp-spdiftx",
708 .probe = mchp_spdiftx_dai_probe,
709 .playback = {709 .playback = {
710 .stream_name = "S/PDIF Playback",710 .stream_name = "S/PDIF Playback",
711 .channels_min = 1,711 .channels_min = 1,
@@ -891,7 +891,7 @@ static struct platform_driver mchp_spdiftx_driver = { · 179 unmodified lines
891 .remove_new = mchp_spdiftx_remove,891 .remove_new = mchp_spdiftx_remove,
892 .driver = {892 .driver = {
893 .name = "mchp_spdiftx",893 .name = "mchp_spdiftx",
894 .of_match_table = of_match_ptr(mchp_spdiftx_dt_ids),894 .of_match_table = mchp_spdiftx_dt_ids,
895 .pm = pm_ptr(&mchp_spdiftx_pm_ops)895 .pm = pm_ptr(&mchp_spdiftx_pm_ops)
896 },896 },
897};897};
sound/soc/atmel/tse850-pcm5142.c+1−1
@@ -430,7 +430,7 @@ MODULE_DEVICE_TABLE(of, tse850_dt_ids); · 429 unmodified lines
430static struct platform_driver tse850_driver = {430static struct platform_driver tse850_driver = {
431 .driver = {431 .driver = {
432 .name = "axentia-tse850-pcm5142",432 .name = "axentia-tse850-pcm5142",
433 .of_match_table = of_match_ptr(tse850_dt_ids),433 .of_match_table = tse850_dt_ids,
434 },434 },
435 .probe = tse850_probe,435 .probe = tse850_probe,
436 .remove_new = tse850_remove,436 .remove_new = tse850_remove,
sound/soc/au1x/ac97c.c+5−5
@@ -195,18 +195,18 @@ static int alchemy_ac97c_startup(struct snd_pcm_substream *substream, · 194 unmodified lines
195 return 0;195 return 0;
196}196}
197 197
198static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
199 .startup = alchemy_ac97c_startup,
200};
201
202static int au1xac97c_dai_probe(struct snd_soc_dai *dai)198static int au1xac97c_dai_probe(struct snd_soc_dai *dai)
203{199{
204 return ac97c_workdata ? 0 : -ENODEV;200 return ac97c_workdata ? 0 : -ENODEV;
205}201}
206 202
203static const struct snd_soc_dai_ops alchemy_ac97c_ops = {
204 .probe = au1xac97c_dai_probe,
205 .startup = alchemy_ac97c_startup,
206};
207
207static struct snd_soc_dai_driver au1xac97c_dai_driver = {208static struct snd_soc_dai_driver au1xac97c_dai_driver = {
208 .name = "alchemy-ac97c",209 .name = "alchemy-ac97c",
209 .probe = au1xac97c_dai_probe,
210 .playback = {210 .playback = {
211 .rates = AC97_RATES,211 .rates = AC97_RATES,
212 .formats = AC97_FMTS,212 .formats = AC97_FMTS,
sound/soc/au1x/psc-ac97.c+1−1
@@ -333,13 +333,13 @@ static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) · 332 unmodified lines
333}333}
334 334
335static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {335static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
336 .probe = au1xpsc_ac97_probe,
336 .startup = au1xpsc_ac97_startup,337 .startup = au1xpsc_ac97_startup,
337 .trigger = au1xpsc_ac97_trigger,338 .trigger = au1xpsc_ac97_trigger,
338 .hw_params = au1xpsc_ac97_hw_params,339 .hw_params = au1xpsc_ac97_hw_params,
339};340};
340 341
341static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {342static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = {
342 .probe = au1xpsc_ac97_probe,
343 .playback = {343 .playback = {
344 .rates = AC97_RATES,344 .rates = AC97_RATES,
345 .formats = AC97_FMTS,345 .formats = AC97_FMTS,
sound/soc/bcm/bcm2835-i2s.c+12−12
@@ -737,7 +737,19 @@ static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream, · 736 unmodified lines
737 bcm2835_i2s_stop_clock(dev);737 bcm2835_i2s_stop_clock(dev);
738}738}
739 739
740static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
741{
742 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
743
744 snd_soc_dai_init_dma_data(dai,
745 &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
746 &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
747
748 return 0;
749}
750
740static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {751static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {
752 .probe = bcm2835_i2s_dai_probe,
741 .startup = bcm2835_i2s_startup,753 .startup = bcm2835_i2s_startup,
742 .shutdown = bcm2835_i2s_shutdown,754 .shutdown = bcm2835_i2s_shutdown,
743 .prepare = bcm2835_i2s_prepare,755 .prepare = bcm2835_i2s_prepare,
@@ -748,20 +760,8 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { · 4 unmodified lines
748 .set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot,760 .set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot,
749};761};
750 762
751static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
752{
753 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
754
755 snd_soc_dai_init_dma_data(dai,
756 &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
757 &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
758
759 return 0;
760}
761
762static struct snd_soc_dai_driver bcm2835_i2s_dai = {763static struct snd_soc_dai_driver bcm2835_i2s_dai = {
763 .name = "bcm2835-i2s",764 .name = "bcm2835-i2s",
764 .probe = bcm2835_i2s_dai_probe,
765 .playback = {765 .playback = {
766 .channels_min = 2,766 .channels_min = 2,
767 .channels_max = 2,767 .channels_max = 2,
sound/soc/bcm/bcm63xx-i2s-whistler.c+1−15
@@ -225,7 +225,6 @@ static int bcm63xx_i2s_dev_probe(struct platform_device *pdev) · 224 unmodified lines
225{225{
226 int ret = 0;226 int ret = 0;
227 void __iomem *regs;227 void __iomem *regs;
228 struct resource *r_mem, *region;
229 struct bcm_i2s_priv *i2s_priv;228 struct bcm_i2s_priv *i2s_priv;
230 struct regmap *regmap_i2s;229 struct regmap *regmap_i2s;
231 struct clk *i2s_clk;230 struct clk *i2s_clk;
@@ -241,20 +240,7 @@ static int bcm63xx_i2s_dev_probe(struct platform_device *pdev) · 9 unmodified lines
241 return PTR_ERR(i2s_clk);240 return PTR_ERR(i2s_clk);
242 }241 }
243 242
244 r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);243 regs = devm_platform_ioremap_resource(pdev, 0);
245 if (!r_mem) {
246 dev_err(&pdev->dev, "Unable to get register resource.\n");
247 return -ENODEV;
248 }
249
250 region = devm_request_mem_region(&pdev->dev, r_mem->start,
251 resource_size(r_mem), DRV_NAME);
252 if (!region) {
253 dev_err(&pdev->dev, "Memory region already claimed\n");
254 return -EBUSY;
255 }
256
257 regs = devm_ioremap_resource(&pdev->dev, r_mem);
258 if (IS_ERR(regs)) {244 if (IS_ERR(regs)) {
259 ret = PTR_ERR(regs);245 ret = PTR_ERR(regs);
260 return ret;246 return ret;
sound/soc/bcm/cygnus-ssp.h+0−2
@@ -117,8 +117,6 @@ struct cygnus_audio { · 116 unmodified lines
117 unsigned long vco_rate;117 unsigned long vco_rate;
118};118};
119 119
120extern int cygnus_ssp_get_mode(struct snd_soc_dai *cpu_dai);
121extern int cygnus_ssp_add_pll_tweak_controls(struct snd_soc_pcm_runtime *rtd);
122extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,120extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,
123 int len);121 int len);
124extern int cygnus_soc_platform_register(struct device *dev,122extern int cygnus_soc_platform_register(struct device *dev,
sound/soc/cirrus/ep93xx-i2s.c+1−1
@@ -407,6 +407,7 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component) · 406 unmodified lines
407#endif407#endif
408 408
409static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {409static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
410 .probe = ep93xx_i2s_dai_probe,
410 .startup = ep93xx_i2s_startup,411 .startup = ep93xx_i2s_startup,
411 .shutdown = ep93xx_i2s_shutdown,412 .shutdown = ep93xx_i2s_shutdown,
412 .hw_params = ep93xx_i2s_hw_params,413 .hw_params = ep93xx_i2s_hw_params,
@@ -418,7 +419,6 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { · 5 unmodified lines
418 419
419static struct snd_soc_dai_driver ep93xx_i2s_dai = {420static struct snd_soc_dai_driver ep93xx_i2s_dai = {
420 .symmetric_rate = 1,421 .symmetric_rate = 1,
421 .probe = ep93xx_i2s_dai_probe,
422 .playback = {422 .playback = {
423 .channels_min = 2,423 .channels_min = 2,
424 .channels_max = 2,424 .channels_max = 2,
sound/soc/codecs/88pm860x-codec.c+2−2
@@ -143,7 +143,7 @@ struct pm860x_priv { · 142 unmodified lines
143 struct pm860x_det det;143 struct pm860x_det det;
144 144
145 int irq[4];145 int irq[4];
146 unsigned char name[4][MAX_NAME_LEN+1];146 unsigned char name[4][MAX_NAME_LEN];
147};147};
148 148
149/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */149/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
@@ -1373,7 +1373,7 @@ static int pm860x_codec_probe(struct platform_device *pdev) · 1223 unmodified lines
1373 return -EINVAL;1373 return -EINVAL;
1374 }1374 }
1375 pm860x->irq[i] = res->start + chip->irq_base;1375 pm860x->irq[i] = res->start + chip->irq_base;
1376 strncpy(pm860x->name[i], res->name, MAX_NAME_LEN);1376 strscpy(pm860x->name[i], res->name, MAX_NAME_LEN);
1377 }1377 }
1378 1378
1379 ret = devm_snd_soc_register_component(&pdev->dev,1379 ret = devm_snd_soc_register_component(&pdev->dev,
sound/soc/codecs/Kconfig+50−8
@@ -15,7 +15,6 @@ config SND_SOC_ALL_CODECS · 14 unmodified lines
15 tristate "Build all ASoC CODEC drivers"15 tristate "Build all ASoC CODEC drivers"
16 depends on COMPILE_TEST16 depends on COMPILE_TEST
17 imply SND_SOC_88PM860X17 imply SND_SOC_88PM860X
18 imply SND_SOC_L3
19 imply SND_SOC_AB8500_CODEC18 imply SND_SOC_AB8500_CODEC
20 imply SND_SOC_AC97_CODEC19 imply SND_SOC_AC97_CODEC
21 imply SND_SOC_AD183620 imply SND_SOC_AD1836
@@ -53,8 +52,10 @@ config SND_SOC_ALL_CODECS · 31 unmodified lines
53 imply SND_SOC_AK555852 imply SND_SOC_AK5558
54 imply SND_SOC_ALC562353 imply SND_SOC_ALC5623
55 imply SND_SOC_ALC563254 imply SND_SOC_ALC5632
55 imply SND_SOC_AUDIO_IIO_AUX
56 imply SND_SOC_AW873856 imply SND_SOC_AW8738
57 imply SND_SOC_AW8839557 imply SND_SOC_AW88395
58 imply SND_SOC_AW88261
58 imply SND_SOC_BT_SCO59 imply SND_SOC_BT_SCO
59 imply SND_SOC_BD2862360 imply SND_SOC_BD28623
60 imply SND_SOC_CHV3_CODEC61 imply SND_SOC_CHV3_CODEC
@@ -74,6 +75,8 @@ config SND_SOC_ALL_CODECS · 13 unmodified lines
74 imply SND_SOC_CS35L56_SDW75 imply SND_SOC_CS35L56_SDW
75 imply SND_SOC_CS42L4276 imply SND_SOC_CS42L42
76 imply SND_SOC_CS42L42_SDW77 imply SND_SOC_CS42L42_SDW
78 imply SND_SOC_CS42L43
79 imply SND_SOC_CS42L43_SDW
77 imply SND_SOC_CS42L51_I2C80 imply SND_SOC_CS42L51_I2C
78 imply SND_SOC_CS42L5281 imply SND_SOC_CS42L52
79 imply SND_SOC_CS42L5682 imply SND_SOC_CS42L56
@@ -183,6 +186,7 @@ config SND_SOC_ALL_CODECS · 103 unmodified lines
183 imply SND_SOC_RT1015186 imply SND_SOC_RT1015
184 imply SND_SOC_RT1015P187 imply SND_SOC_RT1015P
185 imply SND_SOC_RT1016188 imply SND_SOC_RT1016
189 imply SND_SOC_RT1017_SDCA_SDW
186 imply SND_SOC_RT1019190 imply SND_SOC_RT1019
187 imply SND_SOC_RT1305191 imply SND_SOC_RT1305
188 imply SND_SOC_RT1308192 imply SND_SOC_RT1308
@@ -265,7 +269,6 @@ config SND_SOC_ALL_CODECS · 76 unmodified lines
265 imply SND_SOC_TWL4030269 imply SND_SOC_TWL4030
266 imply SND_SOC_TWL6040270 imply SND_SOC_TWL6040
267 imply SND_SOC_UDA1334271 imply SND_SOC_UDA1334
268 imply SND_SOC_UDA134X
269 imply SND_SOC_UDA1380272 imply SND_SOC_UDA1380
270 imply SND_SOC_WCD9335273 imply SND_SOC_WCD9335
271 imply SND_SOC_WCD934X274 imply SND_SOC_WCD934X
@@ -614,6 +617,17 @@ config SND_SOC_ALC5632 · 342 unmodified lines
614 tristate617 tristate
615 depends on I2C618 depends on I2C
616 619
620config SND_SOC_AUDIO_IIO_AUX
621 tristate "Audio IIO Auxiliary device"
622 depends on IIO
623 help
624 Enable support for Industrial I/O devices as audio auxiliary devices.
625 This allows to have an IIO device present in the audio path and
626 controlled using mixer controls.
627
628 To compile this driver as a module, choose M here: the module
629 will be called snd-soc-audio-iio-aux.
630
617config SND_SOC_AW8738631config SND_SOC_AW8738
618 tristate "Awinic AW8738 Audio Amplifier"632 tristate "Awinic AW8738 Audio Amplifier"
619 select GPIOLIB633 select GPIOLIB
@@ -640,6 +654,20 @@ config SND_SOC_AW88395 · 20 unmodified lines
640 digital Smart K audio amplifier with an integrated 10V654 digital Smart K audio amplifier with an integrated 10V
641 smart boost convert.655 smart boost convert.
642 656
657config SND_SOC_AW88261
658 tristate "Soc Audio for awinic aw88261"
659 depends on I2C
660 select CRC8
661 select REGMAP_I2C
662 select GPIOLIB
663 select SND_SOC_AW88395_LIB
664 help
665 This option enables support for aw88261 Smart PA.
666 The awinic AW88261 is an I2S/TDM input, high efficiency
667 digital Smart K audio amplifier. The output voltage of
668 boost converter can be adjusted smartly according to
669 the input amplitude.
670
643config SND_SOC_BD28623671config SND_SOC_BD28623
644 tristate "ROHM BD28623 CODEC"672 tristate "ROHM BD28623 CODEC"
645 help673 help
@@ -789,6 +817,20 @@ config SND_SOC_CS42L42_SDW · 143 unmodified lines
789 help817 help
790 Enable support for Cirrus Logic CS42L42 codec with Soundwire control818 Enable support for Cirrus Logic CS42L42 codec with Soundwire control
791 819
820config SND_SOC_CS42L43
821 tristate "Cirrus Logic CS42L43 CODEC"
822 depends on MFD_CS42L43
823 help
824 Select this to support the audio functions of the Cirrus Logic
825 CS42L43 PC CODEC.
826
827config SND_SOC_CS42L43_SDW
828 tristate "Cirrus Logic CS42L43 CODEC (SoundWire)"
829 depends on SND_SOC_CS42L43 && MFD_CS42L43_SDW
830 help
831 Select this to support the audio functions of the Cirrus Logic
832 CS42L43 PC CODEC over SoundWire.
833
792config SND_SOC_CS42L51834config SND_SOC_CS42L51
793 tristate835 tristate
794 836
@@ -966,9 +1008,6 @@ config SND_SOC_JZ4770_CODEC · 171 unmodified lines
966 This driver can also be built as a module. If so, the module1008 This driver can also be built as a module. If so, the module
967 will be called snd-soc-jz4770-codec.1009 will be called snd-soc-jz4770-codec.
968 1010
969config SND_SOC_L3
970 tristate
971
972config SND_SOC_DA72101011config SND_SOC_DA7210
973 tristate1012 tristate
974 depends on SND_SOC_I2C_AND_SPI1013 depends on SND_SOC_I2C_AND_SPI
@@ -1416,6 +1455,11 @@ config SND_SOC_RT1016 · 441 unmodified lines
1416 tristate1455 tristate
1417 depends on I2C1456 depends on I2C
1418 1457
1458config SND_SOC_RT1017_SDCA_SDW
1459 tristate "Realtek RT1017 SDCA Codec - SDW"
1460 depends on SOUNDWIRE
1461 select REGMAP_SOUNDWIRE
1462
1419config SND_SOC_RT10191463config SND_SOC_RT1019
1420 tristate1464 tristate
1421 depends on I2C1465 depends on I2C
@@ -1708,6 +1752,7 @@ config SND_SOC_STA529 · 286 unmodified lines
1708config SND_SOC_STAC97661752config SND_SOC_STAC9766
1709 tristate1753 tristate
1710 depends on SND_SOC_AC97_BUS1754 depends on SND_SOC_AC97_BUS
1755 select REGMAP_AC97
1711 1756
1712config SND_SOC_STI_SAS1757config SND_SOC_STI_SAS
1713 tristate "codec Audio support for STI SAS codec"1758 tristate "codec Audio support for STI SAS codec"
@@ -1919,9 +1964,6 @@ config SND_SOC_UDA1334 · 205 unmodified lines
1919 and has basic features such as de-emphasis (at 44.1 kHz sampling1964 and has basic features such as de-emphasis (at 44.1 kHz sampling
1920 rate) and mute.1965 rate) and mute.
1921 1966
1922config SND_SOC_UDA134X
1923 tristate
1924
1925config SND_SOC_UDA13801967config SND_SOC_UDA1380
1926 tristate1968 tristate
1927 depends on I2C1969 depends on I2C
sound/soc/codecs/Makefile+10−4
@@ -45,10 +45,12 @@ snd-soc-ak4671-objs := ak4671.o · 44 unmodified lines
45snd-soc-ak5386-objs := ak5386.o45snd-soc-ak5386-objs := ak5386.o
46snd-soc-ak5558-objs := ak5558.o46snd-soc-ak5558-objs := ak5558.o
47snd-soc-arizona-objs := arizona.o arizona-jack.o47snd-soc-arizona-objs := arizona.o arizona-jack.o
48snd-soc-audio-iio-aux-objs := audio-iio-aux.o
48snd-soc-aw8738-objs := aw8738.o49snd-soc-aw8738-objs := aw8738.o
49snd-soc-aw88395-lib-objs := aw88395/aw88395_lib.o50snd-soc-aw88395-lib-objs := aw88395/aw88395_lib.o
50snd-soc-aw88395-objs := aw88395/aw88395.o \51snd-soc-aw88395-objs := aw88395/aw88395.o \
51 aw88395/aw88395_device.o52 aw88395/aw88395_device.o
53snd-soc-aw88261-objs := aw88261.o
52snd-soc-bd28623-objs := bd28623.o54snd-soc-bd28623-objs := bd28623.o
53snd-soc-bt-sco-objs := bt-sco.o55snd-soc-bt-sco-objs := bt-sco.o
54snd-soc-chv3-codec-objs := chv3-codec.o56snd-soc-chv3-codec-objs := chv3-codec.o
@@ -75,6 +77,8 @@ snd-soc-cs35l56-sdw-objs := cs35l56-sdw.o · 20 unmodified lines
75snd-soc-cs42l42-objs := cs42l42.o77snd-soc-cs42l42-objs := cs42l42.o
76snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o78snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
77snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o79snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
80snd-soc-cs42l43-objs := cs42l43.o cs42l43-jack.o
81snd-soc-cs42l43-sdw-objs := cs42l43-sdw.o
78snd-soc-cs42l51-objs := cs42l51.o82snd-soc-cs42l51-objs := cs42l51.o
79snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o83snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
80snd-soc-cs42l52-objs := cs42l52.o84snd-soc-cs42l52-objs := cs42l52.o
@@ -127,7 +131,6 @@ snd-soc-jz4740-codec-objs := jz4740.o · 46 unmodified lines
127snd-soc-jz4725b-codec-objs := jz4725b.o131snd-soc-jz4725b-codec-objs := jz4725b.o
128snd-soc-jz4760-codec-objs := jz4760.o132snd-soc-jz4760-codec-objs := jz4760.o
129snd-soc-jz4770-codec-objs := jz4770.o133snd-soc-jz4770-codec-objs := jz4770.o
130snd-soc-l3-objs := l3.o
131snd-soc-lm4857-objs := lm4857.o134snd-soc-lm4857-objs := lm4857.o
132snd-soc-lm49453-objs := lm49453.o135snd-soc-lm49453-objs := lm49453.o
133snd-soc-lochnagar-sc-objs := lochnagar-sc.o136snd-soc-lochnagar-sc-objs := lochnagar-sc.o
@@ -204,6 +207,7 @@ snd-soc-rt1011-objs := rt1011.o · 70 unmodified lines
204snd-soc-rt1015-objs := rt1015.o207snd-soc-rt1015-objs := rt1015.o
205snd-soc-rt1015p-objs := rt1015p.o208snd-soc-rt1015p-objs := rt1015p.o
206snd-soc-rt1016-objs := rt1016.o209snd-soc-rt1016-objs := rt1016.o
210snd-soc-rt1017-sdca-objs := rt1017-sdca-sdw.o
207snd-soc-rt1019-objs := rt1019.o211snd-soc-rt1019-objs := rt1019.o
208snd-soc-rt1305-objs := rt1305.o212snd-soc-rt1305-objs := rt1305.o
209snd-soc-rt1308-objs := rt1308.o213snd-soc-rt1308-objs := rt1308.o
@@ -298,7 +302,6 @@ snd-soc-ts3a227e-objs := ts3a227e.o · 88 unmodified lines
298snd-soc-twl4030-objs := twl4030.o302snd-soc-twl4030-objs := twl4030.o
299snd-soc-twl6040-objs := twl6040.o303snd-soc-twl6040-objs := twl6040.o
300snd-soc-uda1334-objs := uda1334.o304snd-soc-uda1334-objs := uda1334.o
301snd-soc-uda134x-objs := uda134x.o
302snd-soc-uda1380-objs := uda1380.o305snd-soc-uda1380-objs := uda1380.o
303snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o306snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o
304snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o307snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o
@@ -428,9 +431,11 @@ obj-$(CONFIG_SND_SOC_AK5558) += snd-soc-ak5558.o · 123 unmodified lines
428obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o431obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
429obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o432obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
430obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o433obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
434obj-$(CONFIG_SND_SOC_AUDIO_IIO_AUX) += snd-soc-audio-iio-aux.o
431obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o435obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o
432obj-$(CONFIG_SND_SOC_AW88395_LIB) += snd-soc-aw88395-lib.o436obj-$(CONFIG_SND_SOC_AW88395_LIB) += snd-soc-aw88395-lib.o
433obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o437obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o
438obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o
434obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o439obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o
435obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o440obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
436obj-$(CONFIG_SND_SOC_CHV3_CODEC) += snd-soc-chv3-codec.o441obj-$(CONFIG_SND_SOC_CHV3_CODEC) += snd-soc-chv3-codec.o
@@ -457,6 +462,8 @@ obj-$(CONFIG_SND_SOC_CS35L56_SDW) += snd-soc-cs35l56-sdw.o · 20 unmodified lines
457obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o462obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o
458obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o463obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o
459obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o464obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o
465obj-$(CONFIG_SND_SOC_CS42L43) += snd-soc-cs42l43.o
466obj-$(CONFIG_SND_SOC_CS42L43_SDW) += snd-soc-cs42l43-sdw.o
460obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o467obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
461obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o468obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
462obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o469obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
@@ -509,7 +516,6 @@ obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o · 46 unmodified lines
509obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o516obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o
510obj-$(CONFIG_SND_SOC_JZ4760_CODEC) += snd-soc-jz4760-codec.o517obj-$(CONFIG_SND_SOC_JZ4760_CODEC) += snd-soc-jz4760-codec.o
511obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o518obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o
512obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
513obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o519obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
514obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o520obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
515obj-$(CONFIG_SND_SOC_LOCHNAGAR_SC) += snd-soc-lochnagar-sc.o521obj-$(CONFIG_SND_SOC_LOCHNAGAR_SC) += snd-soc-lochnagar-sc.o
@@ -581,6 +587,7 @@ obj-$(CONFIG_SND_SOC_RT1011) += snd-soc-rt1011.o · 65 unmodified lines
581obj-$(CONFIG_SND_SOC_RT1015) += snd-soc-rt1015.o587obj-$(CONFIG_SND_SOC_RT1015) += snd-soc-rt1015.o
582obj-$(CONFIG_SND_SOC_RT1015P) += snd-soc-rt1015p.o588obj-$(CONFIG_SND_SOC_RT1015P) += snd-soc-rt1015p.o
583obj-$(CONFIG_SND_SOC_RT1016) += snd-soc-rt1016.o589obj-$(CONFIG_SND_SOC_RT1016) += snd-soc-rt1016.o
590obj-$(CONFIG_SND_SOC_RT1017_SDCA_SDW) += snd-soc-rt1017-sdca.o
584obj-$(CONFIG_SND_SOC_RT1019) += snd-soc-rt1019.o591obj-$(CONFIG_SND_SOC_RT1019) += snd-soc-rt1019.o
585obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o592obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o
586obj-$(CONFIG_SND_SOC_RT1308) += snd-soc-rt1308.o593obj-$(CONFIG_SND_SOC_RT1308) += snd-soc-rt1308.o
@@ -677,7 +684,6 @@ obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o · 90 unmodified lines
677obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o684obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
678obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o685obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
679obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o686obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o
680obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
681obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o687obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
682obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o688obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o
683obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o689obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o
sound/soc/codecs/ad1836.c+1−1
@@ -358,7 +358,7 @@ static const struct regmap_config ad1836_regmap_config = { · 357 unmodified lines
358 .max_register = AD1836_ADC_CTRL3,358 .max_register = AD1836_ADC_CTRL3,
359 .reg_defaults = ad1836_reg_defaults,359 .reg_defaults = ad1836_reg_defaults,
360 .num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),360 .num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),
361 .cache_type = REGCACHE_RBTREE,361 .cache_type = REGCACHE_MAPLE,
362};362};
363 363
364static int ad1836_spi_probe(struct spi_device *spi)364static int ad1836_spi_probe(struct spi_device *spi)
sound/soc/codecs/ad1980.c+1−1
@@ -92,7 +92,7 @@ static const struct regmap_config ad1980_regmap_config = { · 91 unmodified lines
92 .reg_stride = 2,92 .reg_stride = 2,
93 .val_bits = 16,93 .val_bits = 16,
94 .max_register = 0x7e,94 .max_register = 0x7e,
95 .cache_type = REGCACHE_RBTREE,95 .cache_type = REGCACHE_MAPLE,
96 96
97 .volatile_reg = regmap_ac97_default_volatile,97 .volatile_reg = regmap_ac97_default_volatile,
98 .readable_reg = ad1980_readable_reg,98 .readable_reg = ad1980_readable_reg,
sound/soc/codecs/adau1372.c+1−1
@@ -1056,7 +1056,7 @@ const struct regmap_config adau1372_regmap_config = { · 1055 unmodified lines
1056 .reg_defaults = adau1372_reg_defaults,1056 .reg_defaults = adau1372_reg_defaults,
1057 .num_reg_defaults = ARRAY_SIZE(adau1372_reg_defaults),1057 .num_reg_defaults = ARRAY_SIZE(adau1372_reg_defaults),
1058 .volatile_reg = adau1372_volatile_register,1058 .volatile_reg = adau1372_volatile_register,
1059 .cache_type = REGCACHE_RBTREE,1059 .cache_type = REGCACHE_MAPLE,
1060};1060};
1061EXPORT_SYMBOL_GPL(adau1372_regmap_config);1061EXPORT_SYMBOL_GPL(adau1372_regmap_config);
1062 1062
sound/soc/codecs/adau1373.c+1−1
@@ -1451,7 +1451,7 @@ static const struct regmap_config adau1373_regmap_config = { · 1450 unmodified lines
1451 .volatile_reg = adau1373_register_volatile,1451 .volatile_reg = adau1373_register_volatile,
1452 .max_register = ADAU1373_SOFT_RESET,1452 .max_register = ADAU1373_SOFT_RESET,
1453 1453
1454 .cache_type = REGCACHE_RBTREE,1454 .cache_type = REGCACHE_MAPLE,
1455 .reg_defaults = adau1373_reg_defaults,1455 .reg_defaults = adau1373_reg_defaults,
1456 .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),1456 .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),
1457};1457};
sound/soc/codecs/adau1701.c+1−1
@@ -778,7 +778,7 @@ static const struct regmap_config adau1701_regmap = { · 777 unmodified lines
778 .reg_bits = 16,778 .reg_bits = 16,
779 .val_bits = 32,779 .val_bits = 32,
780 .max_register = ADAU1701_MAX_REGISTER,780 .max_register = ADAU1701_MAX_REGISTER,
781 .cache_type = REGCACHE_RBTREE,781 .cache_type = REGCACHE_MAPLE,
782 .volatile_reg = adau1701_volatile_reg,782 .volatile_reg = adau1701_volatile_reg,
783 .reg_write = adau1701_reg_write,783 .reg_write = adau1701_reg_write,
784 .reg_read = adau1701_reg_read,784 .reg_read = adau1701_reg_read,
sound/soc/codecs/adau1761.c+1−1
@@ -1014,7 +1014,7 @@ const struct regmap_config adau1761_regmap_config = { · 1013 unmodified lines
1014 .readable_reg = adau1761_readable_register,1014 .readable_reg = adau1761_readable_register,
1015 .volatile_reg = adau17x1_volatile_register,1015 .volatile_reg = adau17x1_volatile_register,
1016 .precious_reg = adau17x1_precious_register,1016 .precious_reg = adau17x1_precious_register,
1017 .cache_type = REGCACHE_RBTREE,1017 .cache_type = REGCACHE_MAPLE,
1018};1018};
1019EXPORT_SYMBOL_GPL(adau1761_regmap_config);1019EXPORT_SYMBOL_GPL(adau1761_regmap_config);
1020 1020
sound/soc/codecs/adau1781.c+1−1
@@ -472,7 +472,7 @@ const struct regmap_config adau1781_regmap_config = { · 471 unmodified lines
472 .readable_reg = adau1781_readable_register,472 .readable_reg = adau1781_readable_register,
473 .volatile_reg = adau17x1_volatile_register,473 .volatile_reg = adau17x1_volatile_register,
474 .precious_reg = adau17x1_precious_register,474 .precious_reg = adau17x1_precious_register,
475 .cache_type = REGCACHE_RBTREE,475 .cache_type = REGCACHE_MAPLE,
476};476};
477EXPORT_SYMBOL_GPL(adau1781_regmap_config);477EXPORT_SYMBOL_GPL(adau1781_regmap_config);
478 478
sound/soc/codecs/adau1977.c+1−1
@@ -991,7 +991,7 @@ const struct regmap_config adau1977_regmap_config = { · 990 unmodified lines
991 .max_register = ADAU1977_REG_DC_HPF_CAL,991 .max_register = ADAU1977_REG_DC_HPF_CAL,
992 .volatile_reg = adau1977_register_volatile,992 .volatile_reg = adau1977_register_volatile,
993 993
994 .cache_type = REGCACHE_RBTREE,994 .cache_type = REGCACHE_MAPLE,
995 .reg_defaults = adau1977_reg_defaults,995 .reg_defaults = adau1977_reg_defaults,
996 .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults),996 .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults),
997};997};
sound/soc/codecs/adau7118-i2c.c+1−1
@@ -43,7 +43,7 @@ static const struct regmap_config adau7118_regmap_config = { · 42 unmodified lines
43 .val_bits = 8,43 .val_bits = 8,
44 .reg_defaults = adau7118_reg_defaults,44 .reg_defaults = adau7118_reg_defaults,
45 .num_reg_defaults = ARRAY_SIZE(adau7118_reg_defaults),45 .num_reg_defaults = ARRAY_SIZE(adau7118_reg_defaults),
46 .cache_type = REGCACHE_RBTREE,46 .cache_type = REGCACHE_MAPLE,
47 .max_register = ADAU7118_REG_RESET,47 .max_register = ADAU7118_REG_RESET,
48 .volatile_reg = adau7118_volatile,48 .volatile_reg = adau7118_volatile,
49};49};
sound/soc/codecs/adav80x.c+1−1
@@ -870,7 +870,7 @@ const struct regmap_config adav80x_regmap_config = { · 869 unmodified lines
870 870
871 .max_register = ADAV80X_PLL_OUTE,871 .max_register = ADAV80X_PLL_OUTE,
872 872
873 .cache_type = REGCACHE_RBTREE,873 .cache_type = REGCACHE_MAPLE,
874 .reg_defaults = adav80x_reg_defaults,874 .reg_defaults = adav80x_reg_defaults,
875 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),875 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
876};876};
sound/soc/codecs/ak4613.c+1−10
@@ -880,20 +880,11 @@ static void ak4613_parse_of(struct ak4613_priv *priv, · 879 unmodified lines
880static int ak4613_i2c_probe(struct i2c_client *i2c)880static int ak4613_i2c_probe(struct i2c_client *i2c)
881{881{
882 struct device *dev = &i2c->dev;882 struct device *dev = &i2c->dev;
883 struct device_node *np = dev->of_node;
884 const struct regmap_config *regmap_cfg;883 const struct regmap_config *regmap_cfg;
885 struct regmap *regmap;884 struct regmap *regmap;
886 struct ak4613_priv *priv;885 struct ak4613_priv *priv;
887 886
888 regmap_cfg = NULL;887 regmap_cfg = i2c_get_match_data(i2c);
889 if (np)
890 regmap_cfg = of_device_get_match_data(dev);
891 else {
892 const struct i2c_device_id *id =
893 i2c_match_id(ak4613_i2c_id, i2c);
894 regmap_cfg = (const struct regmap_config *)id->driver_data;
895 }
896
897 if (!regmap_cfg)888 if (!regmap_cfg)
898 return -EINVAL;889 return -EINVAL;
899 890
sound/soc/codecs/audio-iio-aux.c+344−0
@@ -0,0 +1,344 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// ALSA SoC glue to use IIO devices as audio components
4//
5// Copyright 2023 CS GROUP France
6//
7// Author: Herve Codina <herve.codina@bootlin.com>
8
9#include <linux/iio/consumer.h>
10#include <linux/minmax.h>
11#include <linux/mod_devicetable.h>
12#include <linux/platform_device.h>
13#include <linux/slab.h>
14#include <linux/string_helpers.h>
15
16#include <sound/soc.h>
17#include <sound/tlv.h>
18
19struct audio_iio_aux_chan {
20 struct iio_channel *iio_chan;
21 const char *name;
22 int max;
23 int min;
24 bool is_invert_range;
25};
26
27struct audio_iio_aux {
28 struct device *dev;
29 struct audio_iio_aux_chan *chans;
30 unsigned int num_chans;
31};
32
33static int audio_iio_aux_info_volsw(struct snd_kcontrol *kcontrol,
34 struct snd_ctl_elem_info *uinfo)
35{
36 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value;
37
38 uinfo->count = 1;
39 uinfo->value.integer.min = 0;
40 uinfo->value.integer.max = chan->max - chan->min;
41 uinfo->type = (uinfo->value.integer.max == 1) ?
42 SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
43 return 0;
44}
45
46static int audio_iio_aux_get_volsw(struct snd_kcontrol *kcontrol,
47 struct snd_ctl_elem_value *ucontrol)
48{
49 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value;
50 int max = chan->max;
51 int min = chan->min;
52 bool invert_range = chan->is_invert_range;
53 int ret;
54 int val;
55
56 ret = iio_read_channel_raw(chan->iio_chan, &val);
57 if (ret < 0)
58 return ret;
59
60 ucontrol->value.integer.value[0] = val - min;
61 if (invert_range)
62 ucontrol->value.integer.value[0] = max - ucontrol->value.integer.value[0];
63
64 return 0;
65}
66
67static int audio_iio_aux_put_volsw(struct snd_kcontrol *kcontrol,
68 struct snd_ctl_elem_value *ucontrol)
69{
70 struct audio_iio_aux_chan *chan = (struct audio_iio_aux_chan *)kcontrol->private_value;
71 int max = chan->max;
72 int min = chan->min;
73 bool invert_range = chan->is_invert_range;
74 int val;
75 int ret;
76 int tmp;
77
78 val = ucontrol->value.integer.value[0];
79 if (val < 0)
80 return -EINVAL;
81 if (val > max - min)
82 return -EINVAL;
83
84 val = val + min;
85 if (invert_range)
86 val = max - val;
87
88 ret = iio_read_channel_raw(chan->iio_chan, &tmp);
89 if (ret < 0)
90 return ret;
91
92 if (tmp == val)
93 return 0;
94
95 ret = iio_write_channel_raw(chan->iio_chan, val);
96 if (ret)
97 return ret;
98
99 return 1; /* The value changed */
100}
101
102static int audio_iio_aux_add_controls(struct snd_soc_component *component,
103 struct audio_iio_aux_chan *chan)
104{
105 struct snd_kcontrol_new control = {
106 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
107 .name = chan->name,
108 .info = audio_iio_aux_info_volsw,
109 .get = audio_iio_aux_get_volsw,
110 .put = audio_iio_aux_put_volsw,
111 .private_value = (unsigned long)chan,
112 };
113
114 return snd_soc_add_component_controls(component, &control, 1);
115}
116
117/*
118 * These data could be on stack but they are pretty big.
119 * As ASoC internally copy them and protect them against concurrent accesses
120 * (snd_soc_bind_card() protects using client_mutex), keep them in the global
121 * data area.
122 */
123static struct snd_soc_dapm_widget widgets[3];
124static struct snd_soc_dapm_route routes[2];
125
126/* Be sure sizes are correct (need 3 widgets and 2 routes) */
127static_assert(ARRAY_SIZE(widgets) >= 3, "3 widgets are needed");
128static_assert(ARRAY_SIZE(routes) >= 2, "2 routes are needed");
129
130static int audio_iio_aux_add_dapms(struct snd_soc_component *component,
131 struct audio_iio_aux_chan *chan)
132{
133 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
134 char *output_name;
135 char *input_name;
136 char *pga_name;
137 int ret;
138
139 input_name = kasprintf(GFP_KERNEL, "%s IN", chan->name);
140 if (!input_name)
141 return -ENOMEM;
142
143 output_name = kasprintf(GFP_KERNEL, "%s OUT", chan->name);
144 if (!output_name) {
145 ret = -ENOMEM;
146 goto out_free_input_name;
147 }
148
149 pga_name = kasprintf(GFP_KERNEL, "%s PGA", chan->name);
150 if (!pga_name) {
151 ret = -ENOMEM;
152 goto out_free_output_name;
153 }
154
155 widgets[0] = SND_SOC_DAPM_INPUT(input_name);
156 widgets[1] = SND_SOC_DAPM_OUTPUT(output_name);
157 widgets[2] = SND_SOC_DAPM_PGA(pga_name, SND_SOC_NOPM, 0, 0, NULL, 0);
158 ret = snd_soc_dapm_new_controls(dapm, widgets, 3);
159 if (ret)
160 goto out_free_pga_name;
161
162 routes[0].sink = pga_name;
163 routes[0].control = NULL;
164 routes[0].source = input_name;
165 routes[1].sink = output_name;
166 routes[1].control = NULL;
167 routes[1].source = pga_name;
168 ret = snd_soc_dapm_add_routes(dapm, routes, 2);
169
170 /* Allocated names are no more needed (duplicated in ASoC internals) */
171
172out_free_pga_name:
173 kfree(pga_name);
174out_free_output_name:
175 kfree(output_name);
176out_free_input_name:
177 kfree(input_name);
178 return ret;
179}
180
181static int audio_iio_aux_component_probe(struct snd_soc_component *component)
182{
183 struct audio_iio_aux *iio_aux = snd_soc_component_get_drvdata(component);
184 struct audio_iio_aux_chan *chan;
185 int ret;
186 int i;
187
188 for (i = 0; i < iio_aux->num_chans; i++) {
189 chan = iio_aux->chans + i;
190
191 ret = iio_read_max_channel_raw(chan->iio_chan, &chan->max);
192 if (ret)
193 return dev_err_probe(component->dev, ret,
194 "chan[%d] %s: Cannot get max raw value\n",
195 i, chan->name);
196
197 ret = iio_read_min_channel_raw(chan->iio_chan, &chan->min);
198 if (ret)
199 return dev_err_probe(component->dev, ret,
200 "chan[%d] %s: Cannot get min raw value\n",
201 i, chan->name);
202
203 if (chan->min > chan->max) {
204 /*
205 * This should never happen but to avoid any check
206 * later, just swap values here to ensure that the
207 * minimum value is lower than the maximum value.
208 */
209 dev_dbg(component->dev, "chan[%d] %s: Swap min and max\n",
210 i, chan->name);
211 swap(chan->min, chan->max);
212 }
213
214 /* Set initial value */
215 ret = iio_write_channel_raw(chan->iio_chan,
216 chan->is_invert_range ? chan->max : chan->min);
217 if (ret)
218 return dev_err_probe(component->dev, ret,
219 "chan[%d] %s: Cannot set initial value\n",
220 i, chan->name);
221
222 ret = audio_iio_aux_add_controls(component, chan);
223 if (ret)
224 return ret;
225
226 ret = audio_iio_aux_add_dapms(component, chan);
227 if (ret)
228 return ret;
229
230 dev_dbg(component->dev, "chan[%d]: Added %s (min=%d, max=%d, invert=%s)\n",
231 i, chan->name, chan->min, chan->max,
232 str_on_off(chan->is_invert_range));
233 }
234
235 return 0;
236}
237
238static const struct snd_soc_component_driver audio_iio_aux_component_driver = {
239 .probe = audio_iio_aux_component_probe,
240};
241
242static int audio_iio_aux_probe(struct platform_device *pdev)
243{
244 struct audio_iio_aux_chan *iio_aux_chan;
245 struct device *dev = &pdev->dev;
246 struct audio_iio_aux *iio_aux;
247 const char **names;
248 u32 *invert_ranges;
249 int count;
250 int ret;
251 int i;
252
253 iio_aux = devm_kzalloc(dev, sizeof(*iio_aux), GFP_KERNEL);
254 if (!iio_aux)
255 return -ENOMEM;
256
257 iio_aux->dev = dev;
258
259 count = device_property_string_array_count(dev, "io-channel-names");
260 if (count < 0)
261 return dev_err_probe(dev, count, "failed to count io-channel-names\n");
262
263 iio_aux->num_chans = count;
264
265 iio_aux->chans = devm_kmalloc_array(dev, iio_aux->num_chans,
266 sizeof(*iio_aux->chans), GFP_KERNEL);
267 if (!iio_aux->chans)
268 return -ENOMEM;
269
270 names = kcalloc(iio_aux->num_chans, sizeof(*names), GFP_KERNEL);
271 if (!names)
272 return -ENOMEM;
273
274 invert_ranges = kcalloc(iio_aux->num_chans, sizeof(*invert_ranges), GFP_KERNEL);
275 if (!invert_ranges) {
276 ret = -ENOMEM;
277 goto out_free_names;
278 }
279
280 ret = device_property_read_string_array(dev, "io-channel-names",
281 names, iio_aux->num_chans);
282 if (ret < 0) {
283 dev_err_probe(dev, ret, "failed to read io-channel-names\n");
284 goto out_free_invert_ranges;
285 }
286
287 /*
288 * snd-control-invert-range is optional and can contain fewer items
289 * than the number of channels. Unset values default to 0.
290 */
291 count = device_property_count_u32(dev, "snd-control-invert-range");
292 if (count > 0) {
293 count = min_t(unsigned int, count, iio_aux->num_chans);
294 ret = device_property_read_u32_array(dev, "snd-control-invert-range",
295 invert_ranges, count);
296 if (ret < 0) {
297 dev_err_probe(dev, ret, "failed to read snd-control-invert-range\n");
298 goto out_free_invert_ranges;
299 }
300 }
301
302 for (i = 0; i < iio_aux->num_chans; i++) {
303 iio_aux_chan = iio_aux->chans + i;
304 iio_aux_chan->name = names[i];
305 iio_aux_chan->is_invert_range = invert_ranges[i];
306
307 iio_aux_chan->iio_chan = devm_iio_channel_get(dev, iio_aux_chan->name);
308 if (IS_ERR(iio_aux_chan->iio_chan)) {
309 ret = PTR_ERR(iio_aux_chan->iio_chan);
310 dev_err_probe(dev, ret, "get IIO channel '%s' failed\n",
311 iio_aux_chan->name);
312 goto out_free_invert_ranges;
313 }
314 }
315
316 platform_set_drvdata(pdev, iio_aux);
317
318 ret = devm_snd_soc_register_component(dev, &audio_iio_aux_component_driver,
319 NULL, 0);
320out_free_invert_ranges:
321 kfree(invert_ranges);
322out_free_names:
323 kfree(names);
324 return ret;
325}
326
327static const struct of_device_id audio_iio_aux_ids[] = {
328 { .compatible = "audio-iio-aux" },
329 { }
330};
331MODULE_DEVICE_TABLE(of, audio_iio_aux_ids);
332
333static struct platform_driver audio_iio_aux_driver = {
334 .driver = {
335 .name = "audio-iio-aux",
336 .of_match_table = audio_iio_aux_ids,
337 },
338 .probe = audio_iio_aux_probe,
339};
340module_platform_driver(audio_iio_aux_driver);
341
342MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
343MODULE_DESCRIPTION("IIO ALSA SoC aux driver");
344MODULE_LICENSE("GPL");
sound/soc/codecs/aw88261.c+1300−0
@@ -0,0 +1,1300 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// aw88261.c -- AW88261 ALSA SoC Audio driver
4//
5// Copyright (c) 2023 awinic Technology CO., LTD
6//
7// Author: Jimmy Zhang <zhangjianming@awinic.com>
8// Author: Weidong Wang <wangweidong.a@awinic.com>
9//
10
11#include <linux/i2c.h>
12#include <linux/firmware.h>
13#include <linux/of_gpio.h>
14#include <linux/regmap.h>
15#include <sound/soc.h>
16#include "aw88261.h"
17#include "aw88395/aw88395_data_type.h"
18#include "aw88395/aw88395_device.h"
19
20static const struct regmap_config aw88261_remap_config = {
21 .val_bits = 16,
22 .reg_bits = 8,
23 .max_register = AW88261_REG_MAX - 1,
24 .reg_format_endian = REGMAP_ENDIAN_LITTLE,
25 .val_format_endian = REGMAP_ENDIAN_BIG,
26};
27
28static void aw88261_dev_set_volume(struct aw_device *aw_dev, unsigned int value)
29{
30 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
31 unsigned int real_value, volume;
32 unsigned int reg_value;
33
34 volume = min((value + vol_desc->init_volume), (unsigned int)AW88261_MUTE_VOL);
35 real_value = DB_TO_REG_VAL(volume);
36
37 regmap_read(aw_dev->regmap, AW88261_SYSCTRL2_REG, &reg_value);
38
39 real_value = (real_value | (reg_value & AW88261_VOL_START_MASK));
40
41 dev_dbg(aw_dev->dev, "value 0x%x , real_value:0x%x", value, real_value);
42
43 regmap_write(aw_dev->regmap, AW88261_SYSCTRL2_REG, real_value);
44}
45
46static void aw88261_dev_fade_in(struct aw_device *aw_dev)
47{
48 struct aw_volume_desc *desc = &aw_dev->volume_desc;
49 int fade_in_vol = desc->ctl_volume;
50 int fade_step = aw_dev->fade_step;
51 int i;
52
53 if (fade_step == 0 || aw_dev->fade_in_time == 0) {
54 aw88261_dev_set_volume(aw_dev, fade_in_vol);
55 return;
56 }
57
58 for (i = AW88261_MUTE_VOL; i >= fade_in_vol; i -= fade_step) {
59 aw88261_dev_set_volume(aw_dev, i);
60 usleep_range(aw_dev->fade_in_time,
61 aw_dev->fade_in_time + 10);
62 }
63
64 if (i != fade_in_vol)
65 aw88261_dev_set_volume(aw_dev, fade_in_vol);
66}
67
68static void aw88261_dev_fade_out(struct aw_device *aw_dev)
69{
70 struct aw_volume_desc *desc = &aw_dev->volume_desc;
71 int fade_step = aw_dev->fade_step;
72 int i;
73
74 if (fade_step == 0 || aw_dev->fade_out_time == 0) {
75 aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL);
76 return;
77 }
78
79 for (i = desc->ctl_volume; i <= AW88261_MUTE_VOL; i += fade_step) {
80 aw88261_dev_set_volume(aw_dev, i);
81 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);
82 }
83
84 if (i != AW88261_MUTE_VOL) {
85 aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL);
86 usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10);
87 }
88}
89
90static void aw88261_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag)
91{
92 if (flag)
93 regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG,
94 ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_ENABLE_VALUE);
95 else
96 regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG,
97 ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_DISABLE_VALUE);
98}
99
100static void aw88261_dev_pwd(struct aw_device *aw_dev, bool pwd)
101{
102 if (pwd)
103 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
104 ~AW88261_PWDN_MASK, AW88261_PWDN_POWER_DOWN_VALUE);
105 else
106 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
107 ~AW88261_PWDN_MASK, AW88261_PWDN_WORKING_VALUE);
108}
109
110static void aw88261_dev_amppd(struct aw_device *aw_dev, bool amppd)
111{
112 if (amppd)
113 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
114 ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE);
115 else
116 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
117 ~AW88261_AMPPD_MASK, AW88261_AMPPD_WORKING_VALUE);
118}
119
120static void aw88261_dev_mute(struct aw_device *aw_dev, bool is_mute)
121{
122 if (is_mute) {
123 aw88261_dev_fade_out(aw_dev);
124 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
125 ~AW88261_HMUTE_MASK, AW88261_HMUTE_ENABLE_VALUE);
126 } else {
127 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
128 ~AW88261_HMUTE_MASK, AW88261_HMUTE_DISABLE_VALUE);
129 aw88261_dev_fade_in(aw_dev);
130 }
131}
132
133static void aw88261_dev_clear_int_status(struct aw_device *aw_dev)
134{
135 unsigned int int_status;
136
137 /* read int status and clear */
138 regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status);
139 /* make sure int status is clear */
140 regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status);
141
142 dev_dbg(aw_dev->dev, "read interrupt reg = 0x%04x", int_status);
143}
144
145static int aw88261_dev_get_iis_status(struct aw_device *aw_dev)
146{
147 unsigned int reg_val;
148 int ret;
149
150 ret = regmap_read(aw_dev->regmap, AW88261_SYSST_REG, &reg_val);
151 if (ret)
152 return ret;
153 if ((reg_val & AW88261_BIT_PLL_CHECK) != AW88261_BIT_PLL_CHECK) {
154 dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
155 return -EINVAL;
156 }
157
158 return ret;
159}
160
161static int aw88261_dev_check_mode1_pll(struct aw_device *aw_dev)
162{
163 int ret, i;
164
165 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
166 ret = aw88261_dev_get_iis_status(aw_dev);
167 if (ret) {
168 dev_err(aw_dev->dev, "mode1 iis signal check error");
169 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
170 } else {
171 return ret;
172 }
173 }
174
175 return -EPERM;
176}
177
178static int aw88261_dev_check_mode2_pll(struct aw_device *aw_dev)
179{
180 unsigned int reg_val;
181 int ret, i;
182
183 ret = regmap_read(aw_dev->regmap, AW88261_PLLCTRL1_REG, &reg_val);
184 if (ret)
185 return ret;
186
187 reg_val &= (~AW88261_CCO_MUX_MASK);
188 if (reg_val == AW88261_CCO_MUX_DIVIDED_VALUE) {
189 dev_dbg(aw_dev->dev, "CCO_MUX is already divider");
190 return -EPERM;
191 }
192
193 /* change mode2 */
194 ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG,
195 ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_DIVIDED_VALUE);
196 if (ret)
197 return ret;
198
199 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
200 ret = aw88261_dev_get_iis_status(aw_dev);
201 if (ret) {
202 dev_err(aw_dev->dev, "mode2 iis signal check error");
203 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
204 } else {
205 break;
206 }
207 }
208
209 /* change mode1 */
210 ret = regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG,
211 ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_BYPASS_VALUE);
212 if (ret == 0) {
213 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
214 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
215 ret = aw88261_dev_check_mode1_pll(aw_dev);
216 if (ret) {
217 dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error");
218 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
219 } else {
220 break;
221 }
222 }
223 }
224
225 return ret;
226}
227
228static int aw88261_dev_check_syspll(struct aw_device *aw_dev)
229{
230 int ret;
231
232 ret = aw88261_dev_check_mode1_pll(aw_dev);
233 if (ret) {
234 dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check");
235 ret = aw88261_dev_check_mode2_pll(aw_dev);
236 if (ret) {
237 dev_err(aw_dev->dev, "mode2 check iis failed");
238 return ret;
239 }
240 }
241
242 return ret;
243}
244
245static int aw88261_dev_check_sysst(struct aw_device *aw_dev)
246{
247 unsigned int check_val;
248 unsigned int reg_val;
249 int ret, i;
250
251 for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
252 ret = regmap_read(aw_dev->regmap, AW88261_SYSST_REG, &reg_val);
253 if (ret)
254 return ret;
255
256 check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
257 & AW88261_BIT_SYSST_CHECK;
258 if (check_val != AW88261_BIT_SYSST_CHECK) {
259 dev_err(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
260 reg_val, AW88261_BIT_SYSST_CHECK);
261 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
262 } else {
263 return 0;
264 }
265 }
266
267 return -EPERM;
268}
269
270static void aw88261_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute)
271{
272 if (uls_hmute)
273 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
274 ~AW88261_ULS_HMUTE_MASK,
275 AW88261_ULS_HMUTE_ENABLE_VALUE);
276 else
277 regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG,
278 ~AW88261_ULS_HMUTE_MASK,
279 AW88261_ULS_HMUTE_DISABLE_VALUE);
280}
281
282static void aw88261_reg_force_set(struct aw88261 *aw88261)
283{
284 if (aw88261->frcset_en == AW88261_FRCSET_ENABLE) {
285 /* set FORCE_PWM */
286 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL3_REG,
287 AW88261_FORCE_PWM_MASK, AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE);
288 /* set BOOST_OS_WIDTH */
289 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL5_REG,
290 AW88261_BST_OS_WIDTH_MASK, AW88261_BST_OS_WIDTH_50NS_VALUE);
291 /* set BURST_LOOPR */
292 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL6_REG,
293 AW88261_BST_LOOPR_MASK, AW88261_BST_LOOPR_340K_VALUE);
294 /* set RSQN_DLY */
295 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL7_REG,
296 AW88261_RSQN_DLY_MASK, AW88261_RSQN_DLY_35NS_VALUE);
297 /* set BURST_SSMODE */
298 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL8_REG,
299 AW88261_BURST_SSMODE_MASK, AW88261_BURST_SSMODE_FAST_VALUE);
300 /* set BST_BURST */
301 regmap_update_bits(aw88261->regmap, AW88261_BSTCTRL9_REG,
302 AW88261_BST_BURST_MASK, AW88261_BST_BURST_30MA_VALUE);
303 } else {
304 dev_dbg(aw88261->aw_pa->dev, "needn't set reg value");
305 }
306}
307
308static int aw88261_dev_get_icalk(struct aw_device *aw_dev, int16_t *icalk)
309{
310 u16 reg_icalk, reg_icalkl;
311 unsigned int reg_val;
312 int ret;
313
314 ret = regmap_read(aw_dev->regmap, AW88261_EFRH4_REG, &reg_val);
315 if (ret)
316 return ret;
317
318 reg_icalk = reg_val & (~AW88261_EF_ISN_GESLP_H_MASK);
319
320 ret = regmap_read(aw_dev->regmap, AW88261_EFRL4_REG, &reg_val);
321 if (ret)
322 return ret;
323
324 reg_icalkl = reg_val & (~AW88261_EF_ISN_GESLP_L_MASK);
325
326 reg_icalk = (reg_icalk >> AW88261_ICALK_SHIFT) & (reg_icalkl >> AW88261_ICALKL_SHIFT);
327
328 if (reg_icalk & (~AW88261_EF_ISN_GESLP_SIGN_MASK))
329 reg_icalk = reg_icalk | ~AW88261_EF_ISN_GESLP_NEG;
330
331 *icalk = (int16_t)reg_icalk;
332
333 return ret;
334}
335
336static int aw88261_dev_get_vcalk(struct aw_device *aw_dev, int16_t *vcalk)
337{
338 u16 reg_vcalk, reg_vcalkl;
339 unsigned int reg_val;
340 int ret;
341
342 ret = regmap_read(aw_dev->regmap, AW88261_EFRH3_REG, &reg_val);
343 if (ret)
344 return ret;
345
346 reg_vcalk = (u16)reg_val & (~AW88261_EF_VSN_GESLP_H_MASK);
347
348 ret = regmap_read(aw_dev->regmap, AW88261_EFRL3_REG, &reg_val);
349 if (ret)
350 return ret;
351
352 reg_vcalkl = (u16)reg_val & (~AW88261_EF_VSN_GESLP_L_MASK);
353
354 reg_vcalk = (reg_vcalk >> AW88261_VCALK_SHIFT) & (reg_vcalkl >> AW88261_VCALKL_SHIFT);
355
356 if (reg_vcalk & AW88261_EF_VSN_GESLP_SIGN_MASK)
357 reg_vcalk = reg_vcalk | (~AW88261_EF_VSN_GESLP_NEG);
358 *vcalk = (int16_t)reg_vcalk;
359
360 return ret;
361}
362
363static int aw88261_dev_set_vcalb(struct aw_device *aw_dev)
364{
365 int16_t icalk_val, vcalk_val;
366 int icalk, vcalk, vcalb;
367 u32 reg_val;
368 int ret;
369
370 ret = aw88261_dev_get_icalk(aw_dev, &icalk_val);
371 if (ret)
372 return ret;
373
374 ret = aw88261_dev_get_vcalk(aw_dev, &vcalk_val);
375 if (ret)
376 return ret;
377
378 icalk = AW88261_CABL_BASE_VALUE + AW88261_ICABLK_FACTOR * icalk_val;
379 vcalk = AW88261_CABL_BASE_VALUE + AW88261_VCABLK_FACTOR * vcalk_val;
380 if (!vcalk)
381 return -EINVAL;
382
383 vcalb = AW88261_VCAL_FACTOR * icalk / vcalk;
384 reg_val = (unsigned int)vcalb;
385
386 dev_dbg(aw_dev->dev, "icalk=%d, vcalk=%d, vcalb=%d, reg_val=0x%04x",
387 icalk, vcalk, vcalb, reg_val);
388 ret = regmap_write(aw_dev->regmap, AW88261_VSNTM1_REG, reg_val);
389
390 return ret;
391}
392
393static int aw88261_dev_reg_update(struct aw88261 *aw88261,
394 unsigned char *data, unsigned int len)
395{
396 struct aw_device *aw_dev = aw88261->aw_pa;
397 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
398 unsigned int read_val, efcheck_val, read_vol;
399 int data_len, i, ret;
400 int16_t *reg_data;
401 u16 reg_val;
402 u8 reg_addr;
403
404 if (!len || !data) {
405 dev_err(aw_dev->dev, "reg data is null or len is 0");
406 return -EINVAL;
407 }
408
409 reg_data = (int16_t *)data;
410 data_len = len >> 1;
411
412 if (data_len & 0x1) {
413 dev_err(aw_dev->dev, "data len:%d unsupported", data_len);
414 return -EINVAL;
415 }
416
417 for (i = 0; i < data_len; i += 2) {
418 reg_addr = reg_data[i];
419 reg_val = reg_data[i + 1];
420
421 if (reg_addr == AW88261_SYSCTRL_REG) {
422 aw88261->amppd_st = reg_val & (~AW88261_AMPPD_MASK);
423 ret = regmap_read(aw_dev->regmap, reg_addr, &read_val);
424 if (ret)
425 break;
426
427 read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |
428 (~AW88261_HMUTE_MASK);
429 reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);
430 reg_val |= read_val;
431
432 /* enable uls hmute */
433 reg_val &= AW88261_ULS_HMUTE_MASK;
434 reg_val |= AW88261_ULS_HMUTE_ENABLE_VALUE;
435 }
436
437 if (reg_addr == AW88261_DBGCTRL_REG) {
438 efcheck_val = reg_val & (~AW88261_EF_DBMD_MASK);
439 if (efcheck_val == AW88261_OR_VALUE)
440 aw88261->efuse_check = AW88261_EF_OR_CHECK;
441 else
442 aw88261->efuse_check = AW88261_EF_AND_CHECK;
443 }
444
445 /* i2stxen */
446 if (reg_addr == AW88261_I2SCTRL3_REG) {
447 /* close tx */
448 reg_val &= AW88261_I2STXEN_MASK;
449 reg_val |= AW88261_I2STXEN_DISABLE_VALUE;
450 }
451
452 if (reg_addr == AW88261_SYSCTRL2_REG) {
453 read_vol = (reg_val & (~AW88261_VOL_MASK)) >>
454 AW88261_VOL_START_BIT;
455 aw_dev->volume_desc.init_volume =
456 REG_VAL_TO_DB(read_vol);
457 }
458
459 if (reg_addr == AW88261_VSNTM1_REG)
460 continue;
461
462 ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);
463 if (ret)
464 break;
465 }
466
467 ret = aw88261_dev_set_vcalb(aw_dev);
468 if (ret)
469 return ret;
470
471 if (aw_dev->prof_cur != aw_dev->prof_index)
472 vol_desc->ctl_volume = 0;
473
474 /* keep min volume */
475 aw88261_dev_set_volume(aw_dev, vol_desc->mute_volume);
476
477 return ret;
478}
479
480static char *aw88261_dev_get_prof_name(struct aw_device *aw_dev, int index)
481{
482 struct aw_prof_info *prof_info = &aw_dev->prof_info;
483 struct aw_prof_desc *prof_desc;
484
485 if ((index >= aw_dev->prof_info.count) || (index < 0)) {
486 dev_err(aw_dev->dev, "index[%d] overflow count[%d]",
487 index, aw_dev->prof_info.count);
488 return NULL;
489 }
490
491 prof_desc = &aw_dev->prof_info.prof_desc[index];
492
493 return prof_info->prof_name_list[prof_desc->id];
494}
495
496static int aw88261_dev_get_prof_data(struct aw_device *aw_dev, int index,
497 struct aw_prof_desc **prof_desc)
498{
499 if ((index >= aw_dev->prof_info.count) || (index < 0)) {
500 dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n",
501 __func__, index, aw_dev->prof_info.count);
502 return -EINVAL;
503 }
504
505 *prof_desc = &aw_dev->prof_info.prof_desc[index];
506
507 return 0;
508}
509
510static int aw88261_dev_fw_update(struct aw88261 *aw88261)
511{
512 struct aw_device *aw_dev = aw88261->aw_pa;
513 struct aw_prof_desc *prof_index_desc;
514 struct aw_sec_data_desc *sec_desc;
515 char *prof_name;
516 int ret;
517
518 prof_name = aw88261_dev_get_prof_name(aw_dev, aw_dev->prof_index);
519 if (!prof_name) {
520 dev_err(aw_dev->dev, "get prof name failed");
521 return -EINVAL;
522 }
523
524 dev_dbg(aw_dev->dev, "start update %s", prof_name);
525
526 ret = aw88261_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc);
527 if (ret)
528 return ret;
529
530 /* update reg */
531 sec_desc = prof_index_desc->sec_desc;
532 ret = aw88261_dev_reg_update(aw88261, sec_desc[AW88395_DATA_TYPE_REG].data,
533 sec_desc[AW88395_DATA_TYPE_REG].len);
534 if (ret) {
535 dev_err(aw_dev->dev, "update reg failed");
536 return ret;
537 }
538
539 aw_dev->prof_cur = aw_dev->prof_index;
540
541 return ret;
542}
543
544static int aw88261_dev_start(struct aw88261 *aw88261)
545{
546 struct aw_device *aw_dev = aw88261->aw_pa;
547 int ret;
548
549 if (aw_dev->status == AW88261_DEV_PW_ON) {
550 dev_info(aw_dev->dev, "already power on");
551 return 0;
552 }
553
554 /* power on */
555 aw88261_dev_pwd(aw_dev, false);
556 usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
557
558 ret = aw88261_dev_check_syspll(aw_dev);
559 if (ret) {
560 dev_err(aw_dev->dev, "pll check failed cannot start");
561 goto pll_check_fail;
562 }
563
564 /* amppd on */
565 aw88261_dev_amppd(aw_dev, false);
566 usleep_range(AW88261_1000_US, AW88261_1000_US + 50);
567
568 /* check i2s status */
569 ret = aw88261_dev_check_sysst(aw_dev);
570 if (ret) {
571 dev_err(aw_dev->dev, "sysst check failed");
572 goto sysst_check_fail;
573 }
574
575 /* enable tx feedback */
576 aw88261_dev_i2s_tx_enable(aw_dev, true);
577
578 if (aw88261->amppd_st)
579 aw88261_dev_amppd(aw_dev, true);
580
581 aw88261_reg_force_set(aw88261);
582
583 /* close uls mute */
584 aw88261_dev_uls_hmute(aw_dev, false);
585
586 /* close mute */
587 if (!aw88261->mute_st)
588 aw88261_dev_mute(aw_dev, false);
589
590 /* clear inturrupt */
591 aw88261_dev_clear_int_status(aw_dev);
592 aw_dev->status = AW88261_DEV_PW_ON;
593
594 return 0;
595
596sysst_check_fail:
597 aw88261_dev_i2s_tx_enable(aw_dev, false);
598 aw88261_dev_clear_int_status(aw_dev);
599 aw88261_dev_amppd(aw_dev, true);
600pll_check_fail:
601 aw88261_dev_pwd(aw_dev, true);
602 aw_dev->status = AW88261_DEV_PW_OFF;
603
604 return ret;
605}
606
607static int aw88261_dev_stop(struct aw_device *aw_dev)
608{
609 if (aw_dev->status == AW88261_DEV_PW_OFF) {
610 dev_info(aw_dev->dev, "already power off");
611 return 0;
612 }
613
614 aw_dev->status = AW88261_DEV_PW_OFF;
615
616 /* clear inturrupt */
617 aw88261_dev_clear_int_status(aw_dev);
618
619 aw88261_dev_uls_hmute(aw_dev, true);
620 /* set mute */
621 aw88261_dev_mute(aw_dev, true);
622
623 /* close tx feedback */
624 aw88261_dev_i2s_tx_enable(aw_dev, false);
625 usleep_range(AW88261_1000_US, AW88261_1000_US + 100);
626
627 /* enable amppd */
628 aw88261_dev_amppd(aw_dev, true);
629
630 /* set power down */
631 aw88261_dev_pwd(aw_dev, true);
632
633 return 0;
634}
635
636static int aw88261_reg_update(struct aw88261 *aw88261, bool force)
637{
638 struct aw_device *aw_dev = aw88261->aw_pa;
639 int ret;
640
641 if (force) {
642 ret = regmap_write(aw_dev->regmap,
643 AW88261_ID_REG, AW88261_SOFT_RESET_VALUE);
644 if (ret)
645 return ret;
646
647 ret = aw88261_dev_fw_update(aw88261);
648 if (ret)
649 return ret;
650 } else {
651 if (aw_dev->prof_cur != aw_dev->prof_index) {
652 ret = aw88261_dev_fw_update(aw88261);
653 if (ret)
654 return ret;
655 } else {
656 ret = 0;
657 }
658 }
659
660 aw_dev->prof_cur = aw_dev->prof_index;
661
662 return ret;
663}
664
665static void aw88261_start_pa(struct aw88261 *aw88261)
666{
667 int ret, i;
668
669 for (i = 0; i < AW88261_START_RETRIES; i++) {
670 ret = aw88261_reg_update(aw88261, aw88261->phase_sync);
671 if (ret) {
672 dev_err(aw88261->aw_pa->dev, "fw update failed, cnt:%d\n", i);
673 continue;
674 }
675 ret = aw88261_dev_start(aw88261);
676 if (ret) {
677 dev_err(aw88261->aw_pa->dev, "aw88261 device start failed. retry = %d", i);
678 continue;
679 } else {
680 dev_info(aw88261->aw_pa->dev, "start success\n");
681 break;
682 }
683 }
684}
685
686static void aw88261_startup_work(struct work_struct *work)
687{
688 struct aw88261 *aw88261 =
689 container_of(work, struct aw88261, start_work.work);
690
691 mutex_lock(&aw88261->lock);
692 aw88261_start_pa(aw88261);
693 mutex_unlock(&aw88261->lock);
694}
695
696static void aw88261_start(struct aw88261 *aw88261, bool sync_start)
697{
698 if (aw88261->aw_pa->fw_status != AW88261_DEV_FW_OK)
699 return;
700
701 if (aw88261->aw_pa->status == AW88261_DEV_PW_ON)
702 return;
703
704 if (sync_start == AW88261_SYNC_START)
705 aw88261_start_pa(aw88261);
706 else
707 queue_delayed_work(system_wq,
708 &aw88261->start_work,
709 AW88261_START_WORK_DELAY_MS);
710}
711
712static struct snd_soc_dai_driver aw88261_dai[] = {
713 {
714 .name = "aw88261-aif",
715 .id = 1,
716 .playback = {
717 .stream_name = "Speaker_Playback",
718 .channels_min = 1,
719 .channels_max = 2,
720 .rates = AW88261_RATES,
721 .formats = AW88261_FORMATS,
722 },
723 .capture = {
724 .stream_name = "Speaker_Capture",
725 .channels_min = 1,
726 .channels_max = 2,
727 .rates = AW88261_RATES,
728 .formats = AW88261_FORMATS,
729 },
730 },
731};
732
733static int aw88261_get_fade_in_time(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
735{
736 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
737 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
738 struct aw_device *aw_dev = aw88261->aw_pa;
739
740 ucontrol->value.integer.value[0] = aw_dev->fade_in_time;
741
742 return 0;
743}
744
745static int aw88261_set_fade_in_time(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_value *ucontrol)
747{
748 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
749 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
750 struct soc_mixer_control *mc =
751 (struct soc_mixer_control *)kcontrol->private_value;
752 struct aw_device *aw_dev = aw88261->aw_pa;
753 int time;
754
755 time = ucontrol->value.integer.value[0];
756
757 if (time < mc->min || time > mc->max)
758 return -EINVAL;
759
760 if (time != aw_dev->fade_in_time) {
761 aw_dev->fade_in_time = time;
762 return 1;
763 }
764
765 return 0;
766}
767
768static int aw88261_get_fade_out_time(struct snd_kcontrol *kcontrol,
769 struct snd_ctl_elem_value *ucontrol)
770{
771 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
772 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
773 struct aw_device *aw_dev = aw88261->aw_pa;
774
775 ucontrol->value.integer.value[0] = aw_dev->fade_out_time;
776
777 return 0;
778}
779
780static int aw88261_set_fade_out_time(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
782{
783 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
784 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
785 struct soc_mixer_control *mc =
786 (struct soc_mixer_control *)kcontrol->private_value;
787 struct aw_device *aw_dev = aw88261->aw_pa;
788 int time;
789
790 time = ucontrol->value.integer.value[0];
791 if (time < mc->min || time > mc->max)
792 return -EINVAL;
793
794 if (time != aw_dev->fade_out_time) {
795 aw_dev->fade_out_time = time;
796 return 1;
797 }
798
799 return 0;
800}
801
802static int aw88261_dev_set_profile_index(struct aw_device *aw_dev, int index)
803{
804 /* check the index whether is valid */
805 if ((index >= aw_dev->prof_info.count) || (index < 0))
806 return -EINVAL;
807 /* check the index whether change */
808 if (aw_dev->prof_index == index)
809 return -EPERM;
810
811 aw_dev->prof_index = index;
812
813 return 0;
814}
815
816static int aw88261_profile_info(struct snd_kcontrol *kcontrol,
817 struct snd_ctl_elem_info *uinfo)
818{
819 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
820 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
821 const char *prof_name;
822 char *name;
823 int count;
824
825 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
826 uinfo->count = 1;
827
828 count = aw88261->aw_pa->prof_info.count;
829 if (count <= 0) {
830 uinfo->value.enumerated.items = 0;
831 return 0;
832 }
833
834 uinfo->value.enumerated.items = count;
835
836 if (uinfo->value.enumerated.item >= count)
837 uinfo->value.enumerated.item = count - 1;
838
839 name = uinfo->value.enumerated.name;
840 count = uinfo->value.enumerated.item;
841
842 prof_name = aw88261_dev_get_prof_name(aw88261->aw_pa, count);
843 if (!prof_name) {
844 strscpy(uinfo->value.enumerated.name, "null",
845 strlen("null") + 1);
846 return 0;
847 }
848
849 strscpy(name, prof_name, sizeof(uinfo->value.enumerated.name));
850
851 return 0;
852}
853
854static int aw88261_profile_get(struct snd_kcontrol *kcontrol,
855 struct snd_ctl_elem_value *ucontrol)
856{
857 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
858 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
859
860 ucontrol->value.integer.value[0] = aw88261->aw_pa->prof_index;
861
862 return 0;
863}
864
865static int aw88261_profile_set(struct snd_kcontrol *kcontrol,
866 struct snd_ctl_elem_value *ucontrol)
867{
868 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
869 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
870 int ret;
871
872 /* pa stop or stopping just set profile */
873 mutex_lock(&aw88261->lock);
874 ret = aw88261_dev_set_profile_index(aw88261->aw_pa, ucontrol->value.integer.value[0]);
875 if (ret) {
876 dev_dbg(codec->dev, "profile index does not change");
877 mutex_unlock(&aw88261->lock);
878 return 0;
879 }
880
881 if (aw88261->aw_pa->status) {
882 aw88261_dev_stop(aw88261->aw_pa);
883 aw88261_start(aw88261, AW88261_SYNC_START);
884 }
885
886 mutex_unlock(&aw88261->lock);
887
888 return 1;
889}
890
891static int aw88261_volume_get(struct snd_kcontrol *kcontrol,
892 struct snd_ctl_elem_value *ucontrol)
893{
894 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
895 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
896 struct aw_volume_desc *vol_desc = &aw88261->aw_pa->volume_desc;
897
898 ucontrol->value.integer.value[0] = vol_desc->ctl_volume;
899
900 return 0;
901}
902
903static int aw88261_volume_set(struct snd_kcontrol *kcontrol,
904 struct snd_ctl_elem_value *ucontrol)
905{
906 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
907 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
908 struct aw_volume_desc *vol_desc = &aw88261->aw_pa->volume_desc;
909 struct soc_mixer_control *mc =
910 (struct soc_mixer_control *)kcontrol->private_value;
911 int value;
912
913 value = ucontrol->value.integer.value[0];
914
915 if (value < mc->min || value > mc->max)
916 return -EINVAL;
917
918 if (vol_desc->ctl_volume != value) {
919 vol_desc->ctl_volume = value;
920 aw88261_dev_set_volume(aw88261->aw_pa, vol_desc->ctl_volume);
921
922 return 1;
923 }
924
925 return 0;
926}
927
928static int aw88261_get_fade_step(struct snd_kcontrol *kcontrol,
929 struct snd_ctl_elem_value *ucontrol)
930{
931 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
932 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
933
934 ucontrol->value.integer.value[0] = aw88261->aw_pa->fade_step;
935
936 return 0;
937}
938
939static int aw88261_set_fade_step(struct snd_kcontrol *kcontrol,
940 struct snd_ctl_elem_value *ucontrol)
941{
942 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
943 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(codec);
944 struct soc_mixer_control *mc =
945 (struct soc_mixer_control *)kcontrol->private_value;
946 int value;
947
948 value = ucontrol->value.integer.value[0];
949 if (value < mc->min || value > mc->max)
950 return -EINVAL;
951
952 if (aw88261->aw_pa->fade_step != value) {
953 aw88261->aw_pa->fade_step = value;
954 return 1;
955 }
956
957 return 0;
958}
959
960static const struct snd_kcontrol_new aw88261_controls[] = {
961 SOC_SINGLE_EXT("PCM Playback Volume", AW88261_SYSCTRL2_REG,
962 6, AW88261_MUTE_VOL, 0, aw88261_volume_get,
963 aw88261_volume_set),
964 SOC_SINGLE_EXT("Fade Step", 0, 0, AW88261_MUTE_VOL, 0,
965 aw88261_get_fade_step, aw88261_set_fade_step),
966 SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,
967 aw88261_get_fade_in_time, aw88261_set_fade_in_time),
968 SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,
969 aw88261_get_fade_out_time, aw88261_set_fade_out_time),
970 AW88261_PROFILE_EXT("Profile Set", aw88261_profile_info,
971 aw88261_profile_get, aw88261_profile_set),
972};
973
974static int aw88261_playback_event(struct snd_soc_dapm_widget *w,
975 struct snd_kcontrol *k, int event)
976{
977 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
978 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
979
980 mutex_lock(&aw88261->lock);
981 switch (event) {
982 case SND_SOC_DAPM_PRE_PMU:
983 aw88261_start(aw88261, AW88261_ASYNC_START);
984 break;
985 case SND_SOC_DAPM_POST_PMD:
986 aw88261_dev_stop(aw88261->aw_pa);
987 break;
988 default:
989 break;
990 }
991 mutex_unlock(&aw88261->lock);
992
993 return 0;
994}
995
996static const struct snd_soc_dapm_widget aw88261_dapm_widgets[] = {
997 /* playback */
998 SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0,
999 aw88261_playback_event,
1000 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1001 SND_SOC_DAPM_OUTPUT("DAC Output"),
1002
1003 /* capture */
1004 SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0),
1005 SND_SOC_DAPM_INPUT("ADC Input"),
1006};
1007
1008static const struct snd_soc_dapm_route aw88261_audio_map[] = {
1009 {"DAC Output", NULL, "AIF_RX"},
1010 {"AIF_TX", NULL, "ADC Input"},
1011};
1012
1013static int aw88261_frcset_check(struct aw88261 *aw88261)
1014{
1015 unsigned int reg_val;
1016 u16 temh, teml, tem;
1017 int ret;
1018
1019 ret = regmap_read(aw88261->regmap, AW88261_EFRH3_REG, &reg_val);
1020 if (ret)
1021 return ret;
1022 temh = ((u16)reg_val & (~AW88261_TEMH_MASK));
1023
1024 ret = regmap_read(aw88261->regmap, AW88261_EFRL3_REG, &reg_val);
1025 if (ret)
1026 return ret;
1027 teml = ((u16)reg_val & (~AW88261_TEML_MASK));
1028
1029 if (aw88261->efuse_check == AW88261_EF_OR_CHECK)
1030 tem = (temh | teml);
1031 else
1032 tem = (temh & teml);
1033
1034 if (tem == AW88261_DEFAULT_CFG)
1035 aw88261->frcset_en = AW88261_FRCSET_ENABLE;
1036 else
1037 aw88261->frcset_en = AW88261_FRCSET_DISABLE;
1038
1039 dev_dbg(aw88261->aw_pa->dev, "tem is 0x%04x, frcset_en is %d",
1040 tem, aw88261->frcset_en);
1041
1042 return ret;
1043}
1044
1045static int aw88261_dev_init(struct aw88261 *aw88261, struct aw_container *aw_cfg)
1046{
1047 struct aw_device *aw_dev = aw88261->aw_pa;
1048 int ret;
1049
1050 ret = aw88395_dev_cfg_load(aw_dev, aw_cfg);
1051 if (ret) {
1052 dev_err(aw_dev->dev, "aw_dev acf parse failed");
1053 return -EINVAL;
1054 }
1055
1056 ret = regmap_write(aw_dev->regmap, AW88261_ID_REG, AW88261_SOFT_RESET_VALUE);
1057 if (ret)
1058 return ret;
1059
1060 aw_dev->fade_in_time = AW88261_500_US;
1061 aw_dev->fade_out_time = AW88261_500_US;
1062 aw_dev->prof_cur = AW88261_INIT_PROFILE;
1063 aw_dev->prof_index = AW88261_INIT_PROFILE;
1064
1065 ret = aw88261_dev_fw_update(aw88261);
1066 if (ret) {
1067 dev_err(aw_dev->dev, "fw update failed ret = %d\n", ret);
1068 return ret;
1069 }
1070
1071 ret = aw88261_frcset_check(aw88261);
1072 if (ret) {
1073 dev_err(aw_dev->dev, "aw88261_frcset_check ret = %d\n", ret);
1074 return ret;
1075 }
1076
1077 aw88261_dev_clear_int_status(aw_dev);
1078
1079 aw88261_dev_uls_hmute(aw_dev, true);
1080
1081 aw88261_dev_mute(aw_dev, true);
1082
1083 aw88261_dev_i2s_tx_enable(aw_dev, false);
1084
1085 usleep_range(AW88261_1000_US, AW88261_1000_US + 100);
1086
1087 aw88261_dev_amppd(aw_dev, true);
1088
1089 aw88261_dev_pwd(aw_dev, true);
1090
1091 return 0;
1092}
1093
1094static int aw88261_request_firmware_file(struct aw88261 *aw88261)
1095{
1096 const struct firmware *cont = NULL;
1097 int ret;
1098
1099 aw88261->aw_pa->fw_status = AW88261_DEV_FW_FAILED;
1100
1101 ret = request_firmware(&cont, AW88261_ACF_FILE, aw88261->aw_pa->dev);
1102 if (ret)
1103 return dev_err_probe(aw88261->aw_pa->dev, ret,
1104 "load [%s] failed!", AW88261_ACF_FILE);
1105
1106 dev_info(aw88261->aw_pa->dev, "loaded %s - size: %zu\n",
1107 AW88261_ACF_FILE, cont ? cont->size : 0);
1108
1109 aw88261->aw_cfg = devm_kzalloc(aw88261->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
1110 if (!aw88261->aw_cfg) {
1111 release_firmware(cont);
1112 return -ENOMEM;
1113 }
1114 aw88261->aw_cfg->len = (int)cont->size;
1115 memcpy(aw88261->aw_cfg->data, cont->data, cont->size);
1116 release_firmware(cont);
1117
1118 ret = aw88395_dev_load_acf_check(aw88261->aw_pa, aw88261->aw_cfg);
1119 if (ret) {
1120 dev_err(aw88261->aw_pa->dev, "load [%s] failed !", AW88261_ACF_FILE);
1121 return ret;
1122 }
1123
1124 mutex_lock(&aw88261->lock);
1125 /* aw device init */
1126 ret = aw88261_dev_init(aw88261, aw88261->aw_cfg);
1127 if (ret)
1128 dev_err(aw88261->aw_pa->dev, "dev init failed");
1129 mutex_unlock(&aw88261->lock);
1130
1131 return ret;
1132}
1133
1134static int aw88261_codec_probe(struct snd_soc_component *component)
1135{
1136 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1137 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
1138 int ret;
1139
1140 INIT_DELAYED_WORK(&aw88261->start_work, aw88261_startup_work);
1141
1142 ret = aw88261_request_firmware_file(aw88261);
1143 if (ret)
1144 return dev_err_probe(aw88261->aw_pa->dev, ret,
1145 "aw88261_request_firmware_file failed\n");
1146
1147 /* add widgets */
1148 ret = snd_soc_dapm_new_controls(dapm, aw88261_dapm_widgets,
1149 ARRAY_SIZE(aw88261_dapm_widgets));
1150 if (ret)
1151 return ret;
1152
1153 /* add route */
1154 ret = snd_soc_dapm_add_routes(dapm, aw88261_audio_map,
1155 ARRAY_SIZE(aw88261_audio_map));
1156 if (ret)
1157 return ret;
1158
1159 ret = snd_soc_add_component_controls(component, aw88261_controls,
1160 ARRAY_SIZE(aw88261_controls));
1161
1162 return ret;
1163}
1164
1165static void aw88261_codec_remove(struct snd_soc_component *aw_codec)
1166{
1167 struct aw88261 *aw88261 = snd_soc_component_get_drvdata(aw_codec);
1168
1169 cancel_delayed_work_sync(&aw88261->start_work);
1170}
1171
1172static const struct snd_soc_component_driver soc_codec_dev_aw88261 = {
1173 .probe = aw88261_codec_probe,
1174 .remove = aw88261_codec_remove,
1175};
1176
1177static void aw88261_hw_reset(struct aw88261 *aw88261)
1178{
1179 gpiod_set_value_cansleep(aw88261->reset_gpio, 0);
1180 usleep_range(AW88261_1000_US, AW88261_1000_US + 10);
1181 gpiod_set_value_cansleep(aw88261->reset_gpio, 1);
1182 usleep_range(AW88261_1000_US, AW88261_1000_US + 10);
1183}
1184
1185static void aw88261_parse_channel_dt(struct aw88261 *aw88261)
1186{
1187 struct aw_device *aw_dev = aw88261->aw_pa;
1188 struct device_node *np = aw_dev->dev->of_node;
1189 u32 channel_value = AW88261_DEV_DEFAULT_CH;
1190 u32 sync_enable = false;
1191
1192 of_property_read_u32(np, "sound-channel", &channel_value);
1193 of_property_read_u32(np, "sync-flag", &sync_enable);
1194
1195 aw_dev->channel = channel_value;
1196 aw88261->phase_sync = sync_enable;
1197}
1198
1199static int aw88261_init(struct aw88261 **aw88261, struct i2c_client *i2c, struct regmap *regmap)
1200{
1201 struct aw_device *aw_dev;
1202 unsigned int chip_id;
1203 int ret;
1204
1205 /* read chip id */
1206 ret = regmap_read(regmap, AW88261_ID_REG, &chip_id);
1207 if (ret) {
1208 dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret);
1209 return ret;
1210 }
1211 if (chip_id != AW88261_CHIP_ID) {
1212 dev_err(&i2c->dev, "unsupported device");
1213 return -ENXIO;
1214 }
1215
1216 dev_info(&i2c->dev, "chip id = %x\n", chip_id);
1217
1218 aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);
1219 if (!aw_dev)
1220 return -ENOMEM;
1221
1222 (*aw88261)->aw_pa = aw_dev;
1223 aw_dev->i2c = i2c;
1224 aw_dev->regmap = regmap;
1225 aw_dev->dev = &i2c->dev;
1226 aw_dev->chip_id = AW88261_CHIP_ID;
1227 aw_dev->acf = NULL;
1228 aw_dev->prof_info.prof_desc = NULL;
1229 aw_dev->prof_info.count = 0;
1230 aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID;
1231 aw_dev->channel = 0;
1232 aw_dev->fw_status = AW88261_DEV_FW_FAILED;
1233 aw_dev->fade_step = AW88261_VOLUME_STEP_DB;
1234 aw_dev->volume_desc.ctl_volume = AW88261_VOL_DEFAULT_VALUE;
1235 aw_dev->volume_desc.mute_volume = AW88261_MUTE_VOL;
1236 aw88261_parse_channel_dt(*aw88261);
1237
1238 return ret;
1239}
1240
1241static int aw88261_i2c_probe(struct i2c_client *i2c)
1242{
1243 struct aw88261 *aw88261;
1244 int ret;
1245
1246 ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);
1247 if (!ret)
1248 return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed");
1249
1250 aw88261 = devm_kzalloc(&i2c->dev, sizeof(*aw88261), GFP_KERNEL);
1251 if (!aw88261)
1252 return -ENOMEM;
1253
1254 mutex_init(&aw88261->lock);
1255
1256 i2c_set_clientdata(i2c, aw88261);
1257
1258 aw88261->reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_LOW);
1259 if (IS_ERR(aw88261->reset_gpio))
1260 dev_info(&i2c->dev, "reset gpio not defined\n");
1261 else
1262 aw88261_hw_reset(aw88261);
1263
1264 aw88261->regmap = devm_regmap_init_i2c(i2c, &aw88261_remap_config);
1265 if (IS_ERR(aw88261->regmap)) {
1266 ret = PTR_ERR(aw88261->regmap);
1267 return dev_err_probe(&i2c->dev, ret, "failed to init regmap: %d\n", ret);
1268 }
1269
1270 /* aw pa init */
1271 ret = aw88261_init(&aw88261, i2c, aw88261->regmap);
1272 if (ret)
1273 return ret;
1274
1275 ret = devm_snd_soc_register_component(&i2c->dev,
1276 &soc_codec_dev_aw88261,
1277 aw88261_dai, ARRAY_SIZE(aw88261_dai));
1278 if (ret)
1279 dev_err(&i2c->dev, "failed to register aw88261: %d", ret);
1280
1281 return ret;
1282}
1283
1284static const struct i2c_device_id aw88261_i2c_id[] = {
1285 { AW88261_I2C_NAME, 0 },
1286 { }
1287};
1288MODULE_DEVICE_TABLE(i2c, aw88261_i2c_id);
1289
1290static struct i2c_driver aw88261_i2c_driver = {
1291 .driver = {
1292 .name = AW88261_I2C_NAME,
1293 },
1294 .probe = aw88261_i2c_probe,
1295 .id_table = aw88261_i2c_id,
1296};
1297module_i2c_driver(aw88261_i2c_driver);
1298
1299MODULE_DESCRIPTION("ASoC AW88261 Smart PA Driver");
1300MODULE_LICENSE("GPL v2");
sound/soc/codecs/aw88261.h+459−0
@@ -0,0 +1,459 @@
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// aw88261.h -- AW88261 ALSA SoC Audio driver
4//
5// Copyright (c) 2023 awinic Technology CO., LTD
6//
7// Author: Jimmy Zhang <zhangjianming@awinic.com>
8// Author: Weidong Wang <wangweidong.a@awinic.com>
9//
10
11#ifndef __AW88261_H__
12#define __AW88261_H__
13
14#define AW88261_ID_REG (0x00)
15#define AW88261_SYSST_REG (0x01)
16#define AW88261_SYSINT_REG (0x02)
17#define AW88261_SYSINTM_REG (0x03)
18#define AW88261_SYSCTRL_REG (0x04)
19#define AW88261_SYSCTRL2_REG (0x05)
20#define AW88261_I2SCTRL1_REG (0x06)
21#define AW88261_I2SCTRL2_REG (0x07)
22#define AW88261_I2SCTRL3_REG (0x08)
23#define AW88261_DACCFG1_REG (0x09)
24#define AW88261_DACCFG2_REG (0x0A)
25#define AW88261_DACCFG3_REG (0x0B)
26#define AW88261_DACCFG4_REG (0x0C)
27#define AW88261_DACCFG5_REG (0x0D)
28#define AW88261_DACCFG6_REG (0x0E)
29#define AW88261_DACCFG7_REG (0x0F)
30#define AW88261_DACCFG8_REG (0x10)
31#define AW88261_PWMCTRL1_REG (0x11)
32#define AW88261_PWMCTRL2_REG (0x12)
33#define AW88261_I2SCFG1_REG (0x13)
34#define AW88261_DBGCTRL_REG (0x14)
35#define AW88261_DACCFG9_REG (0x15)
36#define AW88261_DACCFG10_REG (0x16)
37#define AW88261_DACST_REG (0x20)
38#define AW88261_VBAT_REG (0x21)
39#define AW88261_TEMP_REG (0x22)
40#define AW88261_PVDD_REG (0x23)
41#define AW88261_ISNDAT_REG (0x24)
42#define AW88261_VSNDAT_REG (0x25)
43#define AW88261_I2SINT_REG (0x26)
44#define AW88261_I2SCAPCNT_REG (0x27)
45#define AW88261_ANASTA1_REG (0x28)
46#define AW88261_ANASTA2_REG (0x29)
47#define AW88261_ANASTA3_REG (0x2A)
48#define AW88261_TESTDET_REG (0x2B)
49#define AW88261_DSMCFG1_REG (0x30)
50#define AW88261_DSMCFG2_REG (0x31)
51#define AW88261_DSMCFG3_REG (0x32)
52#define AW88261_DSMCFG4_REG (0x33)
53#define AW88261_DSMCFG5_REG (0x34)
54#define AW88261_DSMCFG6_REG (0x35)
55#define AW88261_DSMCFG7_REG (0x36)
56#define AW88261_DSMCFG8_REG (0x37)
57#define AW88261_TESTIN_REG (0x38)
58#define AW88261_TESTOUT_REG (0x39)
59#define AW88261_SADCCTRL1_REG (0x3A)
60#define AW88261_SADCCTRL2_REG (0x3B)
61#define AW88261_SADCCTRL3_REG (0x3C)
62#define AW88261_SADCCTRL4_REG (0x3D)
63#define AW88261_SADCCTRL5_REG (0x3E)
64#define AW88261_SADCCTRL6_REG (0x3F)
65#define AW88261_SADCCTRL7_REG (0x40)
66#define AW88261_VSNTM1_REG (0x50)
67#define AW88261_VSNTM2_REG (0x51)
68#define AW88261_ISNCTRL1_REG (0x52)
69#define AW88261_ISNCTRL2_REG (0x53)
70#define AW88261_PLLCTRL1_REG (0x54)
71#define AW88261_PLLCTRL2_REG (0x55)
72#define AW88261_PLLCTRL3_REG (0x56)
73#define AW88261_CDACTRL1_REG (0x57)
74#define AW88261_CDACTRL2_REG (0x58)
75#define AW88261_DITHERCFG1_REG (0x59)
76#define AW88261_DITHERCFG2_REG (0x5A)
77#define AW88261_DITHERCFG3_REG (0x5B)
78#define AW88261_CPCTRL_REG (0x5C)
79#define AW88261_BSTCTRL1_REG (0x60)
80#define AW88261_BSTCTRL2_REG (0x61)
81#define AW88261_BSTCTRL3_REG (0x62)
82#define AW88261_BSTCTRL4_REG (0x63)
83#define AW88261_BSTCTRL5_REG (0x64)
84#define AW88261_BSTCTRL6_REG (0x65)
85#define AW88261_BSTCTRL7_REG (0x66)
86#define AW88261_BSTCTRL8_REG (0x67)
87#define AW88261_BSTCTRL9_REG (0x68)
88#define AW88261_TM_REG (0x6F)
89#define AW88261_TESTCTRL1_REG (0x70)
90#define AW88261_TESTCTRL2_REG (0x71)
91#define AW88261_EFCTRL1_REG (0x72)
92#define AW88261_EFCTRL2_REG (0x73)
93#define AW88261_EFWH_REG (0x74)
94#define AW88261_EFWM2_REG (0x75)
95#define AW88261_EFWM1_REG (0x76)
96#define AW88261_EFWL_REG (0x77)
97#define AW88261_EFRH4_REG (0x78)
98#define AW88261_EFRH3_REG (0x79)
99#define AW88261_EFRH2_REG (0x7A)
100#define AW88261_EFRH1_REG (0x7B)
101#define AW88261_EFRL4_REG (0x7C)
102#define AW88261_EFRL3_REG (0x7D)
103#define AW88261_EFRL2_REG (0x7E)
104#define AW88261_EFRL1_REG (0x7F)
105
106#define AW88261_REG_MAX (0x80)
107#define AW88261_EF_DBMD_MASK (0xfff7)
108#define AW88261_OR_VALUE (0x0008)
109
110#define AW88261_TEMH_MASK (0x83ff)
111#define AW88261_TEML_MASK (0x83ff)
112#define AW88261_DEFAULT_CFG (0x0000)
113
114#define AW88261_ICALK_SHIFT (0)
115#define AW88261_ICALKL_SHIFT (0)
116#define AW88261_VCALK_SHIFT (0)
117#define AW88261_VCALKL_SHIFT (0)
118
119#define AW88261_AMPPD_START_BIT (1)
120#define AW88261_AMPPD_BITS_LEN (1)
121#define AW88261_AMPPD_MASK \
122 (~(((1<<AW88261_AMPPD_BITS_LEN)-1) << AW88261_AMPPD_START_BIT))
123
124#define AW88261_UVLS_START_BIT (14)
125#define AW88261_UVLS_NORMAL (0)
126#define AW88261_UVLS_NORMAL_VALUE \
127 (AW88261_UVLS_NORMAL << AW88261_UVLS_START_BIT)
128
129#define AW88261_BSTOCS_START_BIT (11)
130#define AW88261_BSTOCS_OVER_CURRENT (1)
131#define AW88261_BSTOCS_OVER_CURRENT_VALUE \
132 (AW88261_BSTOCS_OVER_CURRENT << AW88261_BSTOCS_START_BIT)
133
134#define AW88261_BSTS_START_BIT (9)
135#define AW88261_BSTS_FINISHED (1)
136#define AW88261_BSTS_FINISHED_VALUE \
137 (AW88261_BSTS_FINISHED << AW88261_BSTS_START_BIT)
138
139#define AW88261_SWS_START_BIT (8)
140#define AW88261_SWS_SWITCHING (1)
141#define AW88261_SWS_SWITCHING_VALUE \
142 (AW88261_SWS_SWITCHING << AW88261_SWS_START_BIT)
143
144#define AW88261_NOCLKS_START_BIT (5)
145#define AW88261_NOCLKS_NO_CLOCK (1)
146#define AW88261_NOCLKS_NO_CLOCK_VALUE \
147 (AW88261_NOCLKS_NO_CLOCK << AW88261_NOCLKS_START_BIT)
148
149#define AW88261_CLKS_START_BIT (4)
150#define AW88261_CLKS_STABLE (1)
151#define AW88261_CLKS_STABLE_VALUE \
152 (AW88261_CLKS_STABLE << AW88261_CLKS_START_BIT)
153
154#define AW88261_OCDS_START_BIT (3)
155#define AW88261_OCDS_OC (1)
156#define AW88261_OCDS_OC_VALUE \
157 (AW88261_OCDS_OC << AW88261_OCDS_START_BIT)
158
159#define AW88261_OTHS_START_BIT (1)
160#define AW88261_OTHS_OT (1)
161#define AW88261_OTHS_OT_VALUE \
162 (AW88261_OTHS_OT << AW88261_OTHS_START_BIT)
163
164#define AW88261_PLLS_START_BIT (0)
165#define AW88261_PLLS_LOCKED (1)
166#define AW88261_PLLS_LOCKED_VALUE \
167 (AW88261_PLLS_LOCKED << AW88261_PLLS_START_BIT)
168
169#define AW88261_BIT_PLL_CHECK \
170 (AW88261_CLKS_STABLE_VALUE | \
171 AW88261_PLLS_LOCKED_VALUE)
172
173#define AW88261_BIT_SYSST_CHECK_MASK \
174 (~(AW88261_UVLS_NORMAL_VALUE | \
175 AW88261_BSTOCS_OVER_CURRENT_VALUE | \
176 AW88261_BSTS_FINISHED_VALUE | \
177 AW88261_SWS_SWITCHING_VALUE | \
178 AW88261_NOCLKS_NO_CLOCK_VALUE | \
179 AW88261_CLKS_STABLE_VALUE | \
180 AW88261_OCDS_OC_VALUE | \
181 AW88261_OTHS_OT_VALUE | \
182 AW88261_PLLS_LOCKED_VALUE))
183
184#define AW88261_BIT_SYSST_CHECK \
185 (AW88261_BSTS_FINISHED_VALUE | \
186 AW88261_SWS_SWITCHING_VALUE | \
187 AW88261_CLKS_STABLE_VALUE | \
188 AW88261_PLLS_LOCKED_VALUE)
189
190#define AW88261_ULS_HMUTE_START_BIT (14)
191#define AW88261_ULS_HMUTE_BITS_LEN (1)
192#define AW88261_ULS_HMUTE_MASK \
193 (~(((1<<AW88261_ULS_HMUTE_BITS_LEN)-1) << AW88261_ULS_HMUTE_START_BIT))
194
195#define AW88261_ULS_HMUTE_DISABLE (0)
196#define AW88261_ULS_HMUTE_DISABLE_VALUE \
197 (AW88261_ULS_HMUTE_DISABLE << AW88261_ULS_HMUTE_START_BIT)
198
199#define AW88261_ULS_HMUTE_ENABLE (1)
200#define AW88261_ULS_HMUTE_ENABLE_VALUE \
201 (AW88261_ULS_HMUTE_ENABLE << AW88261_ULS_HMUTE_START_BIT)
202
203#define AW88261_HMUTE_START_BIT (8)
204#define AW88261_HMUTE_BITS_LEN (1)
205#define AW88261_HMUTE_MASK \
206 (~(((1<<AW88261_HMUTE_BITS_LEN)-1) << AW88261_HMUTE_START_BIT))
207
208#define AW88261_HMUTE_DISABLE (0)
209#define AW88261_HMUTE_DISABLE_VALUE \
210 (AW88261_HMUTE_DISABLE << AW88261_HMUTE_START_BIT)
211
212#define AW88261_HMUTE_ENABLE (1)
213#define AW88261_HMUTE_ENABLE_VALUE \
214 (AW88261_HMUTE_ENABLE << AW88261_HMUTE_START_BIT)
215
216#define AW88261_AMPPD_START_BIT (1)
217#define AW88261_AMPPD_BITS_LEN (1)
218#define AW88261_AMPPD_MASK \
219 (~(((1<<AW88261_AMPPD_BITS_LEN)-1) << AW88261_AMPPD_START_BIT))
220
221#define AW88261_AMPPD_WORKING (0)
222#define AW88261_AMPPD_WORKING_VALUE \
223 (AW88261_AMPPD_WORKING << AW88261_AMPPD_START_BIT)
224
225#define AW88261_AMPPD_POWER_DOWN (1)
226#define AW88261_AMPPD_POWER_DOWN_VALUE \
227 (AW88261_AMPPD_POWER_DOWN << AW88261_AMPPD_START_BIT)
228
229#define AW88261_PWDN_START_BIT (0)
230#define AW88261_PWDN_BITS_LEN (1)
231#define AW88261_PWDN_MASK \
232 (~(((1<<AW88261_PWDN_BITS_LEN)-1) << AW88261_PWDN_START_BIT))
233
234#define AW88261_PWDN_WORKING (0)
235#define AW88261_PWDN_WORKING_VALUE \
236 (AW88261_PWDN_WORKING << AW88261_PWDN_START_BIT)
237
238#define AW88261_PWDN_POWER_DOWN (1)
239#define AW88261_PWDN_POWER_DOWN_VALUE \
240 (AW88261_PWDN_POWER_DOWN << AW88261_PWDN_START_BIT)
241
242#define AW88261_MUTE_VOL (90 * 8)
243#define AW88261_VOLUME_STEP_DB (6 * 8)
244
245#define AW88261_VOL_6DB_START (6)
246
247#define AW88261_VOL_START_BIT (0)
248#define AW88261_VOL_BITS_LEN (10)
249#define AW88261_VOL_MASK \
250 (~(((1<<AW88261_VOL_BITS_LEN)-1) << AW88261_VOL_START_BIT))
251
252#define AW88261_VOL_DEFAULT_VALUE (0)
253
254#define AW88261_I2STXEN_START_BIT (6)
255#define AW88261_I2STXEN_BITS_LEN (1)
256#define AW88261_I2STXEN_MASK \
257 (~(((1<<AW88261_I2STXEN_BITS_LEN)-1) << AW88261_I2STXEN_START_BIT))
258
259#define AW88261_I2STXEN_DISABLE (0)
260#define AW88261_I2STXEN_DISABLE_VALUE \
261 (AW88261_I2STXEN_DISABLE << AW88261_I2STXEN_START_BIT)
262
263#define AW88261_I2STXEN_ENABLE (1)
264#define AW88261_I2STXEN_ENABLE_VALUE \
265 (AW88261_I2STXEN_ENABLE << AW88261_I2STXEN_START_BIT)
266
267#define AW88261_CCO_MUX_START_BIT (14)
268#define AW88261_CCO_MUX_BITS_LEN (1)
269#define AW88261_CCO_MUX_MASK \
270 (~(((1<<AW88261_CCO_MUX_BITS_LEN)-1) << AW88261_CCO_MUX_START_BIT))
271
272#define AW88261_CCO_MUX_DIVIDED (0)
273#define AW88261_CCO_MUX_DIVIDED_VALUE \
274 (AW88261_CCO_MUX_DIVIDED << AW88261_CCO_MUX_START_BIT)
275
276#define AW88261_CCO_MUX_BYPASS (1)
277#define AW88261_CCO_MUX_BYPASS_VALUE \
278 (AW88261_CCO_MUX_BYPASS << AW88261_CCO_MUX_START_BIT)
279
280#define AW88261_EF_VSN_GESLP_H_START_BIT (0)
281#define AW88261_EF_VSN_GESLP_H_BITS_LEN (10)
282#define AW88261_EF_VSN_GESLP_H_MASK \
283 (~(((1<<AW88261_EF_VSN_GESLP_H_BITS_LEN)-1) << AW88261_EF_VSN_GESLP_H_START_BIT))
284
285#define AW88261_EF_VSN_GESLP_L_START_BIT (0)
286#define AW88261_EF_VSN_GESLP_L_BITS_LEN (10)
287#define AW88261_EF_VSN_GESLP_L_MASK \
288 (~(((1<<AW88261_EF_VSN_GESLP_L_BITS_LEN)-1) << AW88261_EF_VSN_GESLP_L_START_BIT))
289
290#define AW88261_FORCE_PWM_START_BIT (12)
291#define AW88261_FORCE_PWM_BITS_LEN (1)
292#define AW88261_FORCE_PWM_MASK \
293 (~(((1<<AW88261_FORCE_PWM_BITS_LEN)-1) << AW88261_FORCE_PWM_START_BIT))
294
295#define AW88261_FORCE_PWM_FORCEMINUS_PWM (1)
296#define AW88261_FORCE_PWM_FORCEMINUS_PWM_VALUE \
297 (AW88261_FORCE_PWM_FORCEMINUS_PWM << AW88261_FORCE_PWM_START_BIT)
298
299#define AW88261_BST_OS_WIDTH_START_BIT (0)
300#define AW88261_BST_OS_WIDTH_BITS_LEN (3)
301#define AW88261_BST_OS_WIDTH_MASK \
302 (~(((1<<AW88261_BST_OS_WIDTH_BITS_LEN)-1) << AW88261_BST_OS_WIDTH_START_BIT))
303
304#define AW88261_BST_OS_WIDTH_50NS (4)
305#define AW88261_BST_OS_WIDTH_50NS_VALUE \
306 (AW88261_BST_OS_WIDTH_50NS << AW88261_BST_OS_WIDTH_START_BIT)
307
308/* BST_LOOPR bit 1:0 (BSTCTRL6 0x65) */
309#define AW88261_BST_LOOPR_START_BIT (0)
310#define AW88261_BST_LOOPR_BITS_LEN (2)
311#define AW88261_BST_LOOPR_MASK \
312 (~(((1<<AW88261_BST_LOOPR_BITS_LEN)-1) << AW88261_BST_LOOPR_START_BIT))
313
314#define AW88261_BST_LOOPR_340K (2)
315#define AW88261_BST_LOOPR_340K_VALUE \
316 (AW88261_BST_LOOPR_340K << AW88261_BST_LOOPR_START_BIT)
317
318/* RSQN_DLY bit 15:14 (BSTCTRL7 0x66) */
319#define AW88261_RSQN_DLY_START_BIT (14)
320#define AW88261_RSQN_DLY_BITS_LEN (2)
321#define AW88261_RSQN_DLY_MASK \
322 (~(((1<<AW88261_RSQN_DLY_BITS_LEN)-1) << AW88261_RSQN_DLY_START_BIT))
323
324#define AW88261_RSQN_DLY_35NS (2)
325#define AW88261_RSQN_DLY_35NS_VALUE \
326 (AW88261_RSQN_DLY_35NS << AW88261_RSQN_DLY_START_BIT)
327
328/* BURST_SSMODE bit 3 (BSTCTRL8 0x67) */
329#define AW88261_BURST_SSMODE_START_BIT (3)
330#define AW88261_BURST_SSMODE_BITS_LEN (1)
331#define AW88261_BURST_SSMODE_MASK \
332 (~(((1<<AW88261_BURST_SSMODE_BITS_LEN)-1) << AW88261_BURST_SSMODE_START_BIT))
333
334#define AW88261_BURST_SSMODE_FAST (0)
335#define AW88261_BURST_SSMODE_FAST_VALUE \
336 (AW88261_BURST_SSMODE_FAST << AW88261_BURST_SSMODE_START_BIT)
337
338/* BST_BURST bit 9:7 (BSTCTRL9 0x68) */
339#define AW88261_BST_BURST_START_BIT (7)
340#define AW88261_BST_BURST_BITS_LEN (3)
341#define AW88261_BST_BURST_MASK \
342 (~(((1<<AW88261_BST_BURST_BITS_LEN)-1) << AW88261_BST_BURST_START_BIT))
343
344#define AW88261_BST_BURST_30MA (2)
345#define AW88261_BST_BURST_30MA_VALUE \
346 (AW88261_BST_BURST_30MA << AW88261_BST_BURST_START_BIT)
347
348#define AW88261_EF_VSN_GESLP_SIGN_MASK (~0x0200)
349#define AW88261_EF_VSN_GESLP_NEG (~0xfc00)
350
351#define AW88261_EF_ISN_GESLP_SIGN_MASK (~0x0200)
352#define AW88261_EF_ISN_GESLP_NEG (~0xfc00)
353
354#define AW88261_EF_ISN_GESLP_H_START_BIT (0)
355#define AW88261_EF_ISN_GESLP_H_BITS_LEN (10)
356#define AW88261_EF_ISN_GESLP_H_MASK \
357 (~(((1<<AW88261_EF_ISN_GESLP_H_BITS_LEN)-1) << AW88261_EF_ISN_GESLP_H_START_BIT))
358
359#define AW88261_EF_ISN_GESLP_L_START_BIT (0)
360#define AW88261_EF_ISN_GESLP_L_BITS_LEN (10)
361#define AW88261_EF_ISN_GESLP_L_MASK \
362 (~(((1<<AW88261_EF_ISN_GESLP_L_BITS_LEN)-1) << AW88261_EF_ISN_GESLP_L_START_BIT))
363
364#define AW88261_CABL_BASE_VALUE (1000)
365#define AW88261_ICABLK_FACTOR (1)
366#define AW88261_VCABLK_FACTOR (1)
367
368#define AW88261_VCAL_FACTOR (1<<13)
369
370#define AW88261_START_RETRIES (5)
371#define AW88261_START_WORK_DELAY_MS (0)
372
373#define AW88261_I2C_NAME "aw88261_smartpa"
374
375#define AW88261_RATES (SNDRV_PCM_RATE_8000_48000 | \
376 SNDRV_PCM_RATE_96000)
377#define AW88261_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
378 SNDRV_PCM_FMTBIT_S24_LE | \
379 SNDRV_PCM_FMTBIT_S32_LE)
380
381#define FADE_TIME_MAX 100000
382#define FADE_TIME_MIN 0
383
384#define AW88261_DEV_DEFAULT_CH (0)
385#define AW88261_ACF_FILE "aw88261_acf.bin"
386#define AW88261_DEV_SYSST_CHECK_MAX (10)
387#define AW88261_SOFT_RESET_VALUE (0x55aa)
388#define AW88261_REG_TO_DB (0x3f)
389#define AW88261_VOL_START_MASK (0xfc00)
390#define AW88261_INIT_PROFILE (0)
391
392#define REG_VAL_TO_DB(value) ((((value) >> AW88261_VOL_6DB_START) * \
393 AW88261_VOLUME_STEP_DB) + \
394 ((value) & AW88261_REG_TO_DB))
395#define DB_TO_REG_VAL(value) ((((value) / AW88261_VOLUME_STEP_DB) << \
396 AW88261_VOL_6DB_START) + \
397 ((value) % AW88261_VOLUME_STEP_DB))
398
399#define AW88261_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \
400{ \
401 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
402 .name = xname, \
403 .info = profile_info, \
404 .get = profile_get, \
405 .put = profile_set, \
406}
407
408enum {
409 AW88261_SYNC_START = 0,
410 AW88261_ASYNC_START,
411};
412
413enum aw88261_id {
414 AW88261_CHIP_ID = 0x2113,
415};
416
417enum {
418 AW88261_500_US = 500,
419 AW88261_1000_US = 1000,
420 AW88261_2000_US = 2000,
421};
422
423enum {
424 AW88261_DEV_PW_OFF = 0,
425 AW88261_DEV_PW_ON,
426};
427
428enum {
429 AW88261_DEV_FW_FAILED = 0,
430 AW88261_DEV_FW_OK,
431};
432
433enum {
434 AW88261_EF_AND_CHECK = 0,
435 AW88261_EF_OR_CHECK,
436};
437
438enum {
439 AW88261_FRCSET_DISABLE = 0,
440 AW88261_FRCSET_ENABLE,
441};
442
443struct aw88261 {
444 struct aw_device *aw_pa;
445 struct mutex lock;
446 struct gpio_desc *reset_gpio;
447 struct delayed_work start_work;
448 struct regmap *regmap;
449 struct aw_container *aw_cfg;
450
451 int efuse_check;
452 int frcset_en;
453 unsigned int mute_st;
454 unsigned int amppd_st;
455
456 unsigned char phase_sync;
457};
458
459#endif
sound/soc/codecs/aw88395/aw88395_lib.c+176−17
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/i2c.h>11#include <linux/i2c.h>
12#include "aw88395_lib.h"12#include "aw88395_lib.h"
13#include "aw88395_device.h"13#include "aw88395_device.h"
14#include "aw88395_reg.h"
14 15
15#define AW88395_CRC8_POLYNOMIAL 0x8C16#define AW88395_CRC8_POLYNOMIAL 0x8C
16DECLARE_CRC8_TABLE(aw_crc8_table);17DECLARE_CRC8_TABLE(aw_crc8_table);
@@ -429,6 +430,53 @@ parse_bin_failed: · 412 unmodified lines
429 return ret;430 return ret;
430}431}
431 432
433static int aw_dev_parse_reg_bin_with_hdr(struct aw_device *aw_dev,
434 uint8_t *data, uint32_t data_len, struct aw_prof_desc *prof_desc)
435{
436 struct aw_bin *aw_bin;
437 int ret;
438
439 aw_bin = devm_kzalloc(aw_dev->dev, data_len + sizeof(*aw_bin), GFP_KERNEL);
440 if (!aw_bin)
441 return -ENOMEM;
442
443 aw_bin->info.len = data_len;
444 memcpy(aw_bin->info.data, data, data_len);
445
446 ret = aw_parsing_bin_file(aw_dev, aw_bin);
447 if (ret < 0) {
448 dev_err(aw_dev->dev, "parse bin failed");
449 goto parse_bin_failed;
450 }
451
452 if ((aw_bin->all_bin_parse_num != 1) ||
453 (aw_bin->header_info[0].bin_data_type != DATA_TYPE_REGISTER)) {
454 dev_err(aw_dev->dev, "bin num or type error");
455 goto parse_bin_failed;
456 }
457
458 if (aw_bin->header_info[0].valid_data_len % 4) {
459 dev_err(aw_dev->dev, "bin data len get error!");
460 goto parse_bin_failed;
461 }
462
463 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data =
464 data + aw_bin->header_info[0].valid_data_addr;
465 prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len =
466 aw_bin->header_info[0].valid_data_len;
467 prof_desc->prof_st = AW88395_PROFILE_OK;
468
469 devm_kfree(aw_dev->dev, aw_bin);
470 aw_bin = NULL;
471
472 return 0;
473
474parse_bin_failed:
475 devm_kfree(aw_dev->dev, aw_bin);
476 aw_bin = NULL;
477 return ret;
478}
479
432static int aw_dev_parse_data_by_sec_type(struct aw_device *aw_dev, struct aw_cfg_hdr *cfg_hdr,480static int aw_dev_parse_data_by_sec_type(struct aw_device *aw_dev, struct aw_cfg_hdr *cfg_hdr,
433 struct aw_cfg_dde *cfg_dde, struct aw_prof_desc *scene_prof_desc)481 struct aw_cfg_dde *cfg_dde, struct aw_prof_desc *scene_prof_desc)
434{482{
@@ -447,6 +495,9 @@ static int aw_dev_parse_data_by_sec_type(struct aw_device *aw_dev, struct aw_cfg · 12 unmodified lines
447 return aw_dev_prof_parse_multi_bin(495 return aw_dev_prof_parse_multi_bin(
448 aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset,496 aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset,
449 cfg_dde->data_size, scene_prof_desc);497 cfg_dde->data_size, scene_prof_desc);
498 case ACF_SEC_TYPE_HDR_REG:
499 return aw_dev_parse_reg_bin_with_hdr(aw_dev, (u8 *)cfg_hdr + cfg_dde->data_offset,
500 cfg_dde->data_size, scene_prof_desc);
450 default:501 default:
451 dev_err(aw_dev->dev, "%s cfg_dde->data_type = %d\n", __func__, cfg_dde->data_type);502 dev_err(aw_dev->dev, "%s cfg_dde->data_type = %d\n", __func__, cfg_dde->data_type);
452 break;503 break;
@@ -527,7 +578,49 @@ static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev, · 74 unmodified lines
527 return 0;578 return 0;
528}579}
529 580
530static int aw_dev_cfg_get_valid_prof(struct aw_device *aw_dev,581static int aw88261_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
582 struct aw_all_prof_info all_prof_info)
583{
584 struct aw_prof_desc *prof_desc = all_prof_info.prof_desc;
585 struct aw_prof_info *prof_info = &aw_dev->prof_info;
586 int num = 0;
587 int i;
588
589 for (i = 0; i < AW88395_PROFILE_MAX; i++) {
590 if (prof_desc[i].prof_st == AW88395_PROFILE_OK)
591 prof_info->count++;
592 }
593
594 dev_dbg(aw_dev->dev, "get valid profile:%d", aw_dev->prof_info.count);
595
596 if (!prof_info->count) {
597 dev_err(aw_dev->dev, "no profile data");
598 return -EPERM;
599 }
600
601 prof_info->prof_desc = devm_kcalloc(aw_dev->dev,
602 prof_info->count, sizeof(struct aw_prof_desc),
603 GFP_KERNEL);
604 if (!prof_info->prof_desc)
605 return -ENOMEM;
606
607 for (i = 0; i < AW88395_PROFILE_MAX; i++) {
608 if (prof_desc[i].prof_st == AW88395_PROFILE_OK) {
609 if (num >= prof_info->count) {
610 dev_err(aw_dev->dev, "overflow count[%d]",
611 prof_info->count);
612 return -EINVAL;
613 }
614 prof_info->prof_desc[num] = prof_desc[i];
615 prof_info->prof_desc[num].id = i;
616 num++;
617 }
618 }
619
620 return 0;
621}
622
623static int aw88395_dev_cfg_get_valid_prof(struct aw_device *aw_dev,
531 struct aw_all_prof_info all_prof_info)624 struct aw_all_prof_info all_prof_info)
532{625{
533 struct aw_prof_desc *prof_desc = all_prof_info.prof_desc;626 struct aw_prof_desc *prof_desc = all_prof_info.prof_desc;
@@ -606,9 +699,22 @@ static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev, · 72 unmodified lines
606 goto exit;699 goto exit;
607 }700 }
608 701
609 ret = aw_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);702 switch (aw_dev->chip_id) {
610 if (ret < 0)703 case AW88395_CHIP_ID:
611 goto exit;704 ret = aw88395_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);
705 if (ret < 0)
706 goto exit;
707 break;
708 case AW88261_CHIP_ID:
709 ret = aw88261_dev_cfg_get_valid_prof(aw_dev, *all_prof_info);
710 if (ret < 0)
711 goto exit;
712 break;
713 default:
714 dev_err(aw_dev->dev, "valid prof unsupported");
715 ret = -EINVAL;
716 break;
717 }
612 718
613 aw_dev->prof_info.prof_name_list = profile_name;719 aw_dev->prof_info.prof_name_list = profile_name;
614 720
@@ -679,16 +785,37 @@ static int aw_get_dev_scene_count_v1(struct aw_device *aw_dev, struct aw_contain · 64 unmodified lines
679 struct aw_cfg_dde_v1 *cfg_dde =785 struct aw_cfg_dde_v1 *cfg_dde =
680 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);786 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
681 unsigned int i;787 unsigned int i;
788 int ret;
682 789
683 for (i = 0; i < cfg_hdr->ddt_num; ++i) {790 switch (aw_dev->chip_id) {
684 if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&791 case AW88395_CHIP_ID:
685 (aw_dev->chip_id == cfg_dde[i].chip_id) &&792 for (i = 0; i < cfg_hdr->ddt_num; ++i) {
686 (aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&793 if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
687 (aw_dev->i2c->addr == cfg_dde[i].dev_addr))794 (aw_dev->chip_id == cfg_dde[i].chip_id) &&
688 (*scene_num)++;795 (aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
796 (aw_dev->i2c->addr == cfg_dde[i].dev_addr))
797 (*scene_num)++;
798 }
799 ret = 0;
800 break;
801 case AW88261_CHIP_ID:
802 for (i = 0; i < cfg_hdr->ddt_num; ++i) {
803 if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
804 (cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) &&
805 (aw_dev->chip_id == cfg_dde[i].chip_id) &&
806 (aw_dev->i2c->adapter->nr == cfg_dde[i].dev_bus) &&
807 (aw_dev->i2c->addr == cfg_dde[i].dev_addr))
808 (*scene_num)++;
809 }
810 ret = 0;
811 break;
812 default:
813 dev_err(aw_dev->dev, "unsupported device");
814 ret = -EINVAL;
815 break;
689 }816 }
690 817
691 return 0;818 return ret;
692}819}
693 820
694static int aw_get_default_scene_count_v1(struct aw_device *aw_dev,821static int aw_get_default_scene_count_v1(struct aw_device *aw_dev,
@@ -699,15 +826,35 @@ static int aw_get_default_scene_count_v1(struct aw_device *aw_dev, · 4 unmodified lines
699 struct aw_cfg_dde_v1 *cfg_dde =826 struct aw_cfg_dde_v1 *cfg_dde =
700 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);827 (struct aw_cfg_dde_v1 *)(aw_cfg->data + cfg_hdr->hdr_offset);
701 unsigned int i;828 unsigned int i;
829 int ret;
702 830
703 for (i = 0; i < cfg_hdr->ddt_num; ++i) {831 switch (aw_dev->chip_id) {
704 if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&832 case AW88395_CHIP_ID:
705 (aw_dev->chip_id == cfg_dde[i].chip_id) &&833 for (i = 0; i < cfg_hdr->ddt_num; ++i) {
706 (aw_dev->channel == cfg_dde[i].dev_index))834 if ((cfg_dde[i].data_type == ACF_SEC_TYPE_MULTIPLE_BIN) &&
707 (*scene_num)++;835 (aw_dev->chip_id == cfg_dde[i].chip_id) &&
836 (aw_dev->channel == cfg_dde[i].dev_index))
837 (*scene_num)++;
838 }
839 ret = 0;
840 break;
841 case AW88261_CHIP_ID:
842 for (i = 0; i < cfg_hdr->ddt_num; ++i) {
843 if (((cfg_dde[i].data_type == ACF_SEC_TYPE_REG) ||
844 (cfg_dde[i].data_type == ACF_SEC_TYPE_HDR_REG)) &&
845 (aw_dev->chip_id == cfg_dde[i].chip_id) &&
846 (aw_dev->channel == cfg_dde[i].dev_index))
847 (*scene_num)++;
848 }
849 ret = 0;
850 break;
851 default:
852 dev_err(aw_dev->dev, "unsupported device");
853 ret = -EINVAL;
854 break;
708 }855 }
709 856
710 return 0;857 return ret;
711}858}
712 859
713static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev,860static int aw_dev_parse_scene_count_v1(struct aw_device *aw_dev,
@@ -756,6 +903,18 @@ static int aw_dev_parse_data_by_sec_type_v1(struct aw_device *aw_dev, · 42 unmodified lines
756 prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile;903 prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile;
757 (*cur_scene_id)++;904 (*cur_scene_id)++;
758 break;905 break;
906 case ACF_SEC_TYPE_HDR_REG:
907 ret = aw_dev_parse_reg_bin_with_hdr(aw_dev,
908 (uint8_t *)prof_hdr + cfg_dde->data_offset,
909 cfg_dde->data_size, &prof_info->prof_desc[*cur_scene_id]);
910 if (ret < 0) {
911 dev_err(aw_dev->dev, "parse reg bin with hdr failed");
912 return ret;
913 }
914 prof_info->prof_desc[*cur_scene_id].prf_str = cfg_dde->dev_profile_str;
915 prof_info->prof_desc[*cur_scene_id].id = cfg_dde->dev_profile;
916 (*cur_scene_id)++;
917 break;
759 default:918 default:
760 dev_err(aw_dev->dev, "unsupported SEC_TYPE [%d]", cfg_dde->data_type);919 dev_err(aw_dev->dev, "unsupported SEC_TYPE [%d]", cfg_dde->data_type);
761 return -EINVAL;920 return -EINVAL;
sound/soc/codecs/aw88395/aw88395_reg.h+1−0
@@ -96,6 +96,7 @@ · 95 unmodified lines
96 96
97enum aw88395_id {97enum aw88395_id {
98 AW88395_CHIP_ID = 0x2049,98 AW88395_CHIP_ID = 0x2049,
99 AW88261_CHIP_ID = 0x2113,
99};100};
100 101
101#define AW88395_REG_MAX (0x7D)102#define AW88395_REG_MAX (0x7D)
sound/soc/codecs/cs35l36.c+1−1
@@ -1312,7 +1312,7 @@ static struct regmap_config cs35l36_regmap = { · 1311 unmodified lines
1312 .precious_reg = cs35l36_precious_reg,1312 .precious_reg = cs35l36_precious_reg,
1313 .volatile_reg = cs35l36_volatile_reg,1313 .volatile_reg = cs35l36_volatile_reg,
1314 .readable_reg = cs35l36_readable_reg,1314 .readable_reg = cs35l36_readable_reg,
1315 .cache_type = REGCACHE_RBTREE,1315 .cache_type = REGCACHE_MAPLE,
1316};1316};
1317 1317
1318static irqreturn_t cs35l36_irq(int irq, void *data)1318static irqreturn_t cs35l36_irq(int irq, void *data)
sound/soc/codecs/cs35l41-lib.c+104−18
@@ -743,7 +743,7 @@ struct regmap_config cs35l41_regmap_i2c = { · 742 unmodified lines
743 .volatile_reg = cs35l41_volatile_reg,743 .volatile_reg = cs35l41_volatile_reg,
744 .readable_reg = cs35l41_readable_reg,744 .readable_reg = cs35l41_readable_reg,
745 .precious_reg = cs35l41_precious_reg,745 .precious_reg = cs35l41_precious_reg,
746 .cache_type = REGCACHE_RBTREE,746 .cache_type = REGCACHE_MAPLE,
747};747};
748EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c);748EXPORT_SYMBOL_GPL(cs35l41_regmap_i2c);
749 749
@@ -760,7 +760,7 @@ struct regmap_config cs35l41_regmap_spi = { · 10 unmodified lines
760 .volatile_reg = cs35l41_volatile_reg,760 .volatile_reg = cs35l41_volatile_reg,
761 .readable_reg = cs35l41_readable_reg,761 .readable_reg = cs35l41_readable_reg,
762 .precious_reg = cs35l41_precious_reg,762 .precious_reg = cs35l41_precious_reg,
763 .cache_type = REGCACHE_RBTREE,763 .cache_type = REGCACHE_MAPLE,
764};764};
765EXPORT_SYMBOL_GPL(cs35l41_regmap_spi);765EXPORT_SYMBOL_GPL(cs35l41_regmap_spi);
766 766
@@ -1080,28 +1080,32 @@ static const struct reg_sequence cs35l41_safe_to_reset[] = { · 313 unmodified lines
1080 { 0x00000040, 0x00000033 },1080 { 0x00000040, 0x00000033 },
1081};1081};
1082 1082
1083static const struct reg_sequence cs35l41_active_to_safe[] = {1083static const struct reg_sequence cs35l41_active_to_safe_start[] = {
1084 { 0x00000040, 0x00000055 },1084 { 0x00000040, 0x00000055 },
1085 { 0x00000040, 0x000000AA },1085 { 0x00000040, 0x000000AA },
1086 { 0x00007438, 0x00585941 },1086 { 0x00007438, 0x00585941 },
1087 { CS35L41_PWR_CTRL1, 0x00000000 },1087 { CS35L41_PWR_CTRL1, 0x00000000 },
1088 { 0x0000742C, 0x00000009, 3000 },1088 { 0x0000742C, 0x00000009 },
1089};
1090
1091static const struct reg_sequence cs35l41_active_to_safe_end[] = {
1089 { 0x00007438, 0x00580941 },1092 { 0x00007438, 0x00580941 },
1090 { 0x00000040, 0x000000CC },1093 { 0x00000040, 0x000000CC },
1091 { 0x00000040, 0x00000033 },1094 { 0x00000040, 0x00000033 },
1092};1095};
1093 1096
1094static const struct reg_sequence cs35l41_safe_to_active[] = {1097static const struct reg_sequence cs35l41_safe_to_active_start[] = {
1095 { 0x00000040, 0x00000055 },1098 { 0x00000040, 0x00000055 },
1096 { 0x00000040, 0x000000AA },1099 { 0x00000040, 0x000000AA },
1097 { 0x0000742C, 0x0000000F },1100 { 0x0000742C, 0x0000000F },
1098 { 0x0000742C, 0x00000079 },1101 { 0x0000742C, 0x00000079 },
1099 { 0x00007438, 0x00585941 },1102 { 0x00007438, 0x00585941 },
1100 { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 11103 { CS35L41_PWR_CTRL1, 0x00000001 }, // GLOBAL_EN = 1
1104};
1105
1106static const struct reg_sequence cs35l41_safe_to_active_en_spk[] = {
1101 { 0x0000742C, 0x000000F9 },1107 { 0x0000742C, 0x000000F9 },
1102 { 0x00007438, 0x00580941 },1108 { 0x00007438, 0x00580941 },
1103 { 0x00000040, 0x000000CC },
1104 { 0x00000040, 0x00000033 },
1105};1109};
1106 1110
1107static const struct reg_sequence cs35l41_reset_to_safe[] = {1111static const struct reg_sequence cs35l41_reset_to_safe[] = {
@@ -1188,11 +1192,12 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type) · 80 unmodified lines
1188}1192}
1189EXPORT_SYMBOL_GPL(cs35l41_safe_reset);1193EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
1190 1194
1191int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,1195int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type,
1192 struct completion *pll_lock)1196 int enable, struct completion *pll_lock, bool firmware_running)
1193{1197{
1194 int ret;1198 int ret;
1195 unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3;1199 unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status, pup_pdn_mask;
1200 unsigned int pwr_ctl1_val;
1196 struct reg_sequence cs35l41_mdsync_down_seq[] = {1201 struct reg_sequence cs35l41_mdsync_down_seq[] = {
1197 {CS35L41_PWR_CTRL3, 0},1202 {CS35L41_PWR_CTRL3, 0},
1198 {CS35L41_GPIO_PAD_CONTROL, 0},1203 {CS35L41_GPIO_PAD_CONTROL, 0},
@@ -1204,6 +1209,20 @@ int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, · 5 unmodified lines
1204 {CS35L41_PWR_CTRL1, 0x00000001, 3000},1209 {CS35L41_PWR_CTRL1, 0x00000001, 3000},
1205 };1210 };
1206 1211
1212 pup_pdn_mask = enable ? CS35L41_PUP_DONE_MASK : CS35L41_PDN_DONE_MASK;
1213
1214 ret = regmap_read(regmap, CS35L41_PWR_CTRL1, &pwr_ctl1_val);
1215 if (ret)
1216 return ret;
1217
1218 if ((pwr_ctl1_val & CS35L41_GLOBAL_EN_MASK) && enable) {
1219 dev_dbg(dev, "Cannot set Global Enable - already set.\n");
1220 return 0;
1221 } else if (!(pwr_ctl1_val & CS35L41_GLOBAL_EN_MASK) && !enable) {
1222 dev_dbg(dev, "Cannot unset Global Enable - not set.\n");
1223 return 0;
1224 }
1225
1207 switch (b_type) {1226 switch (b_type) {
1208 case CS35L41_SHD_BOOST_ACTV:1227 case CS35L41_SHD_BOOST_ACTV:
1209 case CS35L41_SHD_BOOST_PASS:1228 case CS35L41_SHD_BOOST_PASS:
@@ -1240,20 +1259,85 @@ int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, · 30 unmodified lines
1240 ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq,1259 ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq,
1241 ARRAY_SIZE(cs35l41_mdsync_up_seq));1260 ARRAY_SIZE(cs35l41_mdsync_up_seq));
1242 }1261 }
1262
1263 ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1,
1264 int_status, int_status & pup_pdn_mask,
1265 1000, 100000);
1266 if (ret)
1267 dev_err(dev, "Enable(%d) failed: %d\n", enable, ret);
1268
1269 // Clear PUP/PDN status
1270 regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask);
1243 break;1271 break;
1244 case CS35L41_INT_BOOST:1272 case CS35L41_INT_BOOST:
1245 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,1273 ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
1246 enable << CS35L41_GLOBAL_EN_SHIFT);1274 enable << CS35L41_GLOBAL_EN_SHIFT);
1247 usleep_range(3000, 3100);1275 if (ret) {
1276 dev_err(dev, "CS35L41_PWR_CTRL1 set failed: %d\n", ret);
1277 return ret;
1278 }
1279
1280 ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1,
1281 int_status, int_status & pup_pdn_mask,
1282 1000, 100000);
1283 if (ret)
1284 dev_err(dev, "Enable(%d) failed: %d\n", enable, ret);
1285
1286 /* Clear PUP/PDN status */
1287 regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask);
1248 break;1288 break;
1249 case CS35L41_EXT_BOOST:1289 case CS35L41_EXT_BOOST:
1250 case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:1290 case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:
1251 if (enable)1291 if (enable) {
1252 ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active,1292 /* Test Key is unlocked here */
1253 ARRAY_SIZE(cs35l41_safe_to_active));1293 ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active_start,
1254 else1294 ARRAY_SIZE(cs35l41_safe_to_active_start));
1255 ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe,1295 if (ret)
1256 ARRAY_SIZE(cs35l41_active_to_safe));1296 return ret;
1297
1298 ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status,
1299 int_status & CS35L41_PUP_DONE_MASK, 1000, 100000);
1300 if (ret) {
1301 dev_err(dev, "Failed waiting for CS35L41_PUP_DONE_MASK: %d\n", ret);
1302 /* Lock the test key, it was unlocked during the multi_reg_write */
1303 cs35l41_test_key_lock(dev, regmap);
1304 return ret;
1305 }
1306 regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PUP_DONE_MASK);
1307
1308 if (firmware_running)
1309 ret = cs35l41_set_cspl_mbox_cmd(dev, regmap,
1310 CSPL_MBOX_CMD_SPK_OUT_ENABLE);
1311 else
1312 ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active_en_spk,
1313 ARRAY_SIZE(cs35l41_safe_to_active_en_spk));
1314
1315 /* Lock the test key, it was unlocked during the multi_reg_write */
1316 cs35l41_test_key_lock(dev, regmap);
1317 } else {
1318 /* Test Key is unlocked here */
1319 ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe_start,
1320 ARRAY_SIZE(cs35l41_active_to_safe_start));
1321 if (ret) {
1322 /* Lock the test key, it was unlocked during the multi_reg_write */
1323 cs35l41_test_key_lock(dev, regmap);
1324 return ret;
1325 }
1326
1327 ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status,
1328 int_status & CS35L41_PDN_DONE_MASK, 1000, 100000);
1329 if (ret) {
1330 dev_err(dev, "Failed waiting for CS35L41_PDN_DONE_MASK: %d\n", ret);
1331 /* Lock the test key, it was unlocked during the multi_reg_write */
1332 cs35l41_test_key_lock(dev, regmap);
1333 return ret;
1334 }
1335 regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PDN_DONE_MASK);
1336
1337 /* Test Key is locked here */
1338 ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe_end,
1339 ARRAY_SIZE(cs35l41_active_to_safe_end));
1340 }
1257 break;1341 break;
1258 default:1342 default:
1259 ret = -EINVAL;1343 ret = -EINVAL;
@@ -1344,6 +1428,8 @@ static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, · 84 unmodified lines
1344 return (sts == CSPL_MBOX_STS_RUNNING);1428 return (sts == CSPL_MBOX_STS_RUNNING);
1345 case CSPL_MBOX_CMD_STOP_PRE_REINIT:1429 case CSPL_MBOX_CMD_STOP_PRE_REINIT:
1346 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);1430 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
1431 case CSPL_MBOX_CMD_SPK_OUT_ENABLE:
1432 return (sts == CSPL_MBOX_STS_RUNNING);
1347 default:1433 default:
1348 return false;1434 return false;
1349 }1435 }
sound/soc/codecs/cs35l41.c+4−14
@@ -491,7 +491,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, · 490 unmodified lines
491{491{
492 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);492 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
493 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);493 struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
494 unsigned int val;
495 int ret = 0;494 int ret = 0;
496 495
497 switch (event) {496 switch (event) {
@@ -500,21 +499,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, · 2 unmodified lines
500 cs35l41_pup_patch,499 cs35l41_pup_patch,
501 ARRAY_SIZE(cs35l41_pup_patch));500 ARRAY_SIZE(cs35l41_pup_patch));
502 501
503 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1,502 ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
504 &cs35l41->pll_lock);503 1, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
505 break;504 break;
506 case SND_SOC_DAPM_POST_PMD:505 case SND_SOC_DAPM_POST_PMD:
507 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0,506 ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
508 &cs35l41->pll_lock);507 0, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
509
510 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
511 val, val & CS35L41_PDN_DONE_MASK,
512 1000, 100000);
513 if (ret)
514 dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
515
516 regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
517 CS35L41_PDN_DONE_MASK);
518 508
519 regmap_multi_reg_write_bypassed(cs35l41->regmap,509 regmap_multi_reg_write_bypassed(cs35l41->regmap,
520 cs35l41_pdn_patch,510 cs35l41_pdn_patch,
sound/soc/codecs/cs35l45-tables.c+2−2
@@ -255,7 +255,7 @@ const struct regmap_config cs35l45_i2c_regmap = { · 254 unmodified lines
255 .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),255 .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),
256 .volatile_reg = cs35l45_volatile_reg,256 .volatile_reg = cs35l45_volatile_reg,
257 .readable_reg = cs35l45_readable_reg,257 .readable_reg = cs35l45_readable_reg,
258 .cache_type = REGCACHE_RBTREE,258 .cache_type = REGCACHE_MAPLE,
259};259};
260EXPORT_SYMBOL_NS_GPL(cs35l45_i2c_regmap, SND_SOC_CS35L45);260EXPORT_SYMBOL_NS_GPL(cs35l45_i2c_regmap, SND_SOC_CS35L45);
261 261
@@ -271,7 +271,7 @@ const struct regmap_config cs35l45_spi_regmap = { · 9 unmodified lines
271 .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),271 .num_reg_defaults = ARRAY_SIZE(cs35l45_defaults),
272 .volatile_reg = cs35l45_volatile_reg,272 .volatile_reg = cs35l45_volatile_reg,
273 .readable_reg = cs35l45_readable_reg,273 .readable_reg = cs35l45_readable_reg,
274 .cache_type = REGCACHE_RBTREE,274 .cache_type = REGCACHE_MAPLE,
275};275};
276EXPORT_SYMBOL_NS_GPL(cs35l45_spi_regmap, SND_SOC_CS35L45);276EXPORT_SYMBOL_NS_GPL(cs35l45_spi_regmap, SND_SOC_CS35L45);
277 277
sound/soc/codecs/cs35l56-i2c.c+7−7
@@ -26,14 +26,14 @@ static int cs35l56_i2c_probe(struct i2c_client *client) · 25 unmodified lines
26 if (!cs35l56)26 if (!cs35l56)
27 return -ENOMEM;27 return -ENOMEM;
28 28
29 cs35l56->dev = dev;29 cs35l56->base.dev = dev;
30 cs35l56->can_hibernate = true;30 cs35l56->base.can_hibernate = true;
31 31
32 i2c_set_clientdata(client, cs35l56);32 i2c_set_clientdata(client, cs35l56);
33 cs35l56->regmap = devm_regmap_init_i2c(client, regmap_config);33 cs35l56->base.regmap = devm_regmap_init_i2c(client, regmap_config);
34 if (IS_ERR(cs35l56->regmap)) {34 if (IS_ERR(cs35l56->base.regmap)) {
35 ret = PTR_ERR(cs35l56->regmap);35 ret = PTR_ERR(cs35l56->base.regmap);
36 return dev_err_probe(cs35l56->dev, ret, "Failed to allocate register map\n");36 return dev_err_probe(cs35l56->base.dev, ret, "Failed to allocate register map\n");
37 }37 }
38 38
39 ret = cs35l56_common_probe(cs35l56);39 ret = cs35l56_common_probe(cs35l56);
@@ -42,7 +42,7 @@ static int cs35l56_i2c_probe(struct i2c_client *client) · 2 unmodified lines
42 42
43 ret = cs35l56_init(cs35l56);43 ret = cs35l56_init(cs35l56);
44 if (ret == 0)44 if (ret == 0)
45 ret = cs35l56_irq_request(cs35l56, client->irq);45 ret = cs35l56_irq_request(&cs35l56->base, client->irq);
46 if (ret < 0)46 if (ret < 0)
47 cs35l56_remove(cs35l56);47 cs35l56_remove(cs35l56);
48 48
sound/soc/codecs/cs35l56-sdw.c+37−35
@@ -166,13 +166,13 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral) · 165 unmodified lines
166 struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);166 struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
167 int ret;167 int ret;
168 168
169 pm_runtime_get_noresume(cs35l56->dev);169 pm_runtime_get_noresume(cs35l56->base.dev);
170 170
171 regcache_cache_only(cs35l56->regmap, false);171 regcache_cache_only(cs35l56->base.regmap, false);
172 172
173 ret = cs35l56_init(cs35l56);173 ret = cs35l56_init(cs35l56);
174 if (ret < 0) {174 if (ret < 0) {
175 regcache_cache_only(cs35l56->regmap, true);175 regcache_cache_only(cs35l56->base.regmap, true);
176 goto out;176 goto out;
177 }177 }
178 178
@@ -180,15 +180,15 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral) · 1 unmodified line
180 * cs35l56_init can return with !init_done if it triggered180 * cs35l56_init can return with !init_done if it triggered
181 * a soft reset.181 * a soft reset.
182 */182 */
183 if (cs35l56->init_done) {183 if (cs35l56->base.init_done) {
184 /* Enable SoundWire interrupts */184 /* Enable SoundWire interrupts */
185 sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1,185 sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1,
186 CS35L56_SDW_INT_MASK_CODEC_IRQ);186 CS35L56_SDW_INT_MASK_CODEC_IRQ);
187 }187 }
188 188
189out:189out:
190 pm_runtime_mark_last_busy(cs35l56->dev);190 pm_runtime_mark_last_busy(cs35l56->base.dev);
191 pm_runtime_put_autosuspend(cs35l56->dev);191 pm_runtime_put_autosuspend(cs35l56->base.dev);
192}192}
193 193
194static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral,194static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral,
@@ -198,7 +198,7 @@ static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral, · 3 unmodified lines
198 198
199 /* SoundWire core holds our pm_runtime when calling this function. */199 /* SoundWire core holds our pm_runtime when calling this function. */
200 200
201 dev_dbg(cs35l56->dev, "int control_port=%#x\n", status->control_port);201 dev_dbg(cs35l56->base.dev, "int control_port=%#x\n", status->control_port);
202 202
203 if ((status->control_port & SDW_SCP_INT1_IMPL_DEF) == 0)203 if ((status->control_port & SDW_SCP_INT1_IMPL_DEF) == 0)
204 return 0;204 return 0;
@@ -207,7 +207,7 @@ static int cs35l56_sdw_interrupt(struct sdw_slave *peripheral, · 2 unmodified lines
207 * Prevent bus manager suspending and possibly issuing a207 * Prevent bus manager suspending and possibly issuing a
208 * bus-reset before the queued work has run.208 * bus-reset before the queued work has run.
209 */209 */
210 pm_runtime_get_noresume(cs35l56->dev);210 pm_runtime_get_noresume(cs35l56->base.dev);
211 211
212 /*212 /*
213 * Mask and clear until it has been handled. The read of GEN_INT_STAT_1213 * Mask and clear until it has been handled. The read of GEN_INT_STAT_1
@@ -230,14 +230,14 @@ static void cs35l56_sdw_irq_work(struct work_struct *work) · 16 unmodified lines
230 struct cs35l56_private,230 struct cs35l56_private,
231 sdw_irq_work);231 sdw_irq_work);
232 232
233 cs35l56_irq(-1, cs35l56);233 cs35l56_irq(-1, &cs35l56->base);
234 234
235 /* unmask interrupts */235 /* unmask interrupts */
236 if (!cs35l56->sdw_irq_no_unmask)236 if (!cs35l56->sdw_irq_no_unmask)
237 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,237 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1,
238 CS35L56_SDW_INT_MASK_CODEC_IRQ);238 CS35L56_SDW_INT_MASK_CODEC_IRQ);
239 239
240 pm_runtime_put_autosuspend(cs35l56->dev);240 pm_runtime_put_autosuspend(cs35l56->base.dev);
241}241}
242 242
243static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)243static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral)
@@ -246,7 +246,7 @@ static int cs35l56_sdw_read_prop(struct sdw_slave *peripheral) · 2 unmodified lines
246 struct sdw_slave_prop *prop = &peripheral->prop;246 struct sdw_slave_prop *prop = &peripheral->prop;
247 struct sdw_dpn_prop *ports;247 struct sdw_dpn_prop *ports;
248 248
249 ports = devm_kcalloc(cs35l56->dev, 2, sizeof(*ports), GFP_KERNEL);249 ports = devm_kcalloc(cs35l56->base.dev, 2, sizeof(*ports), GFP_KERNEL);
250 if (!ports)250 if (!ports)
251 return -ENOMEM;251 return -ENOMEM;
252 252
@@ -279,17 +279,17 @@ static int cs35l56_sdw_update_status(struct sdw_slave *peripheral, · 26 unmodified lines
279 279
280 switch (status) {280 switch (status) {
281 case SDW_SLAVE_ATTACHED:281 case SDW_SLAVE_ATTACHED:
282 dev_dbg(cs35l56->dev, "%s: ATTACHED\n", __func__);282 dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
283 if (cs35l56->sdw_attached)283 if (cs35l56->sdw_attached)
284 break;284 break;
285 285
286 if (!cs35l56->init_done || cs35l56->soft_resetting)286 if (!cs35l56->base.init_done || cs35l56->soft_resetting)
287 cs35l56_sdw_init(peripheral);287 cs35l56_sdw_init(peripheral);
288 288
289 cs35l56->sdw_attached = true;289 cs35l56->sdw_attached = true;
290 break;290 break;
291 case SDW_SLAVE_UNATTACHED:291 case SDW_SLAVE_UNATTACHED:
292 dev_dbg(cs35l56->dev, "%s: UNATTACHED\n", __func__);292 dev_dbg(cs35l56->base.dev, "%s: UNATTACHED\n", __func__);
293 cs35l56->sdw_attached = false;293 cs35l56->sdw_attached = false;
294 break;294 break;
295 default:295 default:
@@ -305,7 +305,7 @@ static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56, · 9 unmodified lines
305 unsigned int curr_scale_reg, next_scale_reg;305 unsigned int curr_scale_reg, next_scale_reg;
306 int curr_scale, next_scale, ret;306 int curr_scale, next_scale, ret;
307 307
308 if (!cs35l56->init_done)308 if (!cs35l56->base.init_done)
309 return 0;309 return 0;
310 310
311 if (peripheral->bus->params.curr_bank) {311 if (peripheral->bus->params.curr_bank) {
@@ -324,13 +324,13 @@ static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56, · 12 unmodified lines
324 */324 */
325 curr_scale = sdw_read_no_pm(peripheral, curr_scale_reg);325 curr_scale = sdw_read_no_pm(peripheral, curr_scale_reg);
326 if (curr_scale < 0) {326 if (curr_scale < 0) {
327 dev_err(cs35l56->dev, "Failed to read current clock scale: %d\n", curr_scale);327 dev_err(cs35l56->base.dev, "Failed to read current clock scale: %d\n", curr_scale);
328 return curr_scale;328 return curr_scale;
329 }329 }
330 330
331 next_scale = sdw_read_no_pm(peripheral, next_scale_reg);331 next_scale = sdw_read_no_pm(peripheral, next_scale_reg);
332 if (next_scale < 0) {332 if (next_scale < 0) {
333 dev_err(cs35l56->dev, "Failed to read next clock scale: %d\n", next_scale);333 dev_err(cs35l56->base.dev, "Failed to read next clock scale: %d\n", next_scale);
334 return next_scale;334 return next_scale;
335 }335 }
336 336
@@ -338,7 +338,8 @@ static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56, · 1 unmodified line
338 next_scale = cs35l56->old_sdw_clock_scale;338 next_scale = cs35l56->old_sdw_clock_scale;
339 ret = sdw_write_no_pm(peripheral, next_scale_reg, next_scale);339 ret = sdw_write_no_pm(peripheral, next_scale_reg, next_scale);
340 if (ret < 0) {340 if (ret < 0) {
341 dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);341 dev_err(cs35l56->base.dev, "Failed to modify current clock scale: %d\n",
342 ret);
342 return ret;343 return ret;
343 }344 }
344 }345 }
@@ -346,11 +347,11 @@ static int cs35l56_a1_kick_divider(struct cs35l56_private *cs35l56, · 1 unmodified line
346 cs35l56->old_sdw_clock_scale = curr_scale;347 cs35l56->old_sdw_clock_scale = curr_scale;
347 ret = sdw_write_no_pm(peripheral, curr_scale_reg, CS35L56_SDW_INVALID_BUS_SCALE);348 ret = sdw_write_no_pm(peripheral, curr_scale_reg, CS35L56_SDW_INVALID_BUS_SCALE);
348 if (ret < 0) {349 if (ret < 0) {
349 dev_err(cs35l56->dev, "Failed to modify current clock scale: %d\n", ret);350 dev_err(cs35l56->base.dev, "Failed to modify current clock scale: %d\n", ret);
350 return ret;351 return ret;
351 }352 }
352 353
353 dev_dbg(cs35l56->dev, "Next bus scale: %#x\n", next_scale);354 dev_dbg(cs35l56->base.dev, "Next bus scale: %#x\n", next_scale);
354 355
355 return 0;356 return 0;
356}357}
@@ -362,9 +363,10 @@ static int cs35l56_sdw_bus_config(struct sdw_slave *peripheral, · 5 unmodified lines
362 int sclk;363 int sclk;
363 364
364 sclk = params->curr_dr_freq / 2;365 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 dev_dbg(cs35l56->base.dev, "%s: sclk=%u c=%u r=%u\n",
367 __func__, sclk, params->col, params->row);
366 368
367 if (cs35l56->rev < 0xb0)369 if (cs35l56->base.rev < 0xb0)
368 return cs35l56_a1_kick_divider(cs35l56, peripheral);370 return cs35l56_a1_kick_divider(cs35l56, peripheral);
369 371
370 return 0;372 return 0;
@@ -376,7 +378,7 @@ static int __maybe_unused cs35l56_sdw_clk_stop(struct sdw_slave *peripheral, · 5 unmodified lines
376{378{
377 struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);379 struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
378 380
379 dev_dbg(cs35l56->dev, "%s: mode:%d type:%d\n", __func__, mode, type);381 dev_dbg(cs35l56->base.dev, "%s: mode:%d type:%d\n", __func__, mode, type);
380 382
381 return 0;383 return 0;
382}384}
@@ -397,10 +399,10 @@ static int __maybe_unused cs35l56_sdw_handle_unattach(struct cs35l56_private *cs · 14 unmodified lines
397 399
398 if (peripheral->unattach_request) {400 if (peripheral->unattach_request) {
399 /* Cannot access registers until bus is re-initialized. */401 /* Cannot access registers until bus is re-initialized. */
400 dev_dbg(cs35l56->dev, "Wait for initialization_complete\n");402 dev_dbg(cs35l56->base.dev, "Wait for initialization_complete\n");
401 if (!wait_for_completion_timeout(&peripheral->initialization_complete,403 if (!wait_for_completion_timeout(&peripheral->initialization_complete,
402 msecs_to_jiffies(5000))) {404 msecs_to_jiffies(5000))) {
403 dev_err(cs35l56->dev, "initialization_complete timed out\n");405 dev_err(cs35l56->base.dev, "initialization_complete timed out\n");
404 return -ETIMEDOUT;406 return -ETIMEDOUT;
405 }407 }
406 408
@@ -419,10 +421,10 @@ static int __maybe_unused cs35l56_sdw_runtime_suspend(struct device *dev) · 12 unmodified lines
419{421{
420 struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);422 struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
421 423
422 if (!cs35l56->init_done)424 if (!cs35l56->base.init_done)
423 return 0;425 return 0;
424 426
425 return cs35l56_runtime_suspend(dev);427 return cs35l56_runtime_suspend_common(&cs35l56->base);
426}428}
427 429
428static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)430static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)
@@ -432,14 +434,14 @@ static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev) · 3 unmodified lines
432 434
433 dev_dbg(dev, "Runtime resume\n");435 dev_dbg(dev, "Runtime resume\n");
434 436
435 if (!cs35l56->init_done)437 if (!cs35l56->base.init_done)
436 return 0;438 return 0;
437 439
438 ret = cs35l56_sdw_handle_unattach(cs35l56);440 ret = cs35l56_sdw_handle_unattach(cs35l56);
439 if (ret < 0)441 if (ret < 0)
440 return ret;442 return ret;
441 443
442 ret = cs35l56_runtime_resume_common(cs35l56);444 ret = cs35l56_runtime_resume_common(&cs35l56->base, true);
443 if (ret)445 if (ret)
444 return ret;446 return ret;
445 447
@@ -454,7 +456,7 @@ static int __maybe_unused cs35l56_sdw_system_suspend(struct device *dev) · 8 unmodified lines
454{456{
455 struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);457 struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
456 458
457 if (!cs35l56->init_done)459 if (!cs35l56->base.init_done)
458 return 0;460 return 0;
459 461
460 /*462 /*
@@ -493,21 +495,21 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi · 32 unmodified lines
493 if (!cs35l56)495 if (!cs35l56)
494 return -ENOMEM;496 return -ENOMEM;
495 497
496 cs35l56->dev = dev;498 cs35l56->base.dev = dev;
497 cs35l56->sdw_peripheral = peripheral;499 cs35l56->sdw_peripheral = peripheral;
498 INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);500 INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work);
499 501
500 dev_set_drvdata(dev, cs35l56);502 dev_set_drvdata(dev, cs35l56);
501 503
502 cs35l56->regmap = devm_regmap_init(dev, &cs35l56_regmap_bus_sdw,504 cs35l56->base.regmap = devm_regmap_init(dev, &cs35l56_regmap_bus_sdw,
503 peripheral, &cs35l56_regmap_sdw);505 peripheral, &cs35l56_regmap_sdw);
504 if (IS_ERR(cs35l56->regmap)) {506 if (IS_ERR(cs35l56->base.regmap)) {
505 ret = PTR_ERR(cs35l56->regmap);507 ret = PTR_ERR(cs35l56->base.regmap);
506 return dev_err_probe(dev, ret, "Failed to allocate register map\n");508 return dev_err_probe(dev, ret, "Failed to allocate register map\n");
507 }509 }
508 510
509 /* Start in cache-only until device is enumerated */511 /* Start in cache-only until device is enumerated */
510 regcache_cache_only(cs35l56->regmap, true);512 regcache_cache_only(cs35l56->base.regmap, true);
511 513
512 ret = cs35l56_common_probe(cs35l56);514 ret = cs35l56_common_probe(cs35l56);
513 if (ret != 0)515 if (ret != 0)
sound/soc/codecs/cs35l56-shared.c+463−19
@@ -11,6 +11,20 @@ · 10 unmodified lines
11 11
12#include "cs35l56.h"12#include "cs35l56.h"

535 more lines aren’t shown here.

sound/soc/codecs/cs35l56-spi.c+5−5

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

sound/soc/codecs/cs35l56.c+156−543

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

sound/soc/codecs/cs35l56.h+2−13

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

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

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

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

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

sound/soc/codecs/cs42l43-jack.c+946−0

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

sound/soc/codecs/cs42l43-sdw.c+74−0

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

sound/soc/codecs/cs42l43.c+2278−0

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

sound/soc/codecs/cs42l43.h+131−0

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

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

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

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

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

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

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

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

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

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

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

sound/soc/codecs/cs43130.h+69−69

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

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

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

sound/soc/codecs/cs47l15.c+5−1

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

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

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

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

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

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

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

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

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

sound/soc/codecs/cs47l92.c+5−1

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

sound/soc/codecs/cx2072x.c+9−2

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

sound/soc/codecs/es8316.c+3−2

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

sound/soc/codecs/es8326.c+270−115

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

sound/soc/codecs/es8326.h+22−8

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

sound/soc/codecs/hdmi-codec.c+22−22

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

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

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

sound/soc/codecs/l3.c+0−132

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

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

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

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

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

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

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

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

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

sound/soc/codecs/max98363.c+24−17

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

sound/soc/codecs/max98373-sdw.c+26−21

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

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

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

sound/soc/codecs/max98927.c+145−212

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

sound/soc/codecs/msm8916-wcd-analog.c+15−41

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

sound/soc/codecs/nau8821.c+41−1

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

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

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

sound/soc/codecs/nau8825.c+3−90

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

sound/soc/codecs/rt1011.c+0−2

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

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

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

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

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

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

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

sound/soc/codecs/rt1017-sdca-sdw.c+824−0

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

sound/soc/codecs/rt1017-sdca-sdw.h+183−0

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

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

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

sound/soc/codecs/rt1305.c+0−2

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

sound/soc/codecs/rt1308-sdw.c+30−24

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

sound/soc/codecs/rt1308.c+0−2

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

sound/soc/codecs/rt1316-sdw.c+39−17

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

sound/soc/codecs/rt1318-sdw.c+26−17

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

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

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

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

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

sound/soc/codecs/rt5640.c+17−42

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

sound/soc/codecs/rt5640.h+1−1

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

sound/soc/codecs/rt5645.c+60−5

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

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

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

sound/soc/codecs/rt5660.c+0−2

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

sound/soc/codecs/rt5665.c+8−9

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

sound/soc/codecs/rt5668.c+8−9

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

sound/soc/codecs/rt5677.c+38−79

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

sound/soc/codecs/rt5677.h+15−77

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

sound/soc/codecs/rt5682-i2c.c+4−7

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

sound/soc/codecs/rt5682-sdw.c+38−25

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

sound/soc/codecs/rt5682.c+18−5

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

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

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

sound/soc/codecs/rt5682s.c+7−9

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

sound/soc/codecs/rt5682s.h+2−0

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

sound/soc/codecs/rt700-sdw.c+2−5

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

sound/soc/codecs/rt700.c+30−16

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

sound/soc/codecs/rt711-sdca-sdw.c+1−2

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

sound/soc/codecs/rt711-sdca.c+34−14

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

sound/soc/codecs/rt711-sdw.c+2−5

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

sound/soc/codecs/rt711.c+31−16

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

sound/soc/codecs/rt712-sdca-dmic.c+29−18

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

sound/soc/codecs/rt712-sdca-sdw.c+1−2

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

sound/soc/codecs/rt712-sdca.c+31−14

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

sound/soc/codecs/rt715-sdca-sdw.c+1−4

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

sound/soc/codecs/rt715-sdca.c+31−10

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

sound/soc/codecs/rt715-sdw.c+2−7

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

sound/soc/codecs/rt715.c+84−16

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

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

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

sound/soc/codecs/rt722-sdca-sdw.c+1−1

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

sound/soc/codecs/rt722-sdca.c+1−2

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

sound/soc/codecs/sigmadsp.c+4−21

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

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

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

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

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

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

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

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

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

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

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

sound/soc/codecs/sti-sas.c+1−1

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

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

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

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

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

sound/soc/codecs/tlv320aic32x4-clk.c+11−5

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

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

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

sound/soc/codecs/tlv320aic32x4.h+3−2

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

sound/soc/codecs/uda134x.c+0−587

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

sound/soc/codecs/uda134x.h+0−33

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

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

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

sound/soc/codecs/wcd938x-sdw.c+1−1

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

sound/soc/codecs/wm2200.c+7−7

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

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

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

sound/soc/codecs/wm5102.c+5−1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sound/soc/codecs/wm8960.c+52−2

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

sound/soc/codecs/wm8960.h+2−2

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

sound/soc/codecs/wm_adsp.c+16−8

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

sound/soc/codecs/wm_adsp.h+2−1

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

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

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

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

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

sound/soc/dwc/dwc-i2s.c+352−29

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

sound/soc/dwc/dwc-pcm.c+4−4

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

sound/soc/dwc/local.h+25−0

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

sound/soc/fsl/fsl_asrc.c+8−8

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

sound/soc/fsl/fsl_aud2htx.c+5−5

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

sound/soc/fsl/fsl_easrc.c+8−8

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

sound/soc/fsl/fsl_esai.c+10−10

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

sound/soc/fsl/fsl_micfil.c+90−26

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

sound/soc/fsl/fsl_micfil.h+64−0

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

sound/soc/fsl/fsl_qmc_audio.c+14−14

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

sound/soc/fsl/fsl_rpmsg.c+8−0

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

sound/soc/fsl/fsl_sai.c+12−12

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

sound/soc/fsl/fsl_spdif.c+14−11

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

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

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

sound/soc/fsl/fsl_ssi.c+1−2

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

sound/soc/fsl/fsl_xcvr.c+8−8

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

sound/soc/fsl/imx-audio-rpmsg.c+0−1

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

sound/soc/fsl/imx-es8328.c+22−3

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

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

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

sound/soc/fsl/mpc5200_psc_ac97.c+1−1

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

sound/soc/generic/audio-graph-card.c+70−73

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

sound/soc/generic/audio-graph-card2-custom-sample.dtsi+7−0

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

sound/soc/generic/audio-graph-card2.c+13−1

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

sound/soc/generic/simple-card-utils.c+19−4

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

sound/soc/generic/simple-card.c+62−4

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

sound/soc/hisilicon/hi6210-i2s.c+1−1

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

sound/soc/img/img-i2s-in.c+7−7

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

sound/soc/img/img-i2s-out.c+7−7

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

sound/soc/img/img-parallel-out.c+7−7

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

sound/soc/img/img-spdif-in.c+6−6

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

sound/soc/img/img-spdif-out.c+6−6

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

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

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

sound/soc/intel/atom/sst/sst.c+10−4

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

sound/soc/intel/atom/sst/sst.h+2−5

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

sound/soc/intel/atom/sst/sst_pci.c+2−2

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

sound/soc/intel/atom/sst/sst_stream.c+7−6

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

sound/soc/intel/avs/board_selection.c+21−5

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

sound/soc/intel/avs/boards/Kconfig+20−0

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

sound/soc/intel/avs/boards/Makefile+4−0

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

sound/soc/intel/avs/boards/da7219.c+30−4

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

sound/soc/intel/avs/boards/es8336.c+315−0

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

sound/soc/intel/avs/boards/rt5663.c+254−0

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

sound/soc/intel/avs/boards/rt5682.c+40−27

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

sound/soc/intel/avs/core.c+8−8

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

sound/soc/intel/avs/probes.c+7−3

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

sound/soc/intel/avs/topology.c+3−3

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

sound/soc/intel/boards/Kconfig+6−4

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

sound/soc/intel/boards/Makefile+1−1

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

sound/soc/intel/boards/bdw_rt286.c+6−0

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

sound/soc/intel/boards/bxt_da7219_max98357a.c+7−0

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

sound/soc/intel/boards/bytcr_wm5102.c+7−0

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

sound/soc/intel/boards/kbl_da7219_max98357a.c+7−0

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

sound/soc/intel/boards/kbl_da7219_max98927.c+7−0

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

sound/soc/intel/boards/sof_da7219_max98373.c+10−0

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

sound/soc/intel/boards/sof_es8336.c+10−0

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

sound/soc/intel/boards/sof_maxim_common.c+100−70

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

sound/soc/intel/boards/sof_maxim_common.h+9−12

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

sound/soc/intel/boards/sof_nau8825.c+10−0

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

sound/soc/intel/boards/sof_rt5682.c+135−37

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

sound/soc/intel/boards/sof_sdw.c+276−332

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

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

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

sound/soc/intel/boards/sof_sdw_cs_amp.c+47−0

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

sound/soc/intel/boards/sof_ssp_amp.c+9−0

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

sound/soc/intel/catpt/pcm.c+6−2

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

sound/soc/intel/common/soc-acpi-intel-adl-match.c+7−0

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

sound/soc/intel/common/soc-acpi-intel-jsl-match.c+12−0

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

sound/soc/intel/common/soc-acpi-intel-mtl-match.c+52−0

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

sound/soc/intel/common/soc-acpi-intel-rpl-match.c+69−0

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

sound/soc/intel/keembay/kmb_platform.c+1−3

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

sound/soc/intel/skylake/skl-messages.c+8−8

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

sound/soc/intel/skylake/skl-pcm.c+2−1

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

sound/soc/intel/skylake/skl.c+10−26

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

sound/soc/jz4740/jz4740-i2s.c+1−2

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

sound/soc/loongson/loongson_card.c+1−1

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

sound/soc/loongson/loongson_i2s.c+8−8

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

sound/soc/mediatek/Kconfig+20−0

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

sound/soc/mediatek/Makefile+1−0

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

sound/soc/mediatek/common/mtk-btcvsd.c+10−17

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

sound/soc/mediatek/mt7986/Makefile+9−0

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

sound/soc/mediatek/mt7986/mt7986-afe-common.h+49−0

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

sound/soc/mediatek/mt7986/mt7986-afe-pcm.c+622−0

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

sound/soc/mediatek/mt7986/mt7986-dai-etdm.c+411−0

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

sound/soc/mediatek/mt7986/mt7986-reg.h+196−0

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

sound/soc/mediatek/mt7986/mt7986-wm8960.c+196−0

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

sound/soc/mediatek/mt8173/mt8173-max98090.c+1−1

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

sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c+18−5

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

sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c+18−5

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

sound/soc/mediatek/mt8173/mt8173-rt5650.c+18−5

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

sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c+36−7

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

sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c+47−6

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

sound/soc/mediatek/mt8186/mt8186-afe-clk.c+0−2

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

sound/soc/mediatek/mt8186/mt8186-afe-pcm.c+1−3

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

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

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

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

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

sound/soc/mediatek/mt8188/mt8188-mt6359.c+16−11

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

sound/soc/mediatek/mt8195/mt8195-dai-etdm.c+31−25

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

sound/soc/meson/aiu-acodec-ctrl.c+2−2

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

sound/soc/meson/aiu-codec-ctrl.c+2−2

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

sound/soc/meson/aiu-fifo-i2s.c+3−0

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

sound/soc/meson/aiu-fifo-spdif.c+3−0

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

sound/soc/meson/aiu.c+0−6

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

sound/soc/meson/axg-frddr.c+2−2

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

sound/soc/meson/axg-pdm.c+9−9

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

sound/soc/meson/axg-spdifin.c+2−2

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

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

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

sound/soc/meson/axg-toddr.c+2−2

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

sound/soc/meson/g12a-toacodec.c+2−2

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

sound/soc/meson/g12a-tohdmitx.c+2−2

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

sound/soc/pxa/mmp-sspa.c+1−1

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

sound/soc/pxa/pxa-ssp.c+3−9

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

sound/soc/pxa/pxa2xx-i2s.c+5−12

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

sound/soc/qcom/apq8016_sbc.c+29−8

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

sound/soc/qcom/lpass-apq8016.c+0−4

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

sound/soc/qcom/lpass-cpu.c+25−15

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

sound/soc/qcom/lpass-ipq806x.c+0−1

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

sound/soc/qcom/lpass-platform.c+7−6

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

sound/soc/qcom/lpass-sc7180.c+1−4

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

sound/soc/qcom/lpass-sc7280.c+0−2

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

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

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

sound/soc/qcom/qdsp6/q6afe-dai.c+48−40

This diff is large: its 109 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/q6apm.h+0−2

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

sound/soc/qcom/qdsp6/q6asm-dai.c+5−1

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

sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c+0−3

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

sound/soc/qcom/sc7180.c+33−7

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

sound/soc/qcom/sc7280.c+27−7

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

sound/soc/qcom/sdm845.c+26−6

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

sound/soc/rockchip/rk3399_gru_sound.c+6−1

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

sound/soc/rockchip/rockchip_i2s.c+1−1

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

sound/soc/rockchip/rockchip_i2s_tdm.c+1−1

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

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

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

sound/soc/rockchip/rockchip_rt5645.c+17−5

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

sound/soc/rockchip/rockchip_spdif.c+1−1

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

sound/soc/samsung/aries_wm8994.c+7−3

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

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

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

sound/soc/samsung/littlemill.c+21−6

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

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

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

sound/soc/samsung/midas_wm1811.c+26−8

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

sound/soc/samsung/odroid.c+8−7

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

sound/soc/samsung/pcm.c+9−9

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

sound/soc/samsung/tm2_wm5110.c+7−3

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

sound/soc/sh/rcar/adg.c+55−13

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

sound/soc/sh/rcar/core.c+114−61

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

sound/soc/sh/rcar/rsnd.h+4−0

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

sound/soc/soc-acpi.c+73−0

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

sound/soc/soc-component.c+7−9

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

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

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

sound/soc/soc-core.c+194−79

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

sound/soc/soc-dai.c+36−19

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

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

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

sound/soc/soc-generic-dmaengine-pcm.c+9−9

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

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

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

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

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

sound/soc/soc-topology.c+5−4

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

sound/soc/sof/amd/Kconfig+19−1

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

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

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

sound/soc/sof/amd/acp-common.c+4−0

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

sound/soc/sof/amd/acp-dsp-offset.h+8−1

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

sound/soc/sof/amd/acp-ipc.c+30−0

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

sound/soc/sof/amd/acp-loader.c+39−3

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

sound/soc/sof/amd/acp-probes.c+147−0

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

sound/soc/sof/amd/acp.c+67−39

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

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

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

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

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

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

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

sound/soc/sof/amd/pci-vangogh.c+105−0

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

sound/soc/sof/amd/vangogh.c+162−0

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

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

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

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

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

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

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

sound/soc/sof/intel/hda-dai-ops.c+176−3

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

sound/soc/sof/intel/hda-dai.c+210−1

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

sound/soc/sof/intel/hda-mlink.c+38−7

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

sound/soc/sof/intel/hda-stream.c+8−60

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

sound/soc/sof/intel/hda.c+56−84

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

sound/soc/sof/intel/hda.h+21−0

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

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

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

sound/soc/sof/intel/lnl.c+188−0

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

sound/soc/sof/intel/mtl.c+12−11

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

sound/soc/sof/intel/mtl.h+20−2

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

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

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

sound/soc/sof/intel/pci-cnl.c+5−10

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

sound/soc/sof/intel/pci-icl.c+4−8

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

sound/soc/sof/intel/pci-lnl.c+71−0

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

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

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

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

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

sound/soc/sof/intel/pci-tgl.c+15−30

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

sound/soc/sof/intel/pci-tng.c+1−2

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

sound/soc/sof/intel/shim.h+1−0

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

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

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

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

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

sound/soc/sof/ipc3-pcm.c+17−0

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

sound/soc/sof/ipc3.c+2−5

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

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

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

sound/soc/sof/ipc4-topology.c+119−48

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

sound/soc/sof/ipc4-topology.h+2−2

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

sound/soc/sof/mediatek/mt8186/mt8186.c+23−17

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

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

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

sound/soc/sof/sof-client-probes.c+6−1

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

sound/soc/sof/topology.c+27−2

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

sound/soc/starfive/jh7110_tdm.c+10−11

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

sound/soc/sti/sti_uniperif.c+5−1

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

sound/soc/stm/stm32_i2s.c+1−1

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

sound/soc/stm/stm32_sai_sub.c+15−5

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

sound/soc/stm/stm32_spdifrx.c+1−1

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

sound/soc/sunxi/sun4i-codec.c+5−1

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

sound/soc/sunxi/sun4i-i2s.c+9−9

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

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

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

sound/soc/sunxi/sun50i-dmic.c+1−1

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

sound/soc/tegra/tegra20_ac97.c+6−7

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

sound/soc/tegra/tegra20_i2s.c+1−1

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

sound/soc/tegra/tegra20_spdif.c+1−1

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

sound/soc/tegra/tegra210_admaif.c+6−6

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

sound/soc/tegra/tegra210_sfc.c+30−1

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

sound/soc/tegra/tegra210_sfc.h+2−2

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

sound/soc/tegra/tegra30_i2s.c+1−1

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

sound/soc/ti/davinci-evm.c+1−12

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

sound/soc/ti/davinci-i2s.c+11−11

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

sound/soc/ti/davinci-mcasp.c+13−14

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

sound/soc/ti/omap-dmic.c+12−14

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

sound/soc/ti/omap-mcbsp.c+16−16

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

sound/soc/ti/omap-mcpdm.c+12−13

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

sound/soc/uniphier/aio-cpu.c+134−27

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

sound/soc/uniphier/aio-ld11.c+9−53

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

sound/soc/uniphier/aio-pxs2.c+7−48

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

sound/soc/uniphier/aio.h+6−4

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

sound/soc/ux500/ux500_msp_dai.c+1−1

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

sound/sparc/amd7930.c+1−2

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

sound/sparc/cs4231.c+1−1

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

sound/sparc/dbri.c+1−1

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

sound/usb/bcd2000/bcd2000.c+2−2

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

sound/usb/endpoint.c+27−13

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

sound/usb/endpoint.h+0−1

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

sound/usb/media.c+2−2

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

sound/usb/midi2.c+8−7

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

sound/usb/stream.c+10−1

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

sound/xen/xen_snd_front_alsa.c+15−49

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

tools/testing/kunit/configs/all_tests.config+5−0

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

tools/testing/selftests/alsa/pcm-test.c+5−3

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t